Opened 6 years ago

Closed 6 years ago

#2936 closed defect (fixed)

%-syntax for GIF output is not respected, can't write individual frames as images

Reported by: slhck Owned by:
Priority: important Component: avformat
Version: git-master Keywords: gif regression
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: yes

Description (last modified by richardpl)

Recent ffmpeg does not correctly create individual GIF files. For example, I expect this to output one .gif file for each frame:

ffmpeg -i input output%04d.gif

This works in ffmpeg 1.2.1, but it only creates a file called output%04d.gif for newer versions.

This creates a file literally called output%04d.gif:

+- % ./ffmpeg -i input.mp4 output%04d.gif
ffmpeg version N-55996-g916549c Copyright (c) 2000-2013 the FFmpeg developers
  built on Sep  3 2013 16:43:43 with llvm-gcc 4.2.1 (LLVM build 2336.11.00)
  configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc
  libavutil      52. 43.100 / 52. 43.100
  libavcodec     55. 31.100 / 55. 31.100
  libavformat    55. 15.100 / 55. 15.100
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 83.101 /  3. 83.101
  libswscale      2.  5.100 /  2.  5.100
  libswresample   0. 17.103 /  0. 17.103
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 2012-01-08 11:16:19
    encoder         : John Doe for ID 14077
  Duration: 00:03:31.58, start: 0.000000, bitrate: 2359 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 2229 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : SoundHandler
[swscaler @ 0x7ff76d000a00] No accelerated colorspace conversion found from yuv420p to bgr8.
Output #0, gif, to 'output%04d.gif':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.15.100
    Stream #0:0(eng): Video: gif, bgr8, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 100 tbn, 25 tbc (default)
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> gif)
Press [q] to stop, [?] for help
frame=  147 fps= 51 q=-1.0 Lsize=   24214kB time=00:00:05.88 bitrate=33734.8kbits/s
video:24360kB audio:0kB subtitle:0 global headers:0kB muxing overhead -0.599030%

This works in 1.2.1, and it creates individual files for each frame:

+- % ffmpeg -i input.mp4 output%04d.gif
ffmpeg version 1.2.1 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jul 24 2013 20:10:19 with Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/1.2.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=cc --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libvpx --enable-librtmp --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-aacenc --enable-libass --enable-ffplay --enable-libspeex --enable-libschroedinger --enable-libfdk-aac --enable-libopus --enable-frei0r --enable-libcaca --enable-libopenjpeg --extra-cflags='-I/usr/local/Cellar/openjpeg/1.5.1/include/openjpeg-1.5 '
  libavutil      52. 18.100 / 52. 18.100
  libavcodec     54. 92.100 / 54. 92.100
  libavformat    54. 63.104 / 54. 63.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 42.103 /  3. 42.103
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 2012-01-08 11:16:19
    encoder         : John Doe for ID 14077
  Duration: 00:03:31.58, start: 0.000000, bitrate: 2359 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 2229 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 125 kb/s
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : SoundHandler
[swscaler @ 0x7fd2e987b800] No accelerated colorspace conversion found from yuv420p to bgr8.
[swscaler @ 0x7fd2e9882c00] No accelerated colorspace conversion found from yuv420p to bgr8.
[swscaler @ 0x7fd2e9847a00] No accelerated colorspace conversion found from yuv420p to bgr8.
Output #0, image2, to 'output%04d.gif':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf54.63.104
    Stream #0:0(eng): Video: gif, bgr8, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 25 tbc
    Metadata:
      creation_time   : 2012-01-08 11:16:19
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> gif)
Press [q] to stop, [?] for help
frame=  135 fps= 51 q=0.0 Lsize=N/A time=00:00:05.40 bitrate=N/A
video:27300kB audio:0kB subtitle:0 global headers:0kB muxing overhead -100.000079%

Change History (14)

comment:1 follow-up: Changed 6 years ago by Cigaes

  • Analyzed by developer set
  • Reproduced by developer set
  • Status changed from new to open

Compare:

Output #0, gif, to 'output%04d.gif':

and:

Output #0, image2, to 'output%04d.gif':

FFmpeg has gained support for creating animated GIF, and therefore the GIF extension is no longer associated to a sequence of images but to a single animated file.

You can get the old behaviour back by adding -f image2, or use PNG instead of GIF.

A warning may be a good idea to ease the transition.

comment:2 in reply to: ↑ 1 ; follow-up: Changed 6 years ago by slhck

Replying to Cigaes:

FFmpeg has gained support for creating animated GIF

AFAICT that has been around for quite some time and could be achieved by simply choosing an output file name without % syntax.

You can get the old behaviour back by adding -f image2

No, because this creates JPEG images under a .gif extension. ffmpeg outputs:

Stream #0:0 -> #0:0 (h264 -> mjpeg)

and if you inspect the files created:

± % mediainfo output0118.gif
General
Complete name                            : output0118.gif
Format                                   : JPEG
File size                                : 38.0 KiB

Image
Format                                   : JPEG
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Color space                              : YUV
Chroma subsampling                       : 4:2:0

comment:3 in reply to: ↑ 2 ; follow-up: Changed 6 years ago by Cigaes

Replying to slhck:

AFAICT that has been around for quite some time and could be achieved by simply choosing an output file name without % syntax.

True, but it did not work well. It was greatly enhanced last April, probably deemed mature enough to become the default.

No, because this creates JPEG images under a .gif extension.

You are right, I missed that. And adding -c gif does not fix it. It seems that the works on animated GIF has completely broken support for GIF as individual images.

± % mediainfo output0118.gif

The output of mediainfo has rarely been any use for anything.

comment:4 in reply to: ↑ 3 Changed 6 years ago by slhck

Replying to Cigaes:

Replying to slhck:

No, because this creates JPEG images under a .gif extension.

You are right, I missed that. And adding -c gif does not fix it. It seems that the works on animated GIF has completely broken support for GIF as individual images.

What do you think would be the proper resolution here?

The only good option, in my opinion, would be to allow image2 to output individual GIFs again, with the proper codec – just like it auto-selects JPEG and PNG properly. The functionality for writing a non-animated GIF is there anyway.

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

  • Description modified (diff)

It should be possible to write separate gifs for each frame with image2 muxer if there is some way to signal such request to gif encoder.

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

Replying to richardpl:

It should be possible to write separate gifs for each frame with image2 muxer if there is some way to signal such request to gif encoder.

Likely simpler to update image2 to support basic GIF muxing.

Note that I didn't bother doing this since I still wonder what is the motivation behind such usage...

comment:7 in reply to: ↑ 6 Changed 6 years ago by slhck

Replying to ubitux:

Note that I didn't bother doing this since I still wonder what is the motivation behind such usage...

Well, I'm not going to disagree with the fact that it's a little odd. But at least ffmpeg shouldn't output JPEGs when you pass it a .gif extension.

Plus, it's already been working, so it's actually a regression.

comment:8 Changed 6 years ago by cehoyos

  • Keywords regression added
  • Priority changed from normal to important

comment:9 Changed 6 years ago by ubitux

I don't really agree with the "regression" part. It's a desired behaviour change. Of course, we can re-add the old behaviour optionally.

comment:10 follow-up: Changed 6 years ago by cehoyos

Iiuc, a command line that used to work (and at least made sense to some degree) and did not produce an invalid file (contrary to tickets #2452 vs #2684) does not work anymore, I suspect this is how we define a regression, especially since reading the communication here in the ticket it appears that this wasn't known.

comment:11 in reply to: ↑ 10 Changed 6 years ago by ubitux

Replying to cehoyos:

Iiuc, a command line that used to work (and at least made sense to some degree) and did not produce an invalid file (contrary to tickets #2452 vs #2684) does not work anymore, I suspect this is how we define a regression, especially since reading the communication here in the ticket it appears that this wasn't known.

I wonder how it really makes sense honestly... Why would you choose GIF to extract the frames? I mean, you could use PNG or even JPEG which are way more relevant. The main benefit of GIF is that it's being animated; it's compression and limitations really sucks. So my point was that I don't like the word "regression" for a changement of behaviour (at least I) wanted.

Note that I didn't remove the keyword and don't plan to, but that sounds like overreacting... It reminds me of http://xkcd.com/1172/.

Now speaking of fixing the issue, I suggest we make the image2 muxer able to mux GIF, basically dupping some code found in the GIF muxer (or duplicate the image2 muxer features into the GIF muxer, but that it likely more complex).

comment:12 Changed 6 years ago by Cigaes

GIF is much simpler than PNG, and for simple images (such as pixel-art icons) requires smaller files than PNG (316 → 206 octets for a 33×33 4-colors icon I just tried). I believe that can make it useful / necessary in a few cases. It is a matter of cost/benefit.

comment:13 Changed 6 years ago by ubitux

Patch on the mailing list, feel free to try it out to speed up its integration.

comment:14 Changed 6 years ago by ubitux

  • Resolution set to fixed
  • Status changed from open to closed

Fixed in f70db22999d713da3306bf29ec763d670b9bf1ea.

Use ffmpeg -i input -c:v gif -f image2 out%03d.gif to mux separate gif files.

Note: See TracTickets for help on using tickets.