dvdemux: Properly set event/message sequence numbers based on the previous seek

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

https://bugzilla.gnome.org/show_bug.cgi?id=767157
This commit is contained in:
Sebastian Dröge 2016-06-03 10:49:17 +03:00
parent 26b37c7acb
commit d62115e15e
2 changed files with 64 additions and 19 deletions

View file

@ -268,6 +268,7 @@ gst_dvdemux_reset (GstDVDemux * dvdemux)
dvdemux->wide = FALSE; dvdemux->wide = FALSE;
gst_segment_init (&dvdemux->byte_segment, GST_FORMAT_BYTES); gst_segment_init (&dvdemux->byte_segment, GST_FORMAT_BYTES);
gst_segment_init (&dvdemux->time_segment, GST_FORMAT_TIME); gst_segment_init (&dvdemux->time_segment, GST_FORMAT_TIME);
dvdemux->segment_seqnum = 0;
dvdemux->upstream_time_segment = FALSE; dvdemux->upstream_time_segment = FALSE;
dvdemux->have_group_id = FALSE; dvdemux->have_group_id = FALSE;
dvdemux->group_id = G_MAXUINT; dvdemux->group_id = G_MAXUINT;
@ -793,12 +794,14 @@ gst_dvdemux_handle_sink_event (GstPad * pad, GstObject * parent,
case GST_FORMAT_BYTES: case GST_FORMAT_BYTES:
gst_segment_copy_into (segment, &dvdemux->byte_segment); gst_segment_copy_into (segment, &dvdemux->byte_segment);
dvdemux->need_segment = TRUE; dvdemux->need_segment = TRUE;
dvdemux->segment_seqnum = gst_event_get_seqnum (event);
gst_event_unref (event); gst_event_unref (event);
break; break;
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
gst_segment_copy_into (segment, &dvdemux->time_segment); gst_segment_copy_into (segment, &dvdemux->time_segment);
dvdemux->upstream_time_segment = TRUE; dvdemux->upstream_time_segment = TRUE;
dvdemux->segment_seqnum = gst_event_get_seqnum (event);
/* and we can just forward this time event */ /* and we can just forward this time event */
res = gst_dvdemux_push_event (dvdemux, event); res = gst_dvdemux_push_event (dvdemux, event);
@ -964,6 +967,7 @@ gst_dvdemux_handle_push_seek (GstDVDemux * dvdemux, GstPad * pad,
/* now this is the updated seek event on bytes */ /* now this is the updated seek event on bytes */
newevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, newevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
cur_type, start_position, stop_type, end_position); cur_type, start_position, stop_type, end_position);
gst_event_set_seqnum (newevent, gst_event_get_seqnum (event));
res = gst_pad_push_event (dvdemux->sinkpad, newevent); res = gst_pad_push_event (dvdemux->sinkpad, newevent);
} }
@ -1049,6 +1053,7 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad,
gboolean flush; gboolean flush;
gboolean update; gboolean update;
GstSegment seeksegment; GstSegment seeksegment;
GstEvent *new_event;
GST_DEBUG_OBJECT (demux, "doing seek"); GST_DEBUG_OBJECT (demux, "doing seek");
@ -1075,13 +1080,18 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad,
flags = 0; flags = 0;
} }
demux->segment_seqnum = gst_event_get_seqnum (event);
flush = flags & GST_SEEK_FLAG_FLUSH; flush = flags & GST_SEEK_FLAG_FLUSH;
/* send flush start */ /* send flush start */
if (flush) if (flush) {
gst_dvdemux_push_event (demux, gst_event_new_flush_start ()); new_event = gst_event_new_flush_start ();
else gst_event_set_seqnum (new_event, demux->segment_seqnum);
gst_dvdemux_push_event (demux, new_event);
} else {
gst_pad_pause_task (demux->sinkpad); gst_pad_pause_task (demux->sinkpad);
}
/* grab streaming lock, this should eventually be possible, either /* grab streaming lock, this should eventually be possible, either
* because the task is paused or our streaming thread stopped * because the task is paused or our streaming thread stopped
@ -1109,7 +1119,9 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad,
if (flush) { if (flush) {
/* send flush stop, peer will accept data and events again. We /* send flush stop, peer will accept data and events again. We
* are not yet providing data as we still have the STREAM_LOCK. */ * are not yet providing data as we still have the STREAM_LOCK. */
gst_dvdemux_push_event (demux, gst_event_new_flush_stop (TRUE)); new_event = gst_event_new_flush_stop (TRUE);
gst_event_set_seqnum (new_event, demux->segment_seqnum);
gst_dvdemux_push_event (demux, new_event);
} }
/* if successfull seek, we update our real segment and push /* if successfull seek, we update our real segment and push
@ -1118,9 +1130,12 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad,
memcpy (&demux->time_segment, &seeksegment, sizeof (GstSegment)); memcpy (&demux->time_segment, &seeksegment, sizeof (GstSegment));
if (demux->time_segment.flags & GST_SEEK_FLAG_SEGMENT) { if (demux->time_segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT_CAST (demux), GstMessage *message;
gst_message_new_segment_start (GST_OBJECT_CAST (demux),
demux->time_segment.format, demux->time_segment.position)); message = gst_message_new_segment_start (GST_OBJECT_CAST (demux),
demux->time_segment.format, demux->time_segment.position);
gst_message_set_seqnum (message, demux->segment_seqnum);
gst_element_post_message (GST_ELEMENT_CAST (demux), message);
} }
if ((stop = demux->time_segment.stop) == -1) if ((stop = demux->time_segment.stop) == -1)
stop = demux->time_segment.duration; stop = demux->time_segment.duration;
@ -1132,6 +1147,7 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad,
gst_event_unref (demux->pending_segment); gst_event_unref (demux->pending_segment);
demux->pending_segment = gst_event_new_segment (&demux->time_segment); demux->pending_segment = gst_event_new_segment (&demux->time_segment);
gst_event_set_seqnum (demux->pending_segment, demux->segment_seqnum);
demux->need_segment = FALSE; demux->need_segment = FALSE;
} }
@ -1489,6 +1505,7 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer)
if (dvdemux->need_segment) { if (dvdemux->need_segment) {
GstFormat format; GstFormat format;
GstEvent *event;
g_assert (!dvdemux->upstream_time_segment); g_assert (!dvdemux->upstream_time_segment);
@ -1516,8 +1533,10 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer)
GST_TIME_ARGS (dvdemux->time_segment.stop), GST_TIME_ARGS (dvdemux->time_segment.stop),
GST_TIME_ARGS (dvdemux->time_segment.start)); GST_TIME_ARGS (dvdemux->time_segment.start));
gst_dvdemux_push_event (dvdemux, event = gst_event_new_segment (&dvdemux->time_segment);
gst_event_new_segment (&dvdemux->time_segment)); if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
gst_dvdemux_push_event (dvdemux, event);
dvdemux->need_segment = FALSE; dvdemux->need_segment = FALSE;
} }
@ -1822,20 +1841,30 @@ done:
/* ERRORS */ /* ERRORS */
parse_header_error: parse_header_error:
{ {
GstEvent *event;
GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE, GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE,
(NULL), ("Error parsing DV header")); (NULL), ("Error parsing DV header"));
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
gst_pad_pause_task (dvdemux->sinkpad); gst_pad_pause_task (dvdemux->sinkpad);
gst_dvdemux_push_event (dvdemux, gst_event_new_eos ()); event = gst_event_new_eos ();
if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
gst_dvdemux_push_event (dvdemux, event);
goto done; goto done;
} }
small_buffer: small_buffer:
{ {
GstEvent *event;
GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE, GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE,
(NULL), ("Error reading buffer")); (NULL), ("Error reading buffer"));
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
gst_pad_pause_task (dvdemux->sinkpad); gst_pad_pause_task (dvdemux->sinkpad);
gst_dvdemux_push_event (dvdemux, gst_event_new_eos ()); event = gst_event_new_eos ();
if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
gst_dvdemux_push_event (dvdemux, event);
goto done; goto done;
} }
pause: pause:
@ -1853,20 +1882,35 @@ pause:
dvdemux->time_segment.position = dvdemux->time_segment.start; dvdemux->time_segment.position = dvdemux->time_segment.start;
/* perform EOS logic */ /* perform EOS logic */
if (dvdemux->time_segment.flags & GST_SEEK_FLAG_SEGMENT) { if (dvdemux->time_segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT (dvdemux), GstMessage *message;
gst_message_new_segment_done (GST_OBJECT_CAST (dvdemux), GstEvent *event;
dvdemux->time_segment.format, dvdemux->time_segment.position));
gst_dvdemux_push_event (dvdemux, event = gst_event_new_segment_done (dvdemux->time_segment.format,
gst_event_new_segment_done (dvdemux->time_segment.format, dvdemux->time_segment.position);
dvdemux->time_segment.position)); if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
message = gst_message_new_segment_done (GST_OBJECT_CAST (dvdemux),
dvdemux->time_segment.format, dvdemux->time_segment.position);
if (dvdemux->segment_seqnum)
gst_message_set_seqnum (message, dvdemux->segment_seqnum);
gst_element_post_message (GST_ELEMENT (dvdemux), message);
gst_dvdemux_push_event (dvdemux, event);
} else { } else {
gst_dvdemux_push_event (dvdemux, gst_event_new_eos ()); GstEvent *event = gst_event_new_eos ();
if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
gst_dvdemux_push_event (dvdemux, event);
} }
} else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
GstEvent *event = gst_event_new_eos ();
/* for fatal errors or not-linked we post an error message */ /* for fatal errors or not-linked we post an error message */
GST_ELEMENT_ERROR (dvdemux, STREAM, FAILED, GST_ELEMENT_ERROR (dvdemux, STREAM, FAILED,
(NULL), ("streaming stopped, reason %s", gst_flow_get_name (ret))); (NULL), ("streaming stopped, reason %s", gst_flow_get_name (ret)));
gst_dvdemux_push_event (dvdemux, gst_event_new_eos ()); if (dvdemux->segment_seqnum)
gst_event_set_seqnum (event, dvdemux->segment_seqnum);
gst_dvdemux_push_event (dvdemux, event);
} }
goto done; goto done;
} }

View file

@ -79,6 +79,7 @@ struct _GstDVDemux {
gboolean upstream_time_segment; gboolean upstream_time_segment;
GstSegment time_segment; GstSegment time_segment;
gboolean need_segment; gboolean need_segment;
guint32 segment_seqnum;
gboolean new_media; gboolean new_media;
int frames_since_new_media; int frames_since_new_media;