Opened 9 years ago

Closed 9 years ago

#2005 closed defect (fixed)

Wrong palette colors with DVD subtitles encoding

Reported by: Clément Bœsch Owned by:
Priority: normal Component: avcodec
Version: git-master Keywords: dvdsub
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: yes

Description (last modified by Clément Bœsch)

Generate a reference file:

% ./ffmpeg -f lavfi -i testsrc=s=720x480:d=400 ref.mkv

Mux DVD subtitles in:

% ./ffmpeg -i ref.mkv -i ~/fate-samples/sub/vobsub.idx -c copy -y test-remux.mkv

Here, colors are fine (yellow foreground):

mpv   --start=03:00 test-remux.mkv
mplayer   -ss 03:00 test-remux.mkv
mplayer2 --ss=03:00 test-remux.mkv

Note: mpv¹ and vlc show this properly, mplayer and mplayer2 display them in black & white (which is fine), ffplay seems to have various troubles.

Now encoding DVD subtitles in:

% ./ffmpeg -i ref.mkv -i ~/fate-samples/sub/vobsub.idx -c copy -c:s dvdsub -y test-encode.mkv      
ffmpeg version N-47665-g18eb319 Copyright (c) 2000-2012 the FFmpeg developers
  built on Dec  9 2012 18:50:45 with gcc 4.7.2 (GCC)
  configuration: --enable-gpl --enable-fontconfig --enable-libfreetype --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-libx264 --enable-libvpx --enable-libtheora --enable-x11grab --enable-libopenjpeg --enable-libass --enable-libmodplug --enable-libv4l2 --cc=colorgcc --samples=/home/ubitux/fate-samples --prefix=/tmp/ffinstall --enable-runtime-cpudetect --enable-libcelt
  libavutil      52. 12.100 / 52. 12.100
  libavcodec     54. 79.101 / 54. 79.101
  libavformat    54. 48.100 / 54. 48.100
  libavdevice    54.  3.102 / 54.  3.102
  libavfilter     3. 26.101 /  3. 26.101
  libswscale      2.  1.103 /  2.  1.103
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
Input #0, matroska,webm, from 'ref.mkv':
  Metadata:
    ENCODER         : Lavf54.48.100
  Duration: 00:06:40.08, start: 0.000000, bitrate: 49 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 720x480 [SAR 1:1 DAR 3:2], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
[vobsub @ 0x18e79a0] Estimating duration from bitrate, this may be inaccurate
Input #1, vobsub, from '/home/ubitux/fate-samples/sub/vobsub.idx':
  Duration: N/A, bitrate: N/A
    Stream #1:0[0x0](en): Subtitle: dvd_subtitle (default)
Output #0, matroska, to 'test-encode.mkv':
  Metadata:
    encoder         : Lavf54.48.100
    Stream #0:0: Video: h264, yuv444p, 720x480 [SAR 1:1 DAR 3:2], q=2-31, 25 fps, 1k tbn, 1k tbc (default)
    Stream #0:1(en): Subtitle: dvd_subtitle (default)
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #1:0 -> #0:1 (dvdsub -> dvdsub)
Press [q] to stop, [?] for help
frame=10000 fps=884 q=-1.0 Lsize=    2507kB time=00:06:39.96 bitrate=  51.3kbits/s    
video:2369kB audio:0kB subtitle:72 global headers:0kB muxing overhead 2.711231%

Problem: the colors of the subtitles are negated (or shuffled dunno). They also appear differently with players displaying them in black and white.

[1]: a mplayer2 fork https://github.com/mpv-player/mpv/, https://github.com/mpv-player/mpv/blob/master/DOCS/man/en/changes.rst

Change History (9)

comment:1 by Clément Bœsch, 9 years ago

Description: modified (diff)

comment:2 by Carl Eugen Hoyos, 9 years ago

Is this mkv-related or reproducible with other containers as well?

comment:3 by Clément Bœsch, 9 years ago

Description: modified (diff)

When encoding and muxing to nut (which seems to be the only other format where muxing dvd subtitles is possible), the subtitles don't appear at all… (but they do on remux). So it's hard to tell.

comment:4 by Nicolas George, 9 years ago

 0 0 00c5c5c5 00000000     116427
 0 1 00c5c5c5 ffffff00     110562
 0 2 00c5c5c5 ff000000     181452
 0 3 00c5c5c5 00000000     116427

In other words, the dvdsub encoder considers that the transparent light gray is slightly nearer opaque yellow than transparent black. The culprit is color_distance() in dvdsubenc.c. A quick fix would be to get it to return 0 when both alphas are 0. A possibly better fix would be to multiply everything by alpha, i.e. consider the colors as a cone rather than an hypercube. Do you have any preference?

comment:5 by Nicolas George, 9 years ago

Analyzed by developer: set
Status: newopen

comment:6 by gjdfgh, 9 years ago

A possibly better fix would be to multiply everything by alpha

Would that change decoder output to premultiplied alpha?

in reply to:  6 comment:7 by Nicolas George, 9 years ago

Replying to gjdfgh:

Would that change decoder output to premultiplied alpha?

No: I meant multiply everything only in the distance function used to select the color map.

in reply to:  4 comment:8 by Clément Bœsch, 9 years ago

Replying to Cigaes:

 0 0 00c5c5c5 00000000     116427
 0 1 00c5c5c5 ffffff00     110562
 0 2 00c5c5c5 ff000000     181452
 0 3 00c5c5c5 00000000     116427

In other words, the dvdsub encoder considers that the transparent light gray is slightly nearer opaque yellow than transparent black. The culprit is color_distance() in dvdsubenc.c. A quick fix would be to get it to return 0 when both alphas are 0. A possibly better fix would be to multiply everything by alpha, i.e. consider the colors as a cone rather than an hypercube. Do you have any preference?

If it solves the issue, using the alpha channel as a weight factor for the color sounds like a good idea to me (assuming that's what you meant).

comment:9 by Carl Eugen Hoyos, 9 years ago

Resolution: fixed
Status: openclosed

Fixed by Nicolas George.

Note: See TracTickets for help on using tickets.