avcodec/mediacodec: add av_mediacodec_render_buffer_at_time()

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>
This commit is contained in:
Aman Gupta 2018-07-31 18:34:15 -07:00
parent e265832c37
commit f6d48b618a
5 changed files with 39 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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, \