summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-05-09 20:58:57 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-05-09 20:58:57 +0000
commit0f94e3f5ede4ab16c0ef4a4b36f03e9a98fa05ac (patch)
tree9f737e0726923d7eeec6f7f3e6cc50a0627376d7
parentf992066731fb27a6d9fc8bae673c638093610292 (diff)
parent7c513b6bef8ed4dfc28e0af6c8594563fdb9f436 (diff)
downloadframeworks_base-0f94e3f5ede4ab16c0ef4a4b36f03e9a98fa05ac.zip
frameworks_base-0f94e3f5ede4ab16c0ef4a4b36f03e9a98fa05ac.tar.gz
frameworks_base-0f94e3f5ede4ab16c0ef4a4b36f03e9a98fa05ac.tar.bz2
Merge "Added MediaCodec.releaseOutputBuffer() method with render timestamp"
-rw-r--r--api/current.txt1
-rw-r--r--media/java/android/media/MediaCodec.java56
-rw-r--r--media/jni/android_media_MediaCodec.cpp13
-rw-r--r--media/jni/android_media_MediaCodec.h3
4 files changed, 66 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt
index ea27c92..89261b2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13834,6 +13834,7 @@ package android.media {
method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
method public final void release();
method public final void releaseOutputBuffer(int, boolean);
+ method public final void releaseOutputBuffer(int, long);
method public void setNotificationCallback(android.media.MediaCodec.NotificationCallback);
method public final void setParameters(android.os.Bundle);
method public final void setVideoScalingMode(int);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 115786c..34c5520 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -585,11 +585,63 @@ final public class MediaCodec {
* the codec. If you previously specified a surface when configuring this
* video decoder you can optionally render the buffer.
* @param index The index of a client-owned output buffer previously returned
- * in a call to {@link #dequeueOutputBuffer}.
+ * from a call to {@link #dequeueOutputBuffer}.
* @param render If a valid surface was specified when configuring the codec,
* passing true renders this output buffer to the surface.
*/
- public native final void releaseOutputBuffer(int index, boolean render);
+ public final void releaseOutputBuffer(int index, boolean render) {
+ releaseOutputBuffer(index, render, false /* updatePTS */, 0 /* dummy */);
+ }
+
+ /**
+ * If you are done with a buffer, use this call to update its surface timestamp
+ * and return it to the codec to render it on the output surface. If you
+ * have not specified an output surface when configuring this video codec,
+ * this call will simply return the buffer to the codec.<p>
+ *
+ * The timestamp may have special meaning depending on the destination surface.
+ *
+ * <table>
+ * <tr><th>SurfaceView specifics</th></tr>
+ * <tr><td>
+ * If you render your buffer on a {@link android.view.SurfaceView},
+ * you can use the timestamp to render the buffer at a specific time (at the
+ * VSYNC at or after the buffer timestamp). For this to work, the timestamp
+ * needs to be <i>reasonably close</i> to the current {@link System#nanoTime}.
+ * Currently, this is set as within one (1) second. A few notes:
+ *
+ * <ul>
+ * <li>the buffer will not be returned to the codec until the timestamp
+ * has passed and the buffer is no longer used by the {@link android.view.Surface}.
+ * <li>buffers are processed sequentially, so you may block subsequent buffers to
+ * be displayed on the {@link android.view.Surface}. This is important if you
+ * want to react to user action, e.g. stop the video or seek.
+ * <li>if multiple buffers are sent to the {@link android.view.Surface} to be
+ * rendered at the same VSYNC, the last one will be shown, and the other ones
+ * will be dropped.
+ * <li>if the timestamp is <em>not</em> "reasonably close" to the current system
+ * time, the {@link android.view.Surface} will ignore the timestamp, and
+ * display the buffer at the earliest feasible time. In this mode it will not
+ * drop frames.
+ * <li>for best performance and quality, call this method when you are about
+ * two VSYNCs' time before the desired render time. For 60Hz displays, this is
+ * about 33 msec.
+ * </ul>
+ * </td></tr>
+ * </table>
+ *
+ * @param index The index of a client-owned output buffer previously returned
+ * from a call to {@link #dequeueOutputBuffer}.
+ * @param renderTimestampNs The timestamp to associate with this buffer when
+ * it is sent to the Surface.
+ */
+ public final void releaseOutputBuffer(int index, long renderTimestampNs) {
+ releaseOutputBuffer(
+ index, true /* render */, true /* updatePTS */, renderTimestampNs);
+ }
+
+ private native final void releaseOutputBuffer(
+ int index, boolean render, boolean updatePTS, long timeNs);
/**
* Signals end-of-stream on input. Equivalent to submitting an empty buffer with
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index a710c03..4a7c096 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -260,7 +260,11 @@ status_t JMediaCodec::dequeueOutputBuffer(
return OK;
}
-status_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) {
+status_t JMediaCodec::releaseOutputBuffer(
+ size_t index, bool render, bool updatePTS, int64_t timestampNs) {
+ if (updatePTS) {
+ return mCodec->renderOutputBufferAndRelease(index, timestampNs);
+ }
return render
? mCodec->renderOutputBufferAndRelease(index)
: mCodec->releaseOutputBuffer(index);
@@ -873,7 +877,8 @@ static jint android_media_MediaCodec_dequeueOutputBuffer(
}
static void android_media_MediaCodec_releaseOutputBuffer(
- JNIEnv *env, jobject thiz, jint index, jboolean render) {
+ JNIEnv *env, jobject thiz,
+ jint index, jboolean render, jboolean updatePTS, jlong timestampNs) {
ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -883,7 +888,7 @@ static void android_media_MediaCodec_releaseOutputBuffer(
return;
}
- status_t err = codec->releaseOutputBuffer(index, render);
+ status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs);
throwExceptionAsNecessary(env, err);
}
@@ -1138,7 +1143,7 @@ static JNINativeMethod gMethods[] = {
{ "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I",
(void *)android_media_MediaCodec_dequeueOutputBuffer },
- { "releaseOutputBuffer", "(IZ)V",
+ { "releaseOutputBuffer", "(IZZJ)V",
(void *)android_media_MediaCodec_releaseOutputBuffer },
{ "signalEndOfInputStream", "()V",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 2f2ea96..bf9f4ea 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -79,7 +79,8 @@ struct JMediaCodec : public AHandler {
status_t dequeueOutputBuffer(
JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs);
- status_t releaseOutputBuffer(size_t index, bool render);
+ status_t releaseOutputBuffer(
+ size_t index, bool render, bool updatePTS, int64_t timestampNs);
status_t signalEndOfInputStream();