Opened 5 years ago

Closed 5 years ago

#2005 closed defect (fixed)

Wrong palette colors with DVD subtitles encoding

Reported by: ubitux 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 ubitux)

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 Changed 5 years ago by ubitux

  • Description modified (diff)

comment:2 Changed 5 years ago by cehoyos

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

comment:3 Changed 5 years ago by ubitux

  • 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 follow-up: Changed 5 years ago by 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?

comment:5 Changed 5 years ago by Cigaes

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

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

A possibly better fix would be to multiply everything by alpha

Would that change decoder output to premultiplied alpha?

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

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.

comment:8 in reply to: ↑ 4 Changed 5 years ago by ubitux

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 Changed 5 years ago by cehoyos

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

Fixed by Nicolas George.

Note: See TracTickets for help on using tickets.