flvdec: initial stream switch support
Codec change midstream gets mapped to a separate stream.
This commit is contained in:
parent
906f9dce85
commit
09a445ce34
@ -76,6 +76,59 @@ static AVStream *create_stream(AVFormatContext *s, int tag, int codec_type)
|
||||
avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
|
||||
return st;
|
||||
}
|
||||
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->codec_id && !acodec->codec_tag)
|
||||
return 1;
|
||||
|
||||
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;
|
||||
case FLV_CODECID_PCM_MULAW:
|
||||
return acodec->sample_rate == 8000 &&
|
||||
acodec->codec_id == CODEC_ID_PCM_MULAW;
|
||||
case FLV_CODECID_PCM_ALAW:
|
||||
return acodec->sample_rate = 8000 &&
|
||||
acodec->codec_id == CODEC_ID_PCM_ALAW;
|
||||
default:
|
||||
return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
|
||||
switch(flv_codecid) {
|
||||
@ -122,6 +175,33 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecCo
|
||||
}
|
||||
}
|
||||
|
||||
static int flv_same_video_codec(AVCodecContext *vcodec, int flags)
|
||||
{
|
||||
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
|
||||
|
||||
if (!vcodec->codec_id && !vcodec->codec_tag)
|
||||
return 1;
|
||||
|
||||
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:
|
||||
return vcodec->codec_id == CODEC_ID_H264;
|
||||
default:
|
||||
return vcodec->codec_tag == flv_codecid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) {
|
||||
AVCodecContext *vcodec = vstream->codec;
|
||||
switch(flv_codecid) {
|
||||
@ -511,7 +591,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;
|
||||
}
|
||||
|
||||
@ -605,11 +685,18 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
/* now find stream */
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user