]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavformat/riff.c
v210 avi fourcc, v210_720p.avi
[frescor/ffmpeg.git] / libavformat / riff.c
index 8dda62354934ffb7ba7b218b563220c3d92a70be..7e404aeb2f1f139f2c2e3d92e9f5f60b4f89d1ae 100644 (file)
@@ -22,6 +22,7 @@
 #include "libavcodec/avcodec.h"
 #include "avformat.h"
 #include "riff.h"
+#include "libavcodec/bytestream.h"
 
 /* Note: when encoding, the first matching tag is used, so order is
    important if multiple tags possible for a given codec. */
@@ -37,6 +38,7 @@ const AVCodecTag codec_bmp_tags[] = {
     { CODEC_ID_H263,         MKTAG('T', '2', '6', '3') },
     { CODEC_ID_H263,         MKTAG('L', '2', '6', '3') },
     { CODEC_ID_H263,         MKTAG('V', 'X', '1', 'K') },
+    { CODEC_ID_H263,         MKTAG('Z', 'y', 'G', 'o') },
     { CODEC_ID_H263P,        MKTAG('H', '2', '6', '3') },
     { CODEC_ID_H263I,        MKTAG('I', '2', '6', '3') }, /* intel h263 */
     { CODEC_ID_H261,         MKTAG('H', '2', '6', '1') },
@@ -99,6 +101,7 @@ const AVCodecTag codec_bmp_tags[] = {
     { CODEC_ID_DVVIDEO,      MKTAG('c', 'd', 'v', 'c') }, /* Canopus DV */
     { CODEC_ID_DVVIDEO,      MKTAG('C', 'D', 'V', 'H') }, /* Canopus DV */
     { CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'c', ' ') },
+    { CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'h', '1') },
     { CODEC_ID_MPEG1VIDEO,   MKTAG('m', 'p', 'g', '1') },
     { CODEC_ID_MPEG1VIDEO,   MKTAG('m', 'p', 'g', '2') },
     { CODEC_ID_MPEG2VIDEO,   MKTAG('m', 'p', 'g', '2') },
@@ -137,6 +140,7 @@ const AVCodecTag codec_bmp_tags[] = {
     { CODEC_ID_RAWVIDEO,     MKTAG('I', 'Y', 'U', 'V') },
     { CODEC_ID_RAWVIDEO,     MKTAG('Y', '8', '0', '0') },
     { CODEC_ID_RAWVIDEO,     MKTAG('H', 'D', 'Y', 'C') },
+    { CODEC_ID_V210,         MKTAG('v', '2', '1', '0') },
     { CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '1') },
     { CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '2') },
     { CODEC_ID_INDEO4,       MKTAG('I', 'V', '4', '1') },
@@ -197,6 +201,7 @@ const AVCodecTag codec_bmp_tags[] = {
     { CODEC_ID_VMNC,         MKTAG('V', 'M', 'n', 'c') },
     { CODEC_ID_TARGA,        MKTAG('t', 'g', 'a', ' ') },
     { CODEC_ID_PNG,          MKTAG('M', 'P', 'N', 'G') },
+    { CODEC_ID_PNG,          MKTAG('P', 'N', 'G', '1') },
     { CODEC_ID_CLJR,         MKTAG('c', 'l', 'j', 'r') },
     { CODEC_ID_DIRAC,        MKTAG('d', 'r', 'a', 'c') },
     { CODEC_ID_RPZA,         MKTAG('a', 'z', 'p', 'r') },
@@ -284,11 +289,20 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
 {
     int bps, blkalign, bytespersec;
     int hdrsize = 18;
+    int waveformatextensible;
+    uint8_t temp[256];
+    uint8_t *riff_extradata= temp;
+    uint8_t *riff_extradata_start= temp;
 
     if(!enc->codec_tag || enc->codec_tag > 0xffff)
         return -1;
+    waveformatextensible = enc->channels > 2 && enc->channel_layout;
 
-    put_le16(pb, enc->codec_tag);
+    if (waveformatextensible) {
+        put_le16(pb, 0xfffe);
+    } else {
+        put_le16(pb, enc->codec_tag);
+    }
     put_le16(pb, enc->channels);
     put_le32(pb, enc->sample_rate);
     if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) {
@@ -326,43 +340,49 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
     put_le16(pb, blkalign); /* block align */
     put_le16(pb, bps); /* bits per sample */
     if (enc->codec_id == CODEC_ID_MP3) {
-        put_le16(pb, 12); /* wav_extra_size */
         hdrsize += 12;
-        put_le16(pb, 1); /* wID */
-        put_le32(pb, 2); /* fdwFlags */
-        put_le16(pb, 1152); /* nBlockSize */
-        put_le16(pb, 1); /* nFramesPerBlock */
-        put_le16(pb, 1393); /* nCodecDelay */
+        bytestream_put_le16(&riff_extradata, 1);    /* wID */
+        bytestream_put_le32(&riff_extradata, 2);    /* fdwFlags */
+        bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
+        bytestream_put_le16(&riff_extradata, 1);    /* nFramesPerBlock */
+        bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
     } else if (enc->codec_id == CODEC_ID_MP2) {
-        put_le16(pb, 22); /* wav_extra_size */
         hdrsize += 22;
-        put_le16(pb, 2);  /* fwHeadLayer */
-        put_le32(pb, enc->bit_rate); /* dwHeadBitrate */
-        put_le16(pb, enc->channels == 2 ? 1 : 8); /* fwHeadMode */
-        put_le16(pb, 0);  /* fwHeadModeExt */
-        put_le16(pb, 1);  /* wHeadEmphasis */
-        put_le16(pb, 16); /* fwHeadFlags */
-        put_le32(pb, 0);  /* dwPTSLow */
-        put_le32(pb, 0);  /* dwPTSHigh */
-    } else if (enc->codec_id == CODEC_ID_GSM_MS) {
-        put_le16(pb, 2); /* wav_extra_size */
-        hdrsize += 2;
-        put_le16(pb, enc->frame_size); /* wSamplesPerBlock */
-    } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
-        put_le16(pb, 2); /* wav_extra_size */
+        bytestream_put_le16(&riff_extradata, 2);                          /* fwHeadLayer */
+        bytestream_put_le32(&riff_extradata, enc->bit_rate);              /* dwHeadBitrate */
+        bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadMode */
+        bytestream_put_le16(&riff_extradata, 0);                          /* fwHeadModeExt */
+        bytestream_put_le16(&riff_extradata, 1);                          /* wHeadEmphasis */
+        bytestream_put_le16(&riff_extradata, 16);                         /* fwHeadFlags */
+        bytestream_put_le32(&riff_extradata, 0);                          /* dwPTSLow */
+        bytestream_put_le32(&riff_extradata, 0);                          /* dwPTSHigh */
+    } else if (enc->codec_id == CODEC_ID_GSM_MS || enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
         hdrsize += 2;
-        put_le16(pb, enc->frame_size); /* wSamplesPerBlock */
+        bytestream_put_le16(&riff_extradata, enc->frame_size); /* wSamplesPerBlock */
     } else if(enc->extradata_size){
-        put_le16(pb, enc->extradata_size);
-        put_buffer(pb, enc->extradata, enc->extradata_size);
+        riff_extradata_start= enc->extradata;
+        riff_extradata= enc->extradata + enc->extradata_size;
         hdrsize += enc->extradata_size;
-        if(hdrsize&1){
-            hdrsize++;
-            put_byte(pb, 0);
-        }
-    } else {
+    } else if (!waveformatextensible){
         hdrsize -= 2;
     }
+    if(waveformatextensible) {                                    /* write WAVEFORMATEXTENSIBLE extensions */
+        hdrsize += 22;
+        put_le16(pb, riff_extradata - riff_extradata_start + 22); /* 22 is WAVEFORMATEXTENSIBLE size */
+        put_le16(pb, enc->bits_per_coded_sample);                 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
+        put_le32(pb, enc->channel_layout);                        /* dwChannelMask */
+        put_le32(pb, enc->codec_tag);                             /* GUID + next 3 */
+        put_le32(pb, 0x00100000);
+        put_le32(pb, 0xAA000080);
+        put_le32(pb, 0x719B3800);
+    } else if(riff_extradata - riff_extradata_start) {
+        put_le16(pb, riff_extradata - riff_extradata_start);
+    }
+    put_buffer(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
+    if(hdrsize&1){
+        hdrsize++;
+        put_byte(pb, 0);
+    }
 
     return hdrsize;
 }