]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/flic.c
avformat: Constify all muxer/demuxers
[ffmpeg] / libavformat / flic.c
index d7844ce04f1d1b0dd58126bc5b46bc7afdd175cd..efd9e5430878232c0bc017be6824d4d2e16979d6 100644 (file)
@@ -89,7 +89,7 @@ static int flic_read_header(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     unsigned char header[FLIC_HEADER_SIZE];
     AVStream *st, *ast;
-    int speed;
+    int speed, ret;
     int magic_number;
     unsigned char preamble[FLIC_PREAMBLE_SIZE];
 
@@ -125,8 +125,8 @@ static int flic_read_header(AVFormatContext *s)
     }
 
     /* send over the whole 128-byte FLIC header */
-    if (ff_alloc_extradata(st->codecpar, FLIC_HEADER_SIZE))
-        return AVERROR(ENOMEM);
+    if ((ret = ff_alloc_extradata(st->codecpar, FLIC_HEADER_SIZE)) < 0)
+        return ret;
     memcpy(st->codecpar->extradata, header, FLIC_HEADER_SIZE);
 
     /* peek at the preamble to detect TFTD videos - they seem to always start with an audio chunk */
@@ -175,9 +175,8 @@ static int flic_read_header(AVFormatContext *s)
         avio_seek(pb, 12, SEEK_SET);
 
         /* send over abbreviated FLIC header chunk */
-        av_freep(&st->codecpar->extradata);
-        if (ff_alloc_extradata(st->codecpar, 12))
-            return AVERROR(ENOMEM);
+        if ((ret = ff_alloc_extradata(st->codecpar, 12)) < 0)
+            return ret;
         memcpy(st->codecpar->extradata, header, 12);
 
     } else if (magic_number == FLIC_FILE_MAGIC_1) {
@@ -203,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)) {
 
@@ -216,37 +216,38 @@ static int flic_read_packet(AVFormatContext *s,
         magic = AV_RL16(&preamble[4]);
 
         if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) {
-            if (av_new_packet(pkt, size)) {
-                ret = AVERROR(EIO);
-                break;
-            }
+            if ((ret = av_new_packet(pkt, size)) < 0)
+                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) {
-                av_packet_unref(pkt);
                 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 (av_new_packet(pkt, size)) {
-                ret = AVERROR(EIO);
-                break;
-            }
+            if ((ret = av_new_packet(pkt, size)) < 0)
+                return ret;
 
             /* skip useless 10B sub-header (yes, it's not accounted for in the chunk header) */
             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) {
-                av_packet_unref(pkt);
                 ret = AVERROR(EIO);
+                break;
             }
 
             packet_read = 1;
@@ -259,11 +260,37 @@ static int flic_read_packet(AVFormatContext *s,
     return avio_feof(pb) ? AVERROR_EOF : ret;
 }
 
-AVInputFormat ff_flic_demuxer = {
+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->internal->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->internal->index_entries[index].pos;
+    ts  = st->internal->index_entries[index].timestamp;
+    flic->frame_number = ts;
+    avio_seek(s->pb, pos, SEEK_SET);
+    return 0;
+}
+
+const AVInputFormat ff_flic_demuxer = {
     .name           = "flic",
     .long_name      = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation"),
     .priv_data_size = sizeof(FlicDemuxContext),
     .read_probe     = flic_probe,
     .read_header    = flic_read_header,
     .read_packet    = flic_read_packet,
+    .read_seek      = flic_read_seek,
 };