[FFmpeg-devel] [PATCH] fix ffmpeg crash on reading "non-interleved" DV type 1 AVI files

Maksym Veremeyenko verem
Thu Jan 14 17:38:37 CET 2010


Michael Niedermayer ???????(??):
[...]
> i dont know what you are trying to do here, so i cannot make any suggestions
> for a correct solution but i do know your patch is wrong
> 
> full bugreport and explanation of why a random piece of the non interleaved
> handling should be skiped is missing

During decode 18Gb avi file in _DV type 1_ format i got a Segmentation 
fault of ffmpeg. Gdb says:

[root at diva-proxy ffmpeg-r21211]# gdb --tty /dev/pts/5 --args ./ffmpeg_g 
-debug 3 -i "/home/lowres/lost+found/Amer001.AVI" -vcodec copy -an -f 
rawvideo -y /tmp/test.dv
GNU gdb Fedora (6.8-32.fc10)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) r
Starting program: /opt/enctools/src/ffmpeg-r21211/ffmpeg_g -debug 3 -i 
/home/lowres/lost+found/Amer001.AVI -vcodec copy -an -f rawvideo -y 
/tmp/test.dv
[Thread debugging using libthread_db enabled]
[New Thread 0xb7ff58d0 (LWP 25599)]

Program received signal SIGSEGV, Segmentation fault.
avi_read_packet (s=0x806a390, pkt=0xbfffe390) at libavformat/avidec.c:691
691	            int64_t ts= ast->frame_offset;
Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.i686 
zlib-1.2.3-18.fc9.i386
(gdb) bt
#0  avi_read_packet (s=0x806a390, pkt=0xbfffe390) at 
libavformat/avidec.c:691
#1  0x00a07443 in av_read_packet (s=0x806a390, pkt=0xbfffe390) at 
libavformat/utils.c:598
#2  0x00a0906e in av_read_frame_internal (s=0x806a390, pkt=0xbffff57c) 
at libavformat/utils.c:1018
#3  0x080521bc in av_encode (output_files=0x805e1c0, nb_output_files=1, 
input_files=0x805cde0, nb_input_files=1,
     stream_maps=0x805e880, nb_stream_maps=0) at ffmpeg.c:2253
#4  0x08052dab in main (argc=Cannot access memory at address 0x0
) at ffmpeg.c:4016
(gdb) print ast
$1 = (AVIStream *) 0x0
(gdb) print i
$2 = 1

The problem happens on accessing AVIStream's frame_offset on 
uninitialized *ast* (that is taken from st->priv_data). Stream's private 
data been initialized only for one track:

libavformat/avidec.c:
[...]
  366                s->nb_streams = 0;
  367                if (CONFIG_DV_DEMUXER) {
  368                    avi->dv_demux = dv_init_demux(s);
  369                    if (!avi->dv_demux)
  370                        goto fail;
  371                }
  372                s->streams[0]->priv_data = ast;
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  373                url_fskip(pb, 3 * 4);
  374                ast->scale = get_le32(pb);
  375                ast->rate = get_le32(pb);
[...]

and second track (audio track) seems been added dynamically in 
dv_produce_packet->dv_extract_audio_info call and private data for this 
stream will not be initialized.

So the solution was to disable code:

--- avidec.c	2010-01-14 17:17:04.000000000 +0200
+++ avidec.c.fixA	2010-01-14 16:12:52.000000000 +0200
@@ -678,7 +678,7 @@
              return size;
      }

-    if(avi->non_interleaved){
+    if(avi->non_interleaved && !(CONFIG_DV_DEMUXER && avi->dv_demux)){
          int best_stream_index = 0;
          AVStream *best_st= NULL;
          AVIStream *best_ast;

because of /comments/ meaning bellow in libavformat/avidec.c:

[...]
1092    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1093        /* One and only one real stream for DV in AVI, and it has 
video  */
1094        /* offsets. Calling with other stream indexes should have 
failed */
1095        /* the av_index_search_timestamp call above. 
      */
1096        assert(stream_index == 0);
1097
1098        /* Feed the DV video stream version of the timestamp to the */
1099        /* DV demux so it can synthesize correct timestamps.        */
1100        dv_offset_reset(avi->dv_demux, timestamp);
1101
1102        url_fseek(s->pb, pos, SEEK_SET);
1103        avi->stream_index= -1;
1104        return 0;
1105    }
[...]

Am i wrong?

-- 
________________________________________
Maksym Veremeyenko




More information about the ffmpeg-devel mailing list