]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/ifv.c
avformat/avio: Add Metacube support
[ffmpeg] / libavformat / ifv.c
index 03c682bb9d2488a2b6392de40df4b003f896aa14..f82328ada0d1c93f259008f98562b139ec7f061a 100644 (file)
@@ -68,6 +68,8 @@ static int read_index(AVFormatContext *s,
     }
 
     for (i = start_index; i < end_index; i++) {
+        if (avio_feof(s->pb))
+            return AVERROR_EOF;
         pos = avio_rl32(s->pb);
         size = avio_rl32(s->pb);
 
@@ -90,7 +92,10 @@ static int parse_header(AVFormatContext *s)
     uint32_t aud_magic;
     uint32_t vid_magic;
 
-    avio_skip(s->pb, 0x5c);
+    avio_skip(s->pb, 0x34);
+    avpriv_dict_set_timestamp(&s->metadata, "creation_time", avio_rl32(s->pb) * 1000000LL);
+    avio_skip(s->pb, 0x24);
+
     ifv->width = avio_rl16(s->pb);
     ifv->height = avio_rl16(s->pb);
 
@@ -190,21 +195,22 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (ifv->next_video_index < ifv->total_vframes) {
         st = s->streams[ifv->video_stream_index];
-        if (ifv->next_video_index < st->nb_index_entries)
-            e_next = ev = &st->index_entries[ifv->next_video_index];
+        if (ifv->next_video_index < st->internal->nb_index_entries)
+            e_next = ev = &st->internal->index_entries[ifv->next_video_index];
     }
 
     if (ifv->is_audio_present &&
         ifv->next_audio_index < ifv->total_aframes) {
         st = s->streams[ifv->audio_stream_index];
-        if (ifv->next_audio_index < st->nb_index_entries) {
-            ea = &st->index_entries[ifv->next_audio_index];
+        if (ifv->next_audio_index < st->internal->nb_index_entries) {
+            ea = &st->internal->index_entries[ifv->next_audio_index];
             if (!ev || ea->timestamp < ev->timestamp)
                 e_next = ea;
         }
     }
 
     if (!ev) {
+        uint64_t vframes, aframes;
         if (ifv->is_audio_present && !ea) {
             /*read new video and audio indexes*/
 
@@ -212,8 +218,12 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt)
             ifv->next_audio_index = ifv->total_aframes;
 
             avio_skip(s->pb, 0x1c);
-            ifv->total_vframes += avio_rl32(s->pb);
-            ifv->total_aframes += avio_rl32(s->pb);
+            vframes = ifv->total_vframes + (uint64_t)avio_rl32(s->pb);
+            aframes = ifv->total_aframes + (uint64_t)avio_rl32(s->pb);
+            if (vframes > INT_MAX || aframes > INT_MAX)
+                return AVERROR_INVALIDDATA;
+            ifv->total_vframes = vframes;
+            ifv->total_aframes = aframes;
             avio_skip(s->pb, 0xc);
 
             if (avio_feof(s->pb))
@@ -235,7 +245,10 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt)
             ifv->next_video_index = ifv->total_vframes;
 
             avio_skip(s->pb, 0x1c);
-            ifv->total_vframes += avio_rl32(s->pb);
+            vframes = ifv->total_vframes + (uint64_t)avio_rl32(s->pb);
+            if (vframes > INT_MAX)
+                return AVERROR_INVALIDDATA;
+            ifv->total_vframes = vframes;
             avio_skip(s->pb, 0x10);
 
             if (avio_feof(s->pb))
@@ -292,7 +305,7 @@ static int ifv_read_seek(AVFormatContext *s, int stream_index, int64_t ts, int f
     return 0;
 }
 
-AVInputFormat ff_ifv_demuxer = {
+const AVInputFormat ff_ifv_demuxer = {
     .name           = "ifv",
     .long_name      = NULL_IF_CONFIG_SMALL("IFV CCTV DVR"),
     .priv_data_size = sizeof(IFVContext),