X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fflvdec.c;h=0167d17c701db9a2e1b2bd39b3a94b77ba9308b2;hb=857e6667f9061ae261c0b951113e4efc4329b05e;hp=56c932c77cd7e1ebcad4506be391bd15ba451e9e;hpb=0f789322efa78a672e4c3027e5cc12b8a947043a;p=ffmpeg diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 56c932c77cd..0167d17c701 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -717,7 +717,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt, 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; } @@ -817,9 +817,12 @@ 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 || @@ -842,9 +845,13 @@ skip: if (s->pb->seekable && (!s->duration || s->duration == AV_NOPTS_VALUE)) { int size; const int64_t pos = avio_tell(s->pb); + // Read the last 4 bytes of the file, this should be the size of the + // previous FLV tag. Use the timestamp of its payload as duration. const int64_t fsize = avio_size(s->pb); avio_seek(s->pb, fsize - 4, SEEK_SET); size = avio_rb32(s->pb); + // Seek to the start of the last FLV tag at position (fsize - 4 - size) + // but skip the byte indicating the type. avio_seek(s->pb, fsize - 3 - size, SEEK_SET); if (size == avio_rb24(s->pb) + 11) { uint32_t ts = avio_rb24(s->pb); @@ -879,6 +886,7 @@ skip: } 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; }