[Ffmpeg-devel] [PATCH] FLV decoder metadata reading
Michael Niedermayer
michaelni
Mon Dec 11 14:13:22 CET 2006
Hi
On Mon, Dec 11, 2006 at 03:57:14AM -0800, Allan Hsu wrote:
>
> On Dec 11, 2006, at 12:49 AM, Allan Hsu wrote:
>
> [...]
> >>
> >>IMHO these should be set directly in AVCodecContext without the
> >>intermediate
> >>FLVDemuxContext layer
> >
> >Same as above. New patch attached that writes metadata straight
> >into the streams.
>
> After more testing I noticed that files with samplerate but otherwise
> incomplete audio metadata would not decode properly. Here's a fixed
> version of the patch.
[...]
> + case AMF_DATA_TYPE_MIXEDARRAY:
> + url_fskip(ioc, 4); //skip 32-bit max array index
> + while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
> + if(amf_parse_object(s, NULL, NULL, NULL, max_pos) < 0)
> + return -1;
> + }
> + if(get_byte(ioc) != AMF_END_OF_OBJECT)
> + return -1;
> + break;
funny indention ...
[...]
> + else if(!strcmp(key, "width") && vcodec && num_val >= 0) vcodec->width = num_val;
> + else if(!strcmp(key, "height") && vcodec && num_val >= 0) vcodec->height = num_val;
0 width/height isnt valid
[...]
> + else if(!strcmp(key, "audiocodecid")) {
> + switch((int)num_val << FLV_AUDIO_CODECID_OFFSET) {
> + //no distinction between S16 and S8 PCM codec flags
> + case FLV_CODECID_PCM_BE:
> + acodec->codec_id = acodec->bits_per_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16BE; break;
> + case FLV_CODECID_PCM_LE:
> + acodec->codec_id = acodec->bits_per_sample == 8 ? CODEC_ID_PCM_S8 : CODEC_ID_PCM_S16LE; break;
> + case FLV_CODECID_ADPCM: acodec->codec_id = CODEC_ID_ADPCM_SWF; break;
> + case FLV_CODECID_MP3 : acodec->codec_id = CODEC_ID_MP3 ; astream->need_parsing = 1 ; break;
> + case FLV_CODECID_NELLYMOSER_8HZ_MONO:
> + acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate
> + case FLV_CODECID_NELLYMOSER:
> + default:
> + acodec->codec_tag = num_val;
> + }
looking at the code in flv_read_packet():
switch(flags & FLV_AUDIO_CODECID_MASK) {
case FLV_CODECID_PCM_BE: if (flags & FLV_AUDIO_SAMPLESIZE_MASK) st->codec->codec_id = CODEC_ID_PCM_S16BE;
else st->codec->codec_id = CODEC_ID_PCM_S8; break;
case FLV_CODECID_ADPCM : st->codec->codec_id = CODEC_ID_ADPCM_SWF; break;
case FLV_CODECID_MP3 : st->codec->codec_id = CODEC_ID_MP3 ; st->need_parsing = 1; break;
// this is not listed at FLV but at SWF, strange...
case FLV_CODECID_PCM_LE: if (flags & FLV_AUDIO_SAMPLESIZE_MASK) st->codec->codec_id = CODEC_ID_PCM_S16LE;
else st->codec->codec_id = CODEC_ID_PCM_S8; break;
default:
av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flags >> 4);
st->codec->codec_tag= (flags >> 4);
}
this and the case for video too can be simplified by moving the code in
a common function
> + }
> + else if(!strcmp(key, "videocodecid")) {
> + switch((int)num_val) {
> + 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_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; break;
> + default:
> + vcodec->codec_tag = num_val;
> + }
> + }
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int flv_read_metabody(AVFormatContext *s, unsigned int next_pos) {
> + AMFDataType type;
> + AVStream *stream, *astream, *vstream;
> + ByteIOContext *ioc;
> + int i, keylen;
> + unsigned int maxindex;
> + char buffer[256];
> +
> + astream = NULL;
> + vstream = NULL;
> + keylen = 0;
> + ioc = &s->pb;
> +
> + //first object needs to be "onMetaData" string
> + type = get_byte(ioc);
> + if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData") != 0)
> + return -1;
> +
> + //second object needs to be a mixedarray
> + type = get_byte(ioc);
> + if(type != AMF_DATA_TYPE_MIXEDARRAY)
> + return -1;
cant a single amf_parse_object() call be used here instead of the special
case for AMF_DATA_TYPE_MIXEDARRAY with a loop with amf_parse_object() calls?
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Freedom in capitalist society always remains about the same as it was in
ancient Greek republics: Freedom for slave owners. -- Vladimir Lenin
More information about the ffmpeg-devel
mailing list