[vlc-commits] mediacodec: add a second way to send codec specific data
Thomas Guillem
git at videolan.org
Tue Apr 28 17:49:37 CEST 2015
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Apr 27 09:28:36 2015 +0200| [88c6f34a703d87e7aa942e5e00f1c39eec27f58e] | committer: Thomas Guillem
mediacodec: add a second way to send codec specific data
Via PutInput with the BUFFER_FLAG_CODEC_CONFIG flag. It allows to send codec
specific data during playback without restarting MediaCodec. If you choose to
configure codec via this flags, you shouldn't set the "csd-0" buffer during
MediaCodec initialization.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=88c6f34a703d87e7aa942e5e00f1c39eec27f58e
---
modules/codec/omxil/android_mediacodec.c | 93 +++++++++++++++++++++---------
1 file changed, 67 insertions(+), 26 deletions(-)
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index 45fe7981..1b0c275 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -45,6 +45,8 @@
#include "android_opaque.h"
#include "../../video_output/android/android_window.h"
+#define BUFFER_FLAG_CODEC_CONFIG 2
+
#define INFO_OUTPUT_BUFFERS_CHANGED -3
#define INFO_OUTPUT_FORMAT_CHANGED -2
#define INFO_TRY_AGAIN_LATER -1
@@ -142,8 +144,13 @@ struct decoder_sys_t
int stride, slice_height;
char *name;
+ /* "csd-0" buffer */
void *p_csd0_buffer;
size_t i_csd0_buffer;
+ /* or buffer sent via BUFFER_FLAG_CODEC_CONFIG flag */
+ uint8_t *p_config_buffer;
+ size_t i_config_buffer;
+ bool b_config_resend;
bool allocated;
bool started;
@@ -530,7 +537,11 @@ loopclean:
jfields.create_video_format, (*env)->NewStringUTF(env, mime),
p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height);
- if (p_dec->fmt_in.i_extra && !p_sys->p_csd0_buffer) {
+ /* Either we use a "csd-0" buffer that is provided before codec
+ * initialisation via the MediaFormat class, or use a CODEC_CONFIG buffer
+ * that can be provided during playback (and must be provided after a flush
+ * and a start). */
+ if (p_dec->fmt_in.i_extra && !p_sys->p_config_buffer) {
uint32_t size = p_dec->fmt_in.i_extra;
int buf_size = p_dec->fmt_in.i_extra + 20;
@@ -804,6 +815,7 @@ static void CloseDecoder(vlc_object_t *p_this)
msg_Warn(p_dec, "Can't get a JNIEnv, can't close mediacodec !");
free(p_sys->p_csd0_buffer);
+ free(p_sys->p_config_buffer);
free(p_sys->name);
ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
free(p_sys->pp_inflight_pictures);
@@ -900,10 +912,12 @@ static int PutInput(decoder_t *p_dec, JNIEnv *env, block_t *p_block, jlong timeo
{
decoder_sys_t *p_sys = p_dec->p_sys;
int index;
- jobject buf;
- jsize size;
- uint8_t *bufptr;
- struct H264ConvertState convert_state = { 0, 0 };
+ int64_t ts = 0;
+ uint8_t *p_mc_buf, *p_buf;
+ size_t i_buf;
+ jobject j_mc_buf;
+ jsize j_mc_size;
+ jint j_flags = 0;
index = (*env)->CallIntMethod(env, p_sys->codec,
jfields.dequeue_input_buffer, timeout);
@@ -914,37 +928,60 @@ static int PutInput(decoder_t *p_dec, JNIEnv *env, block_t *p_block, jlong timeo
if (index < 0)
return 0;
+ if (p_sys->b_config_resend)
+ {
+ p_buf = p_sys->p_config_buffer;
+ i_buf = p_sys->i_config_buffer;
+ j_flags = BUFFER_FLAG_CODEC_CONFIG;
+ msg_Dbg(p_dec, "sending codec specific data of size %d "
+ "via BUFFER_FLAG_CODEC_CONFIG flag", i_buf);
+ } else
+ {
+ p_buf = p_block->p_buffer;
+ i_buf = p_block->i_buffer;
+ }
+
if (jfields.get_input_buffers)
- buf = (*env)->GetObjectArrayElement(env, p_sys->input_buffers, index);
+ j_mc_buf = (*env)->GetObjectArrayElement(env, p_sys->input_buffers,
+ index);
else
- buf = (*env)->CallObjectMethod(env, p_sys->codec, jfields.get_input_buffer, index);
- size = (*env)->GetDirectBufferCapacity(env, buf);
- bufptr = (*env)->GetDirectBufferAddress(env, buf);
- if (size < 0) {
+ j_mc_buf = (*env)->CallObjectMethod(env, p_sys->codec,
+ jfields.get_input_buffer, index);
+ j_mc_size = (*env)->GetDirectBufferCapacity(env, j_mc_buf);
+ p_mc_buf = (*env)->GetDirectBufferAddress(env, j_mc_buf);
+ if (j_mc_size < 0) {
msg_Err(p_dec, "Java buffer has invalid size");
return -1;
}
- if ((size_t) size > p_block->i_buffer)
- size = p_block->i_buffer;
- memcpy(bufptr, p_block->p_buffer, size);
-
- convert_h264_to_annexb(bufptr, size, p_sys->nal_size, &convert_state);
-
- int64_t ts = p_block->i_pts;
- if (!ts && p_block->i_dts)
- ts = p_block->i_dts;
- if (p_block->i_flags & BLOCK_FLAG_PREROLL )
- p_sys->i_preroll_end = ts;
- timestamp_FifoPut(p_sys->timestamp_fifo, p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
- (*env)->CallVoidMethod(env, p_sys->codec, jfields.queue_input_buffer, index, 0, size, ts, 0);
- (*env)->DeleteLocalRef(env, buf);
+ if ((size_t) j_mc_size > i_buf)
+ j_mc_size = i_buf;
+ memcpy(p_mc_buf, p_buf, j_mc_size);
+
+ if (!p_sys->b_config_resend)
+ {
+ ts = p_block->i_pts;
+ if (!ts && p_block->i_dts)
+ ts = p_block->i_dts;
+ if (p_block->i_flags & BLOCK_FLAG_PREROLL )
+ p_sys->i_preroll_end = ts;
+ timestamp_FifoPut(p_sys->timestamp_fifo,
+ p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
+ }
+ (*env)->CallVoidMethod(env, p_sys->codec, jfields.queue_input_buffer,
+ index, 0, j_mc_size, ts, j_flags);
+ (*env)->DeleteLocalRef(env, j_mc_buf);
if (CHECK_EXCEPTION()) {
msg_Err(p_dec, "Exception in MediaCodec.queueInputBuffer");
return -1;
}
p_sys->decoded = true;
- return 1;
+ if (p_sys->b_config_resend)
+ {
+ p_sys->b_config_resend = false;
+ return 0; /* 0 since the p_block is not processed */
+ } else
+ return 1;
}
static int GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t *p_pic, jlong timeout)
@@ -1145,6 +1182,10 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
}
p_sys->decoded = false;
+
+ /* resend CODEC_CONFIG buffer after a flush */
+ if (p_sys->p_config_buffer)
+ p_sys->b_config_resend = true;
goto endclean;
}
@@ -1179,7 +1220,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
do {
- if (p_block && i_input_ret == 0)
+ if ((p_sys->b_config_resend || p_block) && i_input_ret == 0)
i_input_ret = PutInput(p_dec, env, p_block, timeout);
if (i_input_ret != -1 && i_output_ret == 0)
More information about the vlc-commits
mailing list