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
82ab327e
authored
Mar 07, 2023
by
tofunmi
Committed by
tonihei
Mar 14, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Update effect to take in and use a GlObjectsProvider
PiperOrigin-RevId: 514744747
parent
0bec22f3
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
192 additions
and
69 deletions
demos/transformer/src/withMediaPipe/java/com/google/android/exoplayer2/transformerdemo/MediaPipeShaderProgram.java
library/common/src/main/java/com/google/android/exoplayer2/util/VideoFrameProcessor.java
library/effect/src/androidTest/java/com/google/android/exoplayer2/effect/DefaultVideoFrameProcessorVideoFrameReleaseTest.java
library/effect/src/main/java/com/google/android/exoplayer2/effect/DefaultVideoFrameProcessor.java
library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalShaderProgramWrapper.java
library/effect/src/main/java/com/google/android/exoplayer2/effect/FrameCacheGlShaderProgram.java
library/effect/src/main/java/com/google/android/exoplayer2/effect/GlShaderProgram.java
library/effect/src/main/java/com/google/android/exoplayer2/effect/SingleFrameGlShaderProgram.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoSamplePipeline.java
demos/transformer/src/withMediaPipe/java/com/google/android/exoplayer2/transformerdemo/MediaPipeShaderProgram.java
View file @
82ab327e
...
...
@@ -25,6 +25,7 @@ import android.opengl.EGL14;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.effect.GlShaderProgram
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.LibraryLoader
;
import
com.google.android.exoplayer2.util.Util
;
...
...
@@ -160,6 +161,9 @@ import java.util.concurrent.Future;
}
@Override
public
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{}
@Override
public
void
queueInputFrame
(
GlTextureInfo
inputTexture
,
long
presentationTimeUs
)
{
AppTextureFrame
appTextureFrame
=
new
AppTextureFrame
(
inputTexture
.
texId
,
inputTexture
.
width
,
inputTexture
.
height
);
...
...
library/common/src/main/java/com/google/android/exoplayer2/util/VideoFrameProcessor.java
View file @
82ab327e
...
...
@@ -41,6 +41,15 @@ public interface VideoFrameProcessor {
/** A factory for {@link VideoFrameProcessor} instances. */
interface
Factory
{
/**
* Sets the {@link GlObjectsProvider}.
*
* <p>Must be called before {@link #create}.
*/
Factory
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
);
// TODO(271433904): Turn parameters with default values into setters.
/**
* Creates a new {@link VideoFrameProcessor} instance.
*
...
...
library/effect/src/androidTest/java/com/google/android/exoplayer2/effect/DefaultVideoFrameProcessorVideoFrameReleaseTest.java
View file @
82ab327e
...
...
@@ -28,6 +28,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.util.DebugViewProvider
;
import
com.google.android.exoplayer2.util.FrameInfo
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.GlUtil
;
import
com.google.android.exoplayer2.util.SurfaceInfo
;
...
...
@@ -411,6 +412,9 @@ public final class DefaultVideoFrameProcessorVideoFrameReleaseTest {
public
void
setErrorListener
(
Executor
executor
,
ErrorListener
errorListener
)
{}
@Override
public
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{}
@Override
public
void
queueInputFrame
(
GlTextureInfo
inputTexture
,
long
presentationTimeUs
)
{
// No input is queued in these tests. The BlankFrameProducer is used to produce frames.
throw
new
UnsupportedOperationException
();
...
...
library/effect/src/main/java/com/google/android/exoplayer2/effect/DefaultVideoFrameProcessor.java
View file @
82ab327e
...
...
@@ -35,6 +35,7 @@ import com.google.android.exoplayer2.C;
import
com.google.android.exoplayer2.util.DebugViewProvider
;
import
com.google.android.exoplayer2.util.Effect
;
import
com.google.android.exoplayer2.util.FrameInfo
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlUtil
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.SurfaceInfo
;
...
...
@@ -60,6 +61,20 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
/** A factory for {@link DefaultVideoFrameProcessor} instances. */
public
static
final
class
Factory
implements
VideoFrameProcessor
.
Factory
{
private
GlObjectsProvider
glObjectsProvider
=
GlObjectsProvider
.
DEFAULT
;
/**
* {@inheritDoc}
*
* <p>The default value is {@link GlObjectsProvider#DEFAULT}.
*/
@Override
public
DefaultVideoFrameProcessor
.
Factory
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{
this
.
glObjectsProvider
=
glObjectsProvider
;
return
this
;
}
/**
* {@inheritDoc}
*
...
...
@@ -137,7 +152,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
releaseFramesAutomatically
,
singleThreadExecutorService
,
listenerExecutor
,
listener
));
listener
,
glObjectsProvider
));
try
{
return
defaultVideoFrameProcessorFuture
.
get
();
...
...
@@ -365,7 +381,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
boolean
releaseFramesAutomatically
,
ExecutorService
singleThreadExecutorService
,
Executor
executor
,
Listener
listener
)
Listener
listener
,
GlObjectsProvider
glObjectsProvider
)
throws
GlUtil
.
GlException
,
VideoFrameProcessingException
{
checkState
(
Thread
.
currentThread
().
getName
().
equals
(
THREAD_NAME
));
...
...
@@ -378,7 +395,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
:
GlUtil
.
EGL_CONFIG_ATTRIBUTES_RGBA_8888
;
int
openGlVersion
=
ColorInfo
.
isTransferHdr
(
inputColorInfo
)
||
ColorInfo
.
isTransferHdr
(
outputColorInfo
)
?
3
:
2
;
EGLContext
eglContext
=
GlUtil
.
createEglContext
(
eglDisplay
,
openGlVersion
,
configAttributes
);
EGLContext
eglContext
=
glObjectsProvider
.
createEglContext
(
eglDisplay
,
openGlVersion
,
configAttributes
);
GlUtil
.
createFocusedPlaceholderEglSurface
(
eglContext
,
eglDisplay
,
configAttributes
);
// Not releaseFramesAutomatically means outputting to a display surface. HDR display surfaces
...
...
@@ -407,6 +425,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
releaseFramesAutomatically
,
executor
,
listener
);
setGlObjectProviderOnShaderPrograms
(
shaderPrograms
,
glObjectsProvider
);
VideoFrameProcessingTaskExecutor
videoFrameProcessingTaskExecutor
=
new
VideoFrameProcessingTaskExecutor
(
singleThreadExecutorService
,
listener
);
chainShaderProgramsWithListeners
(
...
...
@@ -520,6 +539,15 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
return
shaderProgramListBuilder
.
build
();
}
/** Sets the {@link GlObjectsProvider} on all of the {@linkplain GlShaderProgram}s provided. */
private
static
void
setGlObjectProviderOnShaderPrograms
(
ImmutableList
<
GlShaderProgram
>
shaderPrograms
,
GlObjectsProvider
glObjectsProvider
)
{
for
(
int
i
=
0
;
i
<
shaderPrograms
.
size
()
-
1
;
i
++)
{
GlShaderProgram
shaderProgram
=
shaderPrograms
.
get
(
i
);
shaderProgram
.
setGlObjectsProvider
(
glObjectsProvider
);
}
}
/**
* Chains the given {@link GlShaderProgram} instances using {@link
* ChainingGlShaderProgramListener} instances.
...
...
library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalShaderProgramWrapper.java
View file @
82ab327e
...
...
@@ -34,6 +34,7 @@ import androidx.annotation.GuardedBy;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.util.DebugViewProvider
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.GlUtil
;
import
com.google.android.exoplayer2.util.Log
;
...
...
@@ -86,9 +87,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private
int
inputHeight
;
@Nullable
private
DefaultShaderProgram
defaultShaderProgram
;
@Nullable
private
SurfaceViewWrapper
debugSurfaceViewWrapper
;
private
GlObjectsProvider
glObjectsProvider
;
private
InputListener
inputListener
;
private
@MonotonicNonNull
Size
outputSizeBeforeSurfaceTransformation
;
@Nullable
private
SurfaceView
debugSurfaceView
;
private
boolean
frameProcessingStarted
;
private
volatile
boolean
outputSizeOrRotationChanged
;
...
...
@@ -130,11 +133,20 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
textureTransformMatrix
=
GlUtil
.
create4x4IdentityMatrix
();
streamOffsetUsQueue
=
new
ConcurrentLinkedQueue
<>();
glObjectsProvider
=
GlObjectsProvider
.
DEFAULT
;
inputListener
=
new
InputListener
()
{};
availableFrames
=
new
ConcurrentLinkedQueue
<>();
}
@Override
public
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{
checkState
(
!
frameProcessingStarted
,
"The GlObjectsProvider cannot be set after frame processing has started."
);
this
.
glObjectsProvider
=
glObjectsProvider
;
}
@Override
public
void
setInputListener
(
InputListener
inputListener
)
{
this
.
inputListener
=
inputListener
;
inputListener
.
onReadyToAcceptInputFrame
();
...
...
@@ -154,6 +166,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override
public
void
signalEndOfCurrentInputStream
()
{
frameProcessingStarted
=
true
;
checkState
(!
streamOffsetUsQueue
.
isEmpty
(),
"No input stream to end."
);
streamOffsetUsQueue
.
remove
();
if
(
streamOffsetUsQueue
.
isEmpty
())
{
...
...
@@ -178,6 +191,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override
public
void
queueInputFrame
(
GlTextureInfo
inputTexture
,
long
presentationTimeUs
)
{
frameProcessingStarted
=
true
;
long
streamOffsetUs
=
checkStateNotNull
(
streamOffsetUsQueue
.
peek
(),
"No input stream specified."
);
long
offsetPresentationTimeUs
=
presentationTimeUs
+
streamOffsetUs
;
...
...
@@ -199,6 +213,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
public
void
releaseOutputFrame
(
long
releaseTimeNs
)
{
frameProcessingStarted
=
true
;
checkState
(!
releaseFramesAutomatically
);
Pair
<
GlTextureInfo
,
Long
>
oldestAvailableFrame
=
availableFrames
.
remove
();
renderFrameToSurfaces
(
...
...
@@ -209,6 +224,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override
public
void
flush
()
{
frameProcessingStarted
=
true
;
// Drops all frames that aren't released yet.
availableFrames
.
clear
();
if
(
defaultShaderProgram
!=
null
)
{
...
...
@@ -304,7 +320,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
outputEglSurface
,
outputSurfaceInfo
.
width
,
outputSurfaceInfo
.
height
);
GlUtil
.
clearOutputFrame
();
glObjectsProvider
.
clearOutputFrame
();
defaultShaderProgram
.
drawFrame
(
inputTexture
.
texId
,
presentationTimeUs
);
EGLExt
.
eglPresentationTimeANDROID
(
...
...
@@ -446,7 +462,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
try
{
debugSurfaceViewWrapper
.
maybeRenderToSurfaceView
(
()
->
{
GlUtil
.
clearOutputFrame
();
glObjectsProvider
.
clearOutputFrame
();
@C
.
ColorTransfer
int
configuredColorTransfer
=
defaultShaderProgram
.
getOutputColorTransfer
();
defaultShaderProgram
.
setOutputColorTransfer
(
...
...
library/effect/src/main/java/com/google/android/exoplayer2/effect/FrameCacheGlShaderProgram.java
View file @
82ab327e
...
...
@@ -19,7 +19,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
import
android.content.Context
;
import
android.opengl.GLES20
;
import
com.google.android.exoplayer2.
C
;
import
com.google.android.exoplayer2.
util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlProgram
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.GlUtil
;
...
...
@@ -49,10 +49,12 @@ import java.util.concurrent.Executor;
private
final
int
capacity
;
private
final
boolean
useHdr
;
private
GlObjectsProvider
glObjectsProvider
;
private
InputListener
inputListener
;
private
OutputListener
outputListener
;
private
ErrorListener
errorListener
;
private
Executor
errorListenerExecutor
;
private
boolean
frameProcessingStarted
;
/** Creates a new instance. */
public
FrameCacheGlShaderProgram
(
Context
context
,
int
capacity
,
boolean
useHdr
)
...
...
@@ -80,6 +82,7 @@ import java.util.concurrent.Executor;
GlUtil
.
getNormalizedCoordinateBounds
(),
GlUtil
.
HOMOGENEOUS_COORDINATE_VECTOR_SIZE
);
glObjectsProvider
=
GlObjectsProvider
.
DEFAULT
;
inputListener
=
new
InputListener
()
{};
outputListener
=
new
OutputListener
()
{};
errorListener
=
videoFrameProcessingException
->
{};
...
...
@@ -87,6 +90,14 @@ import java.util.concurrent.Executor;
}
@Override
public
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{
checkState
(
!
frameProcessingStarted
,
"The GlObjectsProvider cannot be set after frame processing has started."
);
this
.
glObjectsProvider
=
glObjectsProvider
;
}
@Override
public
void
setInputListener
(
InputListener
inputListener
)
{
this
.
inputListener
=
inputListener
;
int
numberOfFreeFramesToNotify
;
...
...
@@ -115,6 +126,7 @@ import java.util.concurrent.Executor;
@Override
public
void
queueInputFrame
(
GlTextureInfo
inputTexture
,
long
presentationTimeUs
)
{
frameProcessingStarted
=
true
;
try
{
configureAllOutputTextures
(
inputTexture
.
width
,
inputTexture
.
height
);
...
...
@@ -125,7 +137,7 @@ import java.util.concurrent.Executor;
// Copy frame to fbo.
GlUtil
.
focusFramebufferUsingCurrentContext
(
outputTexture
.
fboId
,
outputTexture
.
width
,
outputTexture
.
height
);
GlUtil
.
clearOutputFrame
();
glObjectsProvider
.
clearOutputFrame
();
drawFrame
(
inputTexture
.
texId
);
inputListener
.
onInputFrameProcessed
(
inputTexture
);
outputListener
.
onOutputFrameAvailable
(
outputTexture
,
presentationTimeUs
);
...
...
@@ -147,6 +159,7 @@ import java.util.concurrent.Executor;
@Override
public
void
releaseOutputFrame
(
GlTextureInfo
outputTexture
)
{
frameProcessingStarted
=
true
;
checkState
(
inUseOutputTextures
.
contains
(
outputTexture
));
inUseOutputTextures
.
remove
(
outputTexture
);
freeOutputTextures
.
add
(
outputTexture
);
...
...
@@ -155,11 +168,13 @@ import java.util.concurrent.Executor;
@Override
public
void
signalEndOfCurrentInputStream
()
{
frameProcessingStarted
=
true
;
outputListener
.
onCurrentOutputStreamEnded
();
}
@Override
public
void
flush
()
{
frameProcessingStarted
=
true
;
freeOutputTextures
.
addAll
(
inUseOutputTextures
);
inUseOutputTextures
.
clear
();
inputListener
.
onFlush
();
...
...
@@ -170,6 +185,7 @@ import java.util.concurrent.Executor;
@Override
public
void
release
()
throws
VideoFrameProcessingException
{
frameProcessingStarted
=
true
;
try
{
deleteAllOutputTextures
();
}
catch
(
GlUtil
.
GlException
e
)
{
...
...
@@ -196,9 +212,8 @@ import java.util.concurrent.Executor;
checkState
(
inUseOutputTextures
.
isEmpty
());
for
(
int
i
=
0
;
i
<
capacity
;
i
++)
{
int
outputTexId
=
GlUtil
.
createTexture
(
width
,
height
,
useHdr
);
int
outputFboId
=
GlUtil
.
createFboForTexture
(
outputTexId
);
GlTextureInfo
outputTexture
=
new
GlTextureInfo
(
outputTexId
,
outputFboId
,
/* rboId= */
C
.
INDEX_UNSET
,
width
,
height
);
glObjectsProvider
.
createBuffersForTexture
(
outputTexId
,
width
,
height
);
freeOutputTextures
.
add
(
outputTexture
);
}
}
...
...
library/effect/src/main/java/com/google/android/exoplayer2/effect/GlShaderProgram.java
View file @
82ab327e
...
...
@@ -15,6 +15,7 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
effect
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.VideoFrameProcessingException
;
import
java.util.concurrent.Executor
;
...
...
@@ -147,6 +148,13 @@ public interface GlShaderProgram {
void
setErrorListener
(
Executor
executor
,
ErrorListener
errorListener
);
/**
* Sets the {@link GlObjectsProvider}.
*
* <p>This method should not be called after any of the frame processing methods.
*/
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
);
/**
* Processes an input frame if possible.
*
* <p>The {@code GlShaderProgram} owns the accepted frame until it calls {@link
...
...
library/effect/src/main/java/com/google/android/exoplayer2/effect/SingleFrameGlShaderProgram.java
View file @
82ab327e
...
...
@@ -18,7 +18,7 @@ package com.google.android.exoplayer2.effect;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkState
;
import
androidx.annotation.CallSuper
;
import
com.google.android.exoplayer2.
C
;
import
com.google.android.exoplayer2.
util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.GlTextureInfo
;
import
com.google.android.exoplayer2.util.GlUtil
;
import
com.google.android.exoplayer2.util.Size
;
...
...
@@ -42,6 +42,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
private
final
boolean
useHdr
;
private
GlObjectsProvider
glObjectsProvider
;
private
InputListener
inputListener
;
private
OutputListener
outputListener
;
private
ErrorListener
errorListener
;
...
...
@@ -50,6 +51,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
private
int
inputHeight
;
private
@MonotonicNonNull
GlTextureInfo
outputTexture
;
private
boolean
outputTextureInUse
;
private
boolean
frameProcessingStarted
;
/**
* Creates a {@code SingleFrameGlShaderProgram} instance.
...
...
@@ -59,6 +61,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
*/
public
SingleFrameGlShaderProgram
(
boolean
useHdr
)
{
this
.
useHdr
=
useHdr
;
glObjectsProvider
=
GlObjectsProvider
.
DEFAULT
;
inputListener
=
new
InputListener
()
{};
outputListener
=
new
OutputListener
()
{};
errorListener
=
(
videoFrameProcessingException
)
->
{};
...
...
@@ -97,6 +100,14 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
throws
VideoFrameProcessingException
;
@Override
public
void
setGlObjectsProvider
(
GlObjectsProvider
glObjectsProvider
)
{
checkState
(
!
frameProcessingStarted
,
"The GlObjectsProvider cannot be set after frame processing has started."
);
this
.
glObjectsProvider
=
glObjectsProvider
;
}
@Override
public
final
void
setInputListener
(
InputListener
inputListener
)
{
this
.
inputListener
=
inputListener
;
if
(!
outputTextureInUse
)
{
...
...
@@ -121,7 +132,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
!
outputTextureInUse
,
"The shader program does not currently accept input frames. Release prior output frames"
+
" first."
);
frameProcessingStarted
=
true
;
try
{
if
(
outputTexture
==
null
||
inputTexture
.
width
!=
inputWidth
...
...
@@ -131,7 +142,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
outputTextureInUse
=
true
;
GlUtil
.
focusFramebufferUsingCurrentContext
(
outputTexture
.
fboId
,
outputTexture
.
width
,
outputTexture
.
height
);
GlUtil
.
clearOutputFrame
();
glObjectsProvider
.
clearOutputFrame
();
drawFrame
(
inputTexture
.
texId
,
presentationTimeUs
);
inputListener
.
onInputFrameProcessed
(
inputTexture
);
outputListener
.
onOutputFrameAvailable
(
outputTexture
,
presentationTimeUs
);
...
...
@@ -159,25 +170,22 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
GlUtil
.
deleteFbo
(
outputTexture
.
fboId
);
}
int
outputTexId
=
GlUtil
.
createTexture
(
outputSize
.
getWidth
(),
outputSize
.
getHeight
(),
useHdr
);
int
outputFboId
=
GlUtil
.
createFboForTexture
(
outputTexId
);
outputTexture
=
new
GlTextureInfo
(
outputTexId
,
outputFboId
,
/* rboId= */
C
.
INDEX_UNSET
,
outputSize
.
getWidth
(),
outputSize
.
getHeight
());
glObjectsProvider
.
createBuffersForTexture
(
outputTexId
,
outputSize
.
getWidth
(),
outputSize
.
getHeight
());
}
}
@Override
public
final
void
releaseOutputFrame
(
GlTextureInfo
outputTexture
)
{
outputTextureInUse
=
false
;
frameProcessingStarted
=
true
;
inputListener
.
onReadyToAcceptInputFrame
();
}
@Override
public
final
void
signalEndOfCurrentInputStream
()
{
frameProcessingStarted
=
true
;
outputListener
.
onCurrentOutputStreamEnded
();
}
...
...
@@ -185,6 +193,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
@CallSuper
public
void
flush
()
{
outputTextureInUse
=
false
;
frameProcessingStarted
=
true
;
inputListener
.
onFlush
();
inputListener
.
onReadyToAcceptInputFrame
();
}
...
...
@@ -192,6 +201,7 @@ public abstract class SingleFrameGlShaderProgram implements GlShaderProgram {
@Override
@CallSuper
public
void
release
()
throws
VideoFrameProcessingException
{
frameProcessingStarted
=
true
;
if
(
outputTexture
!=
null
)
{
try
{
GlUtil
.
deleteTexture
(
outputTexture
.
texId
);
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java
View file @
82ab327e
...
...
@@ -19,6 +19,7 @@ import com.google.android.exoplayer2.MediaItem;
import
com.google.android.exoplayer2.audio.AudioProcessor
;
import
com.google.android.exoplayer2.effect.DefaultVideoFrameProcessor
;
import
com.google.android.exoplayer2.util.Effect
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.VideoFrameProcessor
;
import
com.google.common.collect.ImmutableList
;
import
java.util.List
;
...
...
@@ -47,15 +48,25 @@ public final class Effects {
* applying the {@code videoEffects} to the video frames.
*/
public
final
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
;
/**
* The {@link GlObjectsProvider} used to create and maintain certain GL Objects in the {@link
* VideoFrameProcessor}.
*/
public
final
GlObjectsProvider
glObjectsProvider
;
/**
* Creates an instance using a {@link DefaultVideoFrameProcessor.Factory}.
*
* <p>This is equivalent to calling {@link Effects#Effects(List, List,
* VideoFrameProcessor.Factory)} with a {@link DefaultVideoFrameProcessor.Factory}.
* VideoFrameProcessor.Factory, GlObjectsProvider)} with a {@link
* DefaultVideoFrameProcessor.Factory} and {@link GlObjectsProvider#DEFAULT}.
*/
public
Effects
(
List
<
AudioProcessor
>
audioProcessors
,
List
<
Effect
>
videoEffects
)
{
this
(
audioProcessors
,
videoEffects
,
new
DefaultVideoFrameProcessor
.
Factory
());
this
(
audioProcessors
,
videoEffects
,
new
DefaultVideoFrameProcessor
.
Factory
(),
GlObjectsProvider
.
DEFAULT
);
}
/**
...
...
@@ -64,13 +75,16 @@ public final class Effects {
* @param audioProcessors The {@link #audioProcessors}.
* @param videoEffects The {@link #videoEffects}.
* @param videoFrameProcessorFactory The {@link #videoFrameProcessorFactory}.
* @param glObjectsProvider The {@link GlObjectsProvider}.
*/
public
Effects
(
List
<
AudioProcessor
>
audioProcessors
,
List
<
Effect
>
videoEffects
,
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
)
{
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
,
GlObjectsProvider
glObjectsProvider
)
{
this
.
audioProcessors
=
ImmutableList
.
copyOf
(
audioProcessors
);
this
.
videoEffects
=
ImmutableList
.
copyOf
(
videoEffects
);
this
.
videoFrameProcessorFactory
=
videoFrameProcessorFactory
;
this
.
glObjectsProvider
=
glObjectsProvider
;
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
View file @
82ab327e
...
...
@@ -35,6 +35,7 @@ import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import
com.google.android.exoplayer2.util.Clock
;
import
com.google.android.exoplayer2.util.DebugViewProvider
;
import
com.google.android.exoplayer2.util.Effect
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.HandlerWrapper
;
import
com.google.android.exoplayer2.util.ListenerSet
;
import
com.google.android.exoplayer2.util.MimeTypes
;
...
...
@@ -86,6 +87,7 @@ public final class Transformer {
private
ListenerSet
<
Transformer
.
Listener
>
listeners
;
private
AssetLoader
.
@MonotonicNonNull
Factory
assetLoaderFactory
;
private
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
;
private
GlObjectsProvider
glObjectsProvider
;
private
Codec
.
EncoderFactory
encoderFactory
;
private
Muxer
.
Factory
muxerFactory
;
private
Looper
looper
;
...
...
@@ -103,6 +105,7 @@ public final class Transformer {
audioProcessors
=
ImmutableList
.
of
();
videoEffects
=
ImmutableList
.
of
();
videoFrameProcessorFactory
=
new
DefaultVideoFrameProcessor
.
Factory
();
glObjectsProvider
=
GlObjectsProvider
.
DEFAULT
;
encoderFactory
=
new
DefaultEncoderFactory
.
Builder
(
this
.
context
).
build
();
muxerFactory
=
new
DefaultMuxer
.
Factory
();
looper
=
Util
.
getCurrentOrMainLooper
();
...
...
@@ -122,6 +125,7 @@ public final class Transformer {
this
.
listeners
=
transformer
.
listeners
;
this
.
assetLoaderFactory
=
transformer
.
assetLoaderFactory
;
this
.
videoFrameProcessorFactory
=
transformer
.
videoFrameProcessorFactory
;
this
.
glObjectsProvider
=
transformer
.
glObjectsProvider
;
this
.
encoderFactory
=
transformer
.
encoderFactory
;
this
.
muxerFactory
=
transformer
.
muxerFactory
;
this
.
looper
=
transformer
.
looper
;
...
...
@@ -395,6 +399,7 @@ public final class Transformer {
listeners
,
assetLoaderFactory
,
videoFrameProcessorFactory
,
glObjectsProvider
,
encoderFactory
,
muxerFactory
,
looper
,
...
...
@@ -554,6 +559,7 @@ public final class Transformer {
private
final
ListenerSet
<
Transformer
.
Listener
>
listeners
;
private
final
AssetLoader
.
Factory
assetLoaderFactory
;
private
final
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
;
private
final
GlObjectsProvider
glObjectsProvider
;
private
final
Codec
.
EncoderFactory
encoderFactory
;
private
final
Muxer
.
Factory
muxerFactory
;
private
final
Looper
looper
;
...
...
@@ -573,6 +579,7 @@ public final class Transformer {
ListenerSet
<
Listener
>
listeners
,
AssetLoader
.
Factory
assetLoaderFactory
,
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
,
GlObjectsProvider
glObjectsProvider
,
Codec
.
EncoderFactory
encoderFactory
,
Muxer
.
Factory
muxerFactory
,
Looper
looper
,
...
...
@@ -589,6 +596,7 @@ public final class Transformer {
this
.
listeners
=
listeners
;
this
.
assetLoaderFactory
=
assetLoaderFactory
;
this
.
videoFrameProcessorFactory
=
videoFrameProcessorFactory
;
this
.
glObjectsProvider
=
glObjectsProvider
;
this
.
encoderFactory
=
encoderFactory
;
this
.
muxerFactory
=
muxerFactory
;
this
.
looper
=
looper
;
...
...
@@ -792,7 +800,9 @@ public final class Transformer {
.
setRemoveAudio
(
removeAudio
)
.
setRemoveVideo
(
removeVideo
)
.
setFlattenForSlowMotion
(
flattenForSlowMotion
)
.
setEffects
(
new
Effects
(
audioProcessors
,
videoEffects
,
videoFrameProcessorFactory
))
.
setEffects
(
new
Effects
(
audioProcessors
,
videoEffects
,
videoFrameProcessorFactory
,
glObjectsProvider
))
.
build
();
start
(
editedMediaItem
,
path
);
}
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java
View file @
82ab327e
...
...
@@ -533,6 +533,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
firstEditedMediaItem
.
effects
.
videoEffects
,
compositionPresentation
,
firstEditedMediaItem
.
effects
.
videoFrameProcessorFactory
,
firstEditedMediaItem
.
effects
.
glObjectsProvider
,
encoderFactory
,
muxerWrapper
,
/* errorConsumer= */
this
::
onError
,
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoSamplePipeline.java
View file @
82ab327e
...
...
@@ -37,6 +37,7 @@ import com.google.android.exoplayer2.util.Consumer;
import
com.google.android.exoplayer2.util.DebugViewProvider
;
import
com.google.android.exoplayer2.util.Effect
;
import
com.google.android.exoplayer2.util.FrameInfo
;
import
com.google.android.exoplayer2.util.GlObjectsProvider
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.Size
;
...
...
@@ -81,6 +82,7 @@ import org.checkerframework.dataflow.qual.Pure;
ImmutableList
<
Effect
>
effects
,
@Nullable
Presentation
presentation
,
VideoFrameProcessor
.
Factory
videoFrameProcessorFactory
,
GlObjectsProvider
glObjectsProvider
,
Codec
.
EncoderFactory
encoderFactory
,
MuxerWrapper
muxerWrapper
,
Consumer
<
ExportException
>
errorConsumer
,
...
...
@@ -129,52 +131,54 @@ import org.checkerframework.dataflow.qual.Pure;
}
try
{
videoFrameProcessor
=
videoFrameProcessorFactory
.
create
(
context
,
effectsWithPresentation
,
debugViewProvider
,
videoFrameProcessorInputColor
,
videoFrameProcessorOutputColor
,
MimeTypes
.
isVideo
(
firstInputFormat
.
sampleMimeType
),
/* releaseFramesAutomatically= */
true
,
MoreExecutors
.
directExecutor
(),
new
VideoFrameProcessor
.
Listener
()
{
private
long
lastProcessedFramePresentationTimeUs
;
@Override
public
void
onOutputSizeChanged
(
int
width
,
int
height
)
{
try
{
checkNotNull
(
videoFrameProcessor
)
.
setOutputSurfaceInfo
(
encoderWrapper
.
getSurfaceInfo
(
width
,
height
));
}
catch
(
ExportException
exception
)
{
errorConsumer
.
accept
(
exception
);
}
}
@Override
public
void
onOutputFrameAvailable
(
long
presentationTimeUs
)
{
// Frames are released automatically.
lastProcessedFramePresentationTimeUs
=
presentationTimeUs
;
}
@Override
public
void
onError
(
VideoFrameProcessingException
exception
)
{
errorConsumer
.
accept
(
ExportException
.
createForVideoFrameProcessingException
(
exception
,
ExportException
.
ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED
));
}
@Override
public
void
onEnded
()
{
VideoSamplePipeline
.
this
.
finalFramePresentationTimeUs
=
lastProcessedFramePresentationTimeUs
;
try
{
encoderWrapper
.
signalEndOfInputStream
();
}
catch
(
ExportException
exception
)
{
errorConsumer
.
accept
(
exception
);
}
}
});
videoFrameProcessorFactory
.
setGlObjectsProvider
(
glObjectsProvider
)
.
create
(
context
,
effectsWithPresentation
,
debugViewProvider
,
videoFrameProcessorInputColor
,
videoFrameProcessorOutputColor
,
MimeTypes
.
isVideo
(
firstInputFormat
.
sampleMimeType
),
/* releaseFramesAutomatically= */
true
,
MoreExecutors
.
directExecutor
(),
new
VideoFrameProcessor
.
Listener
()
{
private
long
lastProcessedFramePresentationTimeUs
;
@Override
public
void
onOutputSizeChanged
(
int
width
,
int
height
)
{
try
{
checkNotNull
(
videoFrameProcessor
)
.
setOutputSurfaceInfo
(
encoderWrapper
.
getSurfaceInfo
(
width
,
height
));
}
catch
(
ExportException
exception
)
{
errorConsumer
.
accept
(
exception
);
}
}
@Override
public
void
onOutputFrameAvailable
(
long
presentationTimeUs
)
{
// Frames are released automatically.
lastProcessedFramePresentationTimeUs
=
presentationTimeUs
;
}
@Override
public
void
onError
(
VideoFrameProcessingException
exception
)
{
errorConsumer
.
accept
(
ExportException
.
createForVideoFrameProcessingException
(
exception
,
ExportException
.
ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED
));
}
@Override
public
void
onEnded
()
{
VideoSamplePipeline
.
this
.
finalFramePresentationTimeUs
=
lastProcessedFramePresentationTimeUs
;
try
{
encoderWrapper
.
signalEndOfInputStream
();
}
catch
(
ExportException
exception
)
{
errorConsumer
.
accept
(
exception
);
}
}
});
}
catch
(
VideoFrameProcessingException
e
)
{
throw
ExportException
.
createForVideoFrameProcessingException
(
e
,
ExportException
.
ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED
);
...
...
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