New codec probing system try #1.
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 12 Jul 2008 18:42:00 +0000 (18:42 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 12 Jul 2008 18:42:00 +0000 (18:42 +0000)
Originally committed as revision 14184 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/avcodec.h
libavformat/asf.c
libavformat/avformat.h
libavformat/utils.c

index f7532f7..d286361 100644 (file)
@@ -313,6 +313,8 @@ enum CodecID {
     /* other specific kind of codecs (generally used for attachments) */
     CODEC_ID_TTF= 0x18000,
 
+    CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
+
     CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
                                 * stream (only used by libavformat) */
 };
index dc65574..f285b73 100644 (file)
@@ -264,7 +264,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 if (is_dvr_ms_audio) {
                     // codec_id and codec_tag are unreliable in dvr_ms
                     // files. Set them later by probing stream.
-                    st->codec->codec_id = CODEC_ID_NONE;
+                    st->codec->codec_id = CODEC_ID_PROBE;
                     st->codec->codec_tag = 0;
                 }
                 st->need_parsing = AVSTREAM_PARSE_FULL;
index 500c0cf..23450af 100644 (file)
@@ -391,6 +391,8 @@ typedef struct AVStream {
     char *filename; /**< source filename of the stream */
 
     int disposition; /**< AV_DISPOSITION_* bitfield */
+
+    AVProbeData probe_data;
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
@@ -555,6 +557,14 @@ typedef struct AVFormatContext {
      */
     int debug;
 #define FF_FDEBUG_TS        0x0001
+
+    /**
+     * raw packets from the demuxer, prior to parsing and decoding.
+     * This buffer is used for buffering packets until the codec can
+     * be identified, as parsing cannot be done without knowing the
+     * codec.
+     */
+    struct AVPacketList *raw_packet_buffer;
 } AVFormatContext;
 
 typedef struct AVPacketList {
index 329228d..4faef19 100644 (file)
@@ -540,12 +540,30 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
     AVStream *st;
+
+    for(;;){
+        AVPacketList *pktl = s->raw_packet_buffer;
+
+        if (pktl) {
+            *pkt = pktl->pkt;
+            if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE){
+                s->raw_packet_buffer = pktl->next;
+                av_free(pktl);
+                return 0;
+            }
+        }
+
     av_init_packet(pkt);
     ret= s->iformat->read_packet(s, pkt);
     if (ret < 0)
         return ret;
     st= s->streams[pkt->stream_index];
 
+        if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
+            return ret;
+
+        add_to_pktbuf(&s->raw_packet_buffer, pkt);
+
     switch(st->codec->codec_type){
     case CODEC_TYPE_VIDEO:
         if(s->video_codec_id)   st->codec->codec_id= s->video_codec_id;
@@ -558,7 +576,21 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
         break;
     }
 
-    return ret;
+        if(st->codec->codec_id == CODEC_ID_PROBE){
+            AVProbeData *pd = &st->probe_data;
+
+            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;
+            memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
+
+            set_codec_from_probe_data(st, pd, 1);
+            if(st->codec->codec_id != CODEC_ID_PROBE){
+                pd->buf_size=0;
+                av_freep(&pd->buf);
+            }
+        }
+    }
 }
 
 /**********************************************************/