Commit 61c9c169 by olly Committed by Oliver Woodman

Make sure we report video size after Surface is set

Issue: #2077

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=139451511
parent 051be5c5
...@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer; ...@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -85,8 +86,8 @@ public final class LibvpxVideoRenderer extends BaseRenderer { ...@@ -85,8 +86,8 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
private boolean inputStreamEnded; private boolean inputStreamEnded;
private boolean outputStreamEnded; private boolean outputStreamEnded;
private int previousWidth; private int lastReportedWidth;
private int previousHeight; private int lastReportedHeight;
private long droppedFrameAccumulationStartTimeMs; private long droppedFrameAccumulationStartTimeMs;
private int droppedFrames; private int droppedFrames;
...@@ -146,8 +147,7 @@ public final class LibvpxVideoRenderer extends BaseRenderer { ...@@ -146,8 +147,7 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
this.drmSessionManager = drmSessionManager; this.drmSessionManager = drmSessionManager;
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys; this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
joiningDeadlineMs = -1; joiningDeadlineMs = -1;
previousWidth = -1; clearLastReportedVideoSize();
previousHeight = -1;
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
eventDispatcher = new EventDispatcher(eventHandler, eventListener); eventDispatcher = new EventDispatcher(eventHandler, eventListener);
outputMode = VpxDecoder.OUTPUT_MODE_NONE; outputMode = VpxDecoder.OUTPUT_MODE_NONE;
...@@ -446,6 +446,7 @@ public final class LibvpxVideoRenderer extends BaseRenderer { ...@@ -446,6 +446,7 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
outputBuffer = null; outputBuffer = null;
format = null; format = null;
waitingForKeys = false; waitingForKeys = false;
clearLastReportedVideoSize();
try { try {
releaseDecoder(); releaseDecoder();
} finally { } finally {
...@@ -520,35 +521,29 @@ public final class LibvpxVideoRenderer extends BaseRenderer { ...@@ -520,35 +521,29 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
@Override @Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException { public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
if (messageType == C.MSG_SET_SURFACE) { if (messageType == C.MSG_SET_SURFACE) {
setSurface((Surface) message); setOutput((Surface) message, null);
} else if (messageType == MSG_SET_OUTPUT_BUFFER_RENDERER) { } else if (messageType == MSG_SET_OUTPUT_BUFFER_RENDERER) {
setOutputBufferRenderer((VpxOutputBufferRenderer) message); setOutput(null, (VpxOutputBufferRenderer) message);
} else { } else {
super.handleMessage(messageType, message); super.handleMessage(messageType, message);
} }
} }
private void setSurface(Surface surface) { private void setOutput(Surface surface, VpxOutputBufferRenderer outputBufferRenderer) {
if (this.surface == surface) { // At most one output may be non-null. Both may be null if the output is being cleared.
return; Assertions.checkState(surface == null || outputBufferRenderer == null);
} // Clear state so that we always call the event listener with the video size and when a frame
// is rendered, even if the output hasn't changed.
renderedFirstFrame = false; renderedFirstFrame = false;
this.surface = surface; clearLastReportedVideoSize();
outputBufferRenderer = null; // We only need to update the decoder if the output has changed.
outputMode = (surface != null) ? VpxDecoder.OUTPUT_MODE_RGB : VpxDecoder.OUTPUT_MODE_NONE; if (this.surface != surface || this.outputBufferRenderer != outputBufferRenderer) {
updateDecoder(); this.surface = surface;
} this.outputBufferRenderer = outputBufferRenderer;
outputMode = outputBufferRenderer != null ? VpxDecoder.OUTPUT_MODE_YUV
private void setOutputBufferRenderer(VpxOutputBufferRenderer outputBufferRenderer) { : surface != null ? VpxDecoder.OUTPUT_MODE_RGB : VpxDecoder.OUTPUT_MODE_NONE;
if (this.outputBufferRenderer == outputBufferRenderer) { updateDecoder();
return;
} }
renderedFirstFrame = false;
this.outputBufferRenderer = outputBufferRenderer;
surface = null;
outputMode = (outputBufferRenderer != null) ? VpxDecoder.OUTPUT_MODE_YUV
: VpxDecoder.OUTPUT_MODE_NONE;
updateDecoder();
} }
private void updateDecoder() { private void updateDecoder() {
...@@ -565,10 +560,15 @@ public final class LibvpxVideoRenderer extends BaseRenderer { ...@@ -565,10 +560,15 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
return surface != null || outputBufferRenderer != null; return surface != null || outputBufferRenderer != null;
} }
private void maybeNotifyVideoSizeChanged(final int width, final int height) { private void clearLastReportedVideoSize() {
if (previousWidth != width || previousHeight != height) { lastReportedWidth = Format.NO_VALUE;
previousWidth = width; lastReportedHeight = Format.NO_VALUE;
previousHeight = height; }
private void maybeNotifyVideoSizeChanged(int width, int height) {
if (lastReportedWidth != width || lastReportedHeight != height) {
lastReportedWidth = width;
lastReportedHeight = height;
eventDispatcher.videoSizeChanged(width, height, 0, 1); eventDispatcher.videoSizeChanged(width, height, 0, 1);
} }
} }
......
...@@ -163,9 +163,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -163,9 +163,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
currentHeight = Format.NO_VALUE; currentHeight = Format.NO_VALUE;
currentPixelWidthHeightRatio = Format.NO_VALUE; currentPixelWidthHeightRatio = Format.NO_VALUE;
pendingPixelWidthHeightRatio = Format.NO_VALUE; pendingPixelWidthHeightRatio = Format.NO_VALUE;
lastReportedWidth = Format.NO_VALUE; clearLastReportedVideoSize();
lastReportedHeight = Format.NO_VALUE;
lastReportedPixelWidthHeightRatio = Format.NO_VALUE;
} }
@Override @Override
...@@ -272,9 +270,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -272,9 +270,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
currentHeight = Format.NO_VALUE; currentHeight = Format.NO_VALUE;
currentPixelWidthHeightRatio = Format.NO_VALUE; currentPixelWidthHeightRatio = Format.NO_VALUE;
pendingPixelWidthHeightRatio = Format.NO_VALUE; pendingPixelWidthHeightRatio = Format.NO_VALUE;
lastReportedWidth = Format.NO_VALUE; clearLastReportedVideoSize();
lastReportedHeight = Format.NO_VALUE;
lastReportedPixelWidthHeightRatio = Format.NO_VALUE;
frameReleaseTimeHelper.disable(); frameReleaseTimeHelper.disable();
try { try {
super.onDisabled(); super.onDisabled();
...@@ -294,15 +290,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -294,15 +290,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
private void setSurface(Surface surface) throws ExoPlaybackException { private void setSurface(Surface surface) throws ExoPlaybackException {
if (this.surface == surface) { // Clear state so that we always call the event listener with the video size and when a frame
return; // is rendered, even if the surface hasn't changed.
}
renderedFirstFrame = false; renderedFirstFrame = false;
this.surface = surface; clearLastReportedVideoSize();
int state = getState(); // We only need to actually release and reinitialize the codec if the surface has changed.
if (state == STATE_ENABLED || state == STATE_STARTED) { if (this.surface != surface) {
releaseCodec(); this.surface = surface;
maybeInitCodec(); int state = getState();
if (state == STATE_ENABLED || state == STATE_STARTED) {
releaseCodec();
maybeInitCodec();
}
} }
} }
...@@ -584,6 +583,13 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -584,6 +583,13 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
return (maxPixels * 3) / (2 * minCompressionRatio); return (maxPixels * 3) / (2 * minCompressionRatio);
} }
private void clearLastReportedVideoSize() {
lastReportedWidth = Format.NO_VALUE;
lastReportedHeight = Format.NO_VALUE;
lastReportedPixelWidthHeightRatio = Format.NO_VALUE;
lastReportedUnappliedRotationDegrees = Format.NO_VALUE;
}
private void maybeNotifyVideoSizeChanged() { private void maybeNotifyVideoSizeChanged() {
if (lastReportedWidth != currentWidth || lastReportedHeight != currentHeight if (lastReportedWidth != currentWidth || lastReportedHeight != currentHeight
|| lastReportedUnappliedRotationDegrees != currentUnappliedRotationDegrees || lastReportedUnappliedRotationDegrees != currentUnappliedRotationDegrees
......
...@@ -69,7 +69,8 @@ public interface VideoRendererEventListener { ...@@ -69,7 +69,8 @@ public interface VideoRendererEventListener {
void onDroppedFrames(int count, long elapsedMs); void onDroppedFrames(int count, long elapsedMs);
/** /**
* Called each time there's a change in the size of the video being rendered. * Called before a frame is rendered for the first time since setting the surface, and each time
* there's a change in the size, rotation or pixel aspect ratio of the video being rendered.
* *
* @param width The video width in pixels. * @param width The video width in pixels.
* @param height The video height in pixels. * @param height The video height in pixels.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment