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 745192 - matroskademux: V_MS-VFW-FOURCC streams have DTS instead of PTS
matroskademux: V_MS-VFW-FOURCC streams have DTS instead of PTS
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other All
: Normal blocker
: 1.5.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-02-26 01:17 UTC by Matej Knopp
Modified: 2015-03-16 11:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch (2.24 KB, patch)
2015-02-26 01:17 UTC, Matej Knopp
committed Details | Review
matroskamux: store DTS for V_MS/VFW/FOURCC streams (1.90 KB, patch)
2015-02-26 22:36 UTC, Nicola
committed Details | Review
initialize dts_only (1.30 KB, patch)
2015-02-26 22:44 UTC, Nicola
committed Details | Review
proposed fix (9.57 KB, patch)
2015-02-27 17:59 UTC, Nicola
none Details | Review
use helper method in demux too (1.85 KB, patch)
2015-02-27 18:00 UTC, Nicola
none Details | Review
updated patch (11.82 KB, patch)
2015-03-02 11:01 UTC, Nicola
none Details | Review
update collected pad duration only for buffers with different timestamp (2.61 KB, patch)
2015-03-03 09:01 UTC, Nicola
none Details | Review
updated patch (12.07 KB, patch)
2015-03-03 18:23 UTC, Nicola
committed Details | Review
remove duration accumulation logic (4.67 KB, patch)
2015-03-03 18:23 UTC, Nicola
committed Details | Review
set pts for keyframes in any case (1.20 KB, patch)
2015-03-07 20:06 UTC, Nicola
none Details | Review
tentative patch (3.25 KB, patch)
2015-03-08 11:00 UTC, Nicola
none Details | Review
tentative patch v2 (4.08 KB, patch)
2015-03-08 12:00 UTC, Nicola
none Details | Review
tentative patch v3 (3.17 KB, patch)
2015-03-11 20:28 UTC, Nicola
committed Details | Review

Description Matej Knopp 2015-02-26 01:17:45 UTC
Created attachment 297942 [details] [review]
Patch

When such stream is present demuxer should set DTS on buffers instead of PTS. This is consistent with how VLC and libav/ffmpeg handle VFW streams.

Sample file
https://s3.amazonaws.com/MatejK/Samples/Matroska-VFW-DTS-Only.mkv
Comment 1 Sebastian Dröge (slomo) 2015-02-26 09:12:20 UTC
commit fa283f407f3de4a31ecf756f6cdd02aeb9d162d3
Author: Matej Knopp <matej.knopp@gmail.com>
Date:   Thu Feb 26 02:12:18 2015 +0100

    matroskademux: V_MS/VFW/FOURCC streams have DTS instead of PTS
    
    When such stream is present demuxer should set DTS on buffers instead
    of PTS. This is consistent with how VLC and libav/ffmpeg handle VFW
    streams.
    
    Sample file
    https://s3.amazonaws.com/MatejK/Samples/Matroska-VFW-DTS-Only.mkv
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192
Comment 2 Nicola 2015-02-26 09:57:02 UTC
this patch break even more transmuxing, a simple pipeline like this:

matroskademux ! matroskamux

does not work anymore with the above file since all pts are not setted
Comment 3 Sebastian Dröge (slomo) 2015-02-26 10:03:45 UTC
You need a parser between the two, and ideally that parser would calculate DTS from PTS and the other way around. You already had the same problem with avidemux ! matroskamux for example.
Comment 4 Nicola 2015-02-26 10:14:29 UTC
ideally yes, but actually parser seems unable to do this job
Comment 5 Matej Knopp 2015-02-26 10:41:02 UTC
Well, I guess the muxer should do the same thing. When muxing VFW it should use DTS instead of PTS, as that's what demuxers expect anyway.

As for the timestamps, the MPEG4 parser could compute PTS from DTS, that shouldn't be too difficult. For H.264 and VC1 it would be more complicated.
Comment 6 Nicola 2015-02-26 10:47:43 UTC
(In reply to Matej Knopp from comment #5)
> Well, I guess the muxer should do the same thing. When muxing VFW it should
> use DTS instead of PTS, as that's what demuxers expect anyway.

this more or less the workaround that I use in my application, I demux with something like demuxer ! appsink and when I receive the buffer I set pts from dts if pts is not setted, can something similar be used as fallback in muxers until the parsers are fixed?

> 
> As for the timestamps, the MPEG4 parser could compute PTS from DTS, that
> shouldn't be too difficult. For H.264 and VC1 it would be more complicated.
Comment 7 Matej Knopp 2015-02-26 11:00:40 UTC
You can't just use DTS instead of PTS for streams with bframes when there should be PTS in the output. Such file will not be compliant. It will play in some players but will have problems in other (that use decoders that don't output frames in presentation order and rely on PTS, such as Apple decoders)

The proper way in this case would be to mux DTS instead of PTS for VFW streams. IIRC avidemux already sets DTS (although it seems to set PTS on keyframes as well, which I'm not sure is right; and avimux always muxes PTS which definitely isn't right).

It seems that right now avidemux | matroskamux and avidemux | avimux wouldn't work either.
Comment 8 Nicola 2015-02-26 12:32:20 UTC
Matej, thanks for your explaination, I'll try to make a patch for matroskamux so that it use dts and not pts for V_MS/VFW/FOURCC streams, this should be fine since for this stream pts is supposed to be not setted
Comment 9 Nicola 2015-02-26 22:36:00 UTC
Created attachment 298035 [details] [review]
matroskamux: store DTS for V_MS/VFW/FOURCC streams

this store dts for the following mimetypes:

- video/x-huffyuv
- video/x-divx
- video/x-dv
- video/x-h263
- video/x-msmpeg
- video/x-wmv
- image/jpeg
Comment 10 Nicola 2015-02-26 22:44:26 UTC
Created attachment 298039 [details] [review]
initialize dts_only
Comment 11 Sebastian Dröge (slomo) 2015-02-27 07:54:50 UTC
commit e676b8ba9c1b5969611aab2f4e9ab3742968f1b0
Author: Nicola Murino <nicola.murino@gmail.com>
Date:   Thu Feb 26 23:41:47 2015 +0100

    matroskamux/demux: initialize dts_only
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192

commit 09b8f0efc30368517e839f1ccb284592683321cb
Author: Nicola Murino <nicola.murino@gmail.com>
Date:   Thu Feb 26 23:28:11 2015 +0100

    matroskamux: store DTS for V_MS/VFW/FOURCC streams
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192
Comment 12 Nicola 2015-02-27 17:13:28 UTC
the muxer patch is not completly correct, in matroskamux there are calls like this:

GST_BUFFER_TIMESTAMP (buf)

in a many places (for example for duration calculation), I think an helper method should be done to return the pts/dts, I'll try to work on this the next week if noone is faster than me.

Also the demuxer use GST_BUFFER_TIMESTAMP in a log message, this could be make debug harder
Comment 13 Nicola 2015-02-27 17:59:36 UTC
Created attachment 298106 [details] [review]
proposed fix
Comment 14 Nicola 2015-02-27 18:00:00 UTC
Created attachment 298107 [details] [review]
use helper method in demux too
Comment 15 Sebastian Dröge (slomo) 2015-03-02 10:08:09 UTC
Also an interesting question from IRC:

<drakkan1000> slomo, hi, I have a question about this commit http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=fa283f407f3de4a31ecf756f6cdd02aeb9d162d3 now that the demuxer can output only dts, how to handle for example gap events? In gap events the timestamp is the pts, but now we can have no pts
Comment 16 Sebastian Dröge (slomo) 2015-03-02 10:09:59 UTC
Comment on attachment 298106 [details] [review]
proposed fix

Please give this helper method a proper namespace prefix, otherwise this can easily conflict with other code especially during static linking.

E.g. call it gst_matroska_track_get_buffer_timestamp()
Comment 17 Nicola 2015-03-02 11:01:22 UTC
Created attachment 298269 [details] [review]
updated patch
Comment 18 Nicola 2015-03-02 11:09:14 UTC
(In reply to Sebastian Dröge (slomo) from comment #15)
> Also an interesting question from IRC:
> 
> <drakkan1000> slomo, hi, I have a question about this commit
> http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/
> ?id=fa283f407f3de4a31ecf756f6cdd02aeb9d162d3 now that the demuxer can output
> only dts, how to handle for example gap events? In gap events the timestamp
> is the pts, but now we can have no pts

for matroska timestamp in gap and new segment events should be dts or pts based on the stream type after applying these patches
Comment 19 Nicola 2015-03-02 11:10:34 UTC
so probably the gst_event_parse_gap doc should be fixed
Comment 20 Nicola 2015-03-03 09:01:06 UTC
Created attachment 298389 [details] [review]
update collected pad duration only for buffers with different timestamp

after the latest patch avidemux ! matroskamux works for dts only file (for example divx inside avi) but produce wrong duration for some files because collect pad duration result greater than real duration. This patch solve also this issue,

here is a log that show the duplicated ts for different buffers

/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (4965 bytes, dts: 0:01:05.222222100, pts: none, duration: 0:00:00.039989100, offset: 16690594, offset_end: -1, flags: 00002000 delta-unit ) 0x7fd0d80034c0
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (8 bytes, dts: 0:01:05.222222100, pts: none, duration: 0:00:00.039989100, offset: 16695559, offset_end: -1, flags: 00002000 delta-unit ) 0x7fd0d80035d0

the patch can help in general and collectad duration should be updated from buffer duration only if the buffer timestamps are not equal
Comment 21 Sebastian Dröge (slomo) 2015-03-03 09:57:37 UTC
Review of attachment 298269 [details] [review]:

Looks good, but please do the following cleanup :) Then I'll merge it

::: gst/matroska/matroska-mux.c
@@ +3411,3 @@
       GST_LOG_OBJECT (mux, "have video keyframe, ts=%" GST_TIME_FORMAT,
+          GST_TIME_ARGS (gst_matroska_track_get_buffer_timestamp
+              (collect_pad->track, buf)));

Instead of calling the function many, many times here... just store the timestamp in some local variable :) Will make it easier to read the code.
Comment 22 Sebastian Dröge (slomo) 2015-03-03 09:59:38 UTC
Review of attachment 298389 [details] [review]:

::: gst/matroska/matroska-mux.c
@@ +3480,3 @@
+        || gst_matroska_track_get_buffer_timestamp (collect_pad->track,
+            buf) != collect_pad->last_collected_duration_ts) {
+      collect_pad->duration += GST_BUFFER_DURATION (buf);

I think the duration should rather be the difference between the first buffer's timestamp and the last buffer's timestamp+duration. Counting it here is not going to give useful results and accumulates rounding errors.
Comment 23 Nicola 2015-03-03 18:23:27 UTC
Created attachment 298462 [details] [review]
updated patch
Comment 24 Nicola 2015-03-03 18:23:59 UTC
Created attachment 298463 [details] [review]
remove duration accumulation logic
Comment 25 Sebastian Dröge (slomo) 2015-03-04 10:38:29 UTC
commit c4e542de695e07cab64f390b4523b9b68ba84971
Author: Nicola Murino <nicola.murino@gmail.com>
Date:   Tue Mar 3 19:19:50 2015 +0100

    matroskamux: Remove duration accumulation logic
    
    Duration accumulation can cause rounding errors and generate wrong
    duration with different buffers that share the same timestamp.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192

commit f727762c1f186c15d6e656e92c01306796de8692
Author: Nicola Murino <nicola.murino@gmail.com>
Date:   Tue Mar 3 18:40:16 2015 +0100

    matroska: Add an helper method to get buffer timestamps
    
    ... and replace GST_BUFFER_TIMESTAMP that always return PTS with this method
    that return PTS or DTS based on stream type.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192
Comment 26 Nicola 2015-03-07 20:06:42 UTC
Created attachment 298785 [details] [review]
set pts for keyframes in any case

this should be the last missing place, this way the behaviour is the same as avidemux and for keyframe pts and dts match in any case
Comment 27 Nicola 2015-03-07 20:42:24 UTC
the latest patch fix playback for some jpeg file for example this one:

http://195.250.34.59/temp/jpeg.mkv

jpeg inside matroska is now dts only, a buffer with dts and not pts seems to create problems to jpegdec. I don't know if the bug is in jpegdec, however avidemux put pts on keyframe too
Comment 28 Sebastian Dröge (slomo) 2015-03-08 08:50:58 UTC
I'm not sure if this is correct. IIRC there are situations where the DTS and PTS of keyframes can be different too.

Maybe instead there should be a keyframe-only setting, which is then used for JPEG and similar formats?
Comment 29 Nicolas Dufresne (ndufresne) 2015-03-08 09:26:03 UTC
Indeed, for at least H264, DTS can be smaller then PTS at keyframes. This figure explains a bit that shift:

https://software.intel.com/sites/default/files/pts-dts_shift_explain.gif
https://software.intel.com/en-us/forums/topic/501639
Comment 30 Nicola 2015-03-08 11:00:51 UTC
Created attachment 298803 [details] [review]
tentative patch

added a new context property "is_raw", this property is setted to true for jpeg and raw formats

for VFW case (that is the only one that really matter) we can have raw and not raw formats

For file muxed by gstreamer raw formats should be only jpeg and huffyuv (not sure if dv is raw). The patch handle these codec

I don't know if a matroska file muxed by app different from gstreamer can store other raw formats for VFW streams (probably yes), in this case is there a smarter way than the one in the patch to understand if a stream is raw or not without replicate all gst_riff_create_video_caps code?
Comment 31 Sebastian Dröge (slomo) 2015-03-08 11:14:34 UTC
(In reply to Nicola from comment #30)
> Created attachment 298803 [details] [review] [review]
> tentative patch
> 
> added a new context property "is_raw", this property is setted to true for
> jpeg and raw formats
> 
> for VFW case (that is the only one that really matter) we can have raw and
> not raw formats
> 
> For file muxed by gstreamer raw formats should be only jpeg and huffyuv (not
> sure if dv is raw). The patch handle these codec
> 
> I don't know if a matroska file muxed by app different from gstreamer can
> store other raw formats for VFW streams (probably yes), in this case is
> there a smarter way than the one in the patch to understand if a stream is
> raw or not without replicate all gst_riff_create_video_caps code?

Unfortunately not, but the list of caps that are intra-only shouldn't be too big. (DV is included there btw)

I would call that field intra_only instead of raw btw, that's more accurate.
Comment 32 Nicola 2015-03-08 12:00:44 UTC
Created attachment 298804 [details] [review]
tentative patch v2

I added a list of formats that will be likely find in mkv file based on the entries in gst_riff_create_video_caps and the ones in matroska-ids.h, however the list should be easily extensible
Comment 33 Matej Knopp 2015-03-08 16:16:40 UTC
Avidemux can probably get away with putting PTS=DTS on keyframe because no one sane muxes H.264 in avi anyway and I don't think mpeg 4 video can have open gop. I still think though that demuxer should only put PTS=DTS for streams that don't have reordering (and in that case do it on every frame). And if does set PTS=DTS on keyframes for reordered stream it better knows what it is doing :)
Comment 34 Nicola 2015-03-08 16:42:16 UTC
the latest patch set dts=pts on every frame for intra only stream
Comment 35 Sebastian Dröge (slomo) 2015-03-11 16:01:21 UTC
Review of attachment 298804 [details] [review]:

::: gst/matroska/matroska-demux.c
@@ +4888,3 @@
+            gst_caps_new_empty_simple ("video/x-ffv"));
+        for (iterator = intra_caps; iterator != NULL; iterator = iterator->next) {
+          if (gst_caps_can_intersect ((GstCaps *) iterator->data, caps)) {

Why so complicated?

static GstStaticCaps intra_caps = GST_STATIC_CAPS("image/jpeg; video/x-raw; .....");
context->intra_only = gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
Comment 36 Nicola 2015-03-11 20:28:27 UTC
Created attachment 299131 [details] [review]
tentative patch v3

please review, thanks Nicola
Comment 37 Sebastian Dröge (slomo) 2015-03-15 14:26:46 UTC
commit bb3d82ef04107310e685db0bb0ddcc218dda1721
Author: Nicola Murino <nicola.murino@gmail.com>
Date:   Wed Mar 11 21:25:40 2015 +0100

    matroskademux: for dts only stream set pts=dts for intra only formats
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745192
Comment 38 Jan Alexander Steffens (heftig) 2015-03-16 08:59:07 UTC
As noted in bug 733720 I think the intra-only formats should not have pts=dts but dts=none, as e.g. videorate does not look at or touch dts at all, leading to trouble later if dts is preferred to pts (as sinks do, for example).
Comment 39 Matej Knopp 2015-03-16 11:17:57 UTC
Jan, shouldn't decoder have taken care of that? Once you decode the stream you should have valid PTS on output and no DTS. You don't feed videorate raw stream.
Comment 40 Jan Alexander Steffens (heftig) 2015-03-16 11:31:46 UTC
Matroska can transport raw streams, though.
Comment 41 Jan Alexander Steffens (heftig) 2015-03-16 11:34:05 UTC
To clarify, yes, videorate wants video/x-raw streams (as well as image/jpeg or image/png). I'm using Matroska with raw streams for transport between processes.
Comment 42 Nicola 2015-03-16 11:40:12 UTC
actually matroskademux set pts = dts for intra only VFW streams. Before Matej' patch only pts was setted and never dts for all streams. 

We can easily modify mastroksademux to set pts and not dts for intra only VFW streams, only we need to understand if we agree on this