Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java

Issue 1383983003: Android MediaCodecVideoDecoder: Cleanup to prepare for texture liftime management (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Replace CallBooleanMethod() with CallVoidMethod() Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « talk/app/webrtc/java/jni/androidmediadecoder_jni.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
index 4809cf65b29b13d7d59b0bf623b4b657f489a7c6..7221a36190efed15b3605b2adc2a40280fba84da 100644
--- a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
+++ b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
@@ -42,6 +42,8 @@ import android.view.Surface;
import org.webrtc.Logging;
import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Arrays;
// Java-side of peerconnection_jni.cc:MediaCodecVideoDecoder.
// This class is an implementation detail of the Java PeerConnection API.
@@ -80,19 +82,18 @@ public class MediaCodecVideoDecoder {
private static final int
COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04;
// Allowable color formats supported by codec - in order of preference.
- private static final int[] supportedColorList = {
+ private static final List<Integer> supportedColorList = Arrays.asList(
CodecCapabilities.COLOR_FormatYUV420Planar,
CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
- COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m
- };
+ COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m);
private int colorFormat;
private int width;
private int height;
private int stride;
private int sliceHeight;
private boolean useSurface;
- private int textureID = -1;
+ private int textureID = 0;
private SurfaceTexture surfaceTexture = null;
private Surface surface = null;
private EglBase eglBase;
@@ -171,9 +172,9 @@ public class MediaCodecVideoDecoder {
return findDecoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null;
}
- private void checkOnMediaCodecThread() {
+ private void checkOnMediaCodecThread() throws IllegalStateException {
if (mediaCodecThread.getId() != Thread.currentThread().getId()) {
- throw new RuntimeException(
+ throw new IllegalStateException(
"MediaCodecVideoDecoder previously operated on " + mediaCodecThread +
" but is now called on " + Thread.currentThread());
}
@@ -208,7 +209,6 @@ public class MediaCodecVideoDecoder {
}
mediaCodecThread = Thread.currentThread();
try {
- Surface decodeSurface = null;
this.width = width;
this.height = height;
stride = width;
@@ -225,7 +225,6 @@ public class MediaCodecVideoDecoder {
Logging.d(TAG, "Video decoder TextureID = " + textureID);
surfaceTexture = new SurfaceTexture(textureID);
surface = new Surface(surfaceTexture);
- decodeSurface = surface;
}
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
@@ -238,7 +237,7 @@ public class MediaCodecVideoDecoder {
if (mediaCodec == null) {
return false;
}
- mediaCodec.configure(format, decodeSurface, null, 0);
+ mediaCodec.configure(format, surface, null, 0);
mediaCodec.start();
colorFormat = properties.colorFormat;
outputBuffers = mediaCodec.getOutputBuffers();
@@ -265,11 +264,10 @@ public class MediaCodecVideoDecoder {
mediaCodecThread = null;
if (useSurface) {
surface.release();
- if (textureID != 0) {
- Logging.d(TAG, "Delete video decoder TextureID " + textureID);
- GLES20.glDeleteTextures(1, new int[] {textureID}, 0);
- textureID = 0;
- }
+ surface = null;
+ Logging.d(TAG, "Delete video decoder TextureID " + textureID);
+ GLES20.glDeleteTextures(1, new int[] {textureID}, 0);
+ textureID = 0;
eglBase.release();
eglBase = null;
}
@@ -318,19 +316,26 @@ public class MediaCodecVideoDecoder {
private final long presentationTimestampUs;
}
- // Dequeue and return an output buffer index, -1 if no output
- // buffer available or -2 if error happened.
- private DecoderOutputBufferInfo dequeueOutputBuffer(int dequeueTimeoutUs) {
+ // Dequeue and return a DecoderOutputBufferInfo, or null if no decoded buffer is ready.
+ // Throws IllegalStateException if call is made on the wrong thread, if color format changes to an
+ // unsupported format, or if |mediaCodec| is not in the Executing state. Throws CodecException
+ // upon codec error.
+ private DecoderOutputBufferInfo dequeueOutputBuffer(int dequeueTimeoutUs)
+ throws IllegalStateException, MediaCodec.CodecException {
checkOnMediaCodecThread();
- try {
- MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
- int result = mediaCodec.dequeueOutputBuffer(info, dequeueTimeoutUs);
- while (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED ||
- result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
- if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+ // Drain the decoder until receiving a decoded buffer or hitting
+ // MediaCodec.INFO_TRY_AGAIN_LATER.
+ final MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ while (true) {
+ final int result = mediaCodec.dequeueOutputBuffer(info, dequeueTimeoutUs);
+ switch (result) {
+ case MediaCodec.INFO_TRY_AGAIN_LATER:
+ return null;
+ case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
outputBuffers = mediaCodec.getOutputBuffers();
Logging.d(TAG, "Decoder output buffers changed: " + outputBuffers.length);
- } else if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ break;
+ case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
MediaFormat format = mediaCodec.getOutputFormat();
Logging.d(TAG, "Decoder format changed: " + format.toString());
width = format.getInteger(MediaFormat.KEY_WIDTH);
@@ -338,17 +343,8 @@ public class MediaCodecVideoDecoder {
if (!useSurface && format.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
colorFormat = format.getInteger(MediaFormat.KEY_COLOR_FORMAT);
Logging.d(TAG, "Color: 0x" + Integer.toHexString(colorFormat));
- // Check if new color space is supported.
- boolean validColorFormat = false;
- for (int supportedColorFormat : supportedColorList) {
- if (colorFormat == supportedColorFormat) {
- validColorFormat = true;
- break;
- }
- }
- if (!validColorFormat) {
- Logging.e(TAG, "Non supported color format");
- return new DecoderOutputBufferInfo(-1, 0, 0, -1);
+ if (!supportedColorList.contains(colorFormat)) {
+ throw new IllegalStateException("Non supported color format: " + colorFormat);
}
}
if (format.containsKey("stride")) {
@@ -357,34 +353,24 @@ public class MediaCodecVideoDecoder {
if (format.containsKey("slice-height")) {
sliceHeight = format.getInteger("slice-height");
}
- Logging.d(TAG, "Frame stride and slice height: "
- + stride + " x " + sliceHeight);
+ Logging.d(TAG, "Frame stride and slice height: " + stride + " x " + sliceHeight);
stride = Math.max(width, stride);
sliceHeight = Math.max(height, sliceHeight);
- }
- result = mediaCodec.dequeueOutputBuffer(info, dequeueTimeoutUs);
- }
- if (result >= 0) {
- return new DecoderOutputBufferInfo(result, info.offset, info.size,
- info.presentationTimeUs);
+ break;
+ default:
+ // Output buffer decoded.
+ return new DecoderOutputBufferInfo(
+ result, info.offset, info.size, info.presentationTimeUs);
}
- return null;
- } catch (IllegalStateException e) {
- Logging.e(TAG, "dequeueOutputBuffer failed", e);
- return new DecoderOutputBufferInfo(-1, 0, 0, -1);
}
}
- // Release a dequeued output buffer back to the codec for re-use. Return
- // false if the codec is no longer operable.
- private boolean releaseOutputBuffer(int index) {
+ // Release a dequeued output buffer back to the codec for re-use.
+ // Throws IllegalStateException if the call is made on the wrong thread or if |mediaCodec| is not
+ // in the Executing state. Throws MediaCodec.CodecException upon codec error.
+ private void releaseOutputBuffer(int index)
+ throws IllegalStateException, MediaCodec.CodecException {
checkOnMediaCodecThread();
- try {
- mediaCodec.releaseOutputBuffer(index, useSurface);
- return true;
- } catch (IllegalStateException e) {
- Logging.e(TAG, "releaseOutputBuffer failed", e);
- return false;
- }
+ mediaCodec.releaseOutputBuffer(index, useSurface);
}
}
« no previous file with comments | « talk/app/webrtc/java/jni/androidmediadecoder_jni.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698