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
b410a922
authored
May 03, 2022
by
hschlueter
Committed by
Ian Baker
May 09, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Introduce GlEffect interface for effect specification.
PiperOrigin-RevId: 446143537
parent
90ce9a67
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
159 additions
and
121 deletions
demos/transformer/src/main/java/androidx/media3/demo/transformer/ConfigurationActivity.java
demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java
demos/transformer/src/main/res/layout/configuration_activity.xml
demos/transformer/src/main/res/values/strings.xml
libraries/transformer/src/androidTest/java/androidx/media3/transformer/FrameProcessorChainPixelTest.java
libraries/transformer/src/androidTest/java/androidx/media3/transformer/FrameProcessorChainTest.java
libraries/transformer/src/main/java/androidx/media3/transformer/FrameProcessorChain.java
libraries/transformer/src/main/java/androidx/media3/transformer/GlEffect.java
libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java
libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java
demos/transformer/src/main/java/androidx/media3/demo/transformer/ConfigurationActivity.java
View file @
b410a922
...
@@ -58,7 +58,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -58,7 +58,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
public
static
final
String
ENABLE_FALLBACK
=
"enable_fallback"
;
public
static
final
String
ENABLE_FALLBACK
=
"enable_fallback"
;
public
static
final
String
ENABLE_REQUEST_SDR_TONE_MAPPING
=
"enable_request_sdr_tone_mapping"
;
public
static
final
String
ENABLE_REQUEST_SDR_TONE_MAPPING
=
"enable_request_sdr_tone_mapping"
;
public
static
final
String
ENABLE_HDR_EDITING
=
"enable_hdr_editing"
;
public
static
final
String
ENABLE_HDR_EDITING
=
"enable_hdr_editing"
;
public
static
final
String
DEMO_
FRAME_PROCESSORS_SELECTIONS
=
"demo_frame_processor
s_selections"
;
public
static
final
String
DEMO_
EFFECTS_SELECTIONS
=
"demo_effect
s_selections"
;
public
static
final
String
PERIODIC_VIGNETTE_CENTER_X
=
"periodic_vignette_center_x"
;
public
static
final
String
PERIODIC_VIGNETTE_CENTER_X
=
"periodic_vignette_center_x"
;
public
static
final
String
PERIODIC_VIGNETTE_CENTER_Y
=
"periodic_vignette_center_y"
;
public
static
final
String
PERIODIC_VIGNETTE_CENTER_Y
=
"periodic_vignette_center_y"
;
public
static
final
String
PERIODIC_VIGNETTE_INNER_RADIUS
=
"periodic_vignette_inner_radius"
;
public
static
final
String
PERIODIC_VIGNETTE_INNER_RADIUS
=
"periodic_vignette_inner_radius"
;
...
@@ -91,7 +91,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -91,7 +91,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"DASH stream with non-square pixels"
,
"DASH stream with non-square pixels"
,
"MP4 with HDR (HDR10) H265 video (encoding may fail)"
,
"MP4 with HDR (HDR10) H265 video (encoding may fail)"
,
};
};
private
static
final
String
[]
DEMO_
FRAME_PROCESSOR
S
=
{
private
static
final
String
[]
DEMO_
EFFECT
S
=
{
"Dizzy crop"
,
"Periodic vignette"
,
"3D spin"
,
"Overlay logo & timer"
,
"Zoom in start"
"Dizzy crop"
,
"Periodic vignette"
,
"3D spin"
,
"Overlay logo & timer"
,
"Zoom in start"
};
};
private
static
final
int
PERIODIC_VIGNETTE_INDEX
=
1
;
private
static
final
int
PERIODIC_VIGNETTE_INDEX
=
1
;
...
@@ -111,8 +111,8 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -111,8 +111,8 @@ public final class ConfigurationActivity extends AppCompatActivity {
private
@MonotonicNonNull
CheckBox
enableFallbackCheckBox
;
private
@MonotonicNonNull
CheckBox
enableFallbackCheckBox
;
private
@MonotonicNonNull
CheckBox
enableRequestSdrToneMappingCheckBox
;
private
@MonotonicNonNull
CheckBox
enableRequestSdrToneMappingCheckBox
;
private
@MonotonicNonNull
CheckBox
enableHdrEditingCheckBox
;
private
@MonotonicNonNull
CheckBox
enableHdrEditingCheckBox
;
private
@MonotonicNonNull
Button
selectDemo
FrameProcessor
sButton
;
private
@MonotonicNonNull
Button
selectDemo
Effect
sButton
;
private
boolean
@MonotonicNonNull
[]
demo
FrameProcessor
sSelections
;
private
boolean
@MonotonicNonNull
[]
demo
Effect
sSelections
;
private
int
inputUriPosition
;
private
int
inputUriPosition
;
private
float
periodicVignetteCenterX
;
private
float
periodicVignetteCenterX
;
private
float
periodicVignetteCenterY
;
private
float
periodicVignetteCenterY
;
...
@@ -187,9 +187,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -187,9 +187,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
findViewById
(
R
.
id
.
request_sdr_tone_mapping
).
setEnabled
(
isRequestSdrToneMappingSupported
());
findViewById
(
R
.
id
.
request_sdr_tone_mapping
).
setEnabled
(
isRequestSdrToneMappingSupported
());
enableHdrEditingCheckBox
=
findViewById
(
R
.
id
.
hdr_editing_checkbox
);
enableHdrEditingCheckBox
=
findViewById
(
R
.
id
.
hdr_editing_checkbox
);
demo
FrameProcessorsSelections
=
new
boolean
[
DEMO_FRAME_PROCESSOR
S
.
length
];
demo
EffectsSelections
=
new
boolean
[
DEMO_EFFECT
S
.
length
];
selectDemo
FrameProcessorsButton
=
findViewById
(
R
.
id
.
select_demo_frameprocessor
s_button
);
selectDemo
EffectsButton
=
findViewById
(
R
.
id
.
select_demo_effect
s_button
);
selectDemo
FrameProcessorsButton
.
setOnClickListener
(
this
::
selectFrameProcessor
s
);
selectDemo
EffectsButton
.
setOnClickListener
(
this
::
selectDemoEffect
s
);
}
}
@Override
@Override
...
@@ -220,7 +220,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -220,7 +220,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"enableFallbackCheckBox"
,
"enableFallbackCheckBox"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableHdrEditingCheckBox"
,
"enableHdrEditingCheckBox"
,
"demo
FrameProcessor
sSelections"
"demo
Effect
sSelections"
})
})
private
void
startTransformation
(
View
view
)
{
private
void
startTransformation
(
View
view
)
{
Intent
transformerIntent
=
new
Intent
(
/* packageContext= */
this
,
TransformerActivity
.
class
);
Intent
transformerIntent
=
new
Intent
(
/* packageContext= */
this
,
TransformerActivity
.
class
);
...
@@ -255,7 +255,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -255,7 +255,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
bundle
.
putBoolean
(
bundle
.
putBoolean
(
ENABLE_REQUEST_SDR_TONE_MAPPING
,
enableRequestSdrToneMappingCheckBox
.
isChecked
());
ENABLE_REQUEST_SDR_TONE_MAPPING
,
enableRequestSdrToneMappingCheckBox
.
isChecked
());
bundle
.
putBoolean
(
ENABLE_HDR_EDITING
,
enableHdrEditingCheckBox
.
isChecked
());
bundle
.
putBoolean
(
ENABLE_HDR_EDITING
,
enableHdrEditingCheckBox
.
isChecked
());
bundle
.
putBooleanArray
(
DEMO_
FRAME_PROCESSORS_SELECTIONS
,
demoFrameProcessor
sSelections
);
bundle
.
putBooleanArray
(
DEMO_
EFFECTS_SELECTIONS
,
demoEffect
sSelections
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_CENTER_X
,
periodicVignetteCenterX
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_CENTER_X
,
periodicVignetteCenterX
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_CENTER_Y
,
periodicVignetteCenterY
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_CENTER_Y
,
periodicVignetteCenterY
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_INNER_RADIUS
,
periodicVignetteInnerRadius
);
bundle
.
putFloat
(
PERIODIC_VIGNETTE_INNER_RADIUS
,
periodicVignetteInnerRadius
);
...
@@ -278,13 +278,11 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -278,13 +278,11 @@ public final class ConfigurationActivity extends AppCompatActivity {
.
show
();
.
show
();
}
}
private
void
select
FrameProcessor
s
(
View
view
)
{
private
void
select
DemoEffect
s
(
View
view
)
{
new
AlertDialog
.
Builder
(
/* context= */
this
)
new
AlertDialog
.
Builder
(
/* context= */
this
)
.
setTitle
(
R
.
string
.
select_demo_
frameprocessor
s
)
.
setTitle
(
R
.
string
.
select_demo_
effect
s
)
.
setMultiChoiceItems
(
.
setMultiChoiceItems
(
DEMO_FRAME_PROCESSORS
,
DEMO_EFFECTS
,
checkNotNull
(
demoEffectsSelections
),
this
::
selectDemoEffect
)
checkNotNull
(
demoFrameProcessorsSelections
),
this
::
selectFrameProcessor
)
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
/* listener= */
null
)
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
/* listener= */
null
)
.
create
()
.
create
()
.
show
();
.
show
();
...
@@ -296,9 +294,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -296,9 +294,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
selectedFileTextView
.
setText
(
URI_DESCRIPTIONS
[
inputUriPosition
]);
selectedFileTextView
.
setText
(
URI_DESCRIPTIONS
[
inputUriPosition
]);
}
}
@RequiresNonNull
(
"demo
FrameProcessor
sSelections"
)
@RequiresNonNull
(
"demo
Effect
sSelections"
)
private
void
select
FrameProcessor
(
DialogInterface
dialog
,
int
which
,
boolean
isChecked
)
{
private
void
select
DemoEffect
(
DialogInterface
dialog
,
int
which
,
boolean
isChecked
)
{
demo
FrameProcessor
sSelections
[
which
]
=
isChecked
;
demo
Effect
sSelections
[
which
]
=
isChecked
;
if
(!
isChecked
||
which
!=
PERIODIC_VIGNETTE_INDEX
)
{
if
(!
isChecked
||
which
!=
PERIODIC_VIGNETTE_INDEX
)
{
return
;
return
;
}
}
...
@@ -337,7 +335,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -337,7 +335,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"rotateSpinner"
,
"rotateSpinner"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableHdrEditingCheckBox"
,
"enableHdrEditingCheckBox"
,
"selectDemo
FrameProcessor
sButton"
"selectDemo
Effect
sButton"
})
})
private
void
onRemoveAudio
(
View
view
)
{
private
void
onRemoveAudio
(
View
view
)
{
if
(((
CheckBox
)
view
).
isChecked
())
{
if
(((
CheckBox
)
view
).
isChecked
())
{
...
@@ -357,7 +355,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -357,7 +355,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"rotateSpinner"
,
"rotateSpinner"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableHdrEditingCheckBox"
,
"enableHdrEditingCheckBox"
,
"selectDemo
FrameProcessor
sButton"
"selectDemo
Effect
sButton"
})
})
private
void
onRemoveVideo
(
View
view
)
{
private
void
onRemoveVideo
(
View
view
)
{
if
(((
CheckBox
)
view
).
isChecked
())
{
if
(((
CheckBox
)
view
).
isChecked
())
{
...
@@ -376,7 +374,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -376,7 +374,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"rotateSpinner"
,
"rotateSpinner"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableRequestSdrToneMappingCheckBox"
,
"enableHdrEditingCheckBox"
,
"enableHdrEditingCheckBox"
,
"selectDemo
FrameProcessor
sButton"
"selectDemo
Effect
sButton"
})
})
private
void
enableTrackSpecificOptions
(
boolean
isAudioEnabled
,
boolean
isVideoEnabled
)
{
private
void
enableTrackSpecificOptions
(
boolean
isAudioEnabled
,
boolean
isVideoEnabled
)
{
audioMimeSpinner
.
setEnabled
(
isAudioEnabled
);
audioMimeSpinner
.
setEnabled
(
isAudioEnabled
);
...
@@ -387,7 +385,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
...
@@ -387,7 +385,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
enableRequestSdrToneMappingCheckBox
.
setEnabled
(
enableRequestSdrToneMappingCheckBox
.
setEnabled
(
isRequestSdrToneMappingSupported
()
&&
isVideoEnabled
);
isRequestSdrToneMappingSupported
()
&&
isVideoEnabled
);
enableHdrEditingCheckBox
.
setEnabled
(
isVideoEnabled
);
enableHdrEditingCheckBox
.
setEnabled
(
isVideoEnabled
);
selectDemo
FrameProcessor
sButton
.
setEnabled
(
isVideoEnabled
);
selectDemo
Effect
sButton
.
setEnabled
(
isVideoEnabled
);
findViewById
(
R
.
id
.
audio_mime_text_view
).
setEnabled
(
isAudioEnabled
);
findViewById
(
R
.
id
.
audio_mime_text_view
).
setEnabled
(
isAudioEnabled
);
findViewById
(
R
.
id
.
video_mime_text_view
).
setEnabled
(
isVideoEnabled
);
findViewById
(
R
.
id
.
video_mime_text_view
).
setEnabled
(
isVideoEnabled
);
...
...
demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java
View file @
b410a922
...
@@ -40,7 +40,7 @@ import androidx.media3.exoplayer.ExoPlayer;
...
@@ -40,7 +40,7 @@ import androidx.media3.exoplayer.ExoPlayer;
import
androidx.media3.exoplayer.util.DebugTextViewHelper
;
import
androidx.media3.exoplayer.util.DebugTextViewHelper
;
import
androidx.media3.transformer.DefaultEncoderFactory
;
import
androidx.media3.transformer.DefaultEncoderFactory
;
import
androidx.media3.transformer.EncoderSelector
;
import
androidx.media3.transformer.EncoderSelector
;
import
androidx.media3.transformer.Gl
FrameProcessor
;
import
androidx.media3.transformer.Gl
Effect
;
import
androidx.media3.transformer.ProgressHolder
;
import
androidx.media3.transformer.ProgressHolder
;
import
androidx.media3.transformer.TransformationException
;
import
androidx.media3.transformer.TransformationException
;
import
androidx.media3.transformer.TransformationRequest
;
import
androidx.media3.transformer.TransformationRequest
;
...
@@ -240,35 +240,36 @@ public final class TransformerActivity extends AppCompatActivity {
...
@@ -240,35 +240,36 @@ public final class TransformerActivity extends AppCompatActivity {
EncoderSelector
.
DEFAULT
,
EncoderSelector
.
DEFAULT
,
/* enableFallback= */
bundle
.
getBoolean
(
ConfigurationActivity
.
ENABLE_FALLBACK
)));
/* enableFallback= */
bundle
.
getBoolean
(
ConfigurationActivity
.
ENABLE_FALLBACK
)));
ImmutableList
.
Builder
<
Gl
FrameProcessor
>
frameProcessor
s
=
new
ImmutableList
.
Builder
<>();
ImmutableList
.
Builder
<
Gl
Effect
>
effect
s
=
new
ImmutableList
.
Builder
<>();
@Nullable
@Nullable
boolean
[]
selected
FrameProcessor
s
=
boolean
[]
selected
Effect
s
=
bundle
.
getBooleanArray
(
ConfigurationActivity
.
DEMO_
FRAME_PROCESSOR
S_SELECTIONS
);
bundle
.
getBooleanArray
(
ConfigurationActivity
.
DEMO_
EFFECT
S_SELECTIONS
);
if
(
selected
FrameProcessor
s
!=
null
)
{
if
(
selected
Effect
s
!=
null
)
{
if
(
selected
FrameProcessor
s
[
0
])
{
if
(
selected
Effect
s
[
0
])
{
frameProcessors
.
add
(
AdvancedFrameProcessorFactory
.
createDizzyCropFrameProcessor
()
);
effects
.
add
(
AdvancedFrameProcessorFactory:
:
createDizzyCropFrameProcessor
);
}
}
if
(
selectedFrameProcessors
[
1
])
{
if
(
selectedEffects
[
1
])
{
frameProcessors
.
add
(
effects
.
add
(
new
PeriodicVignetteFrameProcessor
(
()
->
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_CENTER_X
),
new
PeriodicVignetteFrameProcessor
(
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_CENTER_Y
),
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_CENTER_X
),
/* minInnerRadius= */
bundle
.
getFloat
(
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_CENTER_Y
),
ConfigurationActivity
.
PERIODIC_VIGNETTE_INNER_RADIUS
),
/* minInnerRadius= */
bundle
.
getFloat
(
/* maxInnerRadius= */
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_INNER_RADIUS
),
ConfigurationActivity
.
PERIODIC_VIGNETTE_OUTER_RADIUS
),
/* maxInnerRadius= */
bundle
.
getFloat
(
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_OUTER_RADIUS
)));
ConfigurationActivity
.
PERIODIC_VIGNETTE_OUTER_RADIUS
),
bundle
.
getFloat
(
ConfigurationActivity
.
PERIODIC_VIGNETTE_OUTER_RADIUS
)));
}
}
if
(
selected
FrameProcessor
s
[
2
])
{
if
(
selected
Effect
s
[
2
])
{
frameProcessors
.
add
(
AdvancedFrameProcessorFactory
.
createSpin3dFrameProcessor
()
);
effects
.
add
(
AdvancedFrameProcessorFactory:
:
createSpin3dFrameProcessor
);
}
}
if
(
selected
FrameProcessor
s
[
3
])
{
if
(
selected
Effect
s
[
3
])
{
frameProcessors
.
add
(
new
BitmapOverlayFrameProcessor
()
);
effects
.
add
(
BitmapOverlayFrameProcessor:
:
new
);
}
}
if
(
selected
FrameProcessor
s
[
4
])
{
if
(
selected
Effect
s
[
4
])
{
frameProcessors
.
add
(
AdvancedFrameProcessorFactory
.
createZoomInTransitionFrameProcessor
()
);
effects
.
add
(
AdvancedFrameProcessorFactory:
:
createZoomInTransitionFrameProcessor
);
}
}
transformerBuilder
.
set
FrameProcessors
(
frameProcessor
s
.
build
());
transformerBuilder
.
set
VideoFrameEffects
(
effect
s
.
build
());
}
}
}
}
return
transformerBuilder
return
transformerBuilder
...
...
demos/transformer/src/main/res/layout/configuration_activity.xml
View file @
b410a922
...
@@ -64,7 +64,7 @@
...
@@ -64,7 +64,7 @@
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/selected_file_text_view"
app:layout_constraintTop_toBottomOf=
"@+id/selected_file_text_view"
app:layout_constraintBottom_toTopOf=
"@+id/select_demo_
frameprocessor
s_button"
>
app:layout_constraintBottom_toTopOf=
"@+id/select_demo_
effect
s_button"
>
<TableLayout
<TableLayout
android:layout_width=
"fill_parent"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
...
@@ -192,13 +192,13 @@
...
@@ -192,13 +192,13 @@
</TableLayout>
</TableLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
<Button
<Button
android:id=
"@+id/select_demo_
frameprocessor
s_button"
android:id=
"@+id/select_demo_
effect
s_button"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"32dp"
android:layout_marginTop=
"32dp"
android:layout_marginStart=
"32dp"
android:layout_marginStart=
"32dp"
android:layout_marginEnd=
"32dp"
android:layout_marginEnd=
"32dp"
android:text=
"@string/select_demo_
frameprocessor
s"
android:text=
"@string/select_demo_
effect
s"
app:layout_constraintBottom_toTopOf=
"@+id/transform_button"
app:layout_constraintBottom_toTopOf=
"@+id/transform_button"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
app:layout_constraintStart_toStartOf=
"parent"
/>
...
...
demos/transformer/src/main/res/values/strings.xml
View file @
b410a922
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
<string
name=
"enable_fallback"
translatable=
"false"
>
Enable fallback
</string>
<string
name=
"enable_fallback"
translatable=
"false"
>
Enable fallback
</string>
<string
name=
"request_sdr_tone_mapping"
translatable=
"false"
>
Request SDR tone-mapping (API 31+)
</string>
<string
name=
"request_sdr_tone_mapping"
translatable=
"false"
>
Request SDR tone-mapping (API 31+)
</string>
<string
name=
"hdr_editing"
translatable=
"false"
>
[Experimental] HDR editing
</string>
<string
name=
"hdr_editing"
translatable=
"false"
>
[Experimental] HDR editing
</string>
<string
name=
"select_demo_
frameprocessor
s"
translatable=
"false"
>
Add demo effects
</string>
<string
name=
"select_demo_
effect
s"
translatable=
"false"
>
Add demo effects
</string>
<string
name=
"periodic_vignette_options"
translatable=
"false"
>
Periodic vignette options
</string>
<string
name=
"periodic_vignette_options"
translatable=
"false"
>
Periodic vignette options
</string>
<string
name=
"transform"
translatable=
"false"
>
Transform
</string>
<string
name=
"transform"
translatable=
"false"
>
Transform
</string>
<string
name=
"debug_preview"
translatable=
"false"
>
Debug preview:
</string>
<string
name=
"debug_preview"
translatable=
"false"
>
Debug preview:
</string>
...
...
libraries/transformer/src/androidTest/java/androidx/media3/transformer/FrameProcessorChainPixelTest.java
View file @
b410a922
...
@@ -130,7 +130,7 @@ public final class FrameProcessorChainPixelTest {
...
@@ -130,7 +130,7 @@ public final class FrameProcessorChainPixelTest {
Matrix
translateRightMatrix
=
new
Matrix
();
Matrix
translateRightMatrix
=
new
Matrix
();
translateRightMatrix
.
postTranslate
(
/* dx= */
1
,
/* dy= */
0
);
translateRightMatrix
.
postTranslate
(
/* dx= */
1
,
/* dy= */
0
);
GlFrameProcessor
glFrameProcessor
=
new
AdvancedFrameProcessor
(
translateRightMatrix
);
GlFrameProcessor
glFrameProcessor
=
new
AdvancedFrameProcessor
(
translateRightMatrix
);
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
glFrameProcessor
);
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
()
->
glFrameProcessor
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
TRANSLATE_RIGHT_PNG_ASSET_PATH
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
TRANSLATE_RIGHT_PNG_ASSET_PATH
);
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
...
@@ -155,7 +155,9 @@ public final class FrameProcessorChainPixelTest {
...
@@ -155,7 +155,9 @@ public final class FrameProcessorChainPixelTest {
GlFrameProcessor
rotate45FrameProcessor
=
GlFrameProcessor
rotate45FrameProcessor
=
new
ScaleToFitFrameProcessor
.
Builder
().
setRotationDegrees
(
45
).
build
();
new
ScaleToFitFrameProcessor
.
Builder
().
setRotationDegrees
(
45
).
build
();
setUpAndPrepareFirstFrame
(
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
translateRightFrameProcessor
,
rotate45FrameProcessor
);
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
()
->
translateRightFrameProcessor
,
()
->
rotate45FrameProcessor
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
TRANSLATE_THEN_ROTATE_PNG_ASSET_PATH
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
TRANSLATE_THEN_ROTATE_PNG_ASSET_PATH
);
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
...
@@ -180,7 +182,9 @@ public final class FrameProcessorChainPixelTest {
...
@@ -180,7 +182,9 @@ public final class FrameProcessorChainPixelTest {
GlFrameProcessor
translateRightFrameProcessor
=
GlFrameProcessor
translateRightFrameProcessor
=
new
AdvancedFrameProcessor
(
translateRightMatrix
);
new
AdvancedFrameProcessor
(
translateRightMatrix
);
setUpAndPrepareFirstFrame
(
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
rotate45FrameProcessor
,
translateRightFrameProcessor
);
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
()
->
rotate45FrameProcessor
,
()
->
translateRightFrameProcessor
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
ROTATE_THEN_TRANSLATE_PNG_ASSET_PATH
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
ROTATE_THEN_TRANSLATE_PNG_ASSET_PATH
);
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
...
@@ -200,7 +204,7 @@ public final class FrameProcessorChainPixelTest {
...
@@ -200,7 +204,7 @@ public final class FrameProcessorChainPixelTest {
String
testId
=
"processData_withPresentationFrameProcessor_setResolution"
;
String
testId
=
"processData_withPresentationFrameProcessor_setResolution"
;
GlFrameProcessor
glFrameProcessor
=
GlFrameProcessor
glFrameProcessor
=
new
PresentationFrameProcessor
.
Builder
().
setResolution
(
480
).
build
();
new
PresentationFrameProcessor
.
Builder
().
setResolution
(
480
).
build
();
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
glFrameProcessor
);
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
()
->
glFrameProcessor
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
REQUEST_OUTPUT_HEIGHT_PNG_ASSET_PATH
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
REQUEST_OUTPUT_HEIGHT_PNG_ASSET_PATH
);
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
...
@@ -220,7 +224,7 @@ public final class FrameProcessorChainPixelTest {
...
@@ -220,7 +224,7 @@ public final class FrameProcessorChainPixelTest {
String
testId
=
"processData_withScaleToFitFrameProcessor_rotate45"
;
String
testId
=
"processData_withScaleToFitFrameProcessor_rotate45"
;
GlFrameProcessor
glFrameProcessor
=
GlFrameProcessor
glFrameProcessor
=
new
ScaleToFitFrameProcessor
.
Builder
().
setRotationDegrees
(
45
).
build
();
new
ScaleToFitFrameProcessor
.
Builder
().
setRotationDegrees
(
45
).
build
();
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
glFrameProcessor
);
setUpAndPrepareFirstFrame
(
DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO
,
()
->
glFrameProcessor
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
ROTATE45_SCALE_TO_FIT_PNG_ASSET_PATH
);
Bitmap
expectedBitmap
=
BitmapTestUtil
.
readBitmap
(
ROTATE45_SCALE_TO_FIT_PNG_ASSET_PATH
);
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
Bitmap
actualBitmap
=
processFirstFrameAndEnd
();
...
@@ -240,11 +244,10 @@ public final class FrameProcessorChainPixelTest {
...
@@ -240,11 +244,10 @@ public final class FrameProcessorChainPixelTest {
* accessed on the {@link FrameProcessorChain}'s output {@code outputImageReader}.
* accessed on the {@link FrameProcessorChain}'s output {@code outputImageReader}.
*
*
* @param pixelWidthHeightRatio The ratio of width over height for each pixel.
* @param pixelWidthHeightRatio The ratio of width over height for each pixel.
* @param frameProcessors The {@link GlFrameProcessor GlFrameProcessors} that will apply changes
* @param effects The {@link GlEffect GlEffects} to apply to the input frame.
* to the input frame.
*/
*/
private
void
setUpAndPrepareFirstFrame
(
private
void
setUpAndPrepareFirstFrame
(
float
pixelWidthHeightRatio
,
GlEffect
...
effects
)
float
pixelWidthHeightRatio
,
GlFrameProcessor
...
frameProcessors
)
throws
Exception
{
throws
Exception
{
// Set up the extractor to read the first video frame and get its format.
// Set up the extractor to read the first video frame and get its format.
MediaExtractor
mediaExtractor
=
new
MediaExtractor
();
MediaExtractor
mediaExtractor
=
new
MediaExtractor
();
@Nullable
MediaCodec
mediaCodec
=
null
;
@Nullable
MediaCodec
mediaCodec
=
null
;
...
@@ -267,7 +270,7 @@ public final class FrameProcessorChainPixelTest {
...
@@ -267,7 +270,7 @@ public final class FrameProcessorChainPixelTest {
pixelWidthHeightRatio
,
pixelWidthHeightRatio
,
inputWidth
,
inputWidth
,
inputHeight
,
inputHeight
,
asList
(
frameProcessor
s
),
asList
(
effect
s
),
/* enableExperimentalHdrEditing= */
false
);
/* enableExperimentalHdrEditing= */
false
);
Size
outputSize
=
frameProcessorChain
.
getOutputSize
();
Size
outputSize
=
frameProcessorChain
.
getOutputSize
();
outputImageReader
=
outputImageReader
=
...
...
libraries/transformer/src/androidTest/java/androidx/media3/transformer/FrameProcessorChainTest.java
View file @
b410a922
...
@@ -112,16 +112,16 @@ public final class FrameProcessorChainTest {
...
@@ -112,16 +112,16 @@ public final class FrameProcessorChainTest {
private
static
FrameProcessorChain
createFrameProcessorChainWithFakeFrameProcessors
(
private
static
FrameProcessorChain
createFrameProcessorChainWithFakeFrameProcessors
(
float
pixelWidthHeightRatio
,
Size
inputSize
,
List
<
Size
>
frameProcessorOutputSizes
)
float
pixelWidthHeightRatio
,
Size
inputSize
,
List
<
Size
>
frameProcessorOutputSizes
)
throws
TransformationException
{
throws
TransformationException
{
ImmutableList
.
Builder
<
Gl
FrameProcessor
>
frameProcessor
s
=
new
ImmutableList
.
Builder
<>();
ImmutableList
.
Builder
<
Gl
Effect
>
effect
s
=
new
ImmutableList
.
Builder
<>();
for
(
Size
element
:
frameProcessorOutputSizes
)
{
for
(
Size
element
:
frameProcessorOutputSizes
)
{
frameProcessors
.
add
(
new
FakeFrameProcessor
(
element
));
effects
.
add
(()
->
new
FakeFrameProcessor
(
element
));
}
}
return
FrameProcessorChain
.
create
(
return
FrameProcessorChain
.
create
(
getApplicationContext
(),
getApplicationContext
(),
pixelWidthHeightRatio
,
pixelWidthHeightRatio
,
inputSize
.
getWidth
(),
inputSize
.
getWidth
(),
inputSize
.
getHeight
(),
inputSize
.
getHeight
(),
frameProcessor
s
.
build
(),
effect
s
.
build
(),
/* enableExperimentalHdrEditing= */
false
);
/* enableExperimentalHdrEditing= */
false
);
}
}
...
...
libraries/transformer/src/main/java/androidx/media3/transformer/FrameProcessorChain.java
View file @
b410a922
...
@@ -75,7 +75,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -75,7 +75,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* by this ratio so that the output frame's pixels have a ratio of 1.
* by this ratio so that the output frame's pixels have a ratio of 1.
* @param inputWidth The input frame width, in pixels.
* @param inputWidth The input frame width, in pixels.
* @param inputHeight The input frame height, in pixels.
* @param inputHeight The input frame height, in pixels.
* @param
frameProcessors The {@link GlFrameProcessor GlFrameProcessor
s} to apply to each frame.
* @param
effects The {@link GlEffect GlEffect
s} to apply to each frame.
* @param enableExperimentalHdrEditing Whether to attempt to process the input as an HDR signal.
* @param enableExperimentalHdrEditing Whether to attempt to process the input as an HDR signal.
* @return A new instance.
* @return A new instance.
* @throws TransformationException If reading shader files fails, or an OpenGL error occurs while
* @throws TransformationException If reading shader files fails, or an OpenGL error occurs while
...
@@ -86,7 +86,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -86,7 +86,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
float
pixelWidthHeightRatio
,
float
pixelWidthHeightRatio
,
int
inputWidth
,
int
inputWidth
,
int
inputHeight
,
int
inputHeight
,
List
<
Gl
FrameProcessor
>
frameProcessor
s
,
List
<
Gl
Effect
>
effect
s
,
boolean
enableExperimentalHdrEditing
)
boolean
enableExperimentalHdrEditing
)
throws
TransformationException
{
throws
TransformationException
{
checkArgument
(
inputWidth
>
0
,
"inputWidth must be positive"
);
checkArgument
(
inputWidth
>
0
,
"inputWidth must be positive"
);
...
@@ -103,7 +103,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -103,7 +103,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
pixelWidthHeightRatio
,
pixelWidthHeightRatio
,
inputWidth
,
inputWidth
,
inputHeight
,
inputHeight
,
frameProcessor
s
,
effect
s
,
enableExperimentalHdrEditing
,
enableExperimentalHdrEditing
,
singleThreadExecutorService
))
singleThreadExecutorService
))
.
get
();
.
get
();
...
@@ -118,8 +118,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -118,8 +118,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
}
/**
/**
* Creates the OpenGL textures, framebuffers, initializes the {@link GlFrameProcessor
* Creates the OpenGL textures and framebuffers, initializes the {@link GlFrameProcessor
* GlFrameProcessors} and returns a new {@code FrameProcessorChain}.
* GlFrameProcessors} corresponding to the {@link GlEffect GlEffects}, and returns a new {@code
* FrameProcessorChain}.
*
*
* <p>This method must be executed using the {@code singleThreadExecutorService}.
* <p>This method must be executed using the {@code singleThreadExecutorService}.
*/
*/
...
@@ -129,15 +130,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -129,15 +130,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
float
pixelWidthHeightRatio
,
float
pixelWidthHeightRatio
,
int
inputWidth
,
int
inputWidth
,
int
inputHeight
,
int
inputHeight
,
List
<
Gl
FrameProcessor
>
frameProcessor
s
,
List
<
Gl
Effect
>
effect
s
,
boolean
enableExperimentalHdrEditing
,
boolean
enableExperimentalHdrEditing
,
ExecutorService
singleThreadExecutorService
)
ExecutorService
singleThreadExecutorService
)
throws
IOException
{
throws
IOException
{
checkState
(
Thread
.
currentThread
().
getName
().
equals
(
THREAD_NAME
));
checkState
(
Thread
.
currentThread
().
getName
().
equals
(
THREAD_NAME
));
EGLDisplay
eglDisplay
=
GlUtil
.
createEglDisplay
();
EGLDisplay
eglDisplay
=
GlUtil
.
createEglDisplay
();
ExternalCopyFrameProcessor
externalCopyFrameProcessor
=
new
ExternalCopyFrameProcessor
(
enableExperimentalHdrEditing
);
EGLContext
eglContext
=
EGLContext
eglContext
=
enableExperimentalHdrEditing
enableExperimentalHdrEditing
?
GlUtil
.
createEglContextEs3Rgba1010102
(
eglDisplay
)
?
GlUtil
.
createEglContextEs3Rgba1010102
(
eglDisplay
)
...
@@ -153,20 +152,21 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -153,20 +152,21 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
GlUtil
.
focusPlaceholderEglSurface
(
eglContext
,
eglDisplay
);
GlUtil
.
focusPlaceholderEglSurface
(
eglContext
,
eglDisplay
);
}
}
ImmutableList
<
GlFrameProcessor
>
expandedFrameProcessors
=
ExternalCopyFrameProcessor
externalCopyFrameProcessor
=
getExpandedFrameProcessors
(
new
ExternalCopyFrameProcessor
(
enableExperimentalHdrEditing
);
externalCopyFrameProcessor
,
pixelWidthHeightRatio
,
frameProcessors
);
ImmutableList
<
GlFrameProcessor
>
frameProcessors
=
getFrameProcessors
(
externalCopyFrameProcessor
,
pixelWidthHeightRatio
,
effects
);
// Initialize frame processors.
// Initialize frame processors.
int
inputExternalTexId
=
GlUtil
.
createExternalTexture
();
int
inputExternalTexId
=
GlUtil
.
createExternalTexture
();
externalCopyFrameProcessor
.
initialize
(
context
,
inputExternalTexId
,
inputWidth
,
inputHeight
);
externalCopyFrameProcessor
.
initialize
(
context
,
inputExternalTexId
,
inputWidth
,
inputHeight
);
int
[]
framebuffers
=
new
int
[
expandedF
rameProcessors
.
size
()
-
1
];
int
[]
framebuffers
=
new
int
[
f
rameProcessors
.
size
()
-
1
];
Size
inputSize
=
externalCopyFrameProcessor
.
getOutputSize
();
Size
inputSize
=
externalCopyFrameProcessor
.
getOutputSize
();
for
(
int
i
=
1
;
i
<
expandedF
rameProcessors
.
size
();
i
++)
{
for
(
int
i
=
1
;
i
<
f
rameProcessors
.
size
();
i
++)
{
int
inputTexId
=
GlUtil
.
createTexture
(
inputSize
.
getWidth
(),
inputSize
.
getHeight
());
int
inputTexId
=
GlUtil
.
createTexture
(
inputSize
.
getWidth
(),
inputSize
.
getHeight
());
framebuffers
[
i
-
1
]
=
GlUtil
.
createFboForTexture
(
inputTexId
);
framebuffers
[
i
-
1
]
=
GlUtil
.
createFboForTexture
(
inputTexId
);
GlFrameProcessor
frameProcessor
=
expandedF
rameProcessors
.
get
(
i
);
GlFrameProcessor
frameProcessor
=
f
rameProcessors
.
get
(
i
);
frameProcessor
.
initialize
(
context
,
inputTexId
,
inputSize
.
getWidth
(),
inputSize
.
getHeight
());
frameProcessor
.
initialize
(
context
,
inputTexId
,
inputSize
.
getWidth
(),
inputSize
.
getHeight
());
inputSize
=
frameProcessor
.
getOutputSize
();
inputSize
=
frameProcessor
.
getOutputSize
();
}
}
...
@@ -176,31 +176,34 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -176,31 +176,34 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
singleThreadExecutorService
,
singleThreadExecutorService
,
inputExternalTexId
,
inputExternalTexId
,
framebuffers
,
framebuffers
,
expandedF
rameProcessors
,
f
rameProcessors
,
enableExperimentalHdrEditing
);
enableExperimentalHdrEditing
);
}
}
private
static
ImmutableList
<
GlFrameProcessor
>
get
Expanded
FrameProcessors
(
private
static
ImmutableList
<
GlFrameProcessor
>
getFrameProcessors
(
ExternalCopyFrameProcessor
externalCopyFrameProcessor
,
ExternalCopyFrameProcessor
externalCopyFrameProcessor
,
float
pixelWidthHeightRatio
,
float
pixelWidthHeightRatio
,
List
<
Gl
FrameProcessor
>
frameProcessor
s
)
{
List
<
Gl
Effect
>
effect
s
)
{
ImmutableList
.
Builder
<
GlFrameProcessor
>
frameProcessor
ListBuilder
=
ImmutableList
.
Builder
<
GlFrameProcessor
>
frameProcessor
s
=
new
ImmutableList
.
Builder
<
GlFrameProcessor
>().
add
(
externalCopyFrameProcessor
);
new
ImmutableList
.
Builder
<
GlFrameProcessor
>().
add
(
externalCopyFrameProcessor
);
// Scale to expand the frame to apply the pixelWidthHeightRatio.
// Scale to expand the frame to apply the pixelWidthHeightRatio.
if
(
pixelWidthHeightRatio
>
1
f
)
{
if
(
pixelWidthHeightRatio
>
1
f
)
{
frameProcessor
ListBuilder
.
add
(
frameProcessor
s
.
add
(
new
ScaleToFitFrameProcessor
.
Builder
()
new
ScaleToFitFrameProcessor
.
Builder
()
.
setScale
(
/* scaleX= */
pixelWidthHeightRatio
,
/* scaleY= */
1
f
)
.
setScale
(
/* scaleX= */
pixelWidthHeightRatio
,
/* scaleY= */
1
f
)
.
build
());
.
build
());
}
else
if
(
pixelWidthHeightRatio
<
1
f
)
{
}
else
if
(
pixelWidthHeightRatio
<
1
f
)
{
frameProcessor
ListBuilder
.
add
(
frameProcessor
s
.
add
(
new
ScaleToFitFrameProcessor
.
Builder
()
new
ScaleToFitFrameProcessor
.
Builder
()
.
setScale
(
/* scaleX= */
1
f
,
/* scaleY= */
1
f
/
pixelWidthHeightRatio
)
.
setScale
(
/* scaleX= */
1
f
,
/* scaleY= */
1
f
/
pixelWidthHeightRatio
)
.
build
());
.
build
());
}
}
frameProcessorListBuilder
.
addAll
(
frameProcessors
);
return
frameProcessorListBuilder
.
build
();
for
(
int
i
=
0
;
i
<
effects
.
size
();
i
++)
{
frameProcessors
.
add
(
effects
.
get
(
i
).
toGlFrameProcessor
());
}
return
frameProcessors
.
build
();
}
}
private
static
final
String
TAG
=
"FrameProcessorChain"
;
private
static
final
String
TAG
=
"FrameProcessorChain"
;
...
...
libraries/transformer/src/main/java/androidx/media3/transformer/GlEffect.java
0 → 100644
View file @
b410a922
/*
* Copyright 2022 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
androidx
.
media3
.
transformer
;
import
androidx.media3.common.util.UnstableApi
;
/**
* Interface for a video frame effect with a {@link GlFrameProcessor} implementation.
*
* <p>Implementations contain information specifying the effect and can be {@linkplain
* #toGlFrameProcessor() converted} to a {@link GlFrameProcessor} which applies the effect.
*/
@UnstableApi
public
interface
GlEffect
{
/** Returns a {@link GlFrameProcessor} that applies the the effect. */
GlFrameProcessor
toGlFrameProcessor
();
}
libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
View file @
b410a922
...
@@ -104,7 +104,7 @@ public final class Transformer {
...
@@ -104,7 +104,7 @@ public final class Transformer {
private
boolean
removeVideo
;
private
boolean
removeVideo
;
private
String
containerMimeType
;
private
String
containerMimeType
;
private
TransformationRequest
transformationRequest
;
private
TransformationRequest
transformationRequest
;
private
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
;
private
ImmutableList
<
Gl
Effect
>
videoFrameEffect
s
;
private
ListenerSet
<
Transformer
.
Listener
>
listeners
;
private
ListenerSet
<
Transformer
.
Listener
>
listeners
;
private
DebugViewProvider
debugViewProvider
;
private
DebugViewProvider
debugViewProvider
;
private
Looper
looper
;
private
Looper
looper
;
...
@@ -124,7 +124,7 @@ public final class Transformer {
...
@@ -124,7 +124,7 @@ public final class Transformer {
debugViewProvider
=
DebugViewProvider
.
NONE
;
debugViewProvider
=
DebugViewProvider
.
NONE
;
containerMimeType
=
MimeTypes
.
VIDEO_MP4
;
containerMimeType
=
MimeTypes
.
VIDEO_MP4
;
transformationRequest
=
new
TransformationRequest
.
Builder
().
build
();
transformationRequest
=
new
TransformationRequest
.
Builder
().
build
();
frameProcessor
s
=
ImmutableList
.
of
();
videoFrameEffect
s
=
ImmutableList
.
of
();
}
}
/**
/**
...
@@ -142,7 +142,7 @@ public final class Transformer {
...
@@ -142,7 +142,7 @@ public final class Transformer {
debugViewProvider
=
DebugViewProvider
.
NONE
;
debugViewProvider
=
DebugViewProvider
.
NONE
;
containerMimeType
=
MimeTypes
.
VIDEO_MP4
;
containerMimeType
=
MimeTypes
.
VIDEO_MP4
;
transformationRequest
=
new
TransformationRequest
.
Builder
().
build
();
transformationRequest
=
new
TransformationRequest
.
Builder
().
build
();
frameProcessor
s
=
ImmutableList
.
of
();
videoFrameEffect
s
=
ImmutableList
.
of
();
}
}
/** Creates a builder with the values of the provided {@link Transformer}. */
/** Creates a builder with the values of the provided {@link Transformer}. */
...
@@ -154,7 +154,7 @@ public final class Transformer {
...
@@ -154,7 +154,7 @@ public final class Transformer {
this
.
removeVideo
=
transformer
.
removeVideo
;
this
.
removeVideo
=
transformer
.
removeVideo
;
this
.
containerMimeType
=
transformer
.
containerMimeType
;
this
.
containerMimeType
=
transformer
.
containerMimeType
;
this
.
transformationRequest
=
transformer
.
transformationRequest
;
this
.
transformationRequest
=
transformer
.
transformationRequest
;
this
.
frameProcessors
=
transformer
.
frameProcessor
s
;
this
.
videoFrameEffects
=
transformer
.
videoFrameEffect
s
;
this
.
listeners
=
transformer
.
listeners
;
this
.
listeners
=
transformer
.
listeners
;
this
.
looper
=
transformer
.
looper
;
this
.
looper
=
transformer
.
looper
;
this
.
encoderFactory
=
transformer
.
encoderFactory
;
this
.
encoderFactory
=
transformer
.
encoderFactory
;
...
@@ -187,20 +187,20 @@ public final class Transformer {
...
@@ -187,20 +187,20 @@ public final class Transformer {
}
}
/**
/**
* Sets the {@linkplain Gl
FrameProcessor frame processors} to apply to each
frame.
* Sets the {@linkplain Gl
Effect effects} to apply to each video
frame.
*
*
* <p>The {@linkplain Gl
FrameProcessor frame processor
s} are applied before any {@linkplain
* <p>The {@linkplain Gl
Effect effect
s} are applied before any {@linkplain
* TransformationRequest.Builder#setScale(float, float) scale}, {@linkplain
* TransformationRequest.Builder#setScale(float, float) scale}, {@linkplain
* TransformationRequest.Builder#setRotationDegrees(float) rotation}, or {@linkplain
* TransformationRequest.Builder#setRotationDegrees(float) rotation}, or {@linkplain
* TransformationRequest.Builder#setResolution(int) resolution} changes specified in the {@link
* TransformationRequest.Builder#setResolution(int) resolution} changes specified in the {@link
* #setTransformationRequest(TransformationRequest) TransformationRequest} but after {@linkplain
* #setTransformationRequest(TransformationRequest) TransformationRequest} but after {@linkplain
* TransformationRequest.Builder#setFlattenForSlowMotion(boolean) slow-motion flattening}.
* TransformationRequest.Builder#setFlattenForSlowMotion(boolean) slow-motion flattening}.
*
*
* @param
frameProcessors The {@linkplain GlFrameProcessor frame processors}
.
* @param
effects The {@linkplain GlEffect effects} to apply to each video frame
.
* @return This builder.
* @return This builder.
*/
*/
public
Builder
set
FrameProcessors
(
List
<
GlFrameProcessor
>
frameProcessor
s
)
{
public
Builder
set
VideoFrameEffects
(
List
<
GlEffect
>
effect
s
)
{
this
.
frameProcessors
=
ImmutableList
.
copyOf
(
frameProcessor
s
);
this
.
videoFrameEffects
=
ImmutableList
.
copyOf
(
effect
s
);
return
this
;
return
this
;
}
}
...
@@ -432,7 +432,7 @@ public final class Transformer {
...
@@ -432,7 +432,7 @@ public final class Transformer {
removeVideo
,
removeVideo
,
containerMimeType
,
containerMimeType
,
transformationRequest
,
transformationRequest
,
frameProcessor
s
,
videoFrameEffect
s
,
listeners
,
listeners
,
looper
,
looper
,
clock
,
clock
,
...
@@ -554,7 +554,7 @@ public final class Transformer {
...
@@ -554,7 +554,7 @@ public final class Transformer {
private
final
boolean
removeVideo
;
private
final
boolean
removeVideo
;
private
final
String
containerMimeType
;
private
final
String
containerMimeType
;
private
final
TransformationRequest
transformationRequest
;
private
final
TransformationRequest
transformationRequest
;
private
final
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
;
private
final
ImmutableList
<
Gl
Effect
>
videoFrameEffect
s
;
private
final
Looper
looper
;
private
final
Looper
looper
;
private
final
Clock
clock
;
private
final
Clock
clock
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
...
@@ -575,7 +575,7 @@ public final class Transformer {
...
@@ -575,7 +575,7 @@ public final class Transformer {
boolean
removeVideo
,
boolean
removeVideo
,
String
containerMimeType
,
String
containerMimeType
,
TransformationRequest
transformationRequest
,
TransformationRequest
transformationRequest
,
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
,
ImmutableList
<
Gl
Effect
>
videoFrameEffect
s
,
ListenerSet
<
Transformer
.
Listener
>
listeners
,
ListenerSet
<
Transformer
.
Listener
>
listeners
,
Looper
looper
,
Looper
looper
,
Clock
clock
,
Clock
clock
,
...
@@ -590,7 +590,7 @@ public final class Transformer {
...
@@ -590,7 +590,7 @@ public final class Transformer {
this
.
removeVideo
=
removeVideo
;
this
.
removeVideo
=
removeVideo
;
this
.
containerMimeType
=
containerMimeType
;
this
.
containerMimeType
=
containerMimeType
;
this
.
transformationRequest
=
transformationRequest
;
this
.
transformationRequest
=
transformationRequest
;
this
.
frameProcessors
=
frameProcessor
s
;
this
.
videoFrameEffects
=
videoFrameEffect
s
;
this
.
listeners
=
listeners
;
this
.
listeners
=
listeners
;
this
.
looper
=
looper
;
this
.
looper
=
looper
;
this
.
clock
=
clock
;
this
.
clock
=
clock
;
...
@@ -730,7 +730,7 @@ public final class Transformer {
...
@@ -730,7 +730,7 @@ public final class Transformer {
removeAudio
,
removeAudio
,
removeVideo
,
removeVideo
,
transformationRequest
,
transformationRequest
,
frameProcessor
s
,
videoFrameEffect
s
,
encoderFactory
,
encoderFactory
,
decoderFactory
,
decoderFactory
,
new
FallbackListener
(
mediaItem
,
listeners
,
transformationRequest
),
new
FallbackListener
(
mediaItem
,
listeners
,
transformationRequest
),
...
@@ -842,7 +842,7 @@ public final class Transformer {
...
@@ -842,7 +842,7 @@ public final class Transformer {
private
final
boolean
removeAudio
;
private
final
boolean
removeAudio
;
private
final
boolean
removeVideo
;
private
final
boolean
removeVideo
;
private
final
TransformationRequest
transformationRequest
;
private
final
TransformationRequest
transformationRequest
;
private
final
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
;
private
final
ImmutableList
<
Gl
Effect
>
videoFrameEffect
s
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
.
DecoderFactory
decoderFactory
;
private
final
Codec
.
DecoderFactory
decoderFactory
;
private
final
FallbackListener
fallbackListener
;
private
final
FallbackListener
fallbackListener
;
...
@@ -854,7 +854,7 @@ public final class Transformer {
...
@@ -854,7 +854,7 @@ public final class Transformer {
boolean
removeAudio
,
boolean
removeAudio
,
boolean
removeVideo
,
boolean
removeVideo
,
TransformationRequest
transformationRequest
,
TransformationRequest
transformationRequest
,
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
,
ImmutableList
<
Gl
Effect
>
videoFrameEffect
s
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
FallbackListener
fallbackListener
,
FallbackListener
fallbackListener
,
...
@@ -864,7 +864,7 @@ public final class Transformer {
...
@@ -864,7 +864,7 @@ public final class Transformer {
this
.
removeAudio
=
removeAudio
;
this
.
removeAudio
=
removeAudio
;
this
.
removeVideo
=
removeVideo
;
this
.
removeVideo
=
removeVideo
;
this
.
transformationRequest
=
transformationRequest
;
this
.
transformationRequest
=
transformationRequest
;
this
.
frameProcessors
=
frameProcessor
s
;
this
.
videoFrameEffects
=
videoFrameEffect
s
;
this
.
encoderFactory
=
encoderFactory
;
this
.
encoderFactory
=
encoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
this
.
fallbackListener
=
fallbackListener
;
this
.
fallbackListener
=
fallbackListener
;
...
@@ -900,7 +900,7 @@ public final class Transformer {
...
@@ -900,7 +900,7 @@ public final class Transformer {
muxerWrapper
,
muxerWrapper
,
mediaClock
,
mediaClock
,
transformationRequest
,
transformationRequest
,
frameProcessor
s
,
videoFrameEffect
s
,
encoderFactory
,
encoderFactory
,
decoderFactory
,
decoderFactory
,
fallbackListener
,
fallbackListener
,
...
...
libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java
View file @
b410a922
...
@@ -35,7 +35,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -35,7 +35,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private
static
final
String
TAG
=
"TVideoRenderer"
;
private
static
final
String
TAG
=
"TVideoRenderer"
;
private
final
Context
context
;
private
final
Context
context
;
private
final
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
;
private
final
ImmutableList
<
Gl
Effect
>
effect
s
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Codec
.
DecoderFactory
decoderFactory
;
private
final
Codec
.
DecoderFactory
decoderFactory
;
private
final
Transformer
.
DebugViewProvider
debugViewProvider
;
private
final
Transformer
.
DebugViewProvider
debugViewProvider
;
...
@@ -48,14 +48,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -48,14 +48,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
MuxerWrapper
muxerWrapper
,
MuxerWrapper
muxerWrapper
,
TransformerMediaClock
mediaClock
,
TransformerMediaClock
mediaClock
,
TransformationRequest
transformationRequest
,
TransformationRequest
transformationRequest
,
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
,
ImmutableList
<
Gl
Effect
>
effect
s
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
FallbackListener
fallbackListener
,
FallbackListener
fallbackListener
,
Transformer
.
DebugViewProvider
debugViewProvider
)
{
Transformer
.
DebugViewProvider
debugViewProvider
)
{
super
(
C
.
TRACK_TYPE_VIDEO
,
muxerWrapper
,
mediaClock
,
transformationRequest
,
fallbackListener
);
super
(
C
.
TRACK_TYPE_VIDEO
,
muxerWrapper
,
mediaClock
,
transformationRequest
,
fallbackListener
);
this
.
context
=
context
;
this
.
context
=
context
;
this
.
frameProcessors
=
frameProcessor
s
;
this
.
effects
=
effect
s
;
this
.
encoderFactory
=
encoderFactory
;
this
.
encoderFactory
=
encoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
this
.
decoderFactory
=
decoderFactory
;
this
.
debugViewProvider
=
debugViewProvider
;
this
.
debugViewProvider
=
debugViewProvider
;
...
@@ -90,7 +90,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -90,7 +90,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
context
,
context
,
inputFormat
,
inputFormat
,
transformationRequest
,
transformationRequest
,
frameProcessor
s
,
effect
s
,
decoderFactory
,
decoderFactory
,
encoderFactory
,
encoderFactory
,
muxerWrapper
.
getSupportedSampleMimeTypes
(
getTrackType
()),
muxerWrapper
.
getSupportedSampleMimeTypes
(
getTrackType
()),
...
@@ -137,7 +137,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
...
@@ -137,7 +137,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
&&
transformationRequest
.
outputHeight
!=
inputFormat
.
height
)
{
&&
transformationRequest
.
outputHeight
!=
inputFormat
.
height
)
{
return
false
;
return
false
;
}
}
if
(!
frameProcessor
s
.
isEmpty
())
{
if
(!
effect
s
.
isEmpty
())
{
return
false
;
return
false
;
}
}
return
true
;
return
true
;
...
...
libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java
View file @
b410a922
...
@@ -50,7 +50,7 @@ import org.checkerframework.dataflow.qual.Pure;
...
@@ -50,7 +50,7 @@ import org.checkerframework.dataflow.qual.Pure;
Context
context
,
Context
context
,
Format
inputFormat
,
Format
inputFormat
,
TransformationRequest
transformationRequest
,
TransformationRequest
transformationRequest
,
ImmutableList
<
Gl
FrameProcessor
>
frameProcessor
s
,
ImmutableList
<
Gl
Effect
>
effect
s
,
Codec
.
DecoderFactory
decoderFactory
,
Codec
.
DecoderFactory
decoderFactory
,
Codec
.
EncoderFactory
encoderFactory
,
Codec
.
EncoderFactory
encoderFactory
,
List
<
String
>
allowedOutputMimeTypes
,
List
<
String
>
allowedOutputMimeTypes
,
...
@@ -68,33 +68,35 @@ import org.checkerframework.dataflow.qual.Pure;
...
@@ -68,33 +68,35 @@ import org.checkerframework.dataflow.qual.Pure;
int
decodedHeight
=
int
decodedHeight
=
(
inputFormat
.
rotationDegrees
%
180
==
0
)
?
inputFormat
.
height
:
inputFormat
.
width
;
(
inputFormat
.
rotationDegrees
%
180
==
0
)
?
inputFormat
.
height
:
inputFormat
.
width
;
ImmutableList
.
Builder
<
Gl
FrameProcessor
>
frameProcessor
sListBuilder
=
ImmutableList
.
Builder
<
Gl
Effect
>
effect
sListBuilder
=
new
ImmutableList
.
Builder
<
Gl
FrameProcessor
>().
addAll
(
frameProcessor
s
);
new
ImmutableList
.
Builder
<
Gl
Effect
>().
addAll
(
effect
s
);
if
(
transformationRequest
.
scaleX
!=
1
f
if
(
transformationRequest
.
scaleX
!=
1
f
||
transformationRequest
.
scaleY
!=
1
f
||
transformationRequest
.
scaleY
!=
1
f
||
transformationRequest
.
rotationDegrees
!=
0
f
)
{
||
transformationRequest
.
rotationDegrees
!=
0
f
)
{
frameProcessorsListBuilder
.
add
(
effectsListBuilder
.
add
(
new
ScaleToFitFrameProcessor
.
Builder
()
()
->
.
setScale
(
transformationRequest
.
scaleX
,
transformationRequest
.
scaleY
)
new
ScaleToFitFrameProcessor
.
Builder
()
.
setRotationDegrees
(
transformationRequest
.
rotationDegrees
)
.
setScale
(
transformationRequest
.
scaleX
,
transformationRequest
.
scaleY
)
.
build
());
.
setRotationDegrees
(
transformationRequest
.
rotationDegrees
)
.
build
());
}
}
if
(
transformationRequest
.
outputHeight
!=
C
.
LENGTH_UNSET
)
{
if
(
transformationRequest
.
outputHeight
!=
C
.
LENGTH_UNSET
)
{
frameProcessorsListBuilder
.
add
(
effectsListBuilder
.
add
(
new
PresentationFrameProcessor
.
Builder
()
()
->
.
setResolution
(
transformationRequest
.
outputHeight
)
new
PresentationFrameProcessor
.
Builder
()
.
build
());
.
setResolution
(
transformationRequest
.
outputHeight
)
.
build
());
}
}
EncoderCompatibilityFrameProcessor
encoderCompatibilityFrameProcessor
=
EncoderCompatibilityFrameProcessor
encoderCompatibilityFrameProcessor
=
new
EncoderCompatibilityFrameProcessor
();
new
EncoderCompatibilityFrameProcessor
();
frameProcessorsListBuilder
.
add
(
encoderCompatibilityFrameProcessor
);
effectsListBuilder
.
add
(()
->
encoderCompatibilityFrameProcessor
);
frameProcessorChain
=
frameProcessorChain
=
FrameProcessorChain
.
create
(
FrameProcessorChain
.
create
(
context
,
context
,
inputFormat
.
pixelWidthHeightRatio
,
inputFormat
.
pixelWidthHeightRatio
,
/* inputWidth= */
decodedWidth
,
/* inputWidth= */
decodedWidth
,
/* inputHeight= */
decodedHeight
,
/* inputHeight= */
decodedHeight
,
frameProcessor
sListBuilder
.
build
(),
effect
sListBuilder
.
build
(),
transformationRequest
.
enableHdrEditing
);
transformationRequest
.
enableHdrEditing
);
Size
requestedEncoderSize
=
frameProcessorChain
.
getOutputSize
();
Size
requestedEncoderSize
=
frameProcessorChain
.
getOutputSize
();
outputRotationDegrees
=
encoderCompatibilityFrameProcessor
.
getOutputRotationDegrees
();
outputRotationDegrees
=
encoderCompatibilityFrameProcessor
.
getOutputRotationDegrees
();
...
...
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