}
static GstVaapiDecoderStatus
-decode_step(GstVaapiDecoder *decoder)
+decode_step(GstVaapiDecoder *decoder, gboolean *try_again)
{
GstVaapiDecoderStatus status;
GstBuffer *buffer;
return status;
do {
- buffer = pop_buffer(decoder);
+ if (*try_again){
+ buffer = gst_buffer_new();
+ if (buffer){
+ gst_buffer_set_data(buffer, NULL, 0);
+ }
+ *try_again = FALSE;
+ }else{
+ buffer = pop_buffer(decoder);
+ }
if (!buffer)
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
* gst_vaapi_decoder_get_surface:
* @decoder: a #GstVaapiDecoder
* @pstatus: return location for the decoder status, or %NULL
+ * @try_again: a #gboolean
*
* Flushes encoded buffers to the decoder and returns a decoded
* surface, if any.
GstVaapiSurfaceProxy *
gst_vaapi_decoder_get_surface(
GstVaapiDecoder *decoder,
- GstVaapiDecoderStatus *pstatus
+ GstVaapiDecoderStatus *pstatus,
+ gboolean try_again
)
{
GstVaapiSurfaceProxy *proxy;
proxy = pop_surface(decoder);
if (!proxy) {
do {
- status = decode_step(decoder);
+ status = decode_step(decoder, &try_again);
} while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
proxy = pop_surface(decoder);
}
GstBuffer *buffer;
GstFlowReturn ret;
GstClockTime timestamp;
- gint64 end_time;
+ gboolean try_again = FALSE;
for (;;) {
- end_time = decode->render_time_base;
- if (!end_time)
- end_time = g_get_monotonic_time();
- end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time);
- end_time += G_TIME_SPAN_SECOND;
-
- proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status);
+ proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status, try_again);
+ try_again = FALSE;
if (!proxy) {
if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
- gboolean was_signalled;
g_mutex_lock(&decode->decoder_mutex);
- was_signalled = g_cond_wait_until(
+ if (decode->escape_decoding){
+ goto handle_escape_decoding;
+ }
+ g_cond_wait(
&decode->decoder_ready,
- &decode->decoder_mutex,
- end_time
+ &decode->decoder_mutex
);
+ if (decode->escape_decoding){
+ goto handle_escape_decoding;
+ }
g_mutex_unlock(&decode->decoder_mutex);
- if (was_signalled)
- continue;
- goto error_decode_timeout;
+ try_again = TRUE;
+ continue;
}
if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)
goto error_decode;
return GST_FLOW_OK;
/* ERRORS */
-error_decode_timeout:
+handle_escape_decoding:
{
- GST_DEBUG("decode timeout. Decoder required a VA surface but none "
- "got available within one second");
+ g_mutex_unlock(&decode->decoder_mutex);
+ GST_INFO("Escape decoding wait: flush event comes for seek etc.");
return GST_FLOW_UNEXPECTED;
}
error_decode:
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; i<sizeof(gst_state_change_string_map)/sizeof(_GstStateChangeMap);i++) {
+ if (gst_state_change_string_map[i].trans == transition)
+ GST_INFO(gst_state_change_string_map[i].trans_name);
+ }
+
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
decode->is_ready = TRUE;
{
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);
decode->render_time_base = 0;
decode->last_buffer_time = 0;
decode->is_ready = FALSE;
+ decode->escape_decoding = FALSE;
g_mutex_init(&decode->decoder_mutex);
g_cond_init(&decode->decoder_ready);