Opened 7 years ago

Closed 7 years ago

Last modified 6 years ago

#6577 closed defect (invalid)

mkv vs encoding interlacement mismatch

Reported by: dave rice Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords: mkv
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:

The interlacement data between an encoded ffv1 stream and the mkv container appear to contradict each other.

How to reproduce:

Created an interlaced ffv1 mkv file.

ffmpeg -f lavfi -i mandelbrot -vf setfield=tff -vframes 1 -c:v ffv1 -y test.mkv
ffmpeg version N-48208-gdf884e038f Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 8.1.0 (clang-802.0.38)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/HEAD-df884e0 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtesseract --enable-libvpx --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
  libavutil      55. 72.100 / 55. 72.100
  libavcodec     57.102.100 / 57.102.100
  libavformat    57. 76.100 / 57. 76.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 98.100 /  6. 98.100
  libavresample   3.  6.  0 /  3.  6.  0
  libswscale      4.  7.102 /  4.  7.102
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, lavfi, from 'mandelbrot':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (RGB[0] / 0x424752), rgb0, 640x480 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> ffv1 (native))
Press [q] to stop, [?] for help
Output #0, matroska, to 'test.mkv':
  Metadata:
    encoder         : Lavf57.76.100
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), bgr0, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.102.100 ffv1
frame=    1 fps=0.0 q=-0.0 Lsize=     212kB time=00:00:00.00 bitrate=1739832.0kbits/s speed=0.0198x    
video:212kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.362262%

Check Matroska interlacement in Tracks/Video/FieldOrder with mkvinfo

 mkvinfo test.mkv | grep "Field order"
|   + Field order: 9 (bottom field displayed first, top field stored first)

Check FFV1 interlacement with ffprobe:

ffprobe test.mkv -show_entries frame=interlaced_frame,top_field_first 
ffprobe version N-48208-gdf884e038f Copyright (c) 2007-2017 the FFmpeg developers
  built with Apple LLVM version 8.1.0 (clang-802.0.38)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/HEAD-df884e0 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtesseract --enable-libvpx --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
  libavutil      55. 72.100 / 55. 72.100
  libavcodec     57.102.100 / 57.102.100
  libavformat    57. 76.100 / 57. 76.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 98.100 /  6. 98.100
  libavresample   3.  6.  0 /  3.  6.  0
  libswscale      4.  7.102 /  4.  7.102
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, matroska,webm, from 'test.mkv':
  Metadata:
    ENCODER         : Lavf57.76.100
  Duration: 00:00:00.04, start: 0.000000, bitrate: 43495 kb/s
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), bgr0(top coded first (swapped)), 640x480, SAR 1:1 DAR 4:3, 25 fps, 25 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      ENCODER         : Lavc57.102.100 ffv1
      DURATION        : 00:00:00.040000000
[FRAME]
interlaced_frame=1
top_field_first=1
[/FRAME]

The Matroska seems to say bottom field displayed first, top field stored first
FFV1 seems to say top_field_first=1 which IIUC means top field displayed first. Am I understanding this wrong or is ffmpeg writing the wrong value in Matroska here?

Patches should be submitted to the ffmpeg-devel mailing list and not this bug tracker.

Change History (7)

comment:1 by Hendrik, 7 years ago

If you want to set the global field order in the files header, you need to use the -field_order option. the lavfi filter only affects individual frames, not the header option.

comment:2 by kieranjol, 7 years ago

I think this affects more than just matroska, it seems to affect MOV too?
Here's your command line which is switched from MKV to MOV. I launched it twice and piped the output to mediatrace and grep. Seems that TFF produces a value of 9 in the fiel atom, bff produces 14 in the fiel atom.
The quicktime spec says: 9 – B is displayed earliest, T is stored first in the file. 14 – T is displayed earliest, B is stored first in the file.

ffmpeg -f lavfi -i mandelbrot -vf setfield=tff -vframes 1 -c:v ffv1 -y test.mov && mediainfo --Details=1 test.mov | grep fiel -A 1
ffmpeg version N-45635-g369a3e1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 5.3.0 (Homebrew gcc 5.3.0)
  configuration: --prefix=/home/kieranjol/.linuxbrew/Cellar/ffmpeg/HEAD-369a3e1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=gcc-5 --host-cflags= --host-ldflags= --enable-ffplay --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libxvid --disable-lzma --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/home/kieranjol/.linuxbrew/Cellar/openjpeg/2.1.2_1/include/openjpeg-2.1 --disable-vda
  libavutil      55. 67.100 / 55. 67.100
  libavcodec     57.100.103 / 57.100.103
  libavformat    57. 75.100 / 57. 75.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 94.100 /  6. 94.100
  libavresample   3.  6.  0 /  3.  6.  0
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, lavfi, from 'mandelbrot':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (RGB[0] / 0x424752), rgb0, 640x480 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> ffv1 (native))
Press [q] to stop, [?] for help
[mov @ 0xb79c40] Using MS style video codec tag, the file may be unplayable!
Output #0, mov, to 'test.mov':
  Metadata:
    encoder         : Lavf57.75.100
    Stream #0:0: Video: ffv1, bgr0, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.100.103 ffv1
frame=    1 fps=0.0 q=-0.0 Lsize=     212kB time=00:00:00.00 bitrate=22301128.2kbits/s speed=0.00121x    
video:212kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.342418%
350C9          Name:                          fiel
350CD         fields:                         2 (0x02)
350CE         detail:                         9 (0x09)


$ ffmpeg -f lavfi -i mandelbrot -vf setfield=bff -vframes 1 -c:v ffv1 -y test.mov && mediainfo --Details=1 test.mov | grep fiel -A 1
ffmpeg version N-45635-g369a3e1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 5.3.0 (Homebrew gcc 5.3.0)
  configuration: --prefix=/home/kieranjol/.linuxbrew/Cellar/ffmpeg/HEAD-369a3e1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=gcc-5 --host-cflags= --host-ldflags= --enable-ffplay --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libxvid --disable-lzma --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/home/kieranjol/.linuxbrew/Cellar/openjpeg/2.1.2_1/include/openjpeg-2.1 --disable-vda
  libavutil      55. 67.100 / 55. 67.100
  libavcodec     57.100.103 / 57.100.103
  libavformat    57. 75.100 / 57. 75.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 94.100 /  6. 94.100
  libavresample   3.  6.  0 /  3.  6.  0
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, lavfi, from 'mandelbrot':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (RGB[0] / 0x424752), rgb0, 640x480 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> ffv1 (native))
Press [q] to stop, [?] for help
[mov @ 0x10a3c40] Using MS style video codec tag, the file may be unplayable!
Output #0, mov, to 'test.mov':
  Metadata:
    encoder         : Lavf57.75.100
    Stream #0:0: Video: ffv1, bgr0, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.100.103 ffv1
frame=    1 fps=0.0 q=-0.0 Lsize=     212kB time=00:00:00.00 bitrate=22301128.2kbits/s speed=0.00234x    
video:212kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.342418%
350C9          Name:                          fiel
350CD         fields:                         2 (0x02)
350CE         detail:                         14 (0x0E)

in reply to:  1 comment:3 by kieranjol, 7 years ago

Replying to heleppkes:

If you want to set the global field order in the files header, you need to use the -field_order option. the lavfi filter only affects individual frames, not the header option.

Does -field_order work for Matroska? I've never gotten it to work, though it works fine for MOV.

comment:4 by Jérôme Martinez, 7 years ago

Replying to heleppkes:

If you want to set the global field order in the files header, you need to use the -field_order option. the lavfi filter only affects individual frames, not the header option.

In that case, what is the source of Matroska metadata?
If the source is not the frames content, metadata should be not set to an arbitrary value.
Note that if "setfield=tff" is replace by "setfield=bff", the Matroska metadata is changed accordingly so it appears that the global field order in the files header is impacted by "setfield".

Replying to dericed:

The interlacement data between an encoded ffv1 stream and the mkv container appear to contradict each other.

Dave, I think your example is wrong, because ffv1 stream does not store field order or interlaced/progressive with your command.
If you replace 9A 81 01 9D 81 09 by EC 81 00 EC 81 00 (interlace metadata replaced by void), you see that your ffprobe command says 0 everywhere i.e. progressive.
You need to add "-level 3" in order to store such metadata and check any mismatch.
But it does not change the question.

Actually, it is a more global issue, if I try with a MOV you'll get same issue, the issue is about the meaning of the different values from QuickTime specs: how it is stored (separate fields or interleaved fields), temporary order and store order.

*

I already got such debate few years ago, with difficulties to understand specs compared to real world files.
What I understood is that:

1 is for separate fields and T stored/displayed first
6 is for separate fields and B stored/displayed first
9 is for interleaved fields and T stored/displayed first
14 is for interleaved fields and B stored/displayed first

this corresponds to current FFmpeg behavior with FFV1 as FFV1 stores only interleaved fields.

with:
./ffmpeg -f lavfi -i mandelbrot -vf setfield=bff -vframes 1 -c:v ffv1 -level 3 -y test.mov
You get with MediaInfo:
Scan type : Interlaced
Scan type, store method : Interleaved fields
Scan order : Bottom Field First
which seems the expected result (FFV1 stores interleaved fields and you want BFF)

with:
./ffmpeg -f lavfi -i mandelbrot -vf setfield=tff -vframes 1 -c:v ffv1 -level 3 -y test.mov
You get with MediaInfo:
Scan type : Interlaced
Scan type, store method : Interleaved fields
Scan order : Top Field First
which seems the expected result (FFV1 stores interleaved fields and you want TFF)

Note: MI is missing "store method" line for Matroska, I'll add it (same way as with MOV).

From my point of view the spec is slightly misleading, and there no really stored vs displayed (I am curious of usefulness of storing first a field temporary later, but everything may exist...) but more separate fields / interleaved fields and TFF / BFF cases. I am not 100% sure, only empirical tests, and MediaInfo is implemented from theses empirical tests. But if this analysis about fieldorder value is right, the interlacement data between an encoded ffv1 stream and the mkv container do not contradict each other with current FFmpeg.

comment:5 by dave rice, 7 years ago

I'm going to close this issue. From this comment https://github.com/amiaopensource/vrecord/issues/170#issuecomment-321937668 and others on that thread, we see that the Apple QuickTime File Format specification described the field order values (9 and 14) incorrectly. In this case I think that ffmpeg is behaving correctly but that the specification is wrong.

comment:6 by dave rice, 7 years ago

Resolution: invalid
Status: newclosed

comment:7 by Carl Eugen Hoyos, 6 years ago

Keywords: mkv added; matroska removed
Note: See TracTickets for help on using tickets.