aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-09-10 13:55:50 +0200
committerPaul B Mahol <onemda@gmail.com>2020-09-13 16:05:01 +0200
commit2752323046a48003d7046cc662a8835bbf65de5c (patch)
treeafbced5dd09edf35f9a69d3d0c4daacda1c40100 /libavformat
parente1da139a331de753867dc3af2da0d8341f9d2ed5 (diff)
downloadffmpeg-2752323046a48003d7046cc662a8835bbf65de5c.tar.gz
avformat/flic: add support for seeking to start
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/flic.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/libavformat/flic.c b/libavformat/flic.c
index e65c157777..4552bff69c 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -202,6 +202,7 @@ static int flic_read_packet(AVFormatContext *s,
int magic;
int ret = 0;
unsigned char preamble[FLIC_PREAMBLE_SIZE];
+ int64_t pos = avio_tell(pb);
while (!packet_read && !avio_feof(pb)) {
@@ -219,15 +220,19 @@ static int flic_read_packet(AVFormatContext *s,
return ret;
pkt->stream_index = flic->video_stream_index;
- pkt->pts = flic->frame_number++;
- pkt->pos = avio_tell(pb);
+ pkt->pos = pos;
memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE);
ret = avio_read(pb, pkt->data + FLIC_PREAMBLE_SIZE,
size - FLIC_PREAMBLE_SIZE);
if (ret != size - FLIC_PREAMBLE_SIZE) {
ret = AVERROR(EIO);
}
+ pkt->flags = flic->frame_number == 0 ? AV_PKT_FLAG_KEY : 0;
+ pkt->pts = flic->frame_number;
+ if (flic->frame_number == 0)
+ av_add_index_entry(s->streams[flic->video_stream_index], pkt->pos, pkt->pts, pkt->size, 0, AVINDEX_KEYFRAME);
packet_read = 1;
+ flic->frame_number++;
} else if (magic == FLIC_TFTD_CHUNK_AUDIO) {
if ((ret = av_new_packet(pkt, size)) < 0)
return ret;
@@ -236,7 +241,8 @@ static int flic_read_packet(AVFormatContext *s,
avio_skip(pb, 10);
pkt->stream_index = flic->audio_stream_index;
- pkt->pos = avio_tell(pb);
+ pkt->pos = pos;
+ pkt->flags = AV_PKT_FLAG_KEY;
ret = avio_read(pb, pkt->data, size);
if (ret != size) {
@@ -254,6 +260,31 @@ static int flic_read_packet(AVFormatContext *s,
return avio_feof(pb) ? AVERROR_EOF : ret;
}
+static int flic_read_seek(AVFormatContext *s, int stream_index,
+ int64_t pts, int flags)
+{
+ FlicDemuxContext *flic = s->priv_data;
+ AVStream *st = s->streams[stream_index];
+ int64_t pos, ts;
+ int index;
+
+ if (!st->index_entries || stream_index != flic->video_stream_index)
+ return -1;
+
+ index = av_index_search_timestamp(st, pts, flags);
+
+ if (index < 0)
+ index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD);
+ if (index < 0)
+ return -1;
+
+ pos = st->index_entries[index].pos;
+ ts = st->index_entries[index].timestamp;
+ flic->frame_number = ts;
+ avio_seek(s->pb, pos, SEEK_SET);
+ return 0;
+}
+
AVInputFormat ff_flic_demuxer = {
.name = "flic",
.long_name = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation"),
@@ -261,4 +292,5 @@ AVInputFormat ff_flic_demuxer = {
.read_probe = flic_probe,
.read_header = flic_read_header,
.read_packet = flic_read_packet,
+ .read_seek = flic_read_seek,
};