]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/segafilm.c
reverse zero packet dissapearence "feature"
[ffmpeg] / libavformat / segafilm.c
index 818c0d3d8203e0880cb50ce89eaa1fccf26547f5..d984a3b10bc247ca12c24404611688517d6c7ed1 100644 (file)
 
 #include "avformat.h"
 
-#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
-#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \
-                   (((uint8_t*)(x))[1] << 16) | \
-                   (((uint8_t*)(x))[2] << 8) | \
-                    ((uint8_t*)(x))[3])
-
-#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
-        ( (long)(unsigned char)(ch3) | \
-        ( (long)(unsigned char)(ch2) << 8 ) | \
-        ( (long)(unsigned char)(ch1) << 16 ) | \
-        ( (long)(unsigned char)(ch0) << 24 ) )
-
-#define FILM_TAG FOURCC_TAG('F', 'I', 'L', 'M')
-#define FDSC_TAG FOURCC_TAG('F', 'D', 'S', 'C')
-#define STAB_TAG FOURCC_TAG('S', 'T', 'A', 'B')
-#define CVID_TAG FOURCC_TAG('c', 'v', 'i', 'd')
+#define FILM_TAG MKBETAG('F', 'I', 'L', 'M')
+#define FDSC_TAG MKBETAG('F', 'D', 'S', 'C')
+#define STAB_TAG MKBETAG('S', 'T', 'A', 'B')
+#define CVID_TAG MKBETAG('c', 'v', 'i', 'd')
 
 typedef struct {
   int stream;
-  off_t sample_offset;
+  offset_t sample_offset;
   unsigned int sample_size;
   int64_t pts;
   int keyframe;
@@ -104,7 +92,7 @@ static int film_read_header(AVFormatContext *s,
 
     /* load the main FILM header */
     if (get_buffer(pb, scratch, 16) != 16)
-        return -EIO;
+        return AVERROR_IO;
     data_offset = BE_32(&scratch[4]);
     film->version = BE_32(&scratch[8]);
 
@@ -112,7 +100,7 @@ static int film_read_header(AVFormatContext *s,
     if (film->version == 0) {
         /* special case for Lemmings .film files; 20-byte header */
         if (get_buffer(pb, scratch, 20) != 20)
-            return -EIO;
+            return AVERROR_IO;
         /* make some assumptions about the audio parameters */
         film->audio_type = CODEC_ID_PCM_S8;
         film->audio_samplerate = 22050;
@@ -121,7 +109,7 @@ static int film_read_header(AVFormatContext *s,
     } else {
         /* normal Saturn .cpk files; 32-byte header */
         if (get_buffer(pb, scratch, 32) != 32)
-            return -EIO;
+            return AVERROR_IO;
         film->audio_samplerate = BE_16(&scratch[24]);;
         film->audio_channels = scratch[21];
         film->audio_bits = scratch[22];
@@ -178,19 +166,24 @@ static int film_read_header(AVFormatContext *s,
 
     /* load the sample table */
     if (get_buffer(pb, scratch, 16) != 16)
-        return -EIO;
+        return AVERROR_IO;
     if (BE_32(&scratch[0]) != STAB_TAG)
         return AVERROR_INVALIDDATA;
     film->base_clock = BE_32(&scratch[8]);
     film->sample_count = BE_32(&scratch[12]);
+    if(film->sample_count >= UINT_MAX / sizeof(film_sample_t))
+        return -1;
     film->sample_table = av_malloc(film->sample_count * sizeof(film_sample_t));
     
+    for(i=0; i<s->nb_streams; i++)
+        av_set_pts_info(s->streams[i], 33, 1, film->base_clock);
+    
     audio_frame_counter = 0;
     for (i = 0; i < film->sample_count; i++) {
         /* load the next sample record and transfer it to an internal struct */
         if (get_buffer(pb, scratch, 16) != 16) {
             av_free(film->sample_table);
-            return -EIO;
+            return AVERROR_IO;
         }
         film->sample_table[i].sample_offset = 
             data_offset + BE_32(&scratch[0]);
@@ -212,10 +205,6 @@ static int film_read_header(AVFormatContext *s,
 
     film->current_sample = 0;
 
-    /* set the pts reference to match the tick rate of the file */
-    s->pts_num = 1;
-    s->pts_den = film->base_clock;
-
     return 0;
 }
 
@@ -230,7 +219,7 @@ static int film_read_packet(AVFormatContext *s,
     int left, right;
 
     if (film->current_sample >= film->sample_count)
-        return -EIO;
+        return AVERROR_IO;
 
     sample = &film->sample_table[film->current_sample];
 
@@ -242,13 +231,15 @@ static int film_read_packet(AVFormatContext *s,
         (film->video_type == CODEC_ID_CINEPAK)) {
         if (av_new_packet(pkt, sample->sample_size - film->cvid_extra_bytes))
             return AVERROR_NOMEM;
+        if(pkt->size < 10)
+            return -1;
         ret = get_buffer(pb, pkt->data, 10);
         /* skip the non-spec CVID bytes */
         url_fseek(pb, film->cvid_extra_bytes, SEEK_CUR);
         ret += get_buffer(pb, pkt->data + 10, 
             sample->sample_size - 10 - film->cvid_extra_bytes);
         if (ret != sample->sample_size - film->cvid_extra_bytes)
-            ret = -EIO;
+            ret = AVERROR_IO;
     } else if ((sample->stream == film->audio_stream_index) &&
         (film->audio_channels == 2)) {
         /* stereo PCM needs to be interleaved */
@@ -265,7 +256,7 @@ static int film_read_packet(AVFormatContext *s,
 
         ret = get_buffer(pb, film->stereo_buffer, sample->sample_size);
         if (ret != sample->sample_size)
-            ret = -EIO;
+            ret = AVERROR_IO;
 
         left = 0;
         right = sample->sample_size / 2;
@@ -285,7 +276,7 @@ static int film_read_packet(AVFormatContext *s,
             return AVERROR_NOMEM;
         ret = get_buffer(pb, pkt->data, sample->sample_size);
         if (ret != sample->sample_size)
-            ret = -EIO;
+            ret = AVERROR_IO;
     }
 
     pkt->stream_index = sample->stream;