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 its SurfaceView. Available since Android API 21. Signed-off-by: Aman Gupta <aman@tmm1.net>tags/n4.1
@@ -15,6 +15,9 @@ libavutil: 2017-10-21 | |||||
API changes, most recent first: | 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 | 2018-09-09 - xxxxxxxxxx - lavc 58.29.100 - avcodec.h | ||||
Add AV_PKT_DATA_AFD | Add AV_PKT_DATA_AFD | ||||
@@ -102,6 +102,22 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) | |||||
return 0; | 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 | #else | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
@@ -125,4 +141,9 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) | |||||
return AVERROR(ENOSYS); | return AVERROR(ENOSYS); | ||||
} | } | ||||
int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time) | |||||
{ | |||||
return AVERROR(ENOSYS); | |||||
} | |||||
#endif | #endif |
@@ -85,4 +85,17 @@ typedef struct MediaCodecBuffer AVMediaCodecBuffer; | |||||
*/ | */ | ||||
int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); | 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 */ | #endif /* AVCODEC_MEDIACODEC_H */ |
@@ -1432,7 +1432,7 @@ int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, i | |||||
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); | 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) { | if (ff_jni_exception_check(env, 1, codec) < 0) { | ||||
ret = AVERROR_EXTERNAL; | ret = AVERROR_EXTERNAL; | ||||
goto fail; | goto fail; | ||||
@@ -28,7 +28,7 @@ | |||||
#include "libavutil/version.h" | #include "libavutil/version.h" | ||||
#define LIBAVCODEC_VERSION_MAJOR 58 | #define LIBAVCODEC_VERSION_MAJOR 58 | ||||
#define LIBAVCODEC_VERSION_MINOR 32 | |||||
#define LIBAVCODEC_VERSION_MINOR 33 | |||||
#define LIBAVCODEC_VERSION_MICRO 100 | #define LIBAVCODEC_VERSION_MICRO 100 | ||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | ||||