comparison riff.c @ 4833:d607731c2cf8 libavformat

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.
author rbultje
date Wed, 08 Apr 2009 03:04:57 +0000
parents f83f6caa42bc
children 231479c86582
comparison
equal deleted inserted replaced
4832:b367d80986b3 4833:d607731c2cf8
20 */ 20 */
21 21
22 #include "libavcodec/avcodec.h" 22 #include "libavcodec/avcodec.h"
23 #include "avformat.h" 23 #include "avformat.h"
24 #include "riff.h" 24 #include "riff.h"
25 #include "libavcodec/bytestream.h"
25 26
26 /* Note: when encoding, the first matching tag is used, so order is 27 /* Note: when encoding, the first matching tag is used, so order is
27 important if multiple tags possible for a given codec. */ 28 important if multiple tags possible for a given codec. */
28 const AVCodecTag codec_bmp_tags[] = { 29 const AVCodecTag codec_bmp_tags[] = {
29 { CODEC_ID_H264, MKTAG('H', '2', '6', '4') }, 30 { CODEC_ID_H264, MKTAG('H', '2', '6', '4') },
282 /* returns the size or -1 on error */ 283 /* returns the size or -1 on error */
283 int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) 284 int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
284 { 285 {
285 int bps, blkalign, bytespersec; 286 int bps, blkalign, bytespersec;
286 int hdrsize = 18; 287 int hdrsize = 18;
288 int waveformatextensible;
289 uint8_t temp[256];
290 uint8_t *riff_extradata= temp;
291 uint8_t *riff_extradata_start= temp;
287 292
288 if(!enc->codec_tag || enc->codec_tag > 0xffff) 293 if(!enc->codec_tag || enc->codec_tag > 0xffff)
289 return -1; 294 return -1;
290 295 waveformatextensible = enc->channels > 2 && enc->channel_layout;
296
297 if (waveformatextensible) {
298 put_le16(pb, 0xfffe);
299 } else {
291 put_le16(pb, enc->codec_tag); 300 put_le16(pb, enc->codec_tag);
301 }
292 put_le16(pb, enc->channels); 302 put_le16(pb, enc->channels);
293 put_le32(pb, enc->sample_rate); 303 put_le32(pb, enc->sample_rate);
294 if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { 304 if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) {
295 bps = 0; 305 bps = 0;
296 } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV || enc->codec_id == CODEC_ID_ADPCM_MS || enc->codec_id == CODEC_ID_ADPCM_G726 || enc->codec_id == CODEC_ID_ADPCM_YAMAHA) { // 306 } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV || enc->codec_id == CODEC_ID_ADPCM_MS || enc->codec_id == CODEC_ID_ADPCM_G726 || enc->codec_id == CODEC_ID_ADPCM_YAMAHA) { //
324 } 334 }
325 put_le32(pb, bytespersec); /* bytes per second */ 335 put_le32(pb, bytespersec); /* bytes per second */
326 put_le16(pb, blkalign); /* block align */ 336 put_le16(pb, blkalign); /* block align */
327 put_le16(pb, bps); /* bits per sample */ 337 put_le16(pb, bps); /* bits per sample */
328 if (enc->codec_id == CODEC_ID_MP3) { 338 if (enc->codec_id == CODEC_ID_MP3) {
329 put_le16(pb, 12); /* wav_extra_size */
330 hdrsize += 12; 339 hdrsize += 12;
331 put_le16(pb, 1); /* wID */ 340 bytestream_put_le16(&riff_extradata, 1); /* wID */
332 put_le32(pb, 2); /* fdwFlags */ 341 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
333 put_le16(pb, 1152); /* nBlockSize */ 342 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
334 put_le16(pb, 1); /* nFramesPerBlock */ 343 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
335 put_le16(pb, 1393); /* nCodecDelay */ 344 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
336 } else if (enc->codec_id == CODEC_ID_MP2) { 345 } else if (enc->codec_id == CODEC_ID_MP2) {
337 put_le16(pb, 22); /* wav_extra_size */
338 hdrsize += 22; 346 hdrsize += 22;
339 put_le16(pb, 2); /* fwHeadLayer */ 347 bytestream_put_le16(&riff_extradata, 2); /* fwHeadLayer */
340 put_le32(pb, enc->bit_rate); /* dwHeadBitrate */ 348 bytestream_put_le32(&riff_extradata, enc->bit_rate); /* dwHeadBitrate */
341 put_le16(pb, enc->channels == 2 ? 1 : 8); /* fwHeadMode */ 349 bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadMode */
342 put_le16(pb, 0); /* fwHeadModeExt */ 350 bytestream_put_le16(&riff_extradata, 0); /* fwHeadModeExt */
343 put_le16(pb, 1); /* wHeadEmphasis */ 351 bytestream_put_le16(&riff_extradata, 1); /* wHeadEmphasis */
344 put_le16(pb, 16); /* fwHeadFlags */ 352 bytestream_put_le16(&riff_extradata, 16); /* fwHeadFlags */
345 put_le32(pb, 0); /* dwPTSLow */ 353 bytestream_put_le32(&riff_extradata, 0); /* dwPTSLow */
346 put_le32(pb, 0); /* dwPTSHigh */ 354 bytestream_put_le32(&riff_extradata, 0); /* dwPTSHigh */
347 } else if (enc->codec_id == CODEC_ID_GSM_MS) { 355 } else if (enc->codec_id == CODEC_ID_GSM_MS) {
348 put_le16(pb, 2); /* wav_extra_size */
349 hdrsize += 2; 356 hdrsize += 2;
350 put_le16(pb, enc->frame_size); /* wSamplesPerBlock */ 357 bytestream_put_le16(&riff_extradata, enc->frame_size); /* wSamplesPerBlock */
351 } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { 358 } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
352 put_le16(pb, 2); /* wav_extra_size */
353 hdrsize += 2; 359 hdrsize += 2;
354 put_le16(pb, enc->frame_size); /* wSamplesPerBlock */ 360 bytestream_put_le16(&riff_extradata, enc->frame_size); /* wSamplesPerBlock */
355 } else if(enc->extradata_size){ 361 } else if(enc->extradata_size){
356 put_le16(pb, enc->extradata_size); 362 riff_extradata_start= enc->extradata;
357 put_buffer(pb, enc->extradata, enc->extradata_size); 363 riff_extradata= enc->extradata + enc->extradata_size;
358 hdrsize += enc->extradata_size; 364 hdrsize += enc->extradata_size;
365 } else if (!waveformatextensible){
366 hdrsize -= 2;
367 }
368 if(waveformatextensible) { /* write WAVEFORMATEXTENSIBLE extensions */
369 hdrsize += 22;
370 put_le16(pb, riff_extradata - riff_extradata_start + 22); /* 22 is WAVEFORMATEXTENSIBLE size */
371 put_le16(pb, enc->bits_per_coded_sample); /* ValidBitsPerSample || SamplesPerBlock || Reserved */
372 put_le32(pb, enc->channel_layout); /* dwChannelMask */
373 put_le32(pb, enc->codec_tag); /* GUID + next 3 */
374 put_le32(pb, 0x00100000);
375 put_le32(pb, 0xAA000080);
376 put_le32(pb, 0x719B3800);
377 } else if(riff_extradata - riff_extradata_start) {
378 put_le16(pb, riff_extradata - riff_extradata_start);
379 }
380 put_buffer(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
359 if(hdrsize&1){ 381 if(hdrsize&1){
360 hdrsize++; 382 hdrsize++;
361 put_byte(pb, 0); 383 put_byte(pb, 0);
362 } 384 }
363 } else {
364 hdrsize -= 2;
365 }
366 385
367 return hdrsize; 386 return hdrsize;
368 } 387 }
369 388
370 /* BITMAPINFOHEADER header */ 389 /* BITMAPINFOHEADER header */