@ -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 ;
}