diff --git a/doc/APIchanges b/doc/APIchanges index a40476d630308b5e8b8dcf6d9d211d0f7aa2ed4c..9e93555dac8e65180c15d481428583808ddf7476 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2017-10-21 API changes, most recent first: +2018-10-11 - xxxxxxxxxx - lavc 58.33.100 - mediacodec.h + Add av_mediacodec_render_buffer_at_time(). + 2018-09-09 - xxxxxxxxxx - lavc 58.29.100 - avcodec.h Add AV_PKT_DATA_AFD diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c index b0aae43a879d0ea468c680633592fd4ea6e6f18a..aa14624fd0758c58a7df7d7c3dd3b6db019b5430 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 @@ -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 5606d24a1ee6e2a6e3442a80cb7ed7df631a8eec..4c8545df03109a80da77976209d187e046a5e801 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 c47c2c9a410a31a981758f8ff01ca56edac194f1..a024e3bdb11a3e9d3f01eb2d6fc54b3d13831432 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 97d134851fb9703b6f9bb59399e237238383562f..7e51585661c0c4f8dde907456c27b68f3642119a 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 32 +#define LIBAVCODEC_VERSION_MINOR 33 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \