[vlc-commits] mediacodec: factor DecodeVideo
Thomas Guillem
git at videolan.org
Fri Apr 24 12:14:27 CEST 2015
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Apr 24 10:05:31 2015 +0200| [2ab78c748d6bc3e1c4412b780b3e7f11e786049e] | committer: Thomas Guillem
mediacodec: factor DecodeVideo
More comments, try to make it clearer, release p_block and p_pic in only one
place. It also fixes a p_block leak if we were not able to create a p_pic.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2ab78c748d6bc3e1c4412b780b3e7f11e786049e
---
modules/codec/omxil/android_mediacodec.c | 80 ++++++++++++++----------------
1 file changed, 38 insertions(+), 42 deletions(-)
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index 1e716af..cf155dc 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -1114,6 +1114,10 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
picture_t *p_pic = NULL;
JNIEnv *env = NULL;
block_t *p_block = pp_block ? *pp_block : NULL;
+ unsigned int i_attempts = 0;
+ jlong timeout = 0;
+ int i_output_ret = 0;
+ int i_input_ret = 0;
bool b_error = false;
if (p_sys->error_state)
@@ -1126,8 +1130,6 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
if (p_block && p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
- block_Release(p_block);
- *pp_block = NULL;
p_sys->i_preroll_end = 0;
timestamp_FifoEmpty(p_sys->timestamp_fifo);
if (p_sys->decoded) {
@@ -1177,23 +1179,12 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den;
}
- unsigned int i_attempts = 0;
- jlong timeout = 0;
- int i_output_ret = 0;
- int i_input_ret = 0;
do {
- if (p_block && i_input_ret == 0) {
+ if (p_block && i_input_ret == 0)
i_input_ret = PutInput(p_dec, env, p_block, timeout);
- if (i_input_ret == 1) {
- block_Release(p_block);
- *pp_block = NULL;
- } else if (i_input_ret == -1) {
- b_error = true;
- break;
- }
- }
- if (i_output_ret == 0) {
+ if (i_output_ret == 0)
+ {
/* FIXME: A new picture shouldn't be created each time.
* If decoder_NewPicture fails because the decoder is
* flushing/exiting, GetOutput will either fail (or crash in
@@ -1202,7 +1193,8 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
* input is waiting for the output or vice-versa. Therefore, call
* decoder_NewPicture before GetOutput as a safeguard. */
- if (p_sys->pixel_format) {
+ if (p_sys->pixel_format)
+ {
p_pic = decoder_NewPicture(p_dec);
if (!p_pic) {
msg_Warn(p_dec, "NewPicture failed");
@@ -1210,14 +1202,16 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
}
i_output_ret = GetOutput(p_dec, env, p_pic, timeout);
- if (i_output_ret == -1) {
- b_error = true;
- break;
- } else if (i_output_ret == 0) {
- if (p_pic) {
+ if (p_pic)
+ {
+ if (i_output_ret != 1) {
picture_Release(p_pic);
p_pic = NULL;
- } else if (++i_attempts > 100) {
+ }
+ } else
+ {
+ if (i_output_ret == 0 && i_input_ret == 0 && ++i_attempts > 100)
+ {
/* No p_pic, so no pixel_format, thereforce mediacodec
* didn't produce any output or events yet. Don't wait
* indefinitely and abort after 2seconds (100 * 2 * 10ms)
@@ -1229,28 +1223,30 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
}
}
timeout = 10 * 1000; // 10 ms
- /* loop until input is processed or when we got an output pic */
- } while (p_block && i_input_ret != 1 && i_output_ret != 1);
+ /* loop until either the input or the output are processed (i_input_ret
+ * or i_output_ret == 1 ) or caused an error (i_input_ret or
+ * i_output_ret == -1 )*/
+ } while (p_block && i_input_ret == 0 && i_output_ret == 0);
+
+ if (i_input_ret == -1 || i_output_ret == -1)
+ b_error = true;
endclean:
- if (p_sys->error_state || b_error || !p_sys->codec)
- {
- if( p_block )
- {
- block_Release(p_block);
- *pp_block = NULL;
- }
- if (p_pic)
- {
- picture_Release(p_pic);
- p_pic = NULL;
- }
- if (b_error && !p_sys->error_state) {
- /* Signal the error to the Java. */
- jni_EventHardwareAccelerationError();
- p_sys->error_state = true;
- }
+ /* If pf_decode returns NULL, we'll get a new p_block from the next
+ * pf_decode call. Therefore we need to release the current one even if we
+ * couldn't process it (it happens in case or error or if MediaCodec is
+ * still not opened). We also must release the current p_block if we were
+ * able to process it. */
+ if (p_block && (p_pic == NULL || i_input_ret != 0))
+ {
+ block_Release(p_block);
+ *pp_block = NULL;
+ }
+ if (b_error && !p_sys->error_state) {
+ /* Signal the error to the Java. */
+ jni_EventHardwareAccelerationError();
+ p_sys->error_state = true;
}
return p_pic;
More information about the vlc-commits
mailing list