After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 743973 - playbin: Need replace suburidecoderbin's segment with normal uridecoderbin's segment
playbin: Need replace suburidecoderbin's segment with normal uridecoderbin's ...
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-02-04 10:08 UTC by kevin
Modified: 2018-11-03 11:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Draft patch for the issue. (4.11 KB, patch)
2015-04-08 15:57 UTC, kevin
none Details | Review
Update patch based on review comments. (3.90 KB, patch)
2015-05-14 15:06 UTC, kevin
none Details | Review
Update patch based on review comments. (3.90 KB, patch)
2015-05-14 15:16 UTC, kevin
reviewed Details | Review

Description kevin 2015-02-04 10:08:54 UTC
Issue:

External subtitle can't sync with video after seek.

Root Cause:

subparse send the same segment which get from seek event. video demuxer changed the segment as video need send from key frame in fast seek mode. accurate seek is ok as accurate seek needn't change segment.
video demuxer changed segment.time which used to calculate position in basesink. video demuxer changed segment.start which used to calculate render time in basesink.
subtitle can't sync with video if subtitle pipeline and video pipeline send different segment to basesink.

Solution:

Hold all segment event and select the least segment.time and segment.start. and than send the same segment to basesink to keep subtitle sync with video.

I have rough test the solution, it works. If the solution is ok, I can upload the patch for it.
Comment 1 Sebastian Dröge (slomo) 2015-02-04 10:52:14 UTC
Assuming seek goes to position T and the video keyframe is at position T_k, the problem here is that:
- video plays from T_k, which gets running time 0 because of a flushing seek
- audio does the same because it comes from the same demuxer
- subs play from T, which gets running time 0 because of flushing seeks
- sub / video, and sub / audio sync is off by T_k - T

Correct?


I think the solution here would be something inside playbin that adjusts the segment events coming from external subtitle files to match up with the audio/video segments. It can probably be solved by comparing the stream times of both streams and the corresponding running times. Stream time should be the same on both, that's what the seek event controls... and running times of both streams should be the same at the same stream time, otherwise sync is off.
Comment 2 Sebastian Dröge (slomo) 2015-02-04 10:52:53 UTC
Also I don't think this should be done in streamsynchronizer, at least not without additional signalling from playbin somehow. It seems too playbin specific.
Comment 3 kevin 2015-02-04 14:40:39 UTC
So the solution should be below:
1. playbin add pad probe function to probe event from demuxer source pad and subparse source pad.
2. hold segment event until received all segment event.
3. select the least segment.time and segment.start.
4. replace all segment event with the least segment.time and segment.start.

streamsynchronizer already has hold and wait segment function. But the wait only take effect when received segment start event.
Comment 4 kevin 2015-02-13 12:30:43 UTC
Add more information for the issue:

The issue only occur when application set appsink to playbin to sink subtitle. No such kind of issue if combine subtitle with video. Subtitle pipeline segment can't reach basesink as subtitle combined with video, so no such kind of issue.

I do see the issue on Gstreamer 1.4.1. Not sure if fixed this kind of issue on latest code.
Comment 5 kevin 2015-03-04 15:10:08 UTC
(In reply to Sebastian Dröge (slomo) from comment #1)
> Assuming seek goes to position T and the video keyframe is at position T_k,
> the problem here is that:
> - video plays from T_k, which gets running time 0 because of a flushing seek
> - audio does the same because it comes from the same demuxer
> - subs play from T, which gets running time 0 because of flushing seeks
> - sub / video, and sub / audio sync is off by T_k - T
> 
> Correct?
> 
Yes, you are right.
> 
> I think the solution here would be something inside playbin that adjusts the
> segment events coming from external subtitle files to match up with the
> audio/video segments. It can probably be solved by comparing the stream
> times of both streams and the corresponding running times. Stream time
> should be the same on both, that's what the seek event controls... and
> running times of both streams should be the same at the same stream time,
> otherwise sync is off.

Where is the place to change the segment? playbin?
Comment 6 Sebastian Dröge (slomo) 2015-03-04 15:23:17 UTC
In playbin between the subtitle uridecodebin and the input-selector for subtitles
Comment 7 kevin 2015-03-04 15:27:16 UTC
I will try it and upload patch for review. Thanks.
Comment 8 kevin 2015-04-08 15:57:49 UTC
Created attachment 301147 [details] [review]
Draft patch for the issue.
Comment 9 kevin 2015-04-13 05:14:52 UTC
Waiting for review...
Comment 10 kevin 2015-04-22 12:46:48 UTC
Ping2....
Comment 11 Sebastian Dröge (slomo) 2015-04-26 17:56:20 UTC
Review of attachment 301147 [details] [review]:

Please describe in more detail what this is supposed to fix, and in which situation this problem can appear

::: gst/playback/gstplaybin2.c
@@ +3055,3 @@
+
+        GST_SOURCE_GROUP_LOCK (group);
+        _uridecodebin_event_probe_wait (group);

I think it's cleaner to use a blocking pad probe for this instead of using a custom cond. Especially a block pad probe will handle things properly for flushing and pad deactivation

@@ +3058,3 @@
+        if (segment.format == GST_FORMAT_TIME) {
+          segment.start = group->nonsub_segment.start;
+          segment.time = group->nonsub_segment.time;

Why only these two? Should probably replace the whole segment

@@ +5322,3 @@
       }
       gst_element_set_state (suburidecodebin, GST_STATE_READY);
+      g_cond_init (&group->suburidecodebin_segment_cond);

Here you would init the cond on every group switch... it should only be done exactly once when playbin is created (and then cleared in finalize)

@@ +5500,3 @@
+    group->got_nonsub_segment = TRUE;
+    g_cond_broadcast (&group->suburidecodebin_segment_cond);
+    g_cond_clear (&group->suburidecodebin_segment_cond);

Especially this will probably cause problems as at this time another thread is actually still using the cond
Comment 12 kevin 2015-04-28 07:49:46 UTC
(In reply to Sebastian Dröge (slomo) from comment #11)
> Review of attachment 301147 [details] [review] [review]:
> 
> Please describe in more detail what this is supposed to fix, and in which
> situation this problem can appear
> 

External subtitle don't sync with Audio/Video after seek. The root cause is external subtitle's segment is different with Audio/Video's segment after seek. The solution is replace subtitle's segment with Audio/Video's segment.

> ::: gst/playback/gstplaybin2.c
> @@ +3055,3 @@
> +
> +        GST_SOURCE_GROUP_LOCK (group);
> +        _uridecodebin_event_probe_wait (group);
> 
> I think it's cleaner to use a blocking pad probe for this instead of using a
> custom cond. Especially a block pad probe will handle things properly for
> flushing and pad deactivation
> 

Accept. Can reuse function gst_play_bin_suburidecodebin_block() to block the subtitle segment event? When we should add the block probe? Add the block probe when playbin received seed event?

> @@ +3058,3 @@
> +        if (segment.format == GST_FORMAT_TIME) {
> +          segment.start = group->nonsub_segment.start;
> +          segment.time = group->nonsub_segment.time;
> 
> Why only these two? Should probably replace the whole segment
> 
Accept.
> @@ +5322,3 @@
>        }
>        gst_element_set_state (suburidecodebin, GST_STATE_READY);
> +      g_cond_init (&group->suburidecodebin_segment_cond);
> 
> Here you would init the cond on every group switch... it should only be done
> exactly once when playbin is created (and then cleared in finalize)
> 
Needn't custom cond any more.
> @@ +5500,3 @@
> +    group->got_nonsub_segment = TRUE;
> +    g_cond_broadcast (&group->suburidecodebin_segment_cond);
> +    g_cond_clear (&group->suburidecodebin_segment_cond);
> 
> Especially this will probably cause problems as at this time another thread
> is actually still using the cond
Needn't custom cond any more.
Comment 13 Sebastian Dröge (slomo) 2015-05-14 08:22:07 UTC
I think you forgot to attach the updated patch :)
Comment 14 kevin 2015-05-14 15:06:15 UTC
Created attachment 303378 [details] [review]
Update patch based on review comments.
Comment 15 kevin 2015-05-14 15:16:35 UTC
Created attachment 303379 [details] [review]
Update patch based on review comments.
Comment 16 Sebastian Dröge (slomo) 2015-05-18 07:59:40 UTC
(In reply to kevin from comment #4)
> Add more information for the issue:
> 
> The issue only occur when application set appsink to playbin to sink
> subtitle. No such kind of issue if combine subtitle with video. Subtitle
> pipeline segment can't reach basesink as subtitle combined with video, so no
> such kind of issue.

This sounds like something would be wrong in subtitleoverlay/assrender/textoverlay/etc too then. They should show the same behaviour as a text-sink.




Also I think your patch is going to fail if the audio/video upstream is setting a different base time, or otherwise has a non-standard segment. I think we need to do something more clever here by actually not copying the segment... but instead making sure that the subtitle segment is based on the audio/video segment in a way that the first subtitle timestamp inside the segment is the keyframe timestamp.

For this you would have to a) catch the audio/video segment and remember it, b) *modify* the subtitle segment to adjust the start (and possibly other fields) of the segment. The resulting subtitle segment should cause all subs to be before the segment until the keyframe timestamp, the keyframe timestamp should be mapped to running time 0 and to the stream time that the keyframe timestamp also has for the audio/video segment.
Comment 17 GStreamer system administrator 2018-11-03 11:34:42 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/159.