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)) { > + 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
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel