On Sun, Oct 4, 2015 at 1:37 AM, Michael Niedermayer <michae...@gmx.at> wrote: > On Sat, Oct 03, 2015 at 01:14:26AM +0800, Ching-Yi Chan wrote: >> Here is a new patch: >> >> 1. fix compilation warning >> 2. remove ff_ prefix on my patch >> 3. toggle AVFMT_FLAG_FAST_SEEK when no seektalbe in the flac metadata (this >> will disable flac_seek when no seekpoint) > >> flacdec.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 57 insertions(+), 2 deletions(-) >> caa7d32b430da96d0dc377dbe7fe8518e872d132 >> 0001-avformat-flacdec-support-fast-seek.patch >> From ac4c0a99f87c31ac510772172fc13ad82955c0d6 Mon Sep 17 00:00:00 2001 >> From: "Ching Yi, Chan" <chingyichan...@gmail.com> >> Date: Thu, 24 Sep 2015 13:04:40 +0800 >> Subject: [PATCH] avformat/flacdec: support fast-seek >> >> --- >> libavformat/flacdec.c | 59 >> +++++++++++++++++++++++++++++++++++++++++++++++- >> 1 files changed, 57 insertions(+), 2 deletions(-) >> >> diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c >> index 4c1f943..3fdbccc 100644 >> --- a/libavformat/flacdec.c >> +++ b/libavformat/flacdec.c >> @@ -28,9 +28,20 @@ >> #include "vorbiscomment.h" >> #include "replaygain.h" >> >> +#define SEEKPOINT_SIZE 18 >> + >> +static void reset_index_position(int64_t metadata_head_size, AVStream *st) >> +{ >> + /* the real seek index offset should be the size of metadata blocks >> with the offset in the frame blocks */ >> + int i; >> + for(i=0; i<st->nb_index_entries; i++) { >> + st->index_entries[i].pos += metadata_head_size; >> + } >> +} >> + >> static int flac_read_header(AVFormatContext *s) >> { >> - int ret, metadata_last=0, metadata_type, metadata_size, >> found_streaminfo=0; >> + int ret, metadata_last=0, metadata_type, metadata_size, >> found_streaminfo=0, found_seektable=0; >> uint8_t header[4]; >> uint8_t *buffer=NULL; >> AVStream *st = avformat_new_stream(s, NULL); >> @@ -58,6 +69,7 @@ static int flac_read_header(AVFormatContext *s) >> case FLAC_METADATA_TYPE_CUESHEET: >> case FLAC_METADATA_TYPE_PICTURE: >> case FLAC_METADATA_TYPE_VORBIS_COMMENT: >> + case FLAC_METADATA_TYPE_SEEKTABLE: >> buffer = av_mallocz(metadata_size + >> AV_INPUT_BUFFER_PADDING_SIZE); >> if (!buffer) { >> return AVERROR(ENOMEM); >> @@ -132,7 +144,23 @@ static int flac_read_header(AVFormatContext *s) >> av_log(s, AV_LOG_ERROR, "Error parsing attached >> picture.\n"); >> return ret; >> } >> - } else { >> + } else if (metadata_type == FLAC_METADATA_TYPE_SEEKTABLE) { >> + const uint8_t *seekpoint = buffer; >> + int i, seek_point_count = metadata_size/SEEKPOINT_SIZE; >> + found_seektable = 1; >> + if ((s->flags&AVFMT_FLAG_FAST_SEEK)) {
Parsing the seektable should be independent of that flag, no? Its surely still useful even if you do an accurate seek, is it not? >> + for(i=0; i<seek_point_count; i++) { >> + int64_t timestamp = bytestream_get_be64(&seekpoint); >> + int64_t pos = bytestream_get_be64(&seekpoint); >> + /* skip number of samples */ >> + bytestream_get_be16(&seekpoint); >> + av_add_index_entry(st, pos, timestamp, 0, 0, >> AVINDEX_KEYFRAME); >> + } >> + } >> + av_freep(&buffer); >> + } >> + else { >> + >> /* STREAMINFO must be the first block */ >> if (!found_streaminfo) { >> RETURN_ERROR(AVERROR_INVALIDDATA); > >> @@ -169,6 +197,12 @@ static int flac_read_header(AVFormatContext *s) >> if (ret < 0) >> return ret; >> >> + if (!found_seektable) { >> + s->flags &= ~AVFMT_FLAG_FAST_SEEK; >> + av_log(s, AV_LOG_WARNING, "seektable not found, disable >> AVFMT_FLAG_FAST_SEEK flag\n"); >> + } > > iam not sure changing the format flags is a great idea, i think no > other demuxer does that > that said, the documentation does not say that only the user can > change them so this is more a note that this looks a bit odd not that > it is wrong > > >> + >> + reset_index_position(avio_tell(s->pb), st); >> return 0; >> >> fail: >> @@ -249,12 +283,33 @@ static av_unused int64_t >> flac_read_timestamp(AVFormatContext *s, int stream_inde >> return pts; >> } >> >> +static int flac_seek(AVFormatContext *s, int stream_index, int64_t >> timestamp, int flags) { >> + int index; >> + int64_t pos; >> + AVIndexEntry e; >> + if (!(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 pos; > > if pos is larger than INT_MAX the this can overflow and be interpreted > as an error by the caller > > >> + } >> + return -1; >> +} >> + >> AVInputFormat ff_flac_demuxer = { >> .name = "flac", >> .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"), >> .read_probe = flac_probe, >> .read_header = flac_read_header, >> .read_packet = ff_raw_read_partial_packet, >> + .read_seek = flac_seek, >> .read_timestamp = flac_read_timestamp, >> .flags = AVFMT_GENERIC_INDEX, >> .extensions = "flac", >> -- >> 1.7.7 >> > >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Observe your enemies, for they first find out your faults. -- Antisthenes > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel