From 7be24522ce2e1821ad45e7ada7c3f91e6814889a Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Mon, 14 Jul 2014 12:24:56 -0700 Subject: [PATCH] MediaExtractor: set buffer offset/limit in readSampleData also fix setting offset/limit in MediaCodec's getBuffer. Bug: 13008204 Change-Id: Iadf0f006cfccc2546971cc5384058e1a2721780b --- media/java/android/media/MediaCodec.java | 11 ++++++-- media/java/android/media/MediaExtractor.java | 13 ++++++--- media/jni/android_media_MediaCodec.cpp | 8 +++--- media/jni/android_media_MediaExtractor.cpp | 28 +++++++++++++++++--- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index cb9776a322e44..4abcb810440aa 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -1157,6 +1157,9 @@ final public class MediaCodec { * @deprecated Use the new {@link #getInputBuffer} method instead * each time an input buffer is dequeued. * + * Note:As of API 21, dequeued input buffers are + * automatically {@link java.nio.Buffer#clear cleared}. + * * @throws IllegalStateException if not in the Executing state. * @throws MediaCodec.CodecException upon codec error. */ @@ -1180,6 +1183,10 @@ final public class MediaCodec { * each time an output buffer is dequeued. This method is not * supported if codec is configured in asynchronous mode. * + * Note:As of API 21, the position and limit of output + * buffers that are dequeued will be set to the valid data + * range. + * * @throws IllegalStateException if not in the Executing state, * or codec is configured in asynchronous mode. * @throws MediaCodec.CodecException upon codec error. @@ -1213,8 +1220,8 @@ final public class MediaCodec { } /** - * Returns a cleared, writable ByteBuffer object for a dequeued - * input buffer index to contain the input data. + * Returns a {@link java.nio.Buffer#clear cleared}, writable ByteBuffer + * object for a dequeued input buffer index to contain the input data. * * After calling this method any ByteBuffer or Image object * previously returned for the same input index MUST no longer diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java index f2753ee419a8a..b23b540ebee22 100644 --- a/media/java/android/media/MediaExtractor.java +++ b/media/java/android/media/MediaExtractor.java @@ -297,8 +297,12 @@ final public class MediaExtractor { /** * Retrieve the current encoded sample and store it in the byte buffer - * starting at the given offset. Returns the sample size (or -1 if - * no more samples are available). + * starting at the given offset. + *

+ * Note:As of API 21, on success the position and limit of + * {@code byteBuf} is updated to point to the data just read. + * @param byteBuf the destination byte buffer + * @return the sample size (or -1 if no more samples are available). */ public native int readSampleData(ByteBuffer byteBuf, int offset); @@ -316,7 +320,10 @@ final public class MediaExtractor { // Keep these in sync with their equivalents in NuMediaExtractor.h /** - * The sample is a sync sample + * The sample is a sync sample (or in {@link MediaCodec}'s terminology + * it is a key frame.) + * + * @see MediaCodec#BUFFER_FLAG_KEY_FRAME */ public static final int SAMPLE_FLAG_SYNC = 1; diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 6a835d6a7d15c..b7294b8719eb5 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -448,14 +448,14 @@ status_t JMediaCodec::getBuffer( jobject me = env->CallObjectMethod( byteBuffer, orderID, nativeByteOrderObj); env->DeleteLocalRef(me); - me = env->CallObjectMethod( - byteBuffer, positionID, - input ? 0 : buffer->offset()); - env->DeleteLocalRef(me); me = env->CallObjectMethod( byteBuffer, limitID, input ? buffer->capacity() : (buffer->offset() + buffer->size())); env->DeleteLocalRef(me); + me = env->CallObjectMethod( + byteBuffer, positionID, + input ? 0 : buffer->offset()); + env->DeleteLocalRef(me); me = NULL; env->DeleteLocalRef(nativeByteOrderObj); diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index 3dbf77ba74c99..52e99100e8e88 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include "android_util_Binder.h" namespace android { @@ -206,12 +208,12 @@ status_t JMediaExtractor::readSampleData( size_t dstSize; jbyteArray byteArray = NULL; - if (dst == NULL) { - jclass byteBufClass = env->FindClass("java/nio/ByteBuffer"); - CHECK(byteBufClass != NULL); + ScopedLocalRef byteBufClass(env, env->FindClass("java/nio/ByteBuffer")); + CHECK(byteBufClass.get() != NULL); + if (dst == NULL) { jmethodID arrayID = - env->GetMethodID(byteBufClass, "array", "()[B"); + env->GetMethodID(byteBufClass.get(), "array", "()[B"); CHECK(arrayID != NULL); byteArray = @@ -251,6 +253,24 @@ status_t JMediaExtractor::readSampleData( *sampleSize = buffer->size(); + jmethodID positionID = env->GetMethodID( + byteBufClass.get(), "position", "(I)Ljava/nio/Buffer;"); + + CHECK(positionID != NULL); + + jmethodID limitID = env->GetMethodID( + byteBufClass.get(), "limit", "(I)Ljava/nio/Buffer;"); + + CHECK(limitID != NULL); + + jobject me = env->CallObjectMethod( + byteBuf, limitID, offset + *sampleSize); + env->DeleteLocalRef(me); + me = env->CallObjectMethod( + byteBuf, positionID, offset); + env->DeleteLocalRef(me); + me = NULL; + return OK; }