Opened 5 years ago

Closed 5 years ago

Last modified 4 years ago

#3382 closed defect (invalid)

VLC does not reproduce MPEG2 video streams in Matroska properly.

Reported by: xaviour Owned by: fenrir
Priority: normal Milestone: Bugs paradize
Component: Demuxers Version: master git
Severity: normal Keywords: MPEG2, Matroska
Cc: ale5000@… Difficulty: unknown
Platform(s): all Work status: Not started

Description

Files generated by mkvmerge using a MPEG2 video elementary as source are not reproduced properly by VLC while the original video stream is reproduced properly.

This has been tested with VLC 1.0.5 under Windows and VLC 1.0.2 under Ubuntu 9.10.

The original ticket in mkvmerge bugzilla. The file needed to reproduce the bug is available upon request (20 MB).

Attachments (3)

bad.txt (17.0 KB) - added by xaviour 5 years ago.
The content of the message window when reproducing bad.mkv
good.txt (9.7 KB) - added by xaviour 5 years ago.
The content of the message window when reproducing good.mkv
elecard.txt.gz (10.4 KB) - added by xaviour 5 years ago.
Analysis of the reference MPEG2 video by Elecard Stream Analyzer.

Download all attachments as: .zip

Change History (22)

comment:1 Changed 5 years ago by xaviour

Because of the lack of a better mechanism, I uploaded the sample videos in RapidShare and FileFactory. The zip archive contains 3 files:

  • sample.m2v: The original MPEG2 elementary stream. VLC reproduces it properly.
  • good.mkv: The same stream multiplexed using the V_MS/VFW/FOURCC codec id. VLC reproduces it properly.
  • bad.mkv: The same stream multiplexed using the V_MPEG2 codec id. VLC does not reproduce it properly. VLC seams to be jumping back and forth in time of a few frames.

To recreate the second file, first multiplex the elementary stream into an AVI using ffmpeg and then use mkvtoolnix on the resulting AVI:

ffmpeg -i sample.m2v -an -vcodec copy sample.avi
mkvmerge -o "good.mkv"  "--forced-track" "0:no" "--aspect-ratio" "0:16/9" "-d" "0" "-A" "-S" "-T" "--no-global-tags" "--no-chapters" "sample.avi" "--track-order" "0:0"

To recreate the third file, simply multiplex the elementary stream into an MKV using mkvtoolnix:

mkvmerge -o "bad.mkv"  "--forced-track" "0:no" "--aspect-ratio" "0:16/9" "-d" "0" "-A" "-S" "-T" "--no-global-tags" "--no-chapters" "sample.m2v" "--track-order" "0:0"

Changed 5 years ago by xaviour

The content of the message window when reproducing bad.mkv

Changed 5 years ago by xaviour

The content of the message window when reproducing good.mkv

comment:2 follow-up: Changed 5 years ago by jb

  • Version changed from 1.0.x (bugfix) to master

comment:3 in reply to: ↑ 2 Changed 5 years ago by xaviour

The video format is PAL so there is 50 fields per seconds that is to say each field takes 20000 us. All times mentioned in the lines with "pts != current_date" are multiple of 20000 us.

The messages in the log repeat themselves 10 times

main warning: decoder synchro warning: pts != current_date (-20000)
main warning: backward_pts != dts (119062)
main warning: backward_pts != current_pts (100000)
main warning: decoder synchro warning: pts != current_date (-100000)
main warning: backward_pts != dts (119062)
main warning: backward_pts != current_pts (100000)
main warning: decoder synchro warning: pts != current_date (-100000)
main warning: backward_pts != dts (119062)
main warning: backward_pts != current_pts (100000)
main warning: decoder synchro warning: pts != current_date (-100000)
main warning: backward_pts != dts (120000)
main warning: backward_pts != current_pts (100000)
main warning: backward_pts != dts (40000)
main warning: backward_pts != current_pts (-80000)

Using gopchop on the original MPEG PS file, it appears that the sample contains 10 GOP. The sequence of frames is:

Picture : Field Even : Field Old
00      : I(00)      : P(00)
01      : P(03)      : P(03)
02      : B(01)      : B(01)
03      : B(02)      : B(02)
04      : B(06)      : B(06)
05      : B(04)      : B(04)
06      : B(05)      : B(05)
07      : P(09)      : P(09)
08      : B(07)      : B(07)
09      : B(08)      : B(08)
10      : P(12)      : P(12)
11      : B(10)      : B(10)
12      : B(11)      : B(11)

The number in parenthesis after the frame type (I, P or B) is the number of the picture in which the frame should be displayed.

So it is probably not necessary to analyze the full file to find the problem.

comment:4 Changed 5 years ago by xaviour

Changing the FPS field in mkvmerge impacts the values in the "pts != current_date" warnings.

  • If the field is left empty or if it is set to 50 then the sequence is: -20000, -100000, -100000, -100000.
  • If the field is set to 25 then the sequence is: -80000, -40000, -240000, -40000, -240000, -40000, -240000, -40000.

comment:5 follow-up: Changed 5 years ago by fenrir

  • Resolution set to invalid
  • Status changed from new to closed

Unless I made something wrong with my logs, the bad.mkv files does have wrong timestamps for a lot of frames, making the playback jerky.

For example:

TYPE=I pts 0
TYPE=P pts 40000
TYPE=B pts 60000
TYPE=B pts 100000
TYPE=P pts 160000
TYPE=B pts 180000
TYPE=B pts 220000
TYPE=P pts 280000
TYPE=B pts 300000

Here, it is obvious that the pts for the B frame at least are bogus. And so I think that mkvmerge is really the culprit.

comment:6 Changed 5 years ago by xaviour

  • Resolution invalid deleted
  • Status changed from closed to reopened

Laurent, thank you very much for having a look at the problem. The problem however is that Moritz Bunkus (the maintainer of mkvmerge) and you disagree on where the bug is.

On one side, the argument is that all lot of programs reproduce the file flawlessly. On the other side, the argument is that the timestamps on the B frames are bogus.

Could you please try to contact each other directly and reach an agreement? If you wish to keep the conversation private, know that being registered in both bug tracking systems and can help you get each other email addresses.

comment:7 Changed 5 years ago by xaviour

Using as a reference the list of frames you used previously, could you write what are the PTS you would expect?

comment:8 Changed 5 years ago by xaviour

I patched mkvmerge to make it generate PTS that I believe are correct. The file generated can be found here. With this modification, only the FPS field matters:

  • Patched + Leave FPS empty = VLC = OK, mplayer = jerky
  • Patched + set FPS to 50 = VLC = jerky, mplayer = OK.
  • Patched + set FPS to 25 = VLC = slow + jerky, mplayer = slow.

When the FPS field is left empty, the resulting file use 40000000 for the default duration field. Moreover, even on the video that plays correctly, there are still 4 warnings (like the number of P frames in the GOP) in the log repeating. First, can you tell me what they correspond to? Then I have no idea where the value 19062 comes from.

main warning: backward_pts != dts (19062)
main warning: backward_pts != dts (19062)
main warning: backward_pts != dts (19062)
main warning: backward_pts != dts (40000)
main warning: backward_pts != dts (120000)

Also what should be the correct interpretation of "FPS/Default Duration" for the V_MPEG2 codec? The number of pictures per second (so 25) or the number of field (so 50 because the video is interlaced)?

Finally do you have a way to get more information from VLC without recompiling everything or in other terms how did you get the list of packets with their times?

comment:9 Changed 5 years ago by xaviour

Also by moving back and forth in time using the slider, I manage to segfault VLC quite quickly.

xavier@desktop:~/sample$ vlc good_vlc.mkv 
VLC media player 1.0.2 Goldeneye
[0x907c140] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
 m_el[mi_level] == NULL
 arrrrrrrrrrrrrg Up cannot escape itself
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::begin: Paint device returned engine == 0, type: 1
[0x936fba0] libmpeg2 decoder error: DpbUnlinkPicture called on an invalid picture
[0x936fba0] libmpeg2 decoder error: DpbUnlinkPicture called on an invalid picture
[0x936fba0] libmpeg2 decoder error: DpbUnlinkPicture called on an invalid picture
[0x936fba0] libmpeg2 decoder error: DpbUnlinkPicture called on an invalid picture
Segmentation fault

comment:10 in reply to: ↑ 5 Changed 5 years ago by xaviour

Replying to fenrir:

Unless I made something wrong with my logs, the bad.mkv files does have wrong timestamps for a lot of frames, making the playback jerky.

For example:

TYPE=I pts 0
TYPE=P pts 40000
TYPE=B pts 60000
TYPE=B pts 100000
TYPE=P pts 160000
TYPE=B pts 180000
TYPE=B pts 220000
TYPE=P pts 280000
TYPE=B pts 300000

Here, it is obvious that the pts for the B frame at least are bogus. And so I think that mkvmerge is really the culprit.

I decided to look at the problem from another angle. Instead of using mkvtoolnix, I used a tool written by one of the Matroska developers called "mpeg2mkv.exe". It is hard to find as mkvtoolnix do a much better job today. It can be downloaded from there. It works fine under Wine.

This tool is the reference implementation as far as Matroska's spec is concerned. So if VLC cannot reproduce the files that this tool generates then the problem is in VLC.

I uploaded the resulting video in Rapidshare. VLC is not capable of playing it.

Also I do not think that the timestamps from the log you provide are correct. First of all, some frames are missing as the video is interlaced there are 2 coded frames per pictures. The sequence in decoding order is I P P P B B B B and I P B B B B P P in presentation order. The presentation timestamps are actually in milliseconds:

0
20
40
60
80
100
120
140

This is consistent with 25 pictures per seconds or 50 frames per seconds (duration 20 ms per frame). The presentation timestamps are increasing monotonously as expected.

Changed 5 years ago by xaviour

Analysis of the reference MPEG2 video by Elecard Stream Analyzer.

comment:11 Changed 5 years ago by xaviour

Uploaded an analysis of the MPEG2 elementary stream using Elecard to close the topic of what the PTS should be.

Elecard lists the packets in decoding order. The temporal_reference field gives the presentation order (modulo 1024). The counter is also reset to 0 after each GOP header. For the first 26 field frames, take the presentation order and multiply it by 20 ms to get the PTS.

comment:12 Changed 5 years ago by xaviour

  • Resolution set to invalid
  • Status changed from reopened to closed

So after a lot of learning about how both MPEG2 Video and Matroska work, I have been able to find out that:

  • mkvtoolnix generates wrong timecodes. I submitted a patch upstream but it might take some time before it is applied because of the next point.
  • Old versions of ffmpeg and as a consequence old versions of mplayer do not handle matroska files with correct timecodes properly. Newer versions of ffmpeg are fine with it.
  • The odd non multiple of 20 ms PTS displayed by VLC are caused by mkv.cpp line 598.
    if ( f_mandatory )
      p_block->i_dts = p_block->i_pts;
    else
      p_block->i_dts = min( i_pts, tk->i_last_dts + (mtime_t)(tk->i_default_duration >> 10));
    

The variable "tk->i_default_duration" should be divided by 2000 instead of 2048. This optimization does not affect the outcome but it really made debugging harder.

comment:13 Changed 5 years ago by jb

xaviour: do you have patch for us?

comment:14 follow-up: Changed 5 years ago by xaviour

Writing a patch to fix the problem I described is fairly easy. However there might be a hidden bug. I need to figure out if "i_default_duration" already takes into account the "TrackTimecodeScale?" field from the track. By default the value is 1.0 for the TrackTimecodeScale? so everything is fine. Search for "TrackTimecodeScale?" in the spec. It is just before the definition of DefaultDuration?.

The correct formula might be something like:

tk->i_last_dts + (mtime_t)(tk->i_track_timecode_scale * tk->i_default_duration / 2048))

So there is still some studying to be done.

Then probably nobody uses "TrackTimecodeScale?" anyhow.

comment:15 Changed 5 years ago by ale5000

xaviour: For me the most important purpose for use VLC is that it support all videos also broken ones, so it would be nice if VLC support "TrackTimecodeScale?" and also files created by mkvtoolnix with wrong timecodes.

comment:16 Changed 5 years ago by ale5000

  • Cc ale5000@… added

comment:17 in reply to: ↑ 14 ; follow-up: Changed 5 years ago by mike3050

Replying to xaviour:

Writing a patch to fix the problem I described is fairly easy. However there might be a hidden bug. I need to figure out if "i_default_duration" already takes into account the "TrackTimecodeScale?" field from the track. By default the value cheap auto insuranceis 1.0 for the TrackTimecodeScale? so everything is fine. Search for "TrackTimecodeScale?" in the spec. It is just before the definition of DefaultDuration?.

The correct formula might be something like:

tk->i_last_dts + (mtime_t)(tk->i_track_timecode_scale * tk->i_default_duration / 2048))

So there is still some studying to be done.

Then probably nobody uses "TrackTimecodeScale?" anyhow.

Thank you for your solution

comment:18 in reply to: ↑ 17 Changed 5 years ago by itcoll

Replying to mike3050:

Replying to xaviour:

Writing a patch to fix the problem I described is fairly easy. However there might be a hidden bug. I need to figure out if "i_default_duration" already takes into account the "TrackTimecodeScale?" field from the track. By default the value cheap auto insuranceis 1.0 for the TrackTimecodeScale? so everything is fine. Search for "TrackTimecodeScale?" in the spec. It is just before the definition of DefaultDuration?.

The correct formula might be something like:

tk->i_last_dts + (mtime_t)(tk->i_track_timecode_scale * tk->i_default_duration / 2048))

So there is still some studying to be done.

Then probably nobody uses "TrackTimecodeScale?" anyhow.

Thank you for your solution

it resolved the problem,thanks for the help

comment:19 Changed 4 years ago by sharonortigas

It is not easy for me to understand and implement the subject from here. I was wondering why you guys are focus on VLC? there were so many player out there that can support hard coded video files. In my experience, I only use the k-lite codec pack and use the default media player classic with no streaming problems..Storage Pods

Note: See TracTickets for help on using tickets.