[vlc-commits] mediacodec: use vlc_cancel to interrupt the output thread
Thomas Guillem
git at videolan.org
Fri Dec 11 17:43:10 CET 2015
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Dec 11 17:40:37 2015 +0100| [933a5159e482f0c8661b7148bebf85460310c8d0] | committer: Thomas Guillem
mediacodec: use vlc_cancel to interrupt the output thread
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=933a5159e482f0c8661b7148bebf85460310c8d0
---
modules/codec/omxil/mediacodec.c | 84 ++++++++++++++++++++++----------------
1 file changed, 48 insertions(+), 36 deletions(-)
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index b4e2c0c..569f3a3 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -39,6 +39,7 @@
#include <vlc_cpu.h>
#include <vlc_memory.h>
#include <vlc_timestamp_helper.h>
+#include <vlc_threads.h>
#include "mediacodec.h"
#include "../../packetizer/h264_nal.h"
@@ -107,7 +108,6 @@ struct decoder_sys_t
/* Cond used to signal the decoder thread */
vlc_cond_t dec_cond;
/* Set to true by pf_flush to signal the output thread to flush */
- bool b_out_thread_running;
bool b_flush_out;
/* If true, the output thread will start to dequeue output pictures */
bool b_output_ready;
@@ -657,25 +657,19 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
b_late_opening = true;
}
- vlc_mutex_lock(&p_sys->lock);
-
if (!b_late_opening && StartMediaCodec(p_dec) != VLC_SUCCESS)
{
msg_Err(p_dec, "StartMediaCodec failed");
- vlc_mutex_unlock(&p_sys->lock);
goto bailout;
}
- p_sys->b_out_thread_running = true;
if (vlc_clone(&p_sys->out_thread, OutThread, p_dec,
VLC_THREAD_PRIORITY_LOW))
{
msg_Err(p_dec, "vlc_clone failed");
- p_sys->b_out_thread_running = false;
vlc_mutex_unlock(&p_sys->lock);
goto bailout;
}
- vlc_mutex_unlock(&p_sys->lock);
return VLC_SUCCESS;
@@ -694,6 +688,17 @@ static int OpenDecoderJni(vlc_object_t *p_this)
return OpenDecoder(p_this, MediaCodecJni_Init);
}
+static void AbortDecoderLocked(decoder_t *p_dec)
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ if (!p_sys->b_error)
+ {
+ p_sys->b_error = true;
+ vlc_cancel(p_sys->out_thread);
+ }
+}
+
static void CleanDecoder(decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -730,10 +735,12 @@ static void CloseDecoder(vlc_object_t *p_this)
decoder_sys_t *p_sys = p_dec->p_sys;
vlc_mutex_lock(&p_sys->lock);
- p_sys->b_out_thread_running = false;
+ /* Unblock output thread waiting in dequeue_out */
DecodeFlushLocked(p_dec);
- vlc_cond_broadcast(&p_sys->cond);
+ /* Cancel the output thread */
+ AbortDecoderLocked(p_dec);
vlc_mutex_unlock(&p_sys->lock);
+
vlc_join(p_sys->out_thread, NULL);
CleanDecoder(p_dec);
@@ -1081,7 +1088,7 @@ static void DecodeFlushLocked(decoder_t *p_dec)
if (b_had_input && p_sys->api->flush(p_sys->api) != VLC_SUCCESS)
{
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
return;
}
@@ -1105,15 +1112,14 @@ static void *OutThread(void *data)
decoder_t *p_dec = data;
decoder_sys_t *p_sys = p_dec->p_sys;
+ vlc_mutex_lock(&p_sys->lock);
+ mutex_cleanup_push(&p_sys->lock);
for (;;)
{
int i_index;
- vlc_mutex_lock(&p_sys->lock);
-
/* Wait for output ready */
- while (!p_sys->b_error && p_sys->b_out_thread_running
- && !p_sys->b_flush_out && !p_sys->b_output_ready)
+ while (!p_sys->b_flush_out && !p_sys->b_output_ready)
vlc_cond_wait(&p_sys->cond, &p_sys->lock);
if (p_sys->b_flush_out)
@@ -1121,17 +1127,17 @@ static void *OutThread(void *data)
/* Acknowledge flushed state */
p_sys->b_flush_out = false;
vlc_cond_broadcast(&p_sys->dec_cond);
- goto next;
+ continue;
}
- /* Check if thread is not stopped */
- if (!p_sys->b_out_thread_running || p_sys->b_error)
- goto end;
+ int canc = vlc_savecancel();
vlc_mutex_unlock(&p_sys->lock);
+
/* Wait for an output buffer. This function returns when a new output
* is available or if output is flushed. */
i_index = p_sys->api->dequeue_out(p_sys->api, -1);
+
vlc_mutex_lock(&p_sys->lock);
/* Ignore dequeue_out errors caused by flush */
@@ -1145,7 +1151,10 @@ static void *OutThread(void *data)
/* Parse output format/buffers even when we are flushing */
if (i_index != MC_API_INFO_OUTPUT_FORMAT_CHANGED
&& i_index != MC_API_INFO_OUTPUT_BUFFERS_CHANGED)
- goto next;
+ {
+ vlc_restorecancel(canc);
+ continue;
+ }
}
/* Process output returned by dequeue_out */
@@ -1164,7 +1173,8 @@ static void *OutThread(void *data)
&p_block) == -1)
{
msg_Err(p_dec, "pf_process_output failed");
- goto end;
+ vlc_restorecancel(canc);
+ break;
}
if (p_pic)
decoder_QueueVideo(p_dec, p_pic);
@@ -1173,24 +1183,26 @@ static void *OutThread(void *data)
} else if (i_ret != 0)
{
msg_Err(p_dec, "get_out failed");
- goto end;
+ vlc_restorecancel(canc);
+ break;
}
}
else
{
msg_Err(p_dec, "dequeue_out failed");
- goto end;
+ vlc_restorecancel(canc);
+ break;
}
-next:
- vlc_mutex_unlock(&p_sys->lock);
- continue;
-end:
- msg_Warn(p_dec, "OutThread stopped");
- p_sys->b_error = true;
- vlc_cond_signal(&p_sys->dec_cond);
- vlc_mutex_unlock(&p_sys->lock);
- break;
+ vlc_restorecancel(canc);
}
+ msg_Warn(p_dec, "OutThread stopped");
+
+ /* Signal DecoderFlush that the output thread aborted */
+ p_sys->b_error = true;
+ vlc_cond_signal(&p_sys->dec_cond);
+
+ vlc_cleanup_pop();
+ vlc_mutex_unlock(&p_sys->lock);
return NULL;
}
@@ -1253,7 +1265,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
if (StartMediaCodec(p_dec) != VLC_SUCCESS)
{
msg_Err(p_dec, "StartMediaCodec failed");
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
goto end;
}
}
@@ -1263,7 +1275,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
{
if (i_ret != 0)
{
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
msg_Err(p_dec, "pf_on_new_block failed");
}
goto end;
@@ -1324,7 +1336,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
} else
{
msg_Err(p_dec, "queue_in failed");
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
goto end;
}
}
@@ -1347,14 +1359,14 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
else
{
msg_Err(p_dec, "dequeue_in timeout: no input available for 2secs");
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
goto end;
}
}
else
{
msg_Err(p_dec, "dequeue_in failed");
- p_sys->b_error = true;
+ AbortDecoderLocked(p_dec);
goto end;
}
}
More information about the vlc-commits
mailing list