Documentation/API update for MediaCodec/MediaExtractor, fixes to MediaCodec.

and MediaExtractor.readSampleData now works with a non-direct byte buffer.

Change-Id: Ifbe5c152d9550c34d3b1d493e12a223eb98e8b4e
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 4757adf..0c86fc2 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -101,14 +101,37 @@
 
     void *dst = env->GetDirectBufferAddress(byteBuf);
 
+    jlong dstSize;
+    jbyteArray byteArray = NULL;
+
     if (dst == NULL) {
-        // XXX if dst is NULL also fall back to "array()"
-        return INVALID_OPERATION;
+        jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
+        CHECK(byteBufClass != NULL);
+
+        jmethodID arrayID =
+            env->GetMethodID(byteBufClass, "array", "()[B");
+        CHECK(arrayID != NULL);
+
+        byteArray =
+            (jbyteArray)env->CallObjectMethod(byteBuf, arrayID);
+
+        if (byteArray == NULL) {
+            return INVALID_OPERATION;
+        }
+
+        jboolean isCopy;
+        dst = env->GetByteArrayElements(byteArray, &isCopy);
+
+        dstSize = env->GetArrayLength(byteArray);
+    } else {
+        dstSize = env->GetDirectBufferCapacity(byteBuf);
     }
 
-    jlong dstSize = env->GetDirectBufferCapacity(byteBuf);
-
     if (dstSize < offset) {
+        if (byteArray != NULL) {
+            env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
+        }
+
         return -ERANGE;
     }
 
@@ -116,6 +139,10 @@
 
     status_t err = mImpl->readSampleData(buffer);
 
+    if (byteArray != NULL) {
+        env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
+    }
+
     if (err != OK) {
         return err;
     }