[vlc-commits] mediacodec: process input buffers in only one place
Thomas Guillem
git at videolan.org
Tue Mar 24 10:36:10 CET 2015
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Mar 24 10:34:52 2015 +0100| [7ab1842e44d8cee347c17eda0d75094382ae9220] | committer: Jean-Baptiste Kempf
mediacodec: process input buffers in only one place
(behavior not changed)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7ab1842e44d8cee347c17eda0d75094382ae9220
---
modules/codec/omxil/android_mediacodec.c | 170 ++++++++++++++++--------------
1 file changed, 90 insertions(+), 80 deletions(-)
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index 7ccffb2..4f9b709 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -781,6 +781,58 @@ static int InsertInflightPicture(decoder_t *p_dec, picture_t *p_pic,
return 0;
}
+static void PutInput(decoder_t *p_dec, JNIEnv *env, block_t **pp_block, jlong timeout)
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block = *pp_block;
+ int index;
+ jobject buf;
+ jsize size;
+ uint8_t *bufptr;
+ struct H264ConvertState convert_state = { 0, 0 };
+
+ index = (*env)->CallIntMethod(env, p_sys->codec,
+ p_sys->dequeue_input_buffer, timeout);
+ if (CHECK_EXCEPTION()) {
+ msg_Err(p_dec, "Exception occurred in MediaCodec.dequeueInputBuffer");
+ p_sys->error_state = true;
+ return;
+ }
+ if (index < 0)
+ return;
+
+ if (p_sys->get_input_buffers)
+ buf = (*env)->GetObjectArrayElement(env, p_sys->input_buffers, index);
+ else
+ buf = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_input_buffer, index);
+ size = (*env)->GetDirectBufferCapacity(env, buf);
+ bufptr = (*env)->GetDirectBufferAddress(env, buf);
+ if (size < 0) {
+ msg_Err(p_dec, "Java buffer has invalid size");
+ p_sys->error_state = true;
+ return;
+ }
+ 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;
+ timestamp_FifoPut(p_sys->timestamp_fifo, p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
+ (*env)->CallVoidMethod(env, p_sys->codec, p_sys->queue_input_buffer, index, 0, size, ts, 0);
+ (*env)->DeleteLocalRef(env, buf);
+ if (CHECK_EXCEPTION()) {
+ msg_Err(p_dec, "Exception in MediaCodec.queueInputBuffer");
+ return;
+ }
+ block_Release(p_block);
+ *pp_block = NULL;
+ p_sys->decoded = true;
+}
+
static void GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, jlong timeout)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -981,27 +1033,20 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
decoder_sys_t *p_sys = p_dec->p_sys;
picture_t *p_pic = NULL;
JNIEnv *env = NULL;
- struct H264ConvertState convert_state = { 0, 0 };
if (!pp_block || !*pp_block)
return NULL;
- block_t *p_block = *pp_block;
-
- if (p_sys->error_state) {
- block_Release(p_block);
- if (!p_sys->error_event_sent) {
- /* Signal the error to the Java. */
- jni_EventHardwareAccelerationError();
- p_sys->error_event_sent = true;
- }
- return NULL;
- }
+ if (p_sys->error_state)
+ goto endclean;
jni_attach_thread(&env, THREAD_NAME);
+ if (!env)
+ goto endclean;
- if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
- block_Release(p_block);
+ if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
+ block_Release(*pp_block);
+ *pp_block = NULL;
timestamp_FifoEmpty(p_sys->timestamp_fifo);
if (p_sys->decoded) {
/* Invalidate all pictures that are currently in flight
@@ -1017,8 +1062,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
}
p_sys->decoded = false;
- jni_detach_thread();
- return NULL;
+ goto endclean;
}
/* Use the aspect ratio provided by the input (ie read from packetizer).
@@ -1032,37 +1076,30 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
jlong timeout = 0;
const int max_polling_attempts = 50;
int attempts = 0;
- while (true) {
- int index = (*env)->CallIntMethod(env, p_sys->codec, p_sys->dequeue_input_buffer, (jlong) 0);
- if (CHECK_EXCEPTION()) {
- msg_Err(p_dec, "Exception occurred in MediaCodec.dequeueInputBuffer");
- p_sys->error_state = true;
+ /* return when pp_block is processed */
+ while (*pp_block != NULL) {
+ if (*pp_block != NULL)
+ PutInput(p_dec, env, pp_block, (jlong) 0);
+ if (p_sys->error_state)
break;
- }
- if (index < 0) {
+ if (p_pic == NULL) {
GetOutput(p_dec, env, &p_pic, timeout);
if (p_sys->error_state)
break;
- if (p_pic) {
- /* If we couldn't get an available input buffer but a
- * decoded frame is available, we return the frame
- * without assigning NULL to *pp_block. The next call
- * to DecodeVideo will try to send the input packet again.
- */
- jni_detach_thread();
- return p_pic;
- }
+ }
+
+ if (p_pic == NULL && *pp_block != NULL) {
timeout = 30 * 1000;
++attempts;
/* With opaque DR the output buffers are released by the
vout therefore we implement a timeout for polling in
order to avoid being indefinitely stalled in this loop. */
if (p_sys->direct_rendering && attempts == max_polling_attempts) {
- picture_t *invalid_picture = decoder_NewPicture(p_dec);
- if (invalid_picture) {
- invalid_picture->date = VLC_TS_INVALID;
- picture_sys_t *p_picsys = invalid_picture->p_sys;
+ p_pic = decoder_NewPicture(p_dec);
+ if (p_pic) {
+ p_pic->date = VLC_TS_INVALID;
+ picture_sys_t *p_picsys = p_pic->p_sys;
p_picsys->pf_lock_pic = NULL;
p_picsys->pf_unlock_pic = NULL;
p_picsys->priv.hw.p_dec = NULL;
@@ -1073,59 +1110,32 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
/* If we cannot return a picture we must free the
block since the decoder will proceed with the
next block. */
- block_Release(p_block);
+ block_Release(*pp_block);
*pp_block = NULL;
}
- jni_detach_thread();
- return invalid_picture;
}
- continue;
- }
-
- jobject buf;
- if (p_sys->get_input_buffers)
- buf = (*env)->GetObjectArrayElement(env, p_sys->input_buffers, index);
- else
- buf = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_input_buffer, index);
- jsize size = (*env)->GetDirectBufferCapacity(env, buf);
- uint8_t *bufptr = (*env)->GetDirectBufferAddress(env, buf);
- if (size < 0) {
- msg_Err(p_dec, "Java buffer has invalid size");
- p_sys->error_state = true;
- break;
- }
- 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;
- timestamp_FifoPut(p_sys->timestamp_fifo, p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
- (*env)->CallVoidMethod(env, p_sys->codec, p_sys->queue_input_buffer, index, 0, size, ts, 0);
- (*env)->DeleteLocalRef(env, buf);
- if (CHECK_EXCEPTION()) {
- msg_Err(p_dec, "Exception in MediaCodec.queueInputBuffer");
- p_sys->error_state = true;
- break;
}
- p_sys->decoded = true;
- break;
}
+
+endclean:
if (p_sys->error_state) {
+ if( pp_block && *pp_block )
+ {
+ block_Release(*pp_block);
+ *pp_block = NULL;
+ }
if (p_pic)
picture_Release(p_pic);
- jni_detach_thread();
- return NULL;
- }
- if (!p_pic)
- GetOutput(p_dec, env, &p_pic, 0);
- jni_detach_thread();
+ p_pic = NULL;
- block_Release(p_block);
- *pp_block = NULL;
+ if (!p_sys->error_event_sent) {
+ /* Signal the error to the Java. */
+ jni_EventHardwareAccelerationError();
+ p_sys->error_event_sent = true;
+ }
+ }
+ if (env != NULL)
+ jni_detach_thread();
return p_pic;
}
More information about the vlc-commits
mailing list