Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#3545 closed defect (fixed)

Unsupported pix_fmts in avi rawvideo are written without any warning

Reported by: peter_b Owned by:
Priority: minor Component: avformat
Version: git-master Keywords: avi mov
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

Summary of the bug:

I've tried to create AVIs with pix_fmt=yuv420p10le and vcodec=rawvideo (uncompressed). The files are generated without error, but there are 2 issues:

  1. The pix_fmt of the resulting files seems to be rgb555le.
  2. Colors of the resulting video are not correct.

I know that for uncompressed yuv 10bit, I could use v210 (which works fine), but I've noticed similar issues with 16bit, too (see below).

How to reproduce:

I've used "football_422_cif.y4m" as test source.

Commandline:

ffmpeg -i ~/Videos/test-source/football_422_cif.y4m -an -pix_fmt yuv420p10le -c:v rawvideo yuv420p10le.avi

Output:

ffmpeg version N-62305-g7ac2f7e Copyright (c) 2000-2014 the FFmpeg developers
  built on Apr  9 2014 19:49:03 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --prefix=/usr/local --enable-gpl --enable-nonfree --enable-version3 --enable-postproc --enable-swscale --enable-avfilter --enable-pthreads --enable-bzlib --enable-zlib --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-libopenjpeg --enable-decoder=png --enable-encoder=png --disable-decoder=jpeg2000 --enable-libfreetype --enable-libschroedinger --enable-libvpx --enable-libvorbis --enable-libx264 --enable-libfaac
  libavutil      52. 75.100 / 52. 75.100
  libavcodec     55. 58.103 / 55. 58.103
  libavformat    55. 36.102 / 55. 36.102
  libavdevice    55. 11.100 / 55. 11.100
  libavfilter     4.  3.100 /  4.  3.100
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 18.100 /  0. 18.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, yuv4mpegpipe, from '/home/pb/Videos/test-source/football_422_cif.y4m':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuv422p, 352x288, SAR 128:117 DAR 1408:1053, 30 fps, 30 tbr, 30 tbn, 30 tbc
File 'yuv420p10le.avi' already exists. Overwrite ? [y/N] y
Output #0, avi, to 'yuv420p10le.avi':
  Metadata:
    ISFT            : Lavf55.36.102
    Stream #0:0: Video: rawvideo, yuv420p10le, 352x288 [SAR 128:117 DAR 1408:1053], q=2-31, 200 kb/s, 30 tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo -> rawvideo)
Press [q] to stop, [?] for help
frame=  360 fps=0.0 q=0.0 Lsize=  106934kB time=00:00:12.00 bitrate=73000.3kbits/s    
video:106920kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.013151%

ffprobe's output:

ffprobe version N-62305-g7ac2f7e Copyright (c) 2007-2014 the FFmpeg developers
  built on Apr  9 2014 19:49:03 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --prefix=/usr/local --enable-gpl --enable-nonfree --enable-version3 --enable-postproc --enable-swscale --enable-avfilter --enable-pthreads --enable-bzlib --enable-zlib --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-libopenjpeg --enable-decoder=png --enable-encoder=png --disable-decoder=jpeg2000 --enable-libfreetype --enable-libschroedinger --enable-libvpx --enable-libvorbis --enable-libx264 --enable-libfaac
  libavutil      52. 75.100 / 52. 75.100
  libavcodec     55. 58.103 / 55. 58.103
  libavformat    55. 36.102 / 55. 36.102
  libavdevice    55. 11.100 / 55. 11.100
  libavfilter     4.  3.100 /  4.  3.100
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 18.100 /  0. 18.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, avi, from 'yuv420p10le.avi':
  Metadata:
    encoder         : Lavf55.36.102
  Duration: 00:00:12.00, start: 0.000000, bitrate: 73000 kb/s
    Stream #0:0: Video: rawvideo, rgb555le, 352x288, 73194 kb/s, SAR 128:117 DAR 1408:1053, 30 tbr, 30 tbn, 30 tbc

I've also tried it with yuv422p10le, yuv422p16le, and they also show similar defects:
wrong pix_fmt, wrong display of colors.

Is that a bug, or am I trying something absurd?

Thanks.

Attachments (1)

patchrawvideopixfmt (3.8 KB) - added by cehoyos 5 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 in reply to: ↑ description Changed 5 years ago by cehoyos

  • Component changed from undetermined to avformat
  • Keywords uncompressed 10bit 16bit removed
  • Priority changed from normal to minor
  • Reproduced by developer set
  • Status changed from new to open
  • Summary changed from YUV422 >8bit uncompressed not working in AVI to Unsupported pix_fmts in avi rawvideo are written without any warning

Replying to peter_b:

I've tried to create AVIs with pix_fmt=yuv420p10le and vcodec=rawvideo (uncompressed).

Why do you think this is supposed to work? Please use nut for unusual pix_fmts.

The files are generated without error, but there are 2 issues:

  1. The pix_fmt of the resulting files seems to be rgb555le.

This is what you get if an unknown pix_fmt is detected in avi.

There is a bug because you see no warning that the file you created cannot (easily) be decoded.

comment:2 Changed 5 years ago by cehoyos

(Just to make sure: Your goal was not to write v210-in-avi?)

comment:3 follow-up: Changed 5 years ago by peter_b

My goal was to write a script that encodes uncompressed avi in different pix_fmts, including >8bit yuv.

I thought that uncompressed is only about its bit-layout for the colors. Therefore I'm surprised that AVI shouldn't be able to handle rawvideo >8bit, since it can hold v210. I can't use NUT in that case (long story...)

Thanks and regards,
Peter

comment:4 in reply to: ↑ 3 Changed 5 years ago by cehoyos

  • Keywords mov added
  • Resolution set to fixed
  • Status changed from open to closed

Replying to peter_b:

I can't use NUT in that case (long story...)

Since I took a guess in understanding this sentence: Even if you change the avi demuxer to read such files (this is not very difficult but in any case needs user interaction, ie you'd have to specify the pix_fmt at decoding time just as you did at encoding time), the files are still invalid insofar as they do not confirm to any avi specification and likely no other software (no player that is not FFmpeg-based) will decode the files. Even if you change the avi muxer and write NUT tags (so you don't have to specify the pix_fmt for decoding), you still get files that cannot be read by anything but FFmpeg.

A warning (with AV_LOG_ERROR) is shown since 8b122937

Last edited 5 years ago by cehoyos (previous) (diff)

Changed 5 years ago by cehoyos

comment:5 Changed 5 years ago by cehoyos

Attached patch allows you to read the broken files by specifying the same pix_fmt as you did at encoding:

$ ffmpeg -pix_fmt yuv420p10le -i yuv420p10le.avi

comment:6 follow-up: Changed 5 years ago by peter_b

Thanks a lot!

I just compiled ffmpeg git-HEAD and verified your change. Works as expected.

I see that for <=8bit, that depending on the output pix_fmt, a different FOURCC is automatically set when using rawvideo as codec. Since ffmpeg chooses the right FOURCC for <=8bit rawvideo, wouldn't it work to choose, for example fourcc=V210 for pix_fmt=yuv422p10le, etc?

On MSDN, there are FOURCCs listed for YUV 10 & 16bit:

FOURCC Description
P016 Planar, 4:2:0, 16-bit.
P010 Planar, 4:2:0, 10-bit.
P216 Planar, 4:2:2, 16-bit.
P210 Planar, 4:2:2, 10-bit.
Y216 Packed, 4:2:2, 16-bit.
Y210 Packed, 4:2:2, 10-bit.
Y416 Packed, 4:4:4, 16-bit
Y410 Packed, 4:4:4, 10-bit.

What would be the correct way of producing such AVI files with ffmpeg?

Thank you very much.

comment:7 in reply to: ↑ 6 ; follow-up: Changed 5 years ago by cehoyos

Replying to peter_b:

I see that for <=8bit, that depending on the output pix_fmt, a different FOURCC is automatically set when using rawvideo as codec. Since ffmpeg chooses the right FOURCC for <=8bit rawvideo,

Only a (very) small set of <=8bit rawvideo work in avi, just try rgb24.

wouldn't it work to choose, for example fourcc=V210 for pix_fmt=yuv422p10le, etc?

V210 != rawvideo (at least from the FFmpeg pov which is the one relevant for this ticket)
This is fundamental to understand why this ticket cannot be "fixed" the way you hope...

On MSDN, there are FOURCCs listed for YUV 10 & 16bit:

FOURCC Description
P016 Planar, 4:2:0, 16-bit.
P010 Planar, 4:2:0, 10-bit.
P216 Planar, 4:2:2, 16-bit.
P210 Planar, 4:2:2, 10-bit.
Y216 Packed, 4:2:2, 16-bit.
Y210 Packed, 4:2:2, 10-bit.
Y416 Packed, 4:4:4, 16-bit.
Y410 Packed, 4:4:4, 10-bit.

If you can provide an avi sample for one of them that works with (vanilla) WMP, I will implement it.
(I tried once and WMP did not like the files, rereading the link I agree it should work.)

Please note that (for example) H.264 supports more colour spaces than the one listed on MSDN, so even if this gets implemented, there will still be files that you cannot archive like this,

One more thing that is probably important for this discussion: FFmpeg's avi muxer handles large files badly, see various tickets on this tracker.
Or in other words: If you really want to go the avi path (instead of the out-of-the-box working ffv1+audio+nut) then you will have to invest not just testing but also implementation time (the issues are known).

comment:8 in reply to: ↑ 7 Changed 5 years ago by cehoyos

Replying to cehoyos:

If you really want to go the avi path (instead of the out-of-the-box working ffv1+audio+nut)

If this is really what you want, just add the tags from ff_nut_video_tags[] in libavformat/nut.c to ff_codec_bmp_tags[] in libavformat/riff.c
The resulting files will not work with anything but FFmpeg which has the advantage that you don't have to care about the avi size problem either (FFmpeg will not fail decoding for such files), the only problem is that - contrary to choosing nut - you get files that are nowhere specified.

comment:9 follow-ups: Changed 5 years ago by peter_b

I'm using out-of-the-box working ffv1+pcm_s16le+avi for everything (including >8bit) at the moment. Works perfectly :)

More than 8bits-per-component is generally not well supported, varying from application to application, in different containers as well as codecs. Uncompressed >8bit seems to be even more of a "stepchild" ;)

Thanks for pointing out that I'd be creating invalid/unreadable files using the rawvideo approach in AVI.

Is there any way of creating >8bit uncompressed (doesn't have to be rawvideo) AVIs? For yuv422p10le, V210 does just that, but what about e.g. 16bit?

According to the MSDN article, it sounds like it should technically be possible. Even if WMP wouldn't play them, they'd have a defined standards-compliant bitstream, so it'd be the fault of WMP, not ffmpeg.

I'm just trying to understand this.
If this is not the right place to discuss this, should I post it on the ffmpeg-user ML?

Thanks.

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

Replying to peter_b:

Uncompressed >8bit seems to be even more of a "stepchild" ;)

If anything does not work with nut, please tell us!

Is there any way of creating >8bit uncompressed (doesn't have to be rawvideo) AVIs?

I believe I explained two possibilities:
You can either patch FFmpeg to read the files that you (already) created or you can teach FFmpeg's avi muxer to write nut fourccs.

For yuv422p10le, V210 does just that, but what about e.g. 16bit?

From libavformat pov (and as said, this is the only relevant pov for this discussion) v210 is exactly as compressed (or uncompressed) as ffv1 (or huffyuv) or any other intra-only codec.

According to the MSDN article, it sounds like it should technically be possible. Even if WMP wouldn't play them, they'd have a defined standards-compliant bitstream, so it'd be the fault of WMP, not ffmpeg.

How would you know that if you cannot test?

comment:11 in reply to: ↑ 9 Changed 5 years ago by cehoyos

Replying to peter_b:

I'm using out-of-the-box working ffv1+pcm_s16le+avi for everything (including >8bit) at the moment. Works perfectly :)

Does seeking with WMP in large files really work?

Last edited 5 years ago by cehoyos (previous) (diff)

comment:12 in reply to: ↑ 9 Changed 5 years ago by cehoyos

Replying to peter_b:

Is there any way of creating >8bit uncompressed (doesn't have to be rawvideo) AVIs? For yuv422p10le, V210 does just that, but what about e.g. 16bit?

It is of course trivial to implement a "Y416" codec but what use would that be given that no other software would be able to read such files and FFmpeg already supports them without any change?
(This is assuming that WMP does not accept "Y416" in avi, if I am wrong this would simply be an easy enhancement request. You should be able to test by simply changing the fourcc of a v210 file to Y210 and test if WMP plays something or simply declares that it is unable to decode the gibberish.)

Note: See TracTickets for help on using tickets.