[FFmpeg-devel] [PATCH] avcodec/mediacodec: add av_mediacodec_render_buffer_at_time()
Aman Gupta
ffmpeg at tmm1.net
Wed Aug 1 04:34:15 EEST 2018
From: Aman Gupta <aman at tmm1.net>
The existing av_mediacodec_release_buffer allows the user to render
or discard the Surface-backed frame. This new method allows the user
to control exactly when the frame will be rendered to it's SurfaceView.
Available since Android API 21.
Signed-off-by: Aman Gupta <aman at tmm1.net>
---
doc/APIchanges | 3 +++
libavcodec/mediacodec.c | 21 +++++++++++++++++++++
libavcodec/mediacodec.h | 13 +++++++++++++
libavcodec/mediacodec_wrapper.c | 2 +-
libavcodec/version.h | 2 +-
5 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index efe15ba4e0..62394fd837 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil: 2017-10-21
API changes, most recent first:
+2018-08-01 - xxxxxxxxxx - lavc 58.23.100 - mediacodec.h
+ Add av_mediacodec_render_buffer_at_time().
+
2018-05-xx - xxxxxxxxxx - lavf 58.15.100 - avformat.h
Add pmt_version field to AVProgram
diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c
index b0aae43a87..aa14624fd0 100644
--- a/libavcodec/mediacodec.c
+++ b/libavcodec/mediacodec.c
@@ -102,6 +102,22 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render)
return 0;
}
+int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time)
+{
+ MediaCodecDecContext *ctx = buffer->ctx;
+ int released = atomic_fetch_add(&buffer->released, 1);
+
+ if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) {
+ atomic_fetch_sub(&ctx->hw_buffer_count, 1);
+ av_log(ctx->avctx, AV_LOG_DEBUG,
+ "Rendering output buffer %zd (%p) ts=%"PRId64" with time=%"PRId64" [%d pending]\n",
+ buffer->index, buffer, buffer->pts, time, atomic_load(&ctx->hw_buffer_count));
+ return ff_AMediaCodec_releaseOutputBufferAtTime(ctx->codec, buffer->index, time);
+ }
+
+ return 0;
+}
+
#else
#include <stdlib.h>
@@ -125,4 +141,9 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render)
return AVERROR(ENOSYS);
}
+int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time)
+{
+ return AVERROR(ENOSYS);
+}
+
#endif
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 5606d24a1e..4c8545df03 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -85,4 +85,17 @@ typedef struct MediaCodecBuffer AVMediaCodecBuffer;
*/
int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render);
+/**
+ * Release a MediaCodec buffer and render it at the given time to the surface
+ * that is associated with the decoder. The timestamp must be within one second
+ * of the current java/lang/System#nanoTime() (which is implemented using
+ * CLOCK_MONOTONIC on Android). See the Android MediaCodec documentation
+ * of android/media/MediaCodec#releaseOutputBuffer(int,long) for more details.
+ *
+ * @param buffer the buffer to render
+ * @param time timestamp in nanoseconds of when to render the buffer
+ * @return 0 on success, < 0 otherwise
+ */
+int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time);
+
#endif /* AVCODEC_MEDIACODEC_H */
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index c47c2c9a41..a024e3bdb1 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -1432,7 +1432,7 @@ int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, i
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
- (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, timestampNs);
+ (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, (jlong)timestampNs);
if (ff_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 3f0d98efdf..a91e5f01e6 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 22
+#define LIBAVCODEC_VERSION_MINOR 23
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
--
2.18.0
More information about the ffmpeg-devel
mailing list