Add a FrameProcessor flag to drop the processed frame

This mode is supported by using `C.TIME_UNSET` (which is a negative value). The
new logic decouples the value of `C.TIME_UNSET` and the frame dropping
behaviour.

PiperOrigin-RevId: 479368880
This commit is contained in:
claincly 2022-10-06 18:30:14 +00:00 committed by Marc Baechinger
parent 4c73241058
commit ccab9fba03
3 changed files with 10 additions and 6 deletions

View File

@ -28,7 +28,6 @@ import androidx.media3.common.FrameProcessingException;
import androidx.media3.common.FrameProcessor; import androidx.media3.common.FrameProcessor;
import androidx.media3.common.SurfaceInfo; import androidx.media3.common.SurfaceInfo;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.util.GlUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.ColorInfo; import com.google.android.exoplayer2.video.ColorInfo;
@ -180,7 +179,7 @@ public final class GlEffectsFrameProcessorFrameReleaseTest {
} }
@Test @Test
public void controlledFrameRelease_withUnsetReleaseTime_dropsFrame() throws Exception { public void controlledFrameRelease_requestsFrameDropping_dropsFrame() throws Exception {
long originalPresentationTimeUs = 1234; long originalPresentationTimeUs = 1234;
AtomicLong actualPresentationTimeUs = new AtomicLong(); AtomicLong actualPresentationTimeUs = new AtomicLong();
setupGlEffectsFrameProcessorWithBlankFrameProducer( setupGlEffectsFrameProcessorWithBlankFrameProducer(
@ -188,7 +187,7 @@ public final class GlEffectsFrameProcessorFrameReleaseTest {
/* onFrameAvailableListener= */ presentationTimeNs -> { /* onFrameAvailableListener= */ presentationTimeNs -> {
actualPresentationTimeUs.set(presentationTimeNs); actualPresentationTimeUs.set(presentationTimeNs);
checkNotNull(glEffectsFrameProcessor) checkNotNull(glEffectsFrameProcessor)
.releaseOutputFrame(/* releaseTimeNs= */ C.TIME_UNSET); .releaseOutputFrame(FrameProcessor.DROP_OUTPUT_FRAME);
}, },
/* releaseFramesAutomatically= */ false); /* releaseFramesAutomatically= */ false);

View File

@ -174,6 +174,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (releaseTimeNs == FrameProcessor.RELEASE_OUTPUT_FRAME_IMMEDIATELY) { if (releaseTimeNs == FrameProcessor.RELEASE_OUTPUT_FRAME_IMMEDIATELY) {
dropLateFrame = false; dropLateFrame = false;
releaseTimeNs = System.nanoTime(); releaseTimeNs = System.nanoTime();
} else if (releaseTimeNs == FrameProcessor.DROP_OUTPUT_FRAME) {
releaseTimeNs = C.TIME_UNSET;
} }
Pair<TextureInfo, Long> oldestAvailableFrame = availableFrames.remove(); Pair<TextureInfo, Long> oldestAvailableFrame = availableFrames.remove();

View File

@ -107,6 +107,9 @@ public interface FrameProcessor {
*/ */
long RELEASE_OUTPUT_FRAME_IMMEDIATELY = -1; long RELEASE_OUTPUT_FRAME_IMMEDIATELY = -1;
/** Indicates the frame should be dropped after {@link #releaseOutputFrame(long)} is invoked. */
long DROP_OUTPUT_FRAME = -2;
/** Returns the input {@link Surface}, where {@link FrameProcessor} consumes input frames from. */ /** Returns the input {@link Surface}, where {@link FrameProcessor} consumes input frames from. */
Surface getInputSurface(); Surface getInputSurface();
@ -170,9 +173,9 @@ public interface FrameProcessor {
* {@linkplain Listener#onOutputFrameAvailable(long) available}. * {@linkplain Listener#onOutputFrameAvailable(long) available}.
* *
* @param releaseTimeNs The release time to use for the frame, in nanoseconds. Use {@link * @param releaseTimeNs The release time to use for the frame, in nanoseconds. Use {@link
* C#TIME_UNSET} to drop the frame, or {@link #RELEASE_OUTPUT_FRAME_IMMEDIATELY} to release * #DROP_OUTPUT_FRAME} to drop the frame, or {@link #RELEASE_OUTPUT_FRAME_IMMEDIATELY} to
* the frame immediately. If {@code releaseTimeNs} is after {@link System#nanoTime()} at the * release the frame immediately. If {@code releaseTimeNs} is after {@link System#nanoTime()}
* time of the release, the frame is also dropped. * at the time of the release, the frame is also dropped.
*/ */
void releaseOutputFrame(long releaseTimeNs); void releaseOutputFrame(long releaseTimeNs);