[FFmpeg-devel] Add waveformat extensible support in wav muxer (SoC qualification task)
Michael Niedermayer
michaelni
Wed Apr 1 19:31:07 CEST 2009
On Wed, Apr 01, 2009 at 07:37:11PM +0800, zhentan feng wrote:
> Hi
>
> 2009/4/1 Michael Niedermayer <michaelni at gmx.at>
>
> > On Wed, Apr 01, 2009 at 01:45:17AM +0800, zhentan feng wrote:
> > > Hi
> > >
> > > 2009/3/31 Michael Niedermayer <michaelni at gmx.at>
> > >
> > > > On Tue, Mar 31, 2009 at 07:47:59PM +0800, zhentan feng wrote:
> > > > [...]
> > > > > here is new patch attached below.
> > > > >
> > > > > --
> > > > > Best wishes~
> > > >
> > > > > Index: libavformat/riff.c
> > > > > ===================================================================
> > > > > --- libavformat/riff.c (revision 18184)
> > > > > +++ libavformat/riff.c (working copy)
> > > > > @@ -282,12 +282,19 @@
> > > > > int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
> > > > > {
> > > > > int bps, blkalign, bytespersec;
> > > > > + int waveformatextensible = 0;
> > > >
> > > > redundant init
> > > >
> > > >
> > > > > int hdrsize = 18;
> > > > > + int64_t pos, update_size_pos;
> > > > >
> > > > > if(!enc->codec_tag || enc->codec_tag > 0xffff)
> > > > > return -1;
> > > > >
> > > > > - put_le16(pb, enc->codec_tag);
> > > > > + 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) {
> > > > > @@ -324,8 +331,22 @@
> > > > > put_le32(pb, bytespersec); /* bytes per second */
> > > > > put_le16(pb, blkalign); /* block align */
> > > > > put_le16(pb, bps); /* bits per sample */
> > > > > +
> > > > > + if (waveformatextensible) { /* write
> > > > WAVEFORMATEXTENSIBLE extensions */
> > > > > + update_size_pos = url_ftell(pb);
> > > > > + put_le16(pb, enc->extradata_size+22); /* 22 is the
> > size of
> > > > WAVEFORMATEXTENSIBLE-WAVEFORMATEX */
> > > > > + 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);
> > > > > + hdrsize += 22;
> > > > > + }
> > > > > +
> > > > > if (enc->codec_id == CODEC_ID_MP3) {
> > > > > - put_le16(pb, 12); /* wav_extra_size */
> > > > > + if (!waveformatextensible)
> > > > > + put_le16(pb, 12); /* wav_extra_size */
> > > > > hdrsize += 12;
> > > > > put_le16(pb, 1); /* wID */
> > > > > put_le32(pb, 2); /* fdwFlags */
> > > > > @@ -333,7 +354,8 @@
> > > > > put_le16(pb, 1); /* nFramesPerBlock */
> > > > > put_le16(pb, 1393); /* nCodecDelay */
> > > > > } else if (enc->codec_id == CODEC_ID_MP2) {
> > > > > - put_le16(pb, 22); /* wav_extra_size */
> > > > > + if (!waveformatextensible)
> > > > > + put_le16(pb, 22); /* wav_extra_size */
> > > > > hdrsize += 22;
> > > > > put_le16(pb, 2); /* fwHeadLayer */
> > > > > put_le32(pb, enc->bit_rate); /* dwHeadBitrate */
> > > > > @@ -344,15 +366,18 @@
> > > > > 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 */
> > > > > + if (!waveformatextensible)
> > > > > + 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 */
> > > > > + if (!waveformatextensible)
> > > > > + put_le16(pb, 2); /* wav_extra_size */
> > > > > hdrsize += 2;
> > > >
> > > > > put_le16(pb, enc->frame_size); /* wSamplesPerBlock */
> > > > > - } else if(enc->extradata_size){
> > > > > + } else if (enc->extradata_size){
> > > > > - put_le16(pb, enc->extradata_size);
> > > > > + if (!waveformatextensible)
> > > > > + put_le16(pb, enc->extradata_size);
> > > > > put_buffer(pb, enc->extradata, enc->extradata_size);
> > > >
> > > > cosmetic
> > > >
> > > >
> > > > > hdrsize += enc->extradata_size;
> > > > > if(hdrsize&1){
> > > > > @@ -363,6 +388,14 @@
> > > > > hdrsize -= 2;
> > > > > }
> > > > >
> > > > > + if (!url_is_streamed(pb)){
> > > > > + if (hdrsize > 40 && waveformatextensible) { /* 40 means 22
> > > > WAVEFORMATEXTENSBLE size + 18 */
> > > > > + pos = url_ftell(pb);
> > > > > + url_fseek(pb, update_size_pos, SEEK_SET);
> > > > > + put_le16(pb, hdrsize - 18);
> > > > > + url_fseek(pb, pos, SEEK_SET);
> > > > > + }
> > > > > + }
> > > >
> > > > fails if url_is_streamed
> > > >
> > > >
> > > > [...]
> > >
> > >
> > > reference to avienc.c Line 180, write the default MAX value when
> > > url_is_streamed is true.
> > > here is the new patch.
> >
> > we need the correct value written there, the header size is not optional
> >
> > [...]
>
>
> here is the new patch attached below.
>
> zhentan
> --
> Best wishes~
> Index: libavformat/riff.c
> ===================================================================
> --- libavformat/riff.c (revision 18184)
> +++ libavformat/riff.c (working copy)
> @@ -282,18 +282,37 @@
> int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
> {
> int bps, blkalign, bytespersec;
> + int waveformatextensible;
> int hdrsize = 18;
> + int pre_size;
>
> if(!enc->codec_tag || enc->codec_tag > 0xffff)
> return -1;
>
> - put_le16(pb, enc->codec_tag);
> + waveformatextensible = enc->channels > 2 && enc->channel_layout;
> + if (waveformatextensible) {
> + put_le16(pb, 0xfffe);
> + pre_size = enc->extradata_size;
> + }
> + else
these should be on the same line in K&R style
> + 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) {
> bps = 0;
> + if (waveformatextensible) {
> + if (enc->codec_id == CODEC_ID_MP2)
> + pre_size = 22;
> + else if(enc->codec_id == CODEC_ID_MP3)
> + pre_size = 12;
> + else
> + pre_size = 2;
> + }
> } 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) { //
> bps = 4;
> + if (waveformatextensible && enc->codec_id == CODEC_ID_ADPCM_IMA_WAV)
> + pre_size = 2;
> } else {
> if (!(bps = av_get_bits_per_sample(enc->codec_id)))
> bps = 16; // default to 16
> @@ -324,8 +343,21 @@
> put_le32(pb, bytespersec); /* bytes per second */
> put_le16(pb, blkalign); /* block align */
> put_le16(pb, bps); /* bits per sample */
> +
> + if (waveformatextensible) { /* write WAVEFORMATEXTENSIBLE extensions */
> + put_le16(pb, pre_size + 22); /* 22 is the size of WAVEFORMATEXTENSIBLE-WAVEFORMATEX */
> + 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);
> + hdrsize += 22;
> + }
> +
> if (enc->codec_id == CODEC_ID_MP3) {
> - put_le16(pb, 12); /* wav_extra_size */
> + if (!waveformatextensible)
> + put_le16(pb, 12); /* wav_extra_size */
> hdrsize += 12;
> put_le16(pb, 1); /* wID */
> put_le32(pb, 2); /* fdwFlags */
> @@ -333,7 +365,8 @@
> put_le16(pb, 1); /* nFramesPerBlock */
> put_le16(pb, 1393); /* nCodecDelay */
> } else if (enc->codec_id == CODEC_ID_MP2) {
> - put_le16(pb, 22); /* wav_extra_size */
> + if (!waveformatextensible)
> + put_le16(pb, 22); /* wav_extra_size */
> hdrsize += 22;
> put_le16(pb, 2); /* fwHeadLayer */
> put_le32(pb, enc->bit_rate); /* dwHeadBitrate */
> @@ -344,15 +377,18 @@
> 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 */
> + if (!waveformatextensible)
> + 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 */
> + if (!waveformatextensible)
> + put_le16(pb, 2); /* wav_extra_size */
> hdrsize += 2;
> put_le16(pb, enc->frame_size); /* wSamplesPerBlock */
> } else if(enc->extradata_size){
> - put_le16(pb, enc->extradata_size);
> + if (!waveformatextensible)
> + put_le16(pb, enc->extradata_size);
> put_buffer(pb, enc->extradata, enc->extradata_size);
> hdrsize += enc->extradata_size;
> if(hdrsize&1){
iam sorry but this is a unmaintainable mess
There are 2 parts, first the waveformatextensible header, and second the
extradata.
The extradata has a bunch of special cases that write things differently
from just extradata. But in the end it just writes
* the size of all
* optionally the waveformatextensible header
* extadata
this can be done without having 8 special cases added for waveformatextensible
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Opposition brings concord. Out of discord comes the fairest harmony.
-- Heraclitus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090401/16607f66/attachment.pgp>
More information about the ffmpeg-devel
mailing list