changeset 4975:76263311c368 libavformat

fix codec probing, stop after MAX_PROBE_PACKETS and return all packets
author bcoudurier
date Sun, 31 May 2009 00:24:06 +0000
parents 636161c01391
children c236ec233a09
files avformat.h utils.c
diffstat 2 files changed, 31 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/avformat.h	Sat May 30 18:51:15 2009 +0000
+++ b/avformat.h	Sun May 31 00:24:06 2009 +0000
@@ -22,7 +22,7 @@
 #define AVFORMAT_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 33
+#define LIBAVFORMAT_VERSION_MINOR 34
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -443,6 +443,13 @@
      * AV_NOPTS_VALUE by default.
      */
     int64_t reference_dts;
+
+    /**
+     * Number of packets to buffer for codec probing
+     * NOT PART OF PUBLIC API
+     */
+#define MAX_PROBE_PACKETS 100
+    int probe_packets;
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
--- a/utils.c	Sat May 30 18:51:15 2009 +0000
+++ b/utils.c	Sun May 31 00:24:06 2009 +0000
@@ -520,7 +520,7 @@
 
 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    int ret;
+    int ret, i;
     AVStream *st;
 
     for(;;){
@@ -528,7 +528,8 @@
 
         if (pktl) {
             *pkt = pktl->pkt;
-            if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE){
+            if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
+               !s->streams[pkt->stream_index]->probe_packets){
                 s->raw_packet_buffer = pktl->next;
                 av_free(pktl);
                 return 0;
@@ -537,8 +538,13 @@
 
         av_init_packet(pkt);
         ret= s->iformat->read_packet(s, pkt);
-        if (ret < 0)
-            return ret;
+        if (ret < 0) {
+            if (!pktl || ret == AVERROR(EAGAIN))
+                return ret;
+            for (i = 0; i < s->nb_streams; i++)
+                s->streams[i]->probe_packets = 0;
+            continue;
+        }
         st= s->streams[pkt->stream_index];
 
         switch(st->codec->codec_type){
@@ -553,7 +559,8 @@
             break;
         }
 
-        if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
+        if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE ||
+                     !st->probe_packets))
             return ret;
 
         add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
@@ -561,6 +568,8 @@
         if(st->codec->codec_id == CODEC_ID_PROBE){
             AVProbeData *pd = &st->probe_data;
 
+            --st->probe_packets;
+
             pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
             memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
             pd->buf_size += pkt->size;
@@ -1081,6 +1090,12 @@
         av_free_packet(&pktl->pkt);
         av_free(pktl);
     }
+    while(s->raw_packet_buffer){
+        pktl = s->raw_packet_buffer;
+        s->raw_packet_buffer = pktl->next;
+        av_free_packet(&pktl->pkt);
+        av_free(pktl);
+    }
 }
 
 /*******************************************************/
@@ -1132,6 +1147,8 @@
         /* fail safe */
         st->cur_ptr = NULL;
         st->cur_len = 0;
+
+        st->probe_packets = MAX_PROBE_PACKETS;
     }
 }
 
@@ -2342,6 +2359,7 @@
            timestamps corrected before they are returned to the user */
     st->cur_dts = 0;
     st->first_dts = AV_NOPTS_VALUE;
+    st->probe_packets = MAX_PROBE_PACKETS;
 
     /* default pts setting is MPEG-like */
     av_set_pts_info(st, 33, 1, 90000);