[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