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
10050a1e
authored
Jun 15, 2022
by
hschlueter
Committed by
Marc Baechinger
Jun 15, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Replace FrameProcessorChain#isEnded with listener method.
PiperOrigin-RevId: 455114693
parent
d20f6849
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
59 additions
and
24 deletions
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/FrameProcessorChainPixelTest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameProcessorChain.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoTranscodingSamplePipeline.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/FrameProcessorChainPixelTest.java
View file @
10050a1e
...
@@ -89,9 +89,10 @@ public final class FrameProcessorChainPixelTest {
...
@@ -89,9 +89,10 @@ public final class FrameProcessorChainPixelTest {
private
final
AtomicReference
<
FrameProcessingException
>
frameProcessingException
=
private
final
AtomicReference
<
FrameProcessingException
>
frameProcessingException
=
new
AtomicReference
<>();
new
AtomicReference
<>();
private
@MonotonicNonNull
MediaFormat
mediaFormat
;
private
@MonotonicNonNull
FrameProcessorChain
frameProcessorChain
;
private
@MonotonicNonNull
FrameProcessorChain
frameProcessorChain
;
private
volatile
@MonotonicNonNull
ImageReader
outputImageReader
;
private
volatile
@MonotonicNonNull
ImageReader
outputImageReader
;
private
@MonotonicNonNull
MediaFormat
mediaFormat
;
private
volatile
boolean
frameProcessingEnded
;
@After
@After
public
void
release
()
{
public
void
release
()
{
...
@@ -354,7 +355,17 @@ public final class FrameProcessorChainPixelTest {
...
@@ -354,7 +355,17 @@ public final class FrameProcessorChainPixelTest {
checkNotNull
(
checkNotNull
(
FrameProcessorChain
.
create
(
FrameProcessorChain
.
create
(
context
,
context
,
/* listener= */
this
.
frameProcessingException
::
set
,
new
FrameProcessorChain
.
Listener
()
{
@Override
public
void
onFrameProcessingError
(
FrameProcessingException
exception
)
{
frameProcessingException
.
set
(
exception
);
}
@Override
public
void
onFrameProcessingEnded
()
{
frameProcessingEnded
=
true
;
}
},
pixelWidthHeightRatio
,
pixelWidthHeightRatio
,
inputWidth
,
inputWidth
,
inputHeight
,
inputHeight
,
...
@@ -421,7 +432,7 @@ public final class FrameProcessorChainPixelTest {
...
@@ -421,7 +432,7 @@ public final class FrameProcessorChainPixelTest {
private
Bitmap
processFirstFrameAndEnd
()
throws
InterruptedException
{
private
Bitmap
processFirstFrameAndEnd
()
throws
InterruptedException
{
checkNotNull
(
frameProcessorChain
).
signalEndOfInputStream
();
checkNotNull
(
frameProcessorChain
).
signalEndOfInputStream
();
Thread
.
sleep
(
FRAME_PROCESSING_WAIT_MS
);
Thread
.
sleep
(
FRAME_PROCESSING_WAIT_MS
);
assertThat
(
frameProcess
orChain
.
isEnded
()
).
isTrue
();
assertThat
(
frameProcess
ingEnded
).
isTrue
();
assertThat
(
frameProcessingException
.
get
()).
isNull
();
assertThat
(
frameProcessingException
.
get
()).
isNull
();
Image
frameProcessorChainOutputImage
=
checkNotNull
(
outputImageReader
).
acquireLatestImage
();
Image
frameProcessorChainOutputImage
=
checkNotNull
(
outputImageReader
).
acquireLatestImage
();
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameProcessorChain.java
View file @
10050a1e
...
@@ -71,8 +71,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
...
@@ -71,8 +71,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* <p>This listener is only called from the {@link FrameProcessorChain}'s background thread.
* <p>This listener is only called from the {@link FrameProcessorChain}'s background thread.
*/
*/
public
interface
Listener
{
public
interface
Listener
{
/** Called when an exception occurs during asynchronous frame processing. */
/**
* Called when an exception occurs during asynchronous frame processing.
*
* <p>If an error occurred, consuming and producing further frames will not work as expected and
* the {@link FrameProcessorChain} should be released.
*/
void
onFrameProcessingError
(
FrameProcessingException
exception
);
void
onFrameProcessingError
(
FrameProcessingException
exception
);
/** Called after the frame processor has produced its final output frame. */
void
onFrameProcessingEnded
();
}
}
/**
/**
...
@@ -454,22 +462,24 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
...
@@ -454,22 +462,24 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return
pendingFrameCount
.
get
();
return
pendingFrameCount
.
get
();
}
}
/** Informs the {@code FrameProcessorChain} that no further input frames should be accepted. */
/**
* Informs the {@code FrameProcessorChain} that no further input frames should be accepted.
*
* @throws IllegalStateException If called more than once.
*/
public
void
signalEndOfInputStream
()
{
public
void
signalEndOfInputStream
()
{
checkState
(!
inputStreamEnded
);
inputStreamEnded
=
true
;
inputStreamEnded
=
true
;
}
futures
.
add
(
singleThreadExecutorService
.
submit
(
this
::
signalEndOfOutputStream
));
/** Returns whether all frames have been processed. */
public
boolean
isEnded
()
{
return
inputStreamEnded
&&
getPendingFrameCount
()
==
0
;
}
}
/**
/**
* Releases all resources.
* Releases all resources.
*
*
* <p>If the frame processor chain is released before it has {@linkplain #isEnded() ended}, it
* <p>If the frame processor chain is released before it has {@linkplain
* will attempt to cancel processing any input frames that have already become available. Input
* Listener#onFrameProcessingEnded() ended}, it will attempt to cancel processing any input frames
* frames that become available after release are ignored.
* that have already become available. Input frames that become available after release are
* ignored.
*
*
* <p>This method blocks until all OpenGL resources are released or releasing times out.
* <p>This method blocks until all OpenGL resources are released or releasing times out.
*/
*/
...
@@ -563,6 +573,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
...
@@ -563,6 +573,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
}
}
}
/** Calls {@link Listener#onFrameProcessingEnded()} once no more frames are pending. */
@WorkerThread
private
void
signalEndOfOutputStream
()
{
if
(
getPendingFrameCount
()
==
0
)
{
listener
.
onFrameProcessingEnded
();
}
else
{
futures
.
add
(
singleThreadExecutorService
.
submit
(
this
::
signalEndOfOutputStream
));
}
}
/**
/**
* Releases the {@link SingleFrameGlTextureProcessor SingleFrameGlTextureProcessors} and destroys
* Releases the {@link SingleFrameGlTextureProcessor SingleFrameGlTextureProcessors} and destroys
* the OpenGL context.
* the OpenGL context.
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoTranscodingSamplePipeline.java
View file @
10050a1e
...
@@ -51,8 +51,6 @@ import org.checkerframework.dataflow.qual.Pure;
...
@@ -51,8 +51,6 @@ import org.checkerframework.dataflow.qual.Pure;
private
final
EncoderWrapper
encoderWrapper
;
private
final
EncoderWrapper
encoderWrapper
;
private
final
DecoderInputBuffer
encoderOutputBuffer
;
private
final
DecoderInputBuffer
encoderOutputBuffer
;
private
boolean
signaledEndOfStreamToEncoder
;
public
VideoTranscodingSamplePipeline
(
public
VideoTranscodingSamplePipeline
(
Context
context
,
Context
context
,
Format
inputFormat
,
Format
inputFormat
,
...
@@ -110,10 +108,23 @@ import org.checkerframework.dataflow.qual.Pure;
...
@@ -110,10 +108,23 @@ import org.checkerframework.dataflow.qual.Pure;
frameProcessorChain
=
frameProcessorChain
=
FrameProcessorChain
.
create
(
FrameProcessorChain
.
create
(
context
,
context
,
/* listener= */
exception
->
new
FrameProcessorChain
.
Listener
()
{
@Override
public
void
onFrameProcessingError
(
FrameProcessingException
exception
)
{
asyncErrorListener
.
onTransformationException
(
asyncErrorListener
.
onTransformationException
(
TransformationException
.
createForFrameProcessorChain
(
TransformationException
.
createForFrameProcessorChain
(
exception
,
TransformationException
.
ERROR_CODE_GL_PROCESSING_FAILED
)),
exception
,
TransformationException
.
ERROR_CODE_GL_PROCESSING_FAILED
));
}
@Override
public
void
onFrameProcessingEnded
()
{
try
{
encoderWrapper
.
signalEndOfInputStream
();
}
catch
(
TransformationException
exception
)
{
asyncErrorListener
.
onTransformationException
(
exception
);
}
}
},
inputFormat
.
pixelWidthHeightRatio
,
inputFormat
.
pixelWidthHeightRatio
,
/* inputWidth= */
decodedWidth
,
/* inputWidth= */
decodedWidth
,
/* inputHeight= */
decodedHeight
,
/* inputHeight= */
decodedHeight
,
...
@@ -157,13 +168,6 @@ import org.checkerframework.dataflow.qual.Pure;
...
@@ -157,13 +168,6 @@ import org.checkerframework.dataflow.qual.Pure;
@Override
@Override
public
boolean
processData
()
throws
TransformationException
{
public
boolean
processData
()
throws
TransformationException
{
if
(
frameProcessorChain
.
isEnded
())
{
if
(!
signaledEndOfStreamToEncoder
)
{
encoderWrapper
.
signalEndOfInputStream
();
signaledEndOfStreamToEncoder
=
true
;
}
return
false
;
}
if
(
decoder
.
isEnded
())
{
if
(
decoder
.
isEnded
())
{
return
false
;
return
false
;
}
}
...
...
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