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;
+ }
}
}
}
!strcmp(key, "datastream"))
return 0;
+ s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
if (amf_type == AMF_DATA_TYPE_BOOL) {
av_strlcpy(str_val, num_val > 0 ? "true" : "false",
sizeof(str_val));
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
avio_skip(s->pb, 4);
flags = avio_r8(s->pb);
- /* old flvtool cleared this field */
- /* FIXME: better fix needed */
- if (!flags) {
- flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
- av_log(s, AV_LOG_WARNING,
- "Broken FLV file, which says no streams present, "
- "this might fail\n");
- }
s->ctx_flags |= AVFMTCTX_NOHEADER;
if (i == s->nb_streams) {
st = create_stream(s, AVMEDIA_TYPE_DATA);
if (!st)
- return AVERROR_INVALIDDATA;
+ return AVERROR(ENOMEM);
st->codec->codec_id = AV_CODEC_ID_TEXT;
}
return flv_data_packet(s, pkt, dts, next);
} else /* skip packet */
av_log(s, AV_LOG_DEBUG,
- "skipping flv packet: type %d, size %d, flags %d\n",
+ "Skipping flv packet: type %d, size %d, flags %d.\n",
type, size, flags);
skip:
break;
}
}
- if (i == s->nb_streams)
+ if (i == s->nb_streams) {
st = create_stream(s, is_audio ? AVMEDIA_TYPE_AUDIO
: AVMEDIA_TYPE_VIDEO);
+ if (!st)
+ return AVERROR(ENOMEM);
+ }
av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
+
+ if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
+ is_audio)
+ av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
+
if ((st->discard >= AVDISCARD_NONKEY &&
!((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || is_audio)) ||
(st->discard >= AVDISCARD_BIDIR &&
avio_seek(s->pb, next, SEEK_SET);
continue;
}
- if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)
- av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
break;
}
} else {
AVCodecContext ctx;
ctx.sample_rate = sample_rate;
+ ctx.bits_per_coded_sample = bits_per_coded_sample;
flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
sample_rate = ctx.sample_rate;
}
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = dts + cts;
- if (cts < 0) { // dts are wrong
+ if (cts < 0 && !flv->wrong_dts) { // dts might be wrong
flv->wrong_dts = 1;
av_log(s, AV_LOG_WARNING,
- "negative cts, previous timestamps might be wrong\n");
+ "Negative cts, previous timestamps might be wrong.\n");
}
- if (flv->wrong_dts)
- dts = AV_NOPTS_VALUE;
}
if (type == 0) {
if (st->codec->extradata) {
return ret;
if (st->codec->codec_id == AV_CODEC_ID_AAC) {
MPEG4AudioConfig cfg;
+
+ /* Workaround for buggy Omnia A/XE encoder */
+ AVDictionaryEntry *t = av_dict_get(s->metadata, "Encoder", NULL, 0);
+ if (t && !strcmp(t->value, "Omnia A/XE"))
+ st->codec->extradata_size = 2;
+
avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
st->codec->extradata_size * 8, 1);
st->codec->channels = cfg.channels;