[Ffmpeg-devel] corrupt audio when cut [SOLVED]

Cyrus A lists
Tue Jan 23 19:03:48 CET 2007


Wolfram Gloger wrote:
> Hi,
>
>   
>> I first got the most recent svn to my home directory.  Then, I copied 
>> the patch file to my home directory. I used the command "patch -p0 < 
>> patch.diff" to apply the patch, then ran configure --enable-mp3lame and 
>> then make.
>>     
>
> That is correct if you intend to change sources in the 'trunk'
> directory, and configure and compile within the 'trunk' directory.
>
> Actually I missed adding a prototype for av_get_cur_dts as an exercise
> for the reader :-/.  Sorry.  Perhaps that is the reason for your
> continued problem?
>
> Augmented patch attached.
>
> Regards,
> Wolfram.
>
> diff -ur trunk/libavformat/avformat.h ffmpeg-wg/libavformat/avformat.h
> --- trunk/libavformat/avformat.h	Sun Dec 24 11:06:34 2006
> +++ ffmpeg/libavformat/avformat.h	Tue Jan 16 10:14:05 2007
> @@ -437,6 +437,8 @@
>                         int64_t pos, int64_t timestamp, int size, int distance, int flags);
>  int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags);
>  void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
> +/* current dts in AV_TIME_BASE units */
> +int64_t av_get_cur_dts(AVFormatContext *s, int stream_index);
>  int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
>  
>  /* media file output */
> diff -ur trunk/ffmpeg.c ffmpeg/ffmpeg.c
> --- trunk/ffmpeg.c	Sat Jan 13 20:47:31 2007
> +++ ffmpeg/ffmpeg.c	Tue Jan 16 10:46:51 2007
> @@ -2613,6 +2613,16 @@
>          }
>          /* reset seek info */
>          start_time = 0;
> +        if (av_get_cur_dts(ic, -1) != AV_NOPTS_VALUE) {
> +            timestamp = av_get_cur_dts(ic, -1);
> +            fprintf(stderr, "*** after seek timestamp= %lld\n", timestamp);
> +        }
> +        /* reload stream parameters */
> +        ret = av_find_stream_info(ic);
> +        if (ret < 0 && verbose >= 0) {
> +            fprintf(stderr, "%s: could not find codec parameters\n", filename);
> +            exit(1);
> +        }
>      }
>  
>      /* update the current parameters so that they match the one of the input stream */
> diff -ur trunk/libavformat/avidec.c ffmpeg/libavformat/avidec.c
> --- trunk/libavformat/avidec.c	Tue Jan 16 09:34:41 2007
> +++ ffmpeg/libavformat/avidec.c	Tue Jan 16 10:34:16 2007
> @@ -26,8 +26,8 @@
>  #undef NDEBUG
>  #include <assert.h>
>  
> -//#define DEBUG
> -//#define DEBUG_SEEK
> +#define DEBUG
> +#define DEBUG_SEEK
>  
>  typedef struct AVIStream {
>      int64_t frame_offset; /* current frame (video) or byte (audio) counter
> @@ -961,7 +961,7 @@
>  
>  //        av_log(NULL, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
>          /* extract the current frame number */
> -        ast2->frame_offset = st2->index_entries[index].timestamp;
> +        st2->cur_dts = ast2->frame_offset = st2->index_entries[index].timestamp;
>          if(ast2->sample_size)
>              ast2->frame_offset *=ast2->sample_size;
>      }
> diff -ur trunk/libavformat/utils.c ffmpeg/libavformat/utils.c
> --- trunk/libavformat/utils.c	Mon Jan  8 16:01:14 2007
> +++ ffmpeg/libavformat/utils.c	Tue Jan 16 10:46:51 2007
> @@ -1437,6 +1437,27 @@
>          return av_seek_frame_generic(s, stream_index, timestamp, flags);
>  }
>  
> +/**
> + * Obtain the current dts in AV_TIME_BASE units.
> + * @param stream_index If stream_index is (-1), a default
> + * stream is selected.
> + */
> +int64_t av_get_cur_dts(AVFormatContext *s, int stream_index)
> +{
> +    AVStream *st;
> +
> +    if (stream_index < 0){
> +        stream_index= av_find_default_stream_index(s);
> +        if(stream_index < 0)
> +            return AV_NOPTS_VALUE;
> +    }
> +    st= s->streams[stream_index];
> +    if (st->cur_dts == AV_NOPTS_VALUE)
> +        return AV_NOPTS_VALUE;
> +    return av_rescale(st->cur_dts, AV_TIME_BASE * (int64_t)st->time_base.num,
> +                      st->time_base.den);
> +}
> +
>  /*******************************************************/
>  
>  /**
> @@ -1561,6 +1582,7 @@
>      int read_size, i, ret;
>      int64_t end_time;
>      int64_t filesize, offset, duration;
> +    offset_t old_offset;
>  
>      /* free previous packet */
>      if (ic->cur_st && ic->cur_st->parser)
> @@ -1580,7 +1602,8 @@
>  
>      /* we read the first packets to get the first PTS (not fully
>         accurate, but it is enough now) */
> -    url_fseek(&ic->pb, 0, SEEK_SET);
> +    old_offset = url_ftell(&ic->pb);
> +    url_fseek(&ic->pb, 0, SEEK_CUR);
>      read_size = 0;
>      for(;;) {
>          if (read_size >= DURATION_MAX_READ_SIZE)
> @@ -1646,7 +1669,7 @@
>  
>      fill_all_stream_timings(ic);
>  
> -    url_fseek(&ic->pb, 0, SEEK_SET);
> +    url_fseek(&ic->pb, old_offset, SEEK_SET);
>  }
>  
>  static void av_estimate_timings(AVFormatContext *ic)
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> http://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
>   
This patch worked for me, although there was some extra output during 
the cutting process that didn't look normal:

 /home/cyrus/ffmpeg/ffmpeg -ss 48.0 -t 25.8 -y -vcodec copy -acodec copy 
-i test.avi cutfile.avi
FFmpeg version SVN-r7669, Copyright (c) 2000-2006 Fabrice Bellard, et al.
  configuration:  --enable-mp3lame
  libavutil version: 49.2.0
  libavcodec version: 51.29.0
  libavformat version: 51.8.0
  built on Jan 23 2007 12:43:45, gcc: 4.1.1 20060525 (Red Hat 4.1.1-1)
tag: tag=LIST size=0x2276
list: tag=hdrl size=0x0
tag: tag=avih size=0x38
tag: tag=LIST size=0x1090
list: tag=strl size=0x0
tag: tag=strh size=0x38
strh: tag=vids size=0xffffffff
tag: tag=strf size=0x28
video: tag=DX50 size=0x0
tag: tag=JUNK size=0x1014
tag: tag=LIST size=0x1086
list: tag=strl size=0x0
tag: tag=strh size=0x38
strh: tag=auds size=0xffffffff
tag: tag=strf size=0x1e
tag: tag=JUNK size=0x1014
tag: tag=JUNK size=0x104
tag: tag=LIST size=0x18
list: tag=INFO size=0x0
tag: tag=ISFT size=0xb
tag: tag=JUNK size=0x3f8
tag: tag=LIST size=0x51b94c
list: tag=movi size=0x0
movi end=51dffe
movi_end=0x51dffe
tag=idx1 size=0x16ad0
*** after seek timestamp= 47781067

Seems stream 0 codec frame rate differs from container frame rate: 
30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from 'test.avi':
  Duration: 00:01:25.0, start: 0.000000, bitrate: 513 kb/s
  Stream #0.0: Video: mpeg4, yuv420p, 480x384, 29.97 fps(r)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 192 kb/s
Output #0, avi, to 'cutfile.avi':
  Stream #0.0: Video: mpeg4, yuv420p, 480x384, q=2-31, 29.97 fps(c)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 192 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame=  774 q=0.0 Lsize=    1445kB time=25.8 bitrate= 458.8kbits/s   
video:789kB audio:604kB global headers:0kB muxing overhead 3.754022%


Aside from that debugging output, it worked fine. Can we add this patch 
to the main development branch so that future versions have the fix?

Cyrus





More information about the ffmpeg-devel mailing list