---
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