Opened 5 years ago

Last modified 4 months ago

#7941 reopened defect

Transparency broken when encoding animated webp

Reported by: Nirel d Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords: webp alpha
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

ffmpeg -i test.gif animation.webp

How can I convert animated gif (with Alpha channel) to animated webp?

I stuck with transparent background, I can't figure out how to convert gif with transparent background to webP with transparent background, Its keep a 'trail' of the images,

ffmpeg -i test.gif animation.webp

For example, I want to convert this gif - ​https://imgur.com/tCSn2No to webP,
The output for now is - ​https://media.giphy.com/media/UqevOuKr66xO04zRBa/giphy.gif

how can I achieve that using ffmpeg?

ffmpeg version N-93933-geae251ead9 built with gcc 8.3.1

Attachments (3)

tCSn2No.gif (17.2 KB ) - added by pdr0 4 years ago.
webp_anim_lossless.webp (16.5 KB ) - added by pdr0 4 years ago.
gif2webp.webp (16.4 KB ) - added by pdr0 4 years ago.

Download all attachments as: .zip

Change History (24)

comment:1 by Nirel d, 5 years ago

Still didnt get an answer

Last edited 5 years ago by Nirel d (previous) (diff)

comment:2 by Nirel d, 5 years ago

Owner: set to Nirel d
Status: newopen

...

Last edited 5 years ago by Nirel d (previous) (diff)

comment:3 by Nirel d, 5 years ago

..

Last edited 5 years ago by Nirel d (previous) (diff)

comment:4 by Carl Eugen Hoyos, 5 years ago

Component: ffmpegundetermined
Keywords: gif alpha webp animated removed
Priority: importantnormal
Resolution: needs_more_info
Status: openclosed

To make this a valid bug report, please provide the command line you tested together with the complete, uncut console output.

comment:5 by Nirel d, 5 years ago

Priority: normalimportant
Resolution: needs_more_info
Status: closedreopened
ffmpeg -i test.gif animation.webp

ffmpeg version N-93933-geae251ead9 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.3.1 (GCC) 20190414
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 28.100 / 56. 28.100
  libavcodec     58. 52.102 / 58. 52.102
  libavformat    58. 27.103 / 58. 27.103
  libavdevice    58.  7.100 / 58.  7.100
  libavfilter     7. 54.101 /  7. 54.101
  libswscale      5.  4.101 /  5.  4.101
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, gif, from 'test.gif':
  Duration: 00:00:02.00, start: 0.000000, bitrate: 70 kb/s
    Stream #0:0: Video: gif, bgra, 150x150, 18.42 fps, 20 tbr, 100 tbn, 100 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (gif (native) -> webp (libwebp))
Press [q] to stop, [?] for help
Output #0, webp, to 'animation.webp':
  Metadata:
    encoder         : Lavf58.27.103
    Stream #0:0: Video: webp (libwebp), bgra, 150x150, q=2-31, 200 kb/s, 20 fps, 1k tbn, 20 tbc
    Metadata:
      encoder         : Lavc58.52.102 libwebp
[libwebp @ 000001aacbb6a9c0] Using libwebp for RGB-to-YUV conversion. You may want to consider passing in YUV instead for lossy encoding.
frame=   37 fps=0.0 q=-0.0 Lsize=      41kB time=00:00:01.80 bitrate= 187.6kbits/s speed=14.4x
video:41kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Last edited 5 years ago by Carl Eugen Hoyos (previous) (diff)

comment:6 by Carl Eugen Hoyos, 5 years ago

Priority: importantnormal

Do you think this is a regression?

comment:7 by Nirel d, 5 years ago

Not sure, as this functionality already exists for Gifs as you can see here(https://trac.ffmpeg.org/ticket/6813), but webp animation frames still overlapping

comment:8 by Nirel d, 5 years ago

Status: reopenedopen

comment:9 by Nirel d, 5 years ago

@cehoyos
Any workaround?

comment:10 by Nirel d, 5 years ago

Owner: changed from Nirel d to Carl Eugen Hoyos

......?

comment:11 by Carl Eugen Hoyos, 5 years ago

Owner: Carl Eugen Hoyos removed

by pdr0, 4 years ago

Attachment: tCSn2No.gif added

by pdr0, 4 years ago

Attachment: webp_anim_lossless.webp added

comment:12 by pdr0, 4 years ago

Resolution: worksforme
Status: openclosed

Works ok for me with this

ffmpeg -i tCSn2No.gif -loop 0 -c:v libwebp_anim -lossless 1 webp_anim_lossless.webp
Last edited 4 years ago by pdr0 (previous) (diff)

comment:13 by Carl Eugen Hoyos, 4 years ago

Keywords: webp alpha added

If there ever was an issue, it is still reproducible (depends on the playback application), using the default encoder or libwebp_anim makes no difference.

comment:14 by Carl Eugen Hoyos, 4 years ago

Resolution: worksforme
Status: closedreopened

in reply to:  13 comment:15 by pdr0, 4 years ago

Replying to cehoyos:

If there ever was an issue, it is still reproducible (depends on the playback application), using the default encoder or libwebp_anim makes no difference.

This ticket deals with encoding animated webp with transparency

What application are you using to test playback ?

This plays back in firefox, chrome properly for me

If some specific playback application does not work, is that an ffmpeg problem?

comment:16 by pdr0, 4 years ago

Resolution: worksforme
Status: reopenedclosed

Attached is the animated webp produced from gif2webp, from the official google libwebp. It plays the same way in Chrome, Firefox, there is no "trail" of images

If you examine both webp's with the official vwebp viewer , both playback the same way there too. You can hit "d" to toggle the disposal method.

I fail to see how this is a ffmpeg issue

by pdr0, 4 years ago

Attachment: gif2webp.webp added

comment:17 by Carl Eugen Hoyos, 4 years ago

Resolution: worksformeinvalid

So you are saying the format is broken?

in reply to:  17 comment:18 by pdr0, 4 years ago

Replying to cehoyos:

So you are saying the format is broken?

What player are you using? Perhaps that is broken

Eitherway it's not a ffmpeg issue

comment:19 by Mario Zechner, 2 years ago

I've encountered the bug as well. It is indeed an FFmpeg issue (latest git-master) and can be reproduced by encoding a webm file with transparent background to an animated webp file file via e.g.

❯ ./ffmpeg -c:v libvpx-vp9 -i in.webm -c:v libwebp -loop 0 out.webp

ffmpeg version N-105642-g538be75a69 Copyright (c) 2000-2022 the FFmpeg developers
  built with Apple clang version 13.0.0 (clang-1300.0.29.30)
  configuration: --pkg-config-flags=--static --disable-ffplay --disable-ffprobe --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-libxcb --disable-lzma --disable-sdl2 --enable-libvpx --enable-libwebp
  libavutil      57. 21.100 / 57. 21.100
  libavcodec     59. 21.100 / 59. 21.100
  libavformat    59. 17.101 / 59. 17.101
  libavdevice    59.  5.100 / 59.  5.100
  libavfilter     8. 27.100 /  8. 27.100
  libswscale      6.  5.100 /  6.  5.100
  libswresample   4.  4.100 /  4.  4.100
[libvpx-vp9 @ 0x7f8e19412980] v1.11.0
    Last message repeated 1 times
Input #0, matroska,webm, from 'out.webm':
  Metadata:
    ENCODER         : Lavf59.17.101
  Duration: 00:00:00.84, start: 0.000000, bitrate: 2777 kb/s
  Stream #0:0: Video: vp9 (Profile 0), yuva420p(tv, progressive), 511x699, SAR 1:1 DAR 511:699, 25 fps, 25 tbr, 1k tbn
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc59.21.100 libvpx-vp9
      DURATION        : 00:00:00.840000000
File 'out.webp' already exists. Overwrite? [y/N] y
[libvpx-vp9 @ 0x7f8e197043c0] v1.11.0
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (libvpx-vp9) -> webp (libwebp))
Press [q] to stop, [?] for help
[libvpx-vp9 @ 0x7f8e197043c0] v1.11.0
Output #0, webp, to 'out.webp':
  Metadata:
    encoder         : Lavf59.17.101
  Stream #0:0: Video: webp, yuva420p(tv, progressive), 511x699 [SAR 1:1 DAR 511:699], q=2-31, 200 kb/s, 25 fps, 1k tbn
    Metadata:
      alpha_mode      : 1
      DURATION        : 00:00:00.840000000
      encoder         : Lavc59.21.100 libwebp
frame=   21 fps=0.0 q=-0.0 Lsize=     775kB time=00:00:00.80 bitrate=7927.0kbits/s speed=0.848x
video:775kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

You can find the input webm file here: https://marioslab.io/dump/in.webm

The bug is located in line 137 in webpenc.c. This sets the disposal method of the ANMF chunk to 0, which means the previous canvas contents are retained. For transparent frames, that is incorrect. See the specs here: https://developers.google.com/speed/webp/docs/riff_container#animation

The simplest fix is to set the disposal method to 1, like this:

git patch --- a/libavformat/webpenc.c
+++ b/libavformat/webpenc.c
@@ -134,7 +134,7 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts)
                 avio_wl24(s->pb, pts - w->last_pkt->pts);
             } else
                 avio_wl24(s->pb, w->last_pkt->duration);
-            avio_w8(s->pb, 0);
+            avio_w8(s->pb, 0x1);
         }
         avio_write(s->pb, w->last_pkt->data + skip, w->last_pkt->size - skip);
         av_packet_unref(w->last_pkt);

This fixes the issue, but may lead to bigger webp files in case of non-transparent input frames.

Last edited 2 years ago by Mario Zechner (previous) (diff)

comment:20 by Mario Zechner, 2 years ago

Resolution: invalid
Status: closedreopened

in reply to:  19 comment:21 by Cabada, 4 months ago

Replying to Mario Zechner:

+ avio_w8(s->pb, 0x1);

I can confirm that the change that Mario suggests works, but it adds more bytes to the result.

Can we have it added as an option so we can decide which disposal method to use? For transparent animated images we need this.

Note: See TracTickets for help on using tickets.