vaapidecode: properly return from decode loop on downstream errors.

Fixes a hang/race on shutdown where _decode_loop() had already completed
its execution and _finish() was waiting on a GCond for decode_loop()
to complete.  Also fixes the possible race where _finish() is called
but _decode_loop() endlessly returns before signalling completion
iff the decoder instance returns GST_FLOW_OK.

Found with: ... ! vaapidecode ! {glimagesink,cluttersink}

https://bugzilla.gnome.org/show_bug.cgi?id=733897

[factored out GST_VIDEO_DECODER_STREAM_UNLOCK() call]
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
Matthew Waters 2014-07-29 16:22:01 +10:00 committed by Gwenole Beauchesne
parent 1afcede093
commit 6003596e82

View file

@ -439,19 +439,20 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode)
decode->decoder_loop_status = ret;
GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
if (ret == GST_FLOW_OK)
return;
/* If invoked from gst_vaapidecode_finish(), then return right
away no matter the errors, or the GstVaapiDecoder needs further
data to complete decoding (there no more data to feed in) */
if (decode->decoder_finish) {
g_mutex_lock(&decode->decoder_mutex);
decode->decoder_loop_status = GST_FLOW_EOS;
g_cond_signal(&decode->decoder_finish_done);
g_mutex_unlock(&decode->decoder_mutex);
return;
}
if (ret == GST_FLOW_OK)
return;
/* Suspend the task if an error occurred */
if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA)
gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
@ -494,13 +495,16 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec)
/* Make sure the decode loop function has a chance to return, thus
possibly unlocking gst_video_decoder_finish_frame() */
GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
g_mutex_lock(&decode->decoder_mutex);
decode->decoder_finish = TRUE;
g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex);
g_mutex_unlock(&decode->decoder_mutex);
gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
GST_VIDEO_DECODER_STREAM_LOCK(vdec);
if (decode->decoder_loop_status == GST_FLOW_OK) {
GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
g_mutex_lock(&decode->decoder_mutex);
while (decode->decoder_loop_status != GST_FLOW_OK)
g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex);
g_mutex_unlock(&decode->decoder_mutex);
gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
GST_VIDEO_DECODER_STREAM_LOCK(vdec);
}
return ret;
}