Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4240da59
authored
Dec 22, 2021
by
hschlueter
Committed by
tonihei
Jan 04, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add TransformationRequest.
PiperOrigin-RevId: 417786661
parent
5c8b5e5b
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
396 additions
and
96 deletions
RELEASENOTES.md
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/RepeatedTranscodeTransformationTest.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/SefTransformationTest.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/SetTransformationMatrixTransformationTest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioSamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformation.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerBaseRenderer.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoSamplePipeline.java
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformationRequestTest.java
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java
RELEASENOTES.md
View file @
4240da59
...
...
@@ -77,6 +77,7 @@
*
Increase required min API version to 21.
*
`TransformationException`
is now used to describe errors that occur
during a transformation.
*
Add
`TransformationRequest`
for specifying the transformation options.
*
MediaSession extension:
*
Remove deprecated call to
`onStop(/* reset= */ true)`
and provide an
opt-out flag for apps that don't want to clear the playlist on stop.
...
...
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/RepeatedTranscodeTransformationTest.java
View file @
4240da59
...
...
@@ -22,6 +22,7 @@ import android.content.Context;
import
android.graphics.Matrix
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.transformer.TransformationRequest
;
import
com.google.android.exoplayer2.transformer.Transformer
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
java.util.HashSet
;
...
...
@@ -43,9 +44,12 @@ public final class RepeatedTranscodeTransformationTest {
transformationMatrix
.
postTranslate
((
float
)
0.1
,
(
float
)
0.1
);
Transformer
transformer
=
new
Transformer
.
Builder
(
context
)
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setVideoMimeType
(
MimeTypes
.
VIDEO_H265
)
.
setTransformationMatrix
(
transformationMatrix
)
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AMR_NB
)
.
build
())
.
build
();
Set
<
Long
>
differentOutputSizesBytes
=
new
HashSet
<>();
...
...
@@ -74,9 +78,12 @@ public final class RepeatedTranscodeTransformationTest {
transformationMatrix
.
postTranslate
((
float
)
0.1
,
(
float
)
0.1
);
Transformer
transformer
=
new
Transformer
.
Builder
(
context
)
.
setRemoveAudio
(
true
)
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setVideoMimeType
(
MimeTypes
.
VIDEO_H265
)
.
setTransformationMatrix
(
transformationMatrix
)
.
setRemoveAudio
(
true
)
.
build
()
)
.
build
();
Set
<
Long
>
differentOutputSizesBytes
=
new
HashSet
<>();
...
...
@@ -103,8 +110,11 @@ public final class RepeatedTranscodeTransformationTest {
Context
context
=
ApplicationProvider
.
getApplicationContext
();
Transformer
transcodingTransformer
=
new
Transformer
.
Builder
(
context
)
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AMR_NB
)
.
setRemoveVideo
(
true
)
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AMR_NB
)
.
build
())
.
build
();
Set
<
Long
>
differentOutputSizesBytes
=
new
HashSet
<>();
...
...
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/SefTransformationTest.java
View file @
4240da59
...
...
@@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.transformer.mh.AndroidTestUtil.runTr
import
android.content.Context
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.transformer.TransformationRequest
;
import
com.google.android.exoplayer2.transformer.Transformer
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
...
...
@@ -32,7 +33,10 @@ public class SefTransformationTest {
public
void
sefTransform
()
throws
Exception
{
Context
context
=
ApplicationProvider
.
getApplicationContext
();
Transformer
transformer
=
new
Transformer
.
Builder
(
context
).
setFlattenForSlowMotion
(
true
).
build
();
new
Transformer
.
Builder
(
context
)
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
().
setFlattenForSlowMotion
(
true
).
build
())
.
build
();
runTransformer
(
context
,
/* testId = */
"sefTransform"
,
...
...
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/SetTransformationMatrixTransformationTest.java
View file @
4240da59
...
...
@@ -22,6 +22,7 @@ import android.content.Context;
import
android.graphics.Matrix
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.transformer.TransformationRequest
;
import
com.google.android.exoplayer2.transformer.Transformer
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
...
...
@@ -35,7 +36,12 @@ public class SetTransformationMatrixTransformationTest {
Matrix
transformationMatrix
=
new
Matrix
();
transformationMatrix
.
postTranslate
(
/* dx= */
.
2
f
,
/* dy= */
.
1
f
);
Transformer
transformer
=
new
Transformer
.
Builder
(
context
).
setTransformationMatrix
(
transformationMatrix
).
build
();
new
Transformer
.
Builder
(
context
)
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setTransformationMatrix
(
transformationMatrix
)
.
build
())
.
build
();
runTransformer
(
context
,
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioSamplePipeline.java
View file @
4240da59
...
...
@@ -43,7 +43,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private
static
final
int
DEFAULT_ENCODER_BITRATE
=
128
*
1024
;
private
final
Format
inputFormat
;
private
final
Transformation
transformation
;
private
final
Transformation
Request
transformationRequest
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
decoder
;
...
...
@@ -66,12 +66,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public
AudioSamplePipeline
(
Format
inputFormat
,
Transformation
transformation
,
Transformation
Request
transformationRequest
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
)
throws
TransformationException
{
this
.
inputFormat
=
inputFormat
;
this
.
transformation
=
transformation
;
this
.
transformation
Request
=
transformationRequest
;
this
.
encoderFactory
=
encoderFactory
;
decoderInputBuffer
=
new
DecoderInputBuffer
(
DecoderInputBuffer
.
BUFFER_REPLACEMENT_MODE_DISABLED
);
...
...
@@ -294,7 +294,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
decoderOutputFormat
.
sampleRate
,
decoderOutputFormat
.
channelCount
,
decoderOutputFormat
.
pcmEncoding
);
if
(
transformation
.
flattenForSlowMotion
)
{
if
(
transformation
Request
.
flattenForSlowMotion
)
{
try
{
outputAudioFormat
=
sonicAudioProcessor
.
configure
(
outputAudioFormat
);
flushSonicAndSetSpeed
(
currentSpeed
);
...
...
@@ -310,9 +310,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
encoderFactory
.
createForAudioEncoding
(
new
Format
.
Builder
()
.
setSampleMimeType
(
transformation
.
audioMimeType
==
null
transformation
Request
.
audioMimeType
==
null
?
inputFormat
.
sampleMimeType
:
transformation
.
audioMimeType
)
:
transformation
Request
.
audioMimeType
)
.
setSampleRate
(
outputAudioFormat
.
sampleRate
)
.
setChannelCount
(
outputAudioFormat
.
channelCount
)
.
setAverageBitrate
(
DEFAULT_ENCODER_BITRATE
)
...
...
@@ -322,7 +322,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
private
boolean
isSpeedChanging
(
BufferInfo
bufferInfo
)
{
if
(!
transformation
.
flattenForSlowMotion
)
{
if
(!
transformation
Request
.
flattenForSlowMotion
)
{
return
false
;
}
float
newSpeed
=
speedProvider
.
getSpeed
(
bufferInfo
.
presentationTimeUs
);
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformation.java
deleted
100644 → 0
View file @
5c8b5e5b
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
android.graphics.Matrix
;
import
androidx.annotation.Nullable
;
/** A media transformation configuration. */
/* package */
final
class
Transformation
{
public
final
boolean
removeAudio
;
public
final
boolean
removeVideo
;
public
final
boolean
flattenForSlowMotion
;
public
final
int
outputHeight
;
public
final
Matrix
transformationMatrix
;
public
final
String
containerMimeType
;
@Nullable
public
final
String
audioMimeType
;
@Nullable
public
final
String
videoMimeType
;
public
Transformation
(
boolean
removeAudio
,
boolean
removeVideo
,
boolean
flattenForSlowMotion
,
int
outputHeight
,
Matrix
transformationMatrix
,
String
containerMimeType
,
@Nullable
String
audioMimeType
,
@Nullable
String
videoMimeType
)
{
this
.
removeAudio
=
removeAudio
;
this
.
removeVideo
=
removeVideo
;
this
.
flattenForSlowMotion
=
flattenForSlowMotion
;
this
.
outputHeight
=
outputHeight
;
this
.
transformationMatrix
=
transformationMatrix
;
this
.
containerMimeType
=
containerMimeType
;
this
.
audioMimeType
=
audioMimeType
;
this
.
videoMimeType
=
videoMimeType
;
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java
0 → 100644
View file @
4240da59
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
android.graphics.Matrix
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.extractor.mp4.Mp4Extractor
;
import
com.google.android.exoplayer2.source.MediaSourceFactory
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.Util
;
/** A media transformation request. */
public
final
class
TransformationRequest
{
/** A builder for {@link TransformationRequest} instances. */
public
static
final
class
Builder
{
private
Matrix
transformationMatrix
;
private
boolean
flattenForSlowMotion
;
private
int
outputHeight
;
@Nullable
private
String
audioMimeType
;
@Nullable
private
String
videoMimeType
;
/**
* Creates a new instance with default values.
*
* <p>Use {@link TransformationRequest#buildUpon()} to obtain a builder representing an existing
* {@link TransformationRequest}.
*/
public
Builder
()
{
transformationMatrix
=
new
Matrix
();
outputHeight
=
C
.
LENGTH_UNSET
;
}
private
Builder
(
TransformationRequest
transformationRequest
)
{
this
.
transformationMatrix
=
transformationRequest
.
transformationMatrix
;
this
.
flattenForSlowMotion
=
transformationRequest
.
flattenForSlowMotion
;
this
.
outputHeight
=
transformationRequest
.
outputHeight
;
this
.
audioMimeType
=
transformationRequest
.
audioMimeType
;
this
.
videoMimeType
=
transformationRequest
.
videoMimeType
;
}
/**
* Sets the transformation matrix. The default value is to apply no change.
*
* <p>This can be used to perform operations supported by {@link Matrix}, like scaling and
* rotating the video.
*
* <p>For now, resolution will not be affected by this method.
*
* @param transformationMatrix The transformation to apply to video frames.
* @return This builder.
*/
public
Builder
setTransformationMatrix
(
Matrix
transformationMatrix
)
{
// TODO(b/201293185): After {@link #setResolution} supports arbitrary resolutions,
// allow transformations to change the resolution, by scaling to the appropriate min/max
// values. This will also be required to create the VertexTransformation class, in order to
// have aspect ratio helper methods (which require resolution to change).
this
.
transformationMatrix
=
transformationMatrix
;
return
this
;
}
/**
* Sets whether the input should be flattened for media containing slow motion markers. The
* transformed output is obtained by removing the slow motion metadata and by actually slowing
* down the parts of the video and audio streams defined in this metadata. The default value for
* {@code flattenForSlowMotion} is {@code false}.
*
* <p>Only Samsung Extension Format (SEF) slow motion metadata type is supported. The
* transformation has no effect if the input does not contain this metadata type.
*
* <p>For SEF slow motion media, the following assumptions are made on the input:
*
* <ul>
* <li>The input container format is (unfragmented) MP4.
* <li>The input contains an AVC video elementary stream with temporal SVC.
* <li>The recording frame rate of the video is 120 or 240 fps.
* </ul>
*
* <p>If specifying a {@link MediaSourceFactory} using {@link
* Transformer.Builder#setMediaSourceFactory(MediaSourceFactory)}, make sure that {@link
* Mp4Extractor#FLAG_READ_SEF_DATA} is set on the {@link Mp4Extractor} used. Otherwise, the slow
* motion metadata will be ignored and the input won't be flattened.
*
* @param flattenForSlowMotion Whether to flatten for slow motion.
* @return This builder.
*/
public
Builder
setFlattenForSlowMotion
(
boolean
flattenForSlowMotion
)
{
this
.
flattenForSlowMotion
=
flattenForSlowMotion
;
return
this
;
}
/**
* Sets the output resolution using the output height. The default value is the same height as
* the input. Output width will scale to preserve the input video's aspect ratio.
*
* <p>For now, only "popular" heights like 144, 240, 360, 480, 720, 1080, 1440, or 2160 are
* supported, to ensure compatibility on different devices.
*
* <p>For example, a 1920x1440 video can be scaled to 640x480 by calling setResolution(480).
*
* @param outputHeight The output height in pixels.
* @return This builder.
*/
public
Builder
setResolution
(
int
outputHeight
)
{
// TODO(b/201293185): Restructure to input a Presentation class.
// TODO(b/201293185): Check encoder codec capabilities in order to allow arbitrary
// resolutions and reasonable fallbacks.
if
(
outputHeight
!=
144
&&
outputHeight
!=
240
&&
outputHeight
!=
360
&&
outputHeight
!=
480
&&
outputHeight
!=
720
&&
outputHeight
!=
1080
&&
outputHeight
!=
1440
&&
outputHeight
!=
2160
)
{
throw
new
IllegalArgumentException
(
"Please use a height of 144, 240, 360, 480, 720, 1080, 1440, or 2160."
);
}
this
.
outputHeight
=
outputHeight
;
return
this
;
}
/**
* Sets the video MIME type of the output. The default value is to use the same MIME type as the
* input. Supported values are:
*
* <ul>
* <li>{@link MimeTypes#VIDEO_H263}
* <li>{@link MimeTypes#VIDEO_H264}
* <li>{@link MimeTypes#VIDEO_H265} from API level 24
* <li>{@link MimeTypes#VIDEO_MP4V}
* </ul>
*
* @param videoMimeType The MIME type of the video samples in the output.
* @return This builder.
*/
public
Builder
setVideoMimeType
(
String
videoMimeType
)
{
// TODO(b/209469847): Validate videoMimeType here once deprecated
// Transformer.Builder#setOuputMimeType(String) has been removed.
this
.
videoMimeType
=
videoMimeType
;
return
this
;
}
/**
* Sets the audio MIME type of the output. The default value is to use the same MIME type as the
* input. Supported values are:
*
* <ul>
* <li>{@link MimeTypes#AUDIO_AAC}
* <li>{@link MimeTypes#AUDIO_AMR_NB}
* <li>{@link MimeTypes#AUDIO_AMR_WB}
* </ul>
*
* @param audioMimeType The MIME type of the audio samples in the output.
* @return This builder.
*/
public
Builder
setAudioMimeType
(
String
audioMimeType
)
{
// TODO(b/209469847): Validate audioMimeType here once deprecated
// Transformer.Builder#setOuputMimeType(String) has been removed.
this
.
audioMimeType
=
audioMimeType
;
return
this
;
}
/** Builds a {@link TransformationRequest} instance. */
public
TransformationRequest
build
()
{
return
new
TransformationRequest
(
transformationMatrix
,
flattenForSlowMotion
,
outputHeight
,
audioMimeType
,
videoMimeType
);
}
}
public
final
Matrix
transformationMatrix
;
public
final
boolean
flattenForSlowMotion
;
public
final
int
outputHeight
;
@Nullable
public
final
String
audioMimeType
;
@Nullable
public
final
String
videoMimeType
;
private
TransformationRequest
(
Matrix
transformationMatrix
,
boolean
flattenForSlowMotion
,
int
outputHeight
,
@Nullable
String
audioMimeType
,
@Nullable
String
videoMimeType
)
{
this
.
transformationMatrix
=
transformationMatrix
;
this
.
flattenForSlowMotion
=
flattenForSlowMotion
;
this
.
outputHeight
=
outputHeight
;
this
.
audioMimeType
=
audioMimeType
;
this
.
videoMimeType
=
videoMimeType
;
}
@Override
public
boolean
equals
(
@Nullable
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(!(
o
instanceof
TransformationRequest
))
{
return
false
;
}
TransformationRequest
that
=
(
TransformationRequest
)
o
;
return
transformationMatrix
.
equals
(
that
.
transformationMatrix
)
&&
flattenForSlowMotion
==
that
.
flattenForSlowMotion
&&
outputHeight
==
that
.
outputHeight
&&
Util
.
areEqual
(
audioMimeType
,
that
.
audioMimeType
)
&&
Util
.
areEqual
(
videoMimeType
,
that
.
videoMimeType
);
}
@Override
public
int
hashCode
()
{
int
result
=
transformationMatrix
.
hashCode
();
result
=
31
*
result
+
(
flattenForSlowMotion
?
1
:
0
);
result
=
31
*
result
+
outputHeight
;
result
=
31
*
result
+
(
audioMimeType
!=
null
?
audioMimeType
.
hashCode
()
:
0
);
result
=
31
*
result
+
(
videoMimeType
!=
null
?
videoMimeType
.
hashCode
()
:
0
);
return
result
;
}
/**
* Returns a new {@link TransformationRequest.Builder} initialized with the values of this
* instance.
*/
public
Builder
buildUpon
()
{
return
new
Builder
(
this
);
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
View file @
4240da59
This diff is collapsed.
Click to expand it.
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java
View file @
4240da59
...
...
@@ -39,10 +39,10 @@ import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;
public
TransformerAudioRenderer
(
MuxerWrapper
muxerWrapper
,
TransformerMediaClock
mediaClock
,
Transformation
transformation
,
Transformation
Request
transformationRequest
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
)
{
super
(
C
.
TRACK_TYPE_AUDIO
,
muxerWrapper
,
mediaClock
,
transformation
);
super
(
C
.
TRACK_TYPE_AUDIO
,
muxerWrapper
,
mediaClock
,
transformation
Request
);
this
.
encoderFactory
=
encoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
decoderInputBuffer
=
...
...
@@ -69,7 +69,8 @@ import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;
Format
inputFormat
=
checkNotNull
(
formatHolder
.
format
);
if
(
shouldTranscode
(
inputFormat
))
{
samplePipeline
=
new
AudioSamplePipeline
(
inputFormat
,
transformation
,
encoderFactory
,
decoderFactory
);
new
AudioSamplePipeline
(
inputFormat
,
transformationRequest
,
encoderFactory
,
decoderFactory
);
}
else
{
samplePipeline
=
new
PassthroughSamplePipeline
(
inputFormat
);
}
...
...
@@ -77,11 +78,11 @@ import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;
}
private
boolean
shouldTranscode
(
Format
inputFormat
)
{
if
(
transformation
.
audioMimeType
!=
null
&&
!
transformation
.
audioMimeType
.
equals
(
inputFormat
.
sampleMimeType
))
{
if
(
transformation
Request
.
audioMimeType
!=
null
&&
!
transformation
Request
.
audioMimeType
.
equals
(
inputFormat
.
sampleMimeType
))
{
return
true
;
}
if
(
transformation
.
flattenForSlowMotion
&&
isSlowMotion
(
inputFormat
))
{
if
(
transformation
Request
.
flattenForSlowMotion
&&
isSlowMotion
(
inputFormat
))
{
return
true
;
}
return
false
;
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerBaseRenderer.java
View file @
4240da59
...
...
@@ -38,7 +38,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
protected
final
MuxerWrapper
muxerWrapper
;
protected
final
TransformerMediaClock
mediaClock
;
protected
final
Transformation
transformation
;
protected
final
Transformation
Request
transformationRequest
;
protected
boolean
isRendererStarted
;
protected
boolean
muxerWrapperTrackAdded
;
...
...
@@ -50,11 +50,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
int
trackType
,
MuxerWrapper
muxerWrapper
,
TransformerMediaClock
mediaClock
,
Transformation
transformation
)
{
Transformation
Request
transformationRequest
)
{
super
(
trackType
);
this
.
muxerWrapper
=
muxerWrapper
;
this
.
mediaClock
=
mediaClock
;
this
.
transformation
=
transformation
;
this
.
transformation
Request
=
transformationRequest
;
}
@Override
...
...
@@ -65,14 +65,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
return
RendererCapabilities
.
create
(
C
.
FORMAT_UNSUPPORTED_TYPE
);
}
else
if
((
MimeTypes
.
isAudio
(
sampleMimeType
)
&&
muxerWrapper
.
supportsSampleMimeType
(
transformation
.
audioMimeType
==
null
transformation
Request
.
audioMimeType
==
null
?
sampleMimeType
:
transformation
.
audioMimeType
))
:
transformation
Request
.
audioMimeType
))
||
(
MimeTypes
.
isVideo
(
sampleMimeType
)
&&
muxerWrapper
.
supportsSampleMimeType
(
transformation
.
videoMimeType
==
null
transformation
Request
.
videoMimeType
==
null
?
sampleMimeType
:
transformation
.
videoMimeType
)))
{
:
transformation
Request
.
videoMimeType
)))
{
return
RendererCapabilities
.
create
(
C
.
FORMAT_HANDLED
);
}
else
{
return
RendererCapabilities
.
create
(
C
.
FORMAT_UNSUPPORTED_SUBTYPE
);
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java
View file @
4240da59
...
...
@@ -45,11 +45,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
Context
context
,
MuxerWrapper
muxerWrapper
,
TransformerMediaClock
mediaClock
,
Transformation
transformation
,
Transformation
Request
transformationRequest
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
Transformer
.
DebugViewProvider
debugViewProvider
)
{
super
(
C
.
TRACK_TYPE_VIDEO
,
muxerWrapper
,
mediaClock
,
transformation
);
super
(
C
.
TRACK_TYPE_VIDEO
,
muxerWrapper
,
mediaClock
,
transformation
Request
);
this
.
context
=
context
;
this
.
encoderFactory
=
encoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
...
...
@@ -81,29 +81,29 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
new
VideoSamplePipeline
(
context
,
inputFormat
,
transformation
,
transformation
Request
,
encoderFactory
,
decoderFactory
,
debugViewProvider
);
}
else
{
samplePipeline
=
new
PassthroughSamplePipeline
(
inputFormat
);
}
if
(
transformation
.
flattenForSlowMotion
)
{
if
(
transformation
Request
.
flattenForSlowMotion
)
{
sefSlowMotionFlattener
=
new
SefSlowMotionFlattener
(
inputFormat
);
}
return
true
;
}
private
boolean
shouldTranscode
(
Format
inputFormat
)
{
if
(
transformation
.
videoMimeType
!=
null
&&
!
transformation
.
videoMimeType
.
equals
(
inputFormat
.
sampleMimeType
))
{
if
(
transformation
Request
.
videoMimeType
!=
null
&&
!
transformation
Request
.
videoMimeType
.
equals
(
inputFormat
.
sampleMimeType
))
{
return
true
;
}
if
(
transformation
.
outputHeight
!=
C
.
LENGTH_UNSET
&&
transformation
.
outputHeight
!=
inputFormat
.
height
)
{
if
(
transformation
Request
.
outputHeight
!=
C
.
LENGTH_UNSET
&&
transformation
Request
.
outputHeight
!=
inputFormat
.
height
)
{
return
true
;
}
if
(!
transformation
.
transformationMatrix
.
isIdentity
())
{
if
(!
transformation
Request
.
transformationMatrix
.
isIdentity
())
{
return
true
;
}
return
false
;
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoSamplePipeline.java
View file @
4240da59
...
...
@@ -50,7 +50,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public
VideoSamplePipeline
(
Context
context
,
Format
inputFormat
,
Transformation
transformation
,
Transformation
Request
transformationRequest
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
Transformer
.
DebugViewProvider
debugViewProvider
)
...
...
@@ -63,10 +63,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// TODO(internal b/209781577): Think about which edge length should be set for portrait videos.
int
outputWidth
=
inputFormat
.
width
;
int
outputHeight
=
inputFormat
.
height
;
if
(
transformation
.
outputHeight
!=
C
.
LENGTH_UNSET
&&
transformation
.
outputHeight
!=
inputFormat
.
height
)
{
outputWidth
=
inputFormat
.
width
*
transformation
.
outputHeight
/
inputFormat
.
height
;
outputHeight
=
transformation
.
outputHeight
;
if
(
transformation
Request
.
outputHeight
!=
C
.
LENGTH_UNSET
&&
transformation
Request
.
outputHeight
!=
inputFormat
.
height
)
{
outputWidth
=
inputFormat
.
width
*
transformation
Request
.
outputHeight
/
inputFormat
.
height
;
outputHeight
=
transformation
Request
.
outputHeight
;
}
if
(
inputFormat
.
height
>
inputFormat
.
width
)
{
...
...
@@ -83,7 +83,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// them back for improved encoder compatibility.
// TODO(internal b/201293185): After fragment shader transformations are implemented, put
// postrotation in a later vertex shader.
transformation
.
transformationMatrix
.
postRotate
(
outputRotationDegrees
);
transformation
Request
.
transformationMatrix
.
postRotate
(
outputRotationDegrees
);
encoder
=
encoderFactory
.
createForVideoEncoding
(
...
...
@@ -92,19 +92,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
.
setHeight
(
outputHeight
)
.
setRotationDegrees
(
0
)
.
setSampleMimeType
(
transformation
.
videoMimeType
!=
null
?
transformation
.
videoMimeType
transformation
Request
.
videoMimeType
!=
null
?
transformation
Request
.
videoMimeType
:
inputFormat
.
sampleMimeType
)
.
build
());
if
(
inputFormat
.
height
!=
outputHeight
||
inputFormat
.
width
!=
outputWidth
||
!
transformation
.
transformationMatrix
.
isIdentity
())
{
||
!
transformation
Request
.
transformationMatrix
.
isIdentity
())
{
frameEditor
=
FrameEditor
.
create
(
context
,
outputWidth
,
outputHeight
,
transformation
.
transformationMatrix
,
transformation
Request
.
transformationMatrix
,
/* outputSurface= */
checkNotNull
(
encoder
.
getInputSurface
()),
debugViewProvider
);
}
...
...
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformationRequestTest.java
0 → 100644
View file @
4240da59
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
android.graphics.Matrix
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit test for {@link TransformationRequest}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
TransformationRequestTest
{
@Test
public
void
buildUponTransformationRequest_createsEqualTransformationRequest
()
{
TransformationRequest
request
=
createTestTransformationRequest
();
assertThat
(
request
.
buildUpon
().
build
()).
isEqualTo
(
request
);
}
private
static
TransformationRequest
createTestTransformationRequest
()
{
Matrix
transformationMatrix
=
new
Matrix
();
transformationMatrix
.
preRotate
(
36
);
transformationMatrix
.
postTranslate
((
float
)
0.5
,
(
float
)
-
0.2
);
return
new
TransformationRequest
.
Builder
()
.
setFlattenForSlowMotion
(
true
)
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AAC
)
.
setVideoMimeType
(
MimeTypes
.
VIDEO_H264
)
.
setTransformationMatrix
(
transformationMatrix
)
.
build
();
}
}
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java
View file @
4240da59
...
...
@@ -51,4 +51,36 @@ public class TransformerBuilderTest {
IllegalStateException
.
class
,
()
->
new
Transformer
.
Builder
(
context
).
setRemoveAudio
(
true
).
setRemoveVideo
(
true
).
build
());
}
// TODO(b/209469847): Move this test to TransformationRequestBuilderTest once deprecated
// Transformer.Builder#setOuputMimeType(String) has been removed.
@Test
public
void
build_withUnsupportedAudioMimeType_throws
()
{
Context
context
=
ApplicationProvider
.
getApplicationContext
();
TransformationRequest
transformationRequest
=
new
TransformationRequest
.
Builder
().
setAudioMimeType
(
MimeTypes
.
AUDIO_UNKNOWN
).
build
();
assertThrows
(
IllegalStateException
.
class
,
()
->
new
Transformer
.
Builder
(
context
)
.
setTransformationRequest
(
transformationRequest
)
.
build
());
}
// TODO(b/209469847): Move this test to TransformationRequestBuilderTest once deprecated
// Transformer.Builder#setOuputMimeType(String) has been removed.
@Test
public
void
build_withUnsupportedVideoMimeType_throws
()
{
Context
context
=
ApplicationProvider
.
getApplicationContext
();
TransformationRequest
transformationRequest
=
new
TransformationRequest
.
Builder
().
setVideoMimeType
(
MimeTypes
.
VIDEO_UNKNOWN
).
build
();
assertThrows
(
IllegalStateException
.
class
,
()
->
new
Transformer
.
Builder
(
context
)
.
setTransformationRequest
(
transformationRequest
)
.
build
());
}
}
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java
View file @
4240da59
...
...
@@ -224,9 +224,10 @@ public final class TransformerTest {
public
void
startTransformation_flattenForSlowMotion_completesSuccessfully
()
throws
Exception
{
Transformer
transformer
=
new
Transformer
.
Builder
(
context
)
.
setFlattenForSlowMotion
(
true
)
.
setClock
(
clock
)
.
setMuxerFactory
(
new
TestMuxerFactory
())
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
().
setFlattenForSlowMotion
(
true
).
build
())
.
build
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
URI_PREFIX
+
FILE_WITH_SEF_SLOW_MOTION
);
...
...
@@ -243,7 +244,10 @@ public final class TransformerTest {
new
Transformer
.
Builder
(
context
)
.
setClock
(
clock
)
.
setMuxerFactory
(
new
TestMuxerFactory
())
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AMR_WB
)
// unsupported encoder MIME type
.
build
())
.
build
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
URI_PREFIX
+
FILE_AUDIO_ONLY
);
...
...
@@ -262,7 +266,10 @@ public final class TransformerTest {
new
Transformer
.
Builder
(
context
)
.
setClock
(
clock
)
.
setMuxerFactory
(
new
TestMuxerFactory
())
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setAudioMimeType
(
MimeTypes
.
AUDIO_AAC
)
// supported encoder MIME type
.
build
())
.
build
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
URI_PREFIX
+
FILE_WITH_ALL_SAMPLE_FORMATS_UNSUPPORTED
);
...
...
@@ -281,7 +288,10 @@ public final class TransformerTest {
new
Transformer
.
Builder
(
context
)
.
setClock
(
clock
)
.
setMuxerFactory
(
new
TestMuxerFactory
())
.
setTransformationRequest
(
new
TransformationRequest
.
Builder
()
.
setVideoMimeType
(
MimeTypes
.
VIDEO_H263
)
// unsupported encoder MIME type
.
build
())
.
build
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
URI_PREFIX
+
FILE_VIDEO_ONLY
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment