[FFmpeg-devel] [PATCH] avformat/utils: improve get duration

Ping Kai pingkai010 at gmail.com
Thu May 30 17:55:24 CEST 2013


improve the accuracy of getting
duration from bit rate.

Signed-off-by: Ping Kai <pingkai010 at gmail.com>
---
 libavformat/utils.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index baa7177..c4bf871 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2775,7 +2775,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     int64_t old_offset = avio_tell(ic->pb);
     int orig_nb_streams = ic->nb_streams;        // new streams might appear, no options for those
     int flush_codecs = ic->probesize > 0;
+    int64_t *sample_bit_rate_sum = av_malloc(ic->nb_streams * sizeof(int64_t));
+    int *sample_count = av_malloc(ic->nb_streams * sizeof(int));
 
+    if (sample_bit_rate_sum == NULL || sample_count == NULL)
+        return AVERROR_INVALIDDATA;
     if(ic->pb)
         av_log(ic, AV_LOG_DEBUG, "File position before avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
 
@@ -2839,6 +2843,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 
     count = 0;
     read_size = 0;
+    memset(sample_bit_rate_sum ,0 ,ic->nb_streams * sizeof(int64_t));
+    memset(sample_count,0 ,ic->nb_streams * sizeof(int));
     for(;;) {
         if (ff_check_interrupt(&ic->interrupt_callback)){
             ret= AVERROR_EXIT;
@@ -2909,7 +2915,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
             /* EOF or error*/
             break;
         }
-
+        if (pkt1.stream_index < orig_nb_streams
+            &&ic->streams[pkt1.stream_index]->codec->bit_rate > 0){
+            sample_bit_rate_sum += ic->streams[pkt1.stream_index]->codec->bit_rate;
+            sample_count ++;
+        }
         if (ic->flags & AVFMT_FLAG_NOBUFFER) {
             pkt = &pkt1;
         } else {
@@ -3029,7 +3039,10 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
         st->codec_info_nb_frames++;
         count++;
     }
-
+    for(i=0;i<orig_nb_streams;i++){
+        if (sample_count[i] > 0)
+            ic->streams[i]->codec->bit_rate = (int)(sample_bit_rate_sum[i] / sample_count[i]);
+    }
     if (flush_codecs) {
         AVPacket empty_pkt = { 0 };
         int err = 0;
@@ -3185,6 +3198,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
             av_freep(&st->info->duration_error);
         av_freep(&ic->streams[i]->info);
     }
+    av_free(sample_bit_rate_sum);
+    av_free(sample_count);
     if(ic->pb)
         av_log(ic, AV_LOG_DEBUG, "File position after avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
     return ret;
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list