Browse Source

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>
tags/n4.1
Aman Gupta 6 years ago
parent
commit
f6d48b618a
5 changed files with 39 additions and 2 deletions
  1. +3
    -0
      doc/APIchanges
  2. +21
    -0
      libavcodec/mediacodec.c
  3. +13
    -0
      libavcodec/mediacodec.h
  4. +1
    -1
      libavcodec/mediacodec_wrapper.c
  5. +1
    -1
      libavcodec/version.h

+ 3
- 0
doc/APIchanges 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



+ 21
- 0
libavcodec/mediacodec.c 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

+ 13
- 0
libavcodec/mediacodec.h 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 */

+ 1
- 1
libavcodec/mediacodec_wrapper.c 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;


+ 1
- 1
libavcodec/version.h 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, \


Loading…
Cancel
Save