[FFmpeg-trac] #5756(ffmpeg:new): Robustness issue with nul character in ASS subtitle streams
FFmpeg
trac at avcodec.org
Thu Aug 4 15:01:50 EEST 2016
#5756: Robustness issue with nul character in ASS subtitle streams
----------------------------------+---------------------------------------
Reporter: lelegard | Type: enhancement
Status: new | Priority: normal
Component: ffmpeg | Version: git-master
Keywords: | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
----------------------------------+---------------------------------------
This report describes a robustness issue with the processing of ASS
subtitles.
ffmpeg version N-81256-gd3426fb (full text in commands below)
== Summary ==
Some MKV files (but not all) containing ASS subtitles contain a nul
character at the end of the ASS header (this is text). I do not know if
this character is valid or not.
When the subtitle track is extracted using ffmpeg, the nul character can
be seen in the middle of the ASS text file, at the end of the "[V4+
Styles]" section, before the "[Events]" section. Then, when this file is
used to burn the subtitles using the "ass" video filter, no subtitle is
seen in the video. If we manually modify the ASS text file to remove the
nul character and retry the "ass" video filter, then the subtitles are
correctly inserted in the video.
Even if the nul character is invalid (to be confirmed), failing because of
it is a pity. Other tools handle that situation without problem:
1. VLC correctly displays the subtitle track when playing the MKV file.
2. When mkvextract is used to extract the subtitle track, the created ASS
text file does not have the nul character.
So, for the sake of robustness, whether the nul character in the input
file is valid or not, I suggest the following two enhancements. They are
redundant in the specific example of this report, but they are in fact two
independent robustness improvements for distinct use cases.
1. When extracting the ASS header in a text file, remove the nul
character, just like mkvextract.
2. In the "ass" video filter, ignore nul characters from the text file
containing the subtitles.
== Demonstration ==
I have a small MKV file named im.mkv, 10 MB, 30 seconds of playback,
demonstrating the problem. This file is extracted from a larger MKV file.
Several other MKV from multiple origins have the same nul character in the
ASS header.
Extracting the subtitles using mkvextract into a text file named im-
mkvextract.ass:
{{{
$ mkvextract tracks im.mkv 2:im-mkvextract.ass
Extracting track 2 with the CodecID 'S_TEXT/ASS' to the file 'im-
mkvextract.ass'. Container format: SSA/ASS text subtitles
Progress: 100%
$
}}}
Extracting the subtitles using ffmpeg into a text file named im-
ffmpeg.ass:
{{{
$ ffmpeg -i im.mkv -vn -an -codec:s ass -f ass -y im-ffmpeg.ass
ffmpeg version N-81256-gd3426fb Copyright (c) 2000-2016 the FFmpeg
developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
--enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-
bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-
gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b
--enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm
--enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-
libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-libopus --enable-librtmp --enable-libschroedinger --enable-
libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-
libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis
--enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264
--enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg
--enable-lzma --enable-decklink --enable-zlib
libavutil 55. 28.100 / 55. 28.100
libavcodec 57. 51.100 / 57. 51.100
libavformat 57. 44.100 / 57. 44.100
libavdevice 57. 0.102 / 57. 0.102
libavfilter 6. 49.100 / 6. 49.100
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
Input #0, matroska,webm, from 'im.mkv':
Metadata:
ENCODER : Lavf57.25.100
Duration: 00:00:30.60, start: 0.000000, bitrate: 2618 kb/s
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Metadata:
title : Surround
DURATION : 00:00:30.016000000
Stream #0:1: Video: h264 (High), yuv420p(tv, bt709), 1920x800 [SAR 1:1
DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
Metadata:
DURATION : 00:00:30.182000000
Stream #0:2(fre): Subtitle: ass
Metadata:
DURATION : 00:00:30.601000000
[ass @ 0000000002865500] Using AVStream.codec to pass codec parameters to
muxers is deprecated, use AVStream.codecpar instead.
Output #0, ass, to 'im-ffmpeg.ass':
Metadata:
encoder : Lavf57.44.100
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0(fre): Subtitle: ass
Metadata:
DURATION : 00:00:30.601000000
encoder : Lavc57.51.100 ass
Stream mapping:
Stream #0:2 -> #0:0 (ass (ssa) -> ass (native))
Press [q] to stop, [?] for help
size= 1kB time=00:00:28.68 bitrate= 0.4kbits/s speed=50.9x
video:0kB audio:0kB subtitle:1kB other streams:0kB global headers:0kB
muxing overhead: 167.719299%
$
}}}
The file im-ffmpeg.ass contains a nul character as illustrated below. The
file im-mkvextract.ass does not have this nul character.
{{{
[Script Info]
ScriptType: v4.00+
Collisions: Normal
PlayResX: 1920
PlayResY: 800
Timer: 100.0
WrapStyle: 0
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour,
OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX,
ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL,
MarginR, MarginV, Encoding
Style:
Default,Arial,52,&H00FFFFFF,&H00FFFFFF,&H000F0F0F,&H000F0F0F,0,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,0
^@ <==== nul character here
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect,
Text
.....
}}}
Now, we try to burn the two subtitle files im-ffmpeg.ass and im-
mkvextract.ass in the video, separately.
In the file im1.mpg, generated using im-ffmpeg.ass, there is no subtitle
in the video. In the file im2.mpg, generated using im-mkvextract.ass, the
subtitles are correctly inserted in the video.
{{{
$ ffmpeg -i im.mkv -codec:a ac3 -codec:v mpeg2video -vf ass=filename=im-
ffmpeg.ass -f dvd -y im1.mpg
ffmpeg version N-81256-gd3426fb Copyright (c) 2000-2016 the FFmpeg
developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
--enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-
bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-
gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b
--enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm
--enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-
libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-libopus --enable-librtmp --enable-libschroedinger --enable-
libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-
libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis
--enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264
--enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg
--enable-lzma --enable-decklink --enable-zlib
libavutil 55. 28.100 / 55. 28.100
libavcodec 57. 51.100 / 57. 51.100
libavformat 57. 44.100 / 57. 44.100
libavdevice 57. 0.102 / 57. 0.102
libavfilter 6. 49.100 / 6. 49.100
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
Input #0, matroska,webm, from 'im.mkv':
Metadata:
ENCODER : Lavf57.25.100
Duration: 00:00:30.60, start: 0.000000, bitrate: 2618 kb/s
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Metadata:
title : Surround
DURATION : 00:00:30.016000000
Stream #0:1: Video: h264 (High), yuv420p(tv, bt709), 1920x800 [SAR 1:1
DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
Metadata:
DURATION : 00:00:30.182000000
Stream #0:2(fre): Subtitle: ass
Metadata:
DURATION : 00:00:30.601000000
[Parsed_ass_0 @ 000000000073ff20] Shaper: FriBidi 0.19.6 (SIMPLE)
[Parsed_ass_0 @ 000000000073ff20] Using font provider directwrite
[Parsed_ass_0 @ 000000000073ff20] Added subtitle file: 'im-ffmpeg.ass' (2
styles, 0 events)
[dvd @ 00000000027f8500] Using AVStream.codec to pass codec parameters to
muxers is deprecated, use AVStream.codecpar instead.
Last message repeated 1 times
[dvd @ 00000000027f8500] VBV buffer size not set, using default size of
130KB
If you want the mpeg file to be compliant to some specification
Like DVD, VCD or others, make sure you set the correct buffer size
Output #0, dvd, to 'im1.mpg':
Metadata:
encoder : Lavf57.44.100
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0: Video: mpeg2video (Main), yuv420p, 1920x800 [SAR 1:1 DAR
12:5], q=2-31, 200 kb/s, 23.98 fps, 90k tbn, 23.98 tbc (default)
Metadata:
DURATION : 00:00:30.182000000
encoder : Lavc57.51.100 mpeg2video
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
Metadata:
title : Surround
DURATION : 00:00:30.016000000
encoder : Lavc57.51.100 ac3
Stream mapping:
Stream #0:1 -> #0:0 (h264 (native) -> mpeg2video (native))
Stream #0:0 -> #0:1 (ac3 (native) -> ac3 (native))
Press [q] to stop, [?] for help
frame= 724 fps=126 q=24.8 Lsize= 6742kB time=00:00:30.11
bitrate=1834.1kbits/s dup=22 drop=0 speed=5.23x
video:4832kB audio:1642kB subtitle:0kB other streams:0kB global
headers:0kB muxing overhead: 4.153100%
$
$
$ ffmpeg -i im.mkv -codec:a ac3 -codec:v mpeg2video -vf ass=filename=im-
mkvextract.ass -f dvd -y im2.mpg
ffmpeg version N-81256-gd3426fb Copyright (c) 2000-2016 the FFmpeg
developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
--enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-
bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-
gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b
--enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm
--enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-
libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-libopus --enable-librtmp --enable-libschroedinger --enable-
libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-
libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis
--enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264
--enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg
--enable-lzma --enable-decklink --enable-zlib
libavutil 55. 28.100 / 55. 28.100
libavcodec 57. 51.100 / 57. 51.100
libavformat 57. 44.100 / 57. 44.100
libavdevice 57. 0.102 / 57. 0.102
libavfilter 6. 49.100 / 6. 49.100
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
Input #0, matroska,webm, from 'im.mkv':
Metadata:
ENCODER : Lavf57.25.100
Duration: 00:00:30.60, start: 0.000000, bitrate: 2618 kb/s
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Metadata:
title : Surround
DURATION : 00:00:30.016000000
Stream #0:1: Video: h264 (High), yuv420p(tv, bt709), 1920x800 [SAR 1:1
DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
Metadata:
DURATION : 00:00:30.182000000
Stream #0:2(fre): Subtitle: ass
Metadata:
DURATION : 00:00:30.601000000
[Parsed_ass_0 @ 00000000027a96c0] Shaper: FriBidi 0.19.6 (SIMPLE)
[Parsed_ass_0 @ 00000000027a96c0] Using font provider directwrite
[Parsed_ass_0 @ 00000000027a96c0] Added subtitle file: 'im-mkvextract.ass'
(2 styles, 12 events)
[dvd @ 00000000029700a0] Using AVStream.codec to pass codec parameters to
muxers is deprecated, use AVStream.codecpar instead.
Last message repeated 1 times
[dvd @ 00000000029700a0] VBV buffer size not set, using default size of
130KB
If you want the mpeg file to be compliant to some specification
Like DVD, VCD or others, make sure you set the correct buffer size
Output #0, dvd, to 'im2.mpg':
Metadata:
encoder : Lavf57.44.100
Chapter #0:0: start 0.000000, end 30.000000
Metadata:
title : 00:00:00.000
Stream #0:0: Video: mpeg2video (Main), yuv420p, 1920x800 [SAR 1:1 DAR
12:5], q=2-31, 200 kb/s, 23.98 fps, 90k tbn, 23.98 tbc (default)
Metadata:
DURATION : 00:00:30.182000000
encoder : Lavc57.51.100 mpeg2video
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
Metadata:
title : Surround
DURATION : 00:00:30.016000000
encoder : Lavc57.51.100 ac3
Stream mapping:
Stream #0:1 -> #0:0 (h264 (native) -> mpeg2video (native))
Stream #0:0 -> #0:1 (ac3 (native) -> ac3 (native))
Press [q] to stop, [?] for help
[Parsed_ass_0 @ 00000000027a96c0] fontselect: (Arial, 400, 0) -> ArialMT,
0, ArialMTp=20 drop=0 speed=5.77x
frame= 724 fps=110 q=24.8 Lsize= 6914kB time=00:00:30.11
bitrate=1880.9kbits/s dup=22 drop=0 speed= 4.6x
video:5003kB audio:1642kB subtitle:0kB other streams:0kB global
headers:0kB muxing overhead: 4.057209%
$
}}}
--
Ticket URL: <https://trac.ffmpeg.org/ticket/5756>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list