[FFmpeg-devel] [PATCH] avformat/flacdec: support fast-seek
Hendrik Leppkes
h.leppkes at gmail.com
Sun Oct 4 02:02:12 CEST 2015
On Sun, Oct 4, 2015 at 1:37 AM, Michael Niedermayer <michaelni at 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.tw at 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 at 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 at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
More information about the ffmpeg-devel
mailing list