ffmpeg | branch: master | Clément Bœsch <u...@pkh.me> | Wed Mar 15 23:16:23 2017 +0100| [e887d685f74197cda153c0ec57f9cb719a33932b] | committer: Clément Bœsch
Merge commit 'ed1cd81076434b76f37576d4d806973476a8e96c' * commit 'ed1cd81076434b76f37576d4d806973476a8e96c': flac demuxer: improve probing Suggested commit very closely matches our code, except with regards to AVPROBE_SCORE_EXTENSION. The code layout is mostly merged but preserves our behaviour. Merged-by: Clément Bœsch <u...@pkh.me> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e887d685f74197cda153c0ec57f9cb719a33932b --- libavformat/flacdec.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index fee46fc..a032378 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -231,16 +231,27 @@ static int flac_probe(AVProbeData *p) { if ((AV_RB16(p->buf) & 0xFFFE) == 0xFFF8) return raw_flac_probe(p); - if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) - return 0; - if ( p->buf[4] & 0x7f != FLAC_METADATA_TYPE_STREAMINFO - || AV_RB24(p->buf + 5) != FLAC_STREAMINFO_SIZE - || AV_RB16(p->buf + 8) < 16 - || AV_RB16(p->buf + 8) > AV_RB16(p->buf + 10) - || !(AV_RB24(p->buf + 18) >> 4) - || AV_RB24(p->buf + 18) >> 4 > 655350) + + /* file header + metadata header + checked bytes of streaminfo */ + if (p->buf_size >= 4 + 4 + 13) { + int type = p->buf[4] & 0x7f; + int size = AV_RB24(p->buf + 5); + int min_block_size = AV_RB16(p->buf + 8); + int max_block_size = AV_RB16(p->buf + 10); + int sample_rate = AV_RB24(p->buf + 18) >> 4; + + if (memcmp(p->buf, "fLaC", 4)) + return 0; + if (type == FLAC_METADATA_TYPE_STREAMINFO && + size == FLAC_STREAMINFO_SIZE && + min_block_size >= 16 && + max_block_size >= min_block_size && + sample_rate && sample_rate <= 655350) + return AVPROBE_SCORE_MAX; return AVPROBE_SCORE_EXTENSION; - return AVPROBE_SCORE_MAX; + } + + return 0; } static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index, ====================================================================== diff --cc libavformat/flacdec.c index fee46fc,2f4ac56..a032378 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@@ -229,93 -177,26 +229,104 @@@ static int raw_flac_probe(AVProbeData * static int flac_probe(AVProbeData *p) { + if ((AV_RB16(p->buf) & 0xFFFE) == 0xFFF8) + return raw_flac_probe(p); - if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) - return 0; - if ( p->buf[4] & 0x7f != FLAC_METADATA_TYPE_STREAMINFO - || AV_RB24(p->buf + 5) != FLAC_STREAMINFO_SIZE - || AV_RB16(p->buf + 8) < 16 - || AV_RB16(p->buf + 8) > AV_RB16(p->buf + 10) - || !(AV_RB24(p->buf + 18) >> 4) - || AV_RB24(p->buf + 18) >> 4 > 655350) ++ + /* file header + metadata header + checked bytes of streaminfo */ + if (p->buf_size >= 4 + 4 + 13) { + int type = p->buf[4] & 0x7f; + int size = AV_RB24(p->buf + 5); + int min_block_size = AV_RB16(p->buf + 8); + int max_block_size = AV_RB16(p->buf + 10); + int sample_rate = AV_RB24(p->buf + 18) >> 4; + - if (!memcmp(p->buf, "fLaC", 4) && - type == FLAC_METADATA_TYPE_STREAMINFO && ++ if (memcmp(p->buf, "fLaC", 4)) ++ return 0; ++ if (type == FLAC_METADATA_TYPE_STREAMINFO && + size == FLAC_STREAMINFO_SIZE && + min_block_size >= 16 && + max_block_size >= min_block_size && + sample_rate && sample_rate <= 655350) + return AVPROBE_SCORE_MAX; + return AVPROBE_SCORE_EXTENSION; - return AVPROBE_SCORE_MAX; + } + + return 0; } +static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index, + int64_t *ppos, int64_t pos_limit) +{ + AVPacket pkt, out_pkt; + AVStream *st = s->streams[stream_index]; + AVCodecParserContext *parser; + int ret; + int64_t pts = AV_NOPTS_VALUE; + + if (avio_seek(s->pb, *ppos, SEEK_SET) < 0) + return AV_NOPTS_VALUE; + + av_init_packet(&pkt); + parser = av_parser_init(st->codecpar->codec_id); + if (!parser){ + return AV_NOPTS_VALUE; + } + parser->flags |= PARSER_FLAG_USE_CODEC_TS; + + for (;;){ + ret = ff_raw_read_partial_packet(s, &pkt); + if (ret < 0){ + if (ret == AVERROR(EAGAIN)) + continue; + else { + av_packet_unref(&pkt); + av_assert1(!pkt.size); + } + } + av_init_packet(&out_pkt); + av_parser_parse2(parser, st->internal->avctx, + &out_pkt.data, &out_pkt.size, pkt.data, pkt.size, + pkt.pts, pkt.dts, *ppos); + + av_packet_unref(&pkt); + if (out_pkt.size){ + int size = out_pkt.size; + if (parser->pts != AV_NOPTS_VALUE){ + // seeking may not have started from beginning of a frame + // calculate frame start position from next frame backwards + *ppos = parser->next_frame_offset - size; + pts = parser->pts; + break; + } + } else if (ret < 0) + break; + } + av_parser_close(parser); + return pts; +} + +static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { + int index; + int64_t pos; + AVIndexEntry e; + FLACDecContext *flac = s->priv_data; + + if (!flac->found_seektable || !(s->flags&AVFMT_FLAG_FAST_SEEK)) { + return -1; + } + + index = av_index_search_timestamp(s->streams[0], timestamp, flags); + if(index<0 || index >= s->streams[0]->nb_index_entries) + return -1; + + e = s->streams[0]->index_entries[index]; + pos = avio_seek(s->pb, e.pos, SEEK_SET); + if (pos >= 0) { + return 0; + } + return -1; +} + AVInputFormat ff_flac_demuxer = { .name = "flac", .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"), _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog