]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/iff.c
lavf: Remove "Adjusting PTS forward" code
[ffmpeg] / libavformat / iff.c
index c8936d3cb2e44045951e2157a8a02def034df1bb..0e945da7a30379d8da2715a1089557a90247f7de 100644 (file)
@@ -38,6 +38,9 @@
 
 #define ID_8SVX       MKTAG('8','S','V','X')
 #define ID_16SV       MKTAG('1','6','S','V')
+#define ID_MAUD       MKTAG('M','A','U','D')
+#define ID_MHDR       MKTAG('M','H','D','R')
+#define ID_MDAT       MKTAG('M','D','A','T')
 #define ID_VHDR       MKTAG('V','H','D','R')
 #define ID_ATAK       MKTAG('A','T','A','K')
 #define ID_RLSE       MKTAG('R','L','S','E')
@@ -50,6 +53,8 @@
 #define ID_CMAP       MKTAG('C','M','A','P')
 #define ID_ACBM       MKTAG('A','C','B','M')
 #define ID_DEEP       MKTAG('D','E','E','P')
+#define ID_RGB8       MKTAG('R','G','B','8')
+#define ID_RGBN       MKTAG('R','G','B','N')
 
 #define ID_FORM       MKTAG('F','O','R','M')
 #define ID_ANNO       MKTAG('A','N','N','O')
@@ -65,6 +70,7 @@
 #define ID_DBOD       MKTAG('D','B','O','D')
 #define ID_DPEL       MKTAG('D','P','E','L')
 #define ID_DLOC       MKTAG('D','L','O','C')
+#define ID_TVDC       MKTAG('T','V','D','C')
 
 #define LEFT    2
 #define RIGHT   4
@@ -78,7 +84,7 @@
  * set it to smallest possible size of 2 to indicate that there's
  * no extradata changing in this frame.
  */
-#define IFF_EXTRA_VIDEO_SIZE 9
+#define IFF_EXTRA_VIDEO_SIZE 41
 
 typedef enum {
     COMP_NONE,
@@ -91,12 +97,15 @@ typedef struct {
     uint32_t  body_size;
     uint32_t  sent_bytes;
     svx8_compression_type   svx8_compression;
+    unsigned  maud_bits;
+    unsigned  maud_compression;
     unsigned  bitmap_compression;  ///< delta compression method used
     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
     unsigned  transparency; ///< transparency color index in palette
     unsigned  masking;      ///< masking method used
+    uint8_t   tvdc[32];     ///< TVDC lookup table
 } IffDemuxContext;
 
 /* Metadata string read */
@@ -125,10 +134,13 @@ static int iff_probe(AVProbeData *p)
     if (  AV_RL32(d)   == ID_FORM &&
          (AV_RL32(d+8) == ID_8SVX ||
           AV_RL32(d+8) == ID_16SV ||
+          AV_RL32(d+8) == ID_MAUD ||
           AV_RL32(d+8) == ID_PBM  ||
           AV_RL32(d+8) == ID_ACBM ||
           AV_RL32(d+8) == ID_DEEP ||
-          AV_RL32(d+8) == ID_ILBM) )
+          AV_RL32(d+8) == ID_ILBM ||
+          AV_RL32(d+8) == ID_RGB8 ||
+          AV_RL32(d+8) == ID_RGBN) )
         return AVPROBE_SCORE_MAX;
     return 0;
 }
@@ -146,7 +158,7 @@ static int iff_read_header(AVFormatContext *s)
     AVStream *st;
     uint8_t *buf;
     uint32_t chunk_id, data_size;
-    uint32_t screenmode = 0;
+    uint32_t screenmode = 0, num, den;
     unsigned transparency = 0;
     unsigned masking = 0; // no mask
     uint8_t fmt[16];
@@ -161,6 +173,10 @@ static int iff_read_header(AVFormatContext *s)
     avio_skip(pb, 8);
     // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
     st->codec->codec_tag = avio_rl32(pb);
+    iff->bitmap_compression = -1;
+    iff->svx8_compression = -1;
+    iff->maud_bits = -1;
+    iff->maud_compression = -1;
 
     while(!url_feof(pb)) {
         uint64_t orig_pos;
@@ -184,9 +200,32 @@ static int iff_read_header(AVFormatContext *s)
             }
             break;
 
+        case ID_MHDR:
+            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+
+            if (data_size < 32)
+                return AVERROR_INVALIDDATA;
+            avio_skip(pb, 4);
+            iff->maud_bits = avio_rb16(pb);
+            avio_skip(pb, 2);
+            num = avio_rb32(pb);
+            den = avio_rb16(pb);
+            if (!den)
+                return AVERROR_INVALIDDATA;
+            avio_skip(pb, 2);
+            st->codec->sample_rate = num / den;
+            st->codec->channels = avio_rb16(pb);
+            iff->maud_compression = avio_rb16(pb);
+            if (st->codec->channels == 1)
+                st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+            else if (st->codec->channels == 2)
+                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+            break;
+
         case ID_ABIT:
         case ID_BODY:
         case ID_DBOD:
+        case ID_MDAT:
             iff->body_pos = avio_tell(pb);
             iff->body_size = data_size;
             break;
@@ -219,7 +258,6 @@ static int iff_read_header(AVFormatContext *s)
             break;
 
         case ID_BMHD:
-            iff->bitmap_compression = -1;
             st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
             if (data_size <= 8)
                 return AVERROR_INVALIDDATA;
@@ -281,6 +319,14 @@ static int iff_read_header(AVFormatContext *s)
             st->codec->height = avio_rb16(pb);
             break;
 
+        case ID_TVDC:
+            if (data_size < sizeof(iff->tvdc))
+                return AVERROR_INVALIDDATA;
+            res = avio_read(pb, iff->tvdc, sizeof(iff->tvdc));
+            if (res < 0)
+                return res;
+            break;
+
         case ID_ANNO:
         case ID_TEXT:      metadata_tag = "comment";   break;
         case ID_AUTH:      metadata_tag = "artist";    break;
@@ -305,7 +351,26 @@ static int iff_read_header(AVFormatContext *s)
 
         if (st->codec->codec_tag == ID_16SV)
             st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;
-        else {
+        else if (st->codec->codec_tag == ID_MAUD) {
+            if (iff->maud_bits == 8 && !iff->maud_compression) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+            } else if (iff->maud_bits == 16 && !iff->maud_compression) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
+            } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;
+            } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) {
+                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;
+            } else {
+                av_log_ask_for_sample(s, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits);
+                return AVERROR_PATCHWELCOME;
+            }
+
+            st->codec->bits_per_coded_sample =
+                av_get_bits_per_sample(st->codec->codec_id);
+
+            st->codec->block_align =
+                st->codec->bits_per_coded_sample * st->codec->channels / 8;
+        } else {
         switch (iff->svx8_compression) {
         case COMP_NONE:
             st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;
@@ -352,6 +417,7 @@ static int iff_read_header(AVFormatContext *s)
         bytestream_put_byte(&buf, iff->flags);
         bytestream_put_be16(&buf, iff->transparency);
         bytestream_put_byte(&buf, iff->masking);
+        bytestream_put_buffer(&buf, iff->tvdc, sizeof(iff->tvdc));
         st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;
         break;
     default:
@@ -373,7 +439,12 @@ static int iff_read_packet(AVFormatContext *s,
         return AVERROR_EOF;
 
     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-        ret = av_get_packet(pb, pkt, iff->body_size);
+        if (st->codec->codec_tag == ID_MAUD) {
+            ret = av_get_packet(pb, pkt,
+                                FFMIN(iff->body_size - iff->sent_bytes, 1024 * st->codec->block_align));
+        } else {
+            ret = av_get_packet(pb, pkt, iff->body_size);
+        }
     } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
         uint8_t *buf;
 
@@ -390,8 +461,9 @@ static int iff_read_packet(AVFormatContext *s,
 
     if(iff->sent_bytes == 0)
         pkt->flags |= AV_PKT_FLAG_KEY;
-    iff->sent_bytes = iff->body_size;
-
+    if (ret < 0)
+        return ret;
+    iff->sent_bytes += ret;
     pkt->stream_index = 0;
     return ret;
 }