From 289e80df241a77d7b04b0a432546300beb589fb1 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Sat, 20 Apr 2013 15:35:53 +0800 Subject: [PATCH] Update fix for seek 1. Use GST_EVENT_FLUSH_START to help decoder escape from waiting for an availabe surface; correspondingly, GST_EVENT_FLUSH_STOP disables such special exception. 2. Remove such escape by GST_STATE_CHANGE_PAUSED_TO_READY during seek, the status/event happens as following order: GST_STATE_CHANGE_PLAYING_TO_PAUSED -> GST_EVENT_FLUSH_START -> GST_EVENT_FLUSH_STOP -> GST_STATE_CHANGE_PAUSED_TO_PLAYING 3. Remove such escape by GST_EVENT_EOS. EOS is the symptom caused by no surface available, not the reason. I'm afraid the original code will miss some frames if EOS comes earlier than decoder finishes decoding the sent data. --- gst/vaapi/gstvaapidecode.c | 57 ++++++++++++++++++++++++++++++---------------- gst/vaapi/gstvaapidecode.h | 3 ++- 2 files changed, 40 insertions(+), 20 deletions(-) mode change 100644 => 100755 gst/vaapi/gstvaapidecode.c mode change 100644 => 100755 gst/vaapi/gstvaapidecode.h diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c old mode 100644 new mode 100755 index 21139dc..e07867b --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -211,15 +211,15 @@ gst_vaapidecode_step(GstVaapiDecode *decode) if (!proxy) { if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { g_mutex_lock(&decode->decoder_mutex); - if (decode->break_flag){ - goto handle_break_flag; + if (decode->escape_decoding){ + goto handle_escape_decoding; } g_cond_wait( &decode->decoder_ready, &decode->decoder_mutex ); - if (decode->break_flag){ - goto handle_break_flag; + if (decode->escape_decoding){ + goto handle_escape_decoding; } g_mutex_unlock(&decode->decoder_mutex); try_again = TRUE; @@ -273,13 +273,10 @@ gst_vaapidecode_step(GstVaapiDecode *decode) return GST_FLOW_OK; /* ERRORS */ -handle_break_flag: +handle_escape_decoding: { g_mutex_unlock(&decode->decoder_mutex); - goto error_receive_event; - } -error_receive_event: - { + GST_INFO("Escape decoding wait: flush event comes for seek etc."); return GST_FLOW_UNEXPECTED; } error_decode: @@ -519,12 +516,32 @@ gst_vaapidecode_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } +typedef struct { + int trans; + char *trans_name; +} _GstStateChangeMap; +_GstStateChangeMap gst_state_change_string_map[] = { + {GST_STATE_CHANGE_NULL_TO_READY, "GST_STATE_CHANGE_NULL_TO_READY"}, + {GST_STATE_CHANGE_READY_TO_PAUSED, "GST_STATE_CHANGE_READY_TO_PAUSED",}, + {GST_STATE_CHANGE_PAUSED_TO_PLAYING,"GST_STATE_CHANGE_PAUSED_TO_PLAYING"}, + {GST_STATE_CHANGE_PLAYING_TO_PAUSED,"GST_STATE_CHANGE_PLAYING_TO_PAUSED"}, + {GST_STATE_CHANGE_PAUSED_TO_READY, "GST_STATE_CHANGE_PAUSED_TO_READY"}, + {GST_STATE_CHANGE_READY_TO_NULL, "GST_STATE_CHANGE_READY_TO_NULL"}, + {-1, "UNDEFINED_STATE_CHANGE"} +}; + static GstStateChangeReturn gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) { GstVaapiDecode * const decode = GST_VAAPIDECODE(element); GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + int i; + for (i=0; iis_ready = TRUE; @@ -545,10 +562,6 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: - g_mutex_lock(&decode->decoder_mutex); - decode->break_flag = TRUE; - g_cond_signal(&decode->decoder_ready); - g_mutex_unlock(&decode->decoder_mutex); break; case GST_STATE_CHANGE_READY_TO_NULL: gst_vaapidecode_destroy(decode); @@ -717,10 +730,20 @@ gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); + GST_INFO("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); + /* Propagate event downstream */ switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_FLUSH_START: + g_mutex_lock(&decode->decoder_mutex); + decode->escape_decoding = TRUE; + g_cond_signal(&decode->decoder_ready); + g_mutex_unlock(&decode->decoder_mutex); + break; case GST_EVENT_FLUSH_STOP: + g_mutex_lock(&decode->decoder_mutex); + decode->escape_decoding = FALSE; + g_mutex_unlock(&decode->decoder_mutex); gst_segment_init(&decode->segment, GST_FORMAT_UNDEFINED); if (decode->decoder) gst_vaapi_decoder_clear_buffer(decode->decoder); @@ -737,10 +760,6 @@ gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) gst_vaapidecode_configure_segment(decode, event); break; case GST_EVENT_EOS: - g_mutex_lock(&decode->decoder_mutex); - decode->break_flag = TRUE; - g_cond_signal(&decode->decoder_ready); - g_mutex_unlock(&decode->decoder_mutex); if (!gst_vaapidecode_flush(decode)) { GST_WARNING("failed to flush buffers"); } @@ -792,7 +811,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->render_time_base = 0; decode->last_buffer_time = 0; decode->is_ready = FALSE; - decode->break_flag = FALSE; + decode->escape_decoding = FALSE; g_mutex_init(&decode->decoder_mutex); g_cond_init(&decode->decoder_ready); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h old mode 100644 new mode 100755 index a15aeb3..ff27780 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -76,7 +76,8 @@ struct _GstVaapiDecode { gint64 render_time_base; GstClockTime last_buffer_time; unsigned int is_ready : 1; - gboolean break_flag; + // escape decoding (blocked by hw resource) when there is _flush event, usually happens during seek. + unsigned int escape_decoding : 1; }; struct _GstVaapiDecodeClass { -- 2.7.4