Skip to content

Incorrect timestamp compensation for VFW-muxed (VC-1) mkv streams #18089

@arch1t3cht

Description

@arch1t3cht

mpv Information

Latest master:

mpv v0.41.0-724-g71ebd0840 Copyright © 2000-2026 mpv/MPlayer/mplayer2 projects
 built on Jun  7 2026 13:07:57
libplacebo version: v7.360.1
FFmpeg version: N-124282-ga7d42bfba8
FFmpeg library versions:
   libavcodec      62.30.100
   libavdevice     62.4.100
   libavfilter     11.17.100
   libavformat     62.13.102
   libavutil       60.30.100
   libswresample   6.4.100
   libswscale      9.7.100

Important Information

- Platform version: Tested on Arch Linux, should apply on all platforms
- GPU model, driver and version: AMD Cezanne [Radeon Vega Series / Radeon Vega Mobile Series], xf86-video-amdgpu 25.0.0-1
- Source of mpv: Self-compiled from latest master
- Latest known working version: N/A
- Issue started after the following happened: N/A

Reproduction Steps

  1. Add the following logs to mpv:

      diff --git a/filters/f_decoder_wrapper.c b/filters/f_decoder_wrapper.c
    index 08978e49f4..ed7b5698f7 100644
    --- a/filters/f_decoder_wrapper.c
    +++ b/filters/f_decoder_wrapper.c
    @@ -757,8 +757,12 @@ static bool process_decoded_frame(struct priv *p, struct mp_frame *frame)
         if (frame->type == MP_FRAME_VIDEO) {
             struct mp_image *mpi = frame->data;
     
    +        MP_ERR(p, "Video frame before: pts=%f dts=%f\n", mpi->pts, mpi->dts);
    +
             crazy_video_pts_stuff(p, mpi);
     
    +        MP_ERR(p, "Video frame after: pts=%f dts=%f\n", mpi->pts, mpi->dts);
    +
             struct demux_packet *ccpkt = new_demux_packet_from_buf(p->public.f->packet_pool,
                                                                    mpi->a53_cc);
             if (ccpkt) {
    @@ -786,6 +790,7 @@ static bool process_decoded_frame(struct priv *p, struct mp_frame *frame)
     
             mp_aframe_clip_timestamps(aframe, p->start, p->end);
             double pts = mp_aframe_get_pts(aframe);
    +        MP_ERR(p, "Audio frame: pts=%f\n", pts);
             if (pts != MP_NOPTS_VALUE && p->start != MP_NOPTS_VALUE)
                 segment_ended = pts >= p->end;
  2. Play the attached m2ts file in mpv: mpv --no-config --pause 00001.m2ts and observe the logs:

    [...]
    Audio frame: pts=0.000000
    Video frame before: pts=0.000000 dts=0.000000
    Video frame after: pts=0.000000 dts=0.000000
    [...]
    

    Observe that the first audio frame and the first video frame start at the same time (namely, 0)

  3. Remux the m2ts file to mkv using ffmpeg: ffmpeg -i ~/coding/misc/ffmpeg_tests/build/00001.m2ts -c copy -y 00001.mkv, and play the resulting mkv file: mpv --no-config --pause 00001.m2ts:

    [...]
    Audio frame: pts=0.042000
    Video frame before: pts=-9223372036854775808.000000 dts=0.042000
    Video frame after: pts=0.000292 dts=0.042000
    [...]
    

    Observe that the first audio frame now starts 42ms after the first video frame.

  4. Alternatively, remux the m2ts file to mkv using mkvtoolnix: mkvmerge 00001.m2ts 00001.mkv and play it back again:

    [...]
    Audio frame: pts=0.000000
    Video frame before: pts=-9223372036854775808.000000 dts=0.000000
    Video frame after: pts=-0.041708 dts=0.000000
    [...]
    

    This mkv file differs from the ffmpeg-muxed one by a 42ms shift across all streams, but either way the first audio frame still starts 42ms after the first video frame.

    Here, this can also be seen in mpv itself by observing that the first two displayed video frames in mpv both have the timestamp 0 (which can be seen by stepping frame by frame and checking the time on the OSC.


Expected Behavior

In the remuxed mkv file, video and audio start at the same timestamp (give or take some rounding errors), just like they do in the initial m2ts file.

Actual Behavior

mpv's timestamp compensation results in the video starting earlier than the audio in the remuxed mkv file.


Analysis:

  • See also: https://codeberg.org/mbunkus/mkvtoolnix/issues/6194#issuecomment-11515531 - I originally thought this was a bug in mkvtoolnix, but on further investigation I believe this is a bug in mpv.
  • The attached m2ts file has a VC-1 video stream, which is muxed into mkv as a VFW compatibility stream. VFW streams do not support frame reordering, so the muxers write the decoding timestamps rather than the presentation timestamps into the mkv block timestamps, and the demuxers interpret the block timestamps accordingly.
  • The aptly named function crazy_video_pts_stuff in f_decoder_wrapper.c then tries to recover the presentation timestamps from the decoding timestamps. However, to do this it then also shifts all (video) timestamps by the decoder delay. This results in the offset between audio and video.

I don't know if this additional timestamp shift in crazy_video_pts_stuff is just wrong altogether or whether it's only wrong for this specific class of files and not for other VFW-muxed mkv streams or avi streams. I haven't yet found samples for other such files where I can be confident that the input timestamps are all correct.

Some relevant commits are:

  • d3f32cb, which does explicitly state "It works well with VfW-muxed Matroska files, though."
  • dc0b204, in which wm4 seems to disagree with ffmpeg's behavior of dropping the first few decoding timestamps. It's true that it's hard to reason about which behavior is fully correct here, in particular because I haven't yet found any actual specification of how timestamps in VFW-muxed mkv streams should look, but I think the test of whether or not video starts simultaneously with audio is a sensible one.

Note: I am mainly making this issue for completeness and future reference. I gave up on debugging it further after it became a question of whether this behavior is always incorrect or whether there is some other class of files for which it works. I opted to just circumvent this entirely for the future by adding a native mkv codec mapping for VC-1 instead. But I didn't want to sit on this issue without reporting it so I'm opening this issue.

Log File

Log file for the mkvtoolnix-muxed mkv file (./mpv --no-config 00001.mkv --pause --gpu-debug --log-file=output.txt):

output.txt

Let me know if the other logs are also needed.

Sample Files

https://files.catbox.moe/9xlolu.m2ts or https://drive.google.com/file/d/1zgL_nBUQP_izNiBfbu26h3TYj8ceptZE/view?usp=sharing (same file)

I carefully read all instruction and confirm that I did the following:

  • I tested and confirmed that the issue exists with the latest release version or newer.
  • I provided all required information including system and mpv version.
  • I produced the log file with the exact same set of files, parameters, and conditions used in "Reproduction Steps", with the addition of --log-file=output.txt.
  • I produced the log file while the behaviors described in "Actual Behavior" were actively observed.
  • I attached the full, untruncated log file.
  • I attached the backtrace in the case of a crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions