[FFmpeg-devel] [PATCH] avformat/flacdec: support fast-seek
Michael Niedermayer
michaelni at gmx.at
Sun Oct 4 01:37:27 CEST 2015
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)) {
> + 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151004/fce5890a/attachment.sig>
More information about the ffmpeg-devel
mailing list