[FFmpeg-trac] #2657(avformat:new): Fmpeg fails to read some buffered ISML inputs
FFmpeg
trac at avcodec.org
Mon Jun 10 18:08:04 CEST 2013
#2657: Fmpeg fails to read some buffered ISML inputs
-------------------------------------+-------------------------------------
Reporter: libricoleur | Type: defect
Status: new | Priority: normal
Component: avformat | Version: git-
Keywords: isml | master
smoothstreaming | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
I'm trying to get FFmpeg to read a live Smooth Streaming (ISML) movie and
remux
it. The movie is created by a Microsoft Expression Encoder 4 Pro SP1,
retrieved by a script then fed to a FFmpeg process. In short, FFmpeg reads
the
ISML movie from standard input.
While it does produce a correct result in some situations, sometimes the
output
file is only a few seconds long. For instance, I get a correct result with
a
simple three streams (video, audio, text) movie, but it is cut if I add
two more
video streams. When the input is an actual realtime stream instead of a
static
file, FFmpeg stalls while finding stream info.
How to reproduce:
{{{
% ffmpeg -i - -acodec copy -vcodec copy test.mp4 <
buffered_reading_failure.isml
}}}
See attached FFmpeg report log, with MOV debugging enabled. The
''buffered_reading_failure.isml'' file has been uploaded on the FTP
server.
Tested on latest git (9908607363).
I spent some time trying to debug this. Using a realtime stream I was able
to
interrupt right when FFmpeg stalls. Here is the GDB backtrace, including a
breakpoint you can use to reproduce the problem using the command above:
{{{
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004d86f5 in avio_seek at
libavformat/aviobuf.c:203
stop only if offset > 1000000000
breakpoint already hit 1 time
(gdb) backtrace
#0 avio_seek (s=0x188af00, offset=1274828063, whence=1) at
libavformat/aviobuf.c:203
#1 0x00000000004d89f9 in avio_skip (s=0x188af00, offset=1274828063) at
libavformat/aviobuf.c:258
#2 0x000000000052c334 in mov_read_default (c=0x1882ea0, pb=0x188af00,
atom=...) at libavformat/mov.c:2852
#3 0x000000000052da94 in mov_read_packet (s=0x1882880,
pkt=0x7fffffffd370) at libavformat/mov.c:3269
#4 0x00000000005c445c in ff_read_packet (s=0x1882880, pkt=0x7fffffffd370)
at libavformat/utils.c:791
#5 0x00000000005c6b51 in read_frame_internal (s=0x1882880,
pkt=0x7fffffffd6c0) at libavformat/utils.c:1443
#6 0x00000000005cb48b in avformat_find_stream_info (ic=0x1882880,
options=0x18898a0) at libavformat/utils.c:2904
#7 0x00000000004090a1 in open_input_file (o=0x7fffffffd9f0,
filename=0x7fffffffe2fe "/home/mandre/Vidéos/tests/fifo") at
ffmpeg_opt.c:814
#8 0x00000000004101a7 in open_files (l=0x186c058, inout=0xdb8c70 "input",
open_file=0x4089a1 <open_input_file>) at ffmpeg_opt.c:2483
#9 0x000000000041031e in ffmpeg_parse_options (argc=8,
argv=0x7fffffffdf38) at ffmpeg_opt.c:2520
#10 0x000000000041fa2f in main (argc=8, argv=0x7fffffffdf38) at
ffmpeg.c:3361
}}}
As you can see at frame 1, FFmpeg stalls because it tries to skip an atom
of size
INT64_MAX (mov.c:3264). This happens because the atom's position
corresponds to
a video packet, thus it can't be parsed and is skipped.
Here is my understanding of what happens:
* At offset 0x4cba0 a tfhd atom is read. It sets the default sample size
to 926.
* At offset 0x4cbb8 a trun atom is read. It contains 60 empty entries.
* At offset 0x4cc44 the corresponding mdat atom is read. It is of size
934.
* mov_read_packet reads the first sample of size 926.
* 59 samples are left to read, so mov_read_packet reads them even though
they are beyond the mdat atom.
* We are now at offset 0x5a550. mov_read_packet has no samples left to
read, so it seeks to mov->next_root_atom (0x4cc44 + 934). Since the input
buffer size is 32768, the offset is out of reach and the seek fails
(silently). '''This is why it only affects buffered input. The seek is
always possible with a file.'''
* mov_read_default is called with an atom of size INT64_MAX which can't be
parsed and is skipped.
This only happens with the data (TTML) track fragments, as the others do
not
have a default sample size in their tfhd but complete entries in their
trun.
--
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/2657>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list