[Bug 777073] New: Can not complete preroll in case pause/seek is called after one of streams receive EOS

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Tue Jan 10 08:04:56 UTC 2017


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

            Bug ID: 777073
           Summary: Can not complete preroll in case pause/seek is called
                    after one of streams receive EOS
    Classification: Platform
           Product: GStreamer
           Version: git master
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: Normal
         Component: gstreamer (core)
          Assignee: gstreamer-bugs at lists.freedesktop.org
          Reporter: heekyoung.seo at lge.com
        QA Contact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---

Created attachment 343215
  --> https://bugzilla.gnome.org/attachment.cgi?id=343215&action=edit
Issue file (a/v duration is different)

pipeline can not complete preroll when pause/seek is called in situations where
one of the streams receives EOS and the other does not. The phenomenon occurs
when playing multimedia files made of audio and video of different lengths. The
root cause of the problem occurs because the segment position is set to out of
segment.

1. Seek case
- gststreamsynchronizer sink event handler update segment.stop to
segment.position in normal eos case as below

      if (seen_data && stream->segment.position != -1)
        timestamp = stream->segment.position;
      else if (stream->segment.rate < 0.0 || stream->segment.stop == -1)
        timestamp = stream->segment.start;
      else
        timestamp = stream->segment.stop;

      stream->segment.position = timestamp;

- gst_segment_clip function treats the start position of gap_evet as out of
segment if it is greater than or equal to segment.stop.
- gap_event is considered not_syncable then preroll can not be finished.

2. Pause case
- gststreamersynchronzer sink_chain function update the position of eos stream
using position of non eos stream. Therefore segment position of eos stream can
be bigger than own segment stop value.
      /* Is there a 1 second lag? */
      if (position != -1 && GST_CLOCK_TIME_IS_VALID (timestamp_end) &&
          position + GST_SECOND < timestamp_end) {
        gint64 new_start;

        new_start = timestamp_end - GST_SECOND;

        GST_DEBUG_OBJECT (ostream->sinkpad,
            "Advancing stream %u from %" GST_TIME_FORMAT " to %"
            GST_TIME_FORMAT, ostream->stream_number, GST_TIME_ARGS (position),
            GST_TIME_ARGS (new_start));

        ostream->segment.position = new_start;

- gst_segment_clip function treats the start position of gap_evet as out of
segment if it is greater than or equal to segment.stop.
- gap_event is considered not_syncable then preroll can not be finished.


I suggest below solution.

1. Seek case : change segment boundary. It would be aligned with comment, too. 
  if (G_UNLIKELY (segment->stop != -1 && start != -1 && start >=
segment->stop))
  -> if (G_UNLIKELY (segment->stop != -1 && start != -1 && start >
segment->stop))

2. Pause case : add limitation of segment position when it is updated in
sink_chain function of gststreamsynchronizer

         new_start = timestamp_end - GST_SECOND;

+        /* if new_start is bigger than segment.stop, it is out of segment. */
+        if (new_start > ostream->segment.stop)
+          new_start = ostream->segment.stop;
+


It can be fixed another way, but I am trying to change as small as it can be. 
If there is better solution, please fix it or give me the advice about it.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list