---

This is mostly an rfc I started trying to remove the use of stream->id and 
ended up with
this patch.

 libavformat/flvdec.c |  134 ++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 103 insertions(+), 31 deletions(-)

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 8e9759b..47226e5 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -74,6 +74,7 @@ static AVStream *create_stream(AVFormatContext *s, int tag, 
int codec_type)
     st->id = tag;
     st->codec->codec_type = codec_type;
     avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
+    av_log(s, AV_LOG_INFO, "Creating stream %d %d\n", tag, codec_type);
     return st;
 }
 
@@ -114,33 +115,104 @@ static void flv_set_audio_codec(AVFormatContext *s, 
AVStream *astream, AVCodecCo
     }
 }
 
+static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
+{
+    int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
+    int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
+    int codec_id;
+
+    if (acodec->bits_per_coded_sample != bits_per_coded_sample)
+        return 0;
+
+    switch(flv_codecid) {
+        //no distinction between S16 and S8 PCM codec flags
+    case FLV_CODECID_PCM:
+        codec_id = bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 :
+#if HAVE_BIGENDIAN
+                            CODEC_ID_PCM_S16BE;
+#else
+                            CODEC_ID_PCM_S16LE;
+#endif
+        return codec_id == acodec->codec_id;
+    case FLV_CODECID_PCM_LE:
+        codec_id = bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : 
CODEC_ID_PCM_S16LE;
+        return codec_id == acodec->codec_id;
+    case FLV_CODECID_AAC:
+        return acodec->codec_id == CODEC_ID_AAC;
+    case FLV_CODECID_ADPCM:
+        return acodec->codec_id == CODEC_ID_ADPCM_SWF;
+    case FLV_CODECID_SPEEX:
+        return acodec->codec_id == CODEC_ID_SPEEX;
+    case FLV_CODECID_MP3:
+        return acodec->codec_id == CODEC_ID_MP3;
+    case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
+        return acodec->sample_rate == 8000 &&
+               acodec->codec_id == CODEC_ID_NELLYMOSER;
+    case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
+        return acodec->sample_rate == 16000 &&
+               acodec->codec_id == CODEC_ID_NELLYMOSER;
+    case FLV_CODECID_NELLYMOSER:
+        return acodec->codec_id == CODEC_ID_NELLYMOSER;
+    default:
+        return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
+    }
+
+    return 0;
+}
+
+
 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int 
flv_codecid) {
     AVCodecContext *vcodec = vstream->codec;
     switch(flv_codecid) {
-        case FLV_CODECID_H263  : vcodec->codec_id = CODEC_ID_FLV1   ; break;
-        case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break;
-        case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break;
-        case FLV_CODECID_VP6   : vcodec->codec_id = CODEC_ID_VP6F   ;
-        case FLV_CODECID_VP6A  :
-            if(flv_codecid == FLV_CODECID_VP6A)
-                vcodec->codec_id = CODEC_ID_VP6A;
-            if(vcodec->extradata_size != 1) {
-                vcodec->extradata_size = 1;
-                vcodec->extradata = av_malloc(1);
-            }
-            vcodec->extradata[0] = avio_r8(s->pb);
-            return 1; // 1 byte body size adjustment for flv_read_packet()
+    case FLV_CODECID_H263  : vcodec->codec_id = CODEC_ID_FLV1   ; break;
+    case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break;
+    case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break;
+    case FLV_CODECID_VP6   : vcodec->codec_id = CODEC_ID_VP6F   ;
+    case FLV_CODECID_VP6A  :
+        if(flv_codecid == FLV_CODECID_VP6A)
+            vcodec->codec_id = CODEC_ID_VP6A;
+        if(vcodec->extradata_size != 1) {
+            vcodec->extradata_size = 1;
+            vcodec->extradata = av_malloc(1);
+        }
+        vcodec->extradata[0] = avio_r8(s->pb);
+        return 1; // 1 byte body size adjustment for flv_read_packet()
+    case FLV_CODECID_H264:
+        vcodec->codec_id = CODEC_ID_H264;
+        return 3; // not 4, reading packet type will consume one byte
+    default:
+        av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
+        vcodec->codec_tag = flv_codecid;
+    }
+
+    return 0;
+}
+
+static int flv_same_video_codec(AVCodecContext *vcodec, int flags)
+{
+    int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+    switch (flv_codecid) {
+        case FLV_CODECID_H263:
+            return vcodec->codec_id == CODEC_ID_FLV1;
+        case FLV_CODECID_SCREEN:
+            return vcodec->codec_id == CODEC_ID_FLASHSV;
+        case FLV_CODECID_SCREEN2:
+            return vcodec->codec_id == CODEC_ID_FLASHSV2;
+        case FLV_CODECID_VP6:
+            return vcodec->codec_id == CODEC_ID_VP6F;
+        case FLV_CODECID_VP6A:
+            return vcodec->codec_id == CODEC_ID_VP6A;
         case FLV_CODECID_H264:
-            vcodec->codec_id = CODEC_ID_H264;
-            return 3; // not 4, reading packet type will consume one byte
+            return vcodec->codec_id == CODEC_ID_H264;
         default:
-            av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", 
flv_codecid);
-            vcodec->codec_tag = flv_codecid;
+            return vcodec->codec_tag == flv_codecid;
     }
 
     return 0;
 }
 
+
+
 static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
     int length = avio_rb16(ioc);
     if(length >= buffsize) {
@@ -402,15 +474,6 @@ static int flv_read_header(AVFormatContext *s)
              != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO))
         s->ctx_flags |= AVFMTCTX_NOHEADER;
 
-    if(flags & FLV_HEADER_FLAG_HASVIDEO){
-        if(!create_stream(s, 0, AVMEDIA_TYPE_VIDEO))
-            return AVERROR(ENOMEM);
-    }
-    if(flags & FLV_HEADER_FLAG_HASAUDIO){
-        if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
-            return AVERROR(ENOMEM);
-    }
-
     offset = avio_rb32(s->pb);
     avio_seek(s->pb, offset, SEEK_SET);
     avio_skip(s->pb, 4);
@@ -503,7 +566,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket 
*pkt,
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
-        if (st->id == 2)
+        if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
             break;
     }
 
@@ -595,16 +658,25 @@ static int flv_read_packet(AVFormatContext *s, AVPacket 
*pkt)
         continue;
 
     /* now find stream */
-    for(i=0;i<s->nb_streams;i++) {
+    for (i=0;i<s->nb_streams;i++) {
         st = s->streams[i];
-        if (st->id == is_audio)
-            break;
+        if (is_audio && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            if (flv_same_audio_codec(st->codec, flags)) {
+                break;
+            }
+        } else
+        if (!is_audio && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            if (flv_same_video_codec(st->codec, flags)) {
+                break;
+            }
+        }
     }
+
     if(i == s->nb_streams){
-        av_log(s, AV_LOG_ERROR, "invalid stream\n");
         st = create_stream(s, is_audio,
              is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
         s->ctx_flags &= ~AVFMTCTX_NOHEADER;
+        av_log(s, AV_LOG_ERROR, "New stream count %d\n", s->nb_streams);
     }
     av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
     if(  (st->discard >= AVDISCARD_NONKEY && !((flags & 
FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
-- 
1.7.8.rc1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to