aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrent Nelson <trent.a.b.nelson@gmail.com>2014-04-15 11:55:01 -0600
committerTrent Nelson <trent.a.b.nelson@gmail.com>2014-04-15 12:16:35 -0600
commit3eb113857c64e5bb4d2f60c32e722427414d8949 (patch)
treec44108b5b24dabc236932f29bb0d9358eb0d6884
parentafc7ecfb6c9905c71ee07fcbc5a3ad425f6716ab (diff)
Merge pull request #4562 from FernetMenta/flac
ffmpeg backport: improve seeking in flac files
-rw-r--r--lib/ffmpeg/libavcodec/flac_parser.c8
-rw-r--r--lib/ffmpeg/libavformat/flacdec.c45
-rw-r--r--lib/ffmpeg/patches/0072-flac-demuxer-improve-seeking.patch94
3 files changed, 147 insertions, 0 deletions
diff --git a/lib/ffmpeg/libavcodec/flac_parser.c b/lib/ffmpeg/libavcodec/flac_parser.c
index e2c6744d78..0b7bf9b70c 100644
--- a/lib/ffmpeg/libavcodec/flac_parser.c
+++ b/lib/ffmpeg/libavcodec/flac_parser.c
@@ -468,6 +468,14 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
+
+ if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
+ if (header->fi.is_var_size)
+ fpc->pc->pts = header->fi.frame_or_sample_num;
+ else if (header->best_child)
+ fpc->pc->pts = header->fi.frame_or_sample_num * header->fi.blocksize;
+ }
+
fpc->best_header_valid = 0;
/* Return the negative overread index so the client can compute pos.
This should be the amount overread to the beginning of the child */
diff --git a/lib/ffmpeg/libavformat/flacdec.c b/lib/ffmpeg/libavformat/flacdec.c
index ecc47e6ccd..66c8809ece 100644
--- a/lib/ffmpeg/libavformat/flacdec.c
+++ b/lib/ffmpeg/libavformat/flacdec.c
@@ -284,12 +284,57 @@ static int flac_probe(AVProbeData *p)
else return AVPROBE_SCORE_MAX/2;
}
+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];
+ int ret;
+
+ if (avio_seek(s->pb, *ppos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+
+ av_init_packet(&pkt);
+ st->parser = av_parser_init(st->codec->codec_id);
+ if (!st->parser){
+ return AV_NOPTS_VALUE;
+ }
+ st->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
+ return AV_NOPTS_VALUE;
+ }
+ av_init_packet(&out_pkt);
+ ret = av_parser_parse2(st->parser, st->codec,
+ &out_pkt.data, &out_pkt.size, pkt.data, pkt.size,
+ pkt.pts, pkt.dts, *ppos);
+
+ if (out_pkt.size){
+ int size = out_pkt.size;
+ av_free_packet(&out_pkt);
+ if (st->parser->pts != AV_NOPTS_VALUE){
+ // seeking may not have started from beginning of a frame
+ // calculate frame start position from next frame backwards
+ *ppos = st->parser->next_frame_offset - size;
+ return st->parser->pts;
+ }
+ }
+ }
+ return AV_NOPTS_VALUE;
+}
+
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_timestamp = flac_read_timestamp,
.flags = AVFMT_GENERIC_INDEX,
.extensions = "flac",
.raw_codec_id = AV_CODEC_ID_FLAC,
diff --git a/lib/ffmpeg/patches/0072-flac-demuxer-improve-seeking.patch b/lib/ffmpeg/patches/0072-flac-demuxer-improve-seeking.patch
new file mode 100644
index 0000000000..a6b64887c7
--- /dev/null
+++ b/lib/ffmpeg/patches/0072-flac-demuxer-improve-seeking.patch
@@ -0,0 +1,94 @@
+From 0c510ff6acea4a9afc049006ad8a173256aa8290 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 12 Apr 2014 18:13:32 +0200
+Subject: [PATCH] flac demuxer: improve seeking
+
+---
+ lib/ffmpeg/libavcodec/flac_parser.c | 8 +++++++
+ lib/ffmpeg/libavformat/flacdec.c | 45 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+)
+
+diff --git a/lib/ffmpeg/libavcodec/flac_parser.c b/lib/ffmpeg/libavcodec/flac_parser.c
+index e2c6744..0b7bf9b 100644
+--- a/lib/ffmpeg/libavcodec/flac_parser.c
++++ b/lib/ffmpeg/libavcodec/flac_parser.c
+@@ -468,6 +468,14 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
+ &fpc->wrap_buf,
+ &fpc->wrap_buf_allocated_size);
+
++
++ if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
++ if (header->fi.is_var_size)
++ fpc->pc->pts = header->fi.frame_or_sample_num;
++ else if (header->best_child)
++ fpc->pc->pts = header->fi.frame_or_sample_num * header->fi.blocksize;
++ }
++
+ fpc->best_header_valid = 0;
+ /* Return the negative overread index so the client can compute pos.
+ This should be the amount overread to the beginning of the child */
+diff --git a/lib/ffmpeg/libavformat/flacdec.c b/lib/ffmpeg/libavformat/flacdec.c
+index ecc47e6..66c8809 100644
+--- a/lib/ffmpeg/libavformat/flacdec.c
++++ b/lib/ffmpeg/libavformat/flacdec.c
+@@ -284,12 +284,57 @@ static int flac_probe(AVProbeData *p)
+ else return AVPROBE_SCORE_MAX/2;
+ }
+
++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];
++ int ret;
++
++ if (avio_seek(s->pb, *ppos, SEEK_SET) < 0)
++ return AV_NOPTS_VALUE;
++
++ av_init_packet(&pkt);
++ st->parser = av_parser_init(st->codec->codec_id);
++ if (!st->parser){
++ return AV_NOPTS_VALUE;
++ }
++ st->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
++ return AV_NOPTS_VALUE;
++ }
++ av_init_packet(&out_pkt);
++ ret = av_parser_parse2(st->parser, st->codec,
++ &out_pkt.data, &out_pkt.size, pkt.data, pkt.size,
++ pkt.pts, pkt.dts, *ppos);
++
++ if (out_pkt.size){
++ int size = out_pkt.size;
++ av_free_packet(&out_pkt);
++ if (st->parser->pts != AV_NOPTS_VALUE){
++ // seeking may not have started from beginning of a frame
++ // calculate frame start position from next frame backwards
++ *ppos = st->parser->next_frame_offset - size;
++ return st->parser->pts;
++ }
++ }
++ }
++ return AV_NOPTS_VALUE;
++}
++
+ 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_timestamp = flac_read_timestamp,
+ .flags = AVFMT_GENERIC_INDEX,
+ .extensions = "flac",
+ .raw_codec_id = AV_CODEC_ID_FLAC,
+--
+1.9.1
+