diff options
author | Andrew Stone <andrew@clovar.com> | 2014-08-11 13:35:09 -0400 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2014-08-13 16:11:43 +0000 |
commit | 93c04e095dc37ebdab22174e88cfa91e24940866 (patch) | |
tree | b1f7b5959ea21a8fff4b3d3ab9eb9dc7bf42c8b9 | |
parent | 019d3fccc4dcf5c8379112f697ce9eb08edee9b9 (diff) | |
download | ffmpeg-93c04e095dc37ebdab22174e88cfa91e24940866.tar.gz |
Expose metadata found in onCuePoint events in .flv files.
Currently, only onMetaData is used, but some providers (wrongly)
put metadata into onCuePoint events, and it's still nice to be
able to use that data.
onCuePoint events also present metadata slightly differently than
onMetaData events: all metadata is found inside an object called
"parameters". In order to extract this metadata, it's easiest to
recurse through the object tree and pull out anything found in
child objects and put it in the top-level metadata.
Reference: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/help.html?content=00001404.html
Signed-off-by: Anton Khirnov <anton@khirnov.net>
-rw-r--r-- | libavformat/flvdec.c | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 034e3468ce..b9391c3796 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -438,45 +438,47 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, return -1; } - // only look for metadata values when we are not nested and key != NULL - if (depth == 1 && key) { - acodec = astream ? astream->codec : NULL; - vcodec = vstream ? vstream->codec : NULL; - - if (amf_type == AMF_DATA_TYPE_NUMBER || - amf_type == AMF_DATA_TYPE_BOOL) { - if (!strcmp(key, "duration")) - s->duration = num_val * AV_TIME_BASE; - else if (!strcmp(key, "videodatarate") && vcodec && - 0 <= (int)(num_val * 1024.0)) - vcodec->bit_rate = num_val * 1024.0; - else if (!strcmp(key, "audiodatarate") && acodec && - 0 <= (int)(num_val * 1024.0)) - acodec->bit_rate = num_val * 1024.0; - else if (!strcmp(key, "datastream")) { - AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_TEXT; - } else if (flv->trust_metadata) { - if (!strcmp(key, "videocodecid") && vcodec) { - flv_set_video_codec(s, vstream, num_val, 0); - } else if (!strcmp(key, "audiocodecid") && acodec) { - int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET; - flv_set_audio_codec(s, astream, acodec, id); - } else if (!strcmp(key, "audiosamplerate") && acodec) { - acodec->sample_rate = num_val; - } else if (!strcmp(key, "audiosamplesize") && acodec) { - acodec->bits_per_coded_sample = num_val; - } else if (!strcmp(key, "stereo") && acodec) { - acodec->channels = num_val + 1; - acodec->channel_layout = acodec->channels == 2 ? - AV_CH_LAYOUT_STEREO : - AV_CH_LAYOUT_MONO; - } else if (!strcmp(key, "width") && vcodec) { - vcodec->width = num_val; - } else if (!strcmp(key, "height") && vcodec) { - vcodec->height = num_val; + if (key) { + // stream info doesn't live any deeper than the first object + if (depth == 1) { + acodec = astream ? astream->codec : NULL; + vcodec = vstream ? vstream->codec : NULL; + + if (amf_type == AMF_DATA_TYPE_NUMBER || + amf_type == AMF_DATA_TYPE_BOOL) { + if (!strcmp(key, "duration")) + s->duration = num_val * AV_TIME_BASE; + else if (!strcmp(key, "videodatarate") && vcodec && + 0 <= (int)(num_val * 1024.0)) + vcodec->bit_rate = num_val * 1024.0; + else if (!strcmp(key, "audiodatarate") && acodec && + 0 <= (int)(num_val * 1024.0)) + acodec->bit_rate = num_val * 1024.0; + else if (!strcmp(key, "datastream")) { + AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA); + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_id = AV_CODEC_ID_TEXT; + } else if (flv->trust_metadata) { + if (!strcmp(key, "videocodecid") && vcodec) { + flv_set_video_codec(s, vstream, num_val, 0); + } else if (!strcmp(key, "audiocodecid") && acodec) { + int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET; + flv_set_audio_codec(s, astream, acodec, id); + } else if (!strcmp(key, "audiosamplerate") && acodec) { + acodec->sample_rate = num_val; + } else if (!strcmp(key, "audiosamplesize") && acodec) { + acodec->bits_per_coded_sample = num_val; + } else if (!strcmp(key, "stereo") && acodec) { + acodec->channels = num_val + 1; + acodec->channel_layout = acodec->channels == 2 ? + AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; + } else if (!strcmp(key, "width") && vcodec) { + vcodec->width = num_val; + } else if (!strcmp(key, "height") && vcodec) { + vcodec->height = num_val; + } } } } @@ -533,7 +535,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) if (!strcmp(buffer, "onTextData")) return 1; - if (strcmp(buffer, "onMetaData")) + if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint")) return -1; // find the streams now so that amf_parse_object doesn't need to do |