fix codec probing, stop after MAX_PROBE_PACKETS and return all packets
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>
Sun, 31 May 2009 00:24:06 +0000 (00:24 +0000)
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>
Sun, 31 May 2009 00:24:06 +0000 (00:24 +0000)
Originally committed as revision 19000 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/avformat.h
libavformat/utils.c

index 30caea3..b22cdce 100644 (file)
@@ -22,7 +22,7 @@
 #define AVFORMAT_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
 #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, \
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -443,6 +443,13 @@ typedef struct AVStream {
      * AV_NOPTS_VALUE by default.
      */
     int64_t reference_dts;
      * 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
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
index c39f76b..a93a954 100644 (file)
@@ -520,7 +520,7 @@ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
 
 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
 
 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    int ret;
+    int ret, i;
     AVStream *st;
 
     for(;;){
     AVStream *st;
 
     for(;;){
@@ -528,7 +528,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 
         if (pktl) {
             *pkt = pktl->pkt;
 
         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;
                 s->raw_packet_buffer = pktl->next;
                 av_free(pktl);
                 return 0;
@@ -537,8 +538,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 
         av_init_packet(pkt);
         ret= s->iformat->read_packet(s, pkt);
 
         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){
         st= s->streams[pkt->stream_index];
 
         switch(st->codec->codec_type){
@@ -553,7 +559,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
             break;
         }
 
             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);
             return ret;
 
         add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
@@ -561,6 +568,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
         if(st->codec->codec_id == CODEC_ID_PROBE){
             AVProbeData *pd = &st->probe_data;
 
         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;
             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 @@ static void flush_packet_queue(AVFormatContext *s)
         av_free_packet(&pktl->pkt);
         av_free(pktl);
     }
         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 @@ static void av_read_frame_flush(AVFormatContext *s)
         /* fail safe */
         st->cur_ptr = NULL;
         st->cur_len = 0;
         /* fail safe */
         st->cur_ptr = NULL;
         st->cur_len = 0;
+
+        st->probe_packets = MAX_PROBE_PACKETS;
     }
 }
 
     }
 }
 
@@ -2342,6 +2359,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
            timestamps corrected before they are returned to the user */
     st->cur_dts = 0;
     st->first_dts = AV_NOPTS_VALUE;
            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);
 
     /* default pts setting is MPEG-like */
     av_set_pts_info(st, 33, 1, 90000);