summaryrefslogtreecommitdiff
path: root/libavformat/flvdec.c
diff options
context:
space:
mode:
authorAndrew Stone <andrew@clovar.com>2014-08-11 13:35:09 -0400
committerAnton Khirnov <anton@khirnov.net>2014-08-13 16:11:43 +0000
commit93c04e095dc37ebdab22174e88cfa91e24940866 (patch)
treeb1f7b5959ea21a8fff4b3d3ab9eb9dc7bf42c8b9 /libavformat/flvdec.c
parent019d3fccc4dcf5c8379112f697ce9eb08edee9b9 (diff)
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>
Diffstat (limited to 'libavformat/flvdec.c')
-rw-r--r--libavformat/flvdec.c82
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