mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Refactor frame rate notification to release control
Frame rate change is currently notified to the release control when the video frame processor input frame rate changes, but it should be when the video frame processor output frame rate changes. PiperOrigin-RevId: 688512300
This commit is contained in:
parent
31ece8cbd2
commit
8260bb3d2e
@ -157,6 +157,14 @@ public interface VideoFrameProcessor {
|
||||
*/
|
||||
default void onOutputSizeChanged(int width, int height) {}
|
||||
|
||||
/**
|
||||
* Called when the output frame rate changes.
|
||||
*
|
||||
* @param frameRate The output frame rate in frames per second, or {@link Format#NO_VALUE} if
|
||||
* unknown.
|
||||
*/
|
||||
default void onOutputFrameRateChanged(float frameRate) {}
|
||||
|
||||
/**
|
||||
* Called when an output frame with the given {@code presentationTimeUs} becomes available for
|
||||
* rendering.
|
||||
|
@ -35,6 +35,14 @@ public interface VideoGraph {
|
||||
*/
|
||||
default void onOutputSizeChanged(int width, int height) {}
|
||||
|
||||
/**
|
||||
* Called when the output frame rate changes.
|
||||
*
|
||||
* @param frameRate The output frame rate in frames per second, or {@link Format#NO_VALUE} if
|
||||
* unknown.
|
||||
*/
|
||||
default void onOutputFrameRateChanged(float frameRate) {}
|
||||
|
||||
/**
|
||||
* Called when an output frame with the given {@code framePresentationTimeUs} becomes available
|
||||
* for rendering.
|
||||
|
@ -457,6 +457,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
private final List<GlShaderProgram> intermediateGlShaderPrograms;
|
||||
private final ConditionVariable inputStreamRegisteredCondition;
|
||||
|
||||
private @MonotonicNonNull InputStreamInfo currentInputStreamInfo;
|
||||
|
||||
/**
|
||||
* The input stream that is {@linkplain #registerInputStream registered}, but the pipeline has not
|
||||
* adapted to processing it.
|
||||
@ -515,7 +517,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
if (pendingInputStreamInfo != null) {
|
||||
InputStreamInfo pendingInputStreamInfo = this.pendingInputStreamInfo;
|
||||
videoFrameProcessingTaskExecutor.submit(
|
||||
() -> configureEffects(pendingInputStreamInfo, /* forceReconfigure= */ false));
|
||||
() -> configure(pendingInputStreamInfo, /* forceReconfigure= */ false));
|
||||
this.pendingInputStreamInfo = null;
|
||||
}
|
||||
}
|
||||
@ -659,7 +661,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
registeredFirstInputStream = true;
|
||||
inputStreamRegisteredCondition.close();
|
||||
videoFrameProcessingTaskExecutor.submit(
|
||||
() -> configureEffects(pendingInputStreamInfo, /* forceReconfigure= */ true));
|
||||
() -> configure(pendingInputStreamInfo, /* forceReconfigure= */ true));
|
||||
} else {
|
||||
// Rejects further inputs after signaling EOS and before the next input stream is fully
|
||||
// configured.
|
||||
@ -988,16 +990,17 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link GlShaderProgram} instances for {@code effects}.
|
||||
* Configures for a new input stream.
|
||||
*
|
||||
* <p>The pipeline will only re-configure if the {@link InputStreamInfo#effects new effects}
|
||||
* doesn't match the {@link #activeEffects}, or when {@code forceReconfigure} is set to {@code
|
||||
* true}.
|
||||
* <p>The effect pipeline will only re-configure if the {@link InputStreamInfo#effects new
|
||||
* effects} don't match the {@link #activeEffects}, or when {@code forceReconfigure} is set to
|
||||
* {@code true}.
|
||||
*/
|
||||
private void configureEffects(InputStreamInfo inputStreamInfo, boolean forceReconfigure)
|
||||
private void configure(InputStreamInfo inputStreamInfo, boolean forceReconfigure)
|
||||
throws VideoFrameProcessingException {
|
||||
checkColors(
|
||||
/* inputColorInfo= */ checkNotNull(inputStreamInfo.format.colorInfo), outputColorInfo);
|
||||
|
||||
if (forceReconfigure || !activeEffects.equals(inputStreamInfo.effects)) {
|
||||
if (!intermediateGlShaderPrograms.isEmpty()) {
|
||||
for (int i = 0; i < intermediateGlShaderPrograms.size(); i++) {
|
||||
@ -1035,10 +1038,17 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
onInputSurfaceReadyListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
listenerExecutor.execute(
|
||||
() ->
|
||||
listener.onInputStreamRegistered(
|
||||
inputStreamInfo.inputType, inputStreamInfo.format, inputStreamInfo.effects));
|
||||
if (currentInputStreamInfo == null
|
||||
|| inputStreamInfo.format.frameRate != currentInputStreamInfo.format.frameRate) {
|
||||
listenerExecutor.execute(
|
||||
() -> listener.onOutputFrameRateChanged(inputStreamInfo.format.frameRate));
|
||||
}
|
||||
this.currentInputStreamInfo = inputStreamInfo;
|
||||
}
|
||||
|
||||
/** Checks that color configuration is valid for {@link DefaultVideoFrameProcessor}. */
|
||||
|
@ -176,6 +176,11 @@ public abstract class MultipleInputVideoGraph implements VideoGraph {
|
||||
listenerExecutor.execute(() -> listener.onOutputSizeChanged(width, height));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameRateChanged(float frameRate) {
|
||||
listenerExecutor.execute(() -> listener.onOutputFrameRateChanged(frameRate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameAvailableForRendering(long presentationTimeUs) {
|
||||
if (presentationTimeUs == 0) {
|
||||
|
@ -114,6 +114,11 @@ public abstract class SingleInputVideoGraph implements VideoGraph {
|
||||
listenerExecutor.execute(() -> listener.onOutputSizeChanged(width, height));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameRateChanged(float frameRate) {
|
||||
listenerExecutor.execute(() -> listener.onOutputFrameRateChanged(frameRate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameAvailableForRendering(long presentationTimeUs) {
|
||||
if (isEnded) {
|
||||
|
@ -339,6 +339,11 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
defaultVideoSink.onInputStreamChanged(INPUT_TYPE_SURFACE, format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameRateChanged(float frameRate) {
|
||||
videoFrameReleaseControl.setFrameRate(frameRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameAvailableForRendering(long framePresentationTimeUs) {
|
||||
if (pendingFlushCount > 0) {
|
||||
@ -596,7 +601,6 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported input type " + inputType);
|
||||
}
|
||||
videoFrameReleaseControl.setFrameRate(format.frameRate);
|
||||
this.inputType = inputType;
|
||||
this.inputFormat = format;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user