Add waveformat-extensible support in the wav muxer.
Patch (GSoC qualfication task) by Zhentan Feng spyfeng gmail com, see "[FFmpeg-devel] Add waveformat extensible support in wav muxer (SoC qualification task)" thread on mailinglist. Originally committed as revision 18372 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							parent
							
								
									7b356d3951
								
							
						
					
					
						commit
						6e9f56c127
					
				@ -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. */
 | 
			
		||||
@ -284,11 +285,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;
 | 
			
		||||
 | 
			
		||||
    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 +336,52 @@ 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 */
 | 
			
		||||
        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) {
 | 
			
		||||
        put_le16(pb, 2); /* wav_extra_size */
 | 
			
		||||
        hdrsize += 2;
 | 
			
		||||
        put_le16(pb, enc->frame_size); /* wSamplesPerBlock */
 | 
			
		||||
        bytestream_put_le16(&riff_extradata, enc->frame_size); /* wSamplesPerBlock */
 | 
			
		||||
    } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
 | 
			
		||||
        put_le16(pb, 2); /* wav_extra_size */
 | 
			
		||||
        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;
 | 
			
		||||
    } 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);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        hdrsize -= 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return hdrsize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user