From: Tom Yan <tom.ty89@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: Tom Yan <tom.ty89@gmail.com> Subject: [FFmpeg-devel] [PATCH] avformat/wavenc: allow WAVEFORMATEXTENSIBLE to be suppressed Date: Mon, 27 Dec 2021 16:01:33 +0800 Message-ID: <20211227080133.340609-1-tom.ty89@gmail.com> (raw) While WAVEFORMATEX sort of mandates WAVEFORMATEXTENSIBLE to be used for audio with sample size other than 8 or 16, PCMWAVEFORMAT does not practically have any limitation in supporting higher sample size that is a multiple of 8 (or sample rate higher than 48000). In terms of sample size, the only real reason that the extension exists is that it allows both an actual sample size and a multiple-of-8 container size to be stored. However, such facility is of no use when the actual sample size is a multiple of 8, let alone that muxer never made use of it (since it never actually supported sample size like 20 anyway; at least not in the way it is supposed to.) Although WAVEFORMATEXTENSIBLE has been around for more than two decades, apparently programs and libraries that do not support the format still exist. Therefore, adding an option that allows the WAVEFORMATEXTENSIBLE "extensions" to be suppressed and the format tag field to be set to WAVE_FORMAT_PCM (0x0001) for audio with sample size higher than 16 (or sample rate higher than 48000). Signed-off-by: Tom Yan <tom.ty89@gmail.com> --- libavformat/riff.h | 5 +++++ libavformat/riffenc.c | 4 ++-- libavformat/wavenc.c | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libavformat/riff.h b/libavformat/riff.h index 85d6786663..5794857f53 100644 --- a/libavformat/riff.h +++ b/libavformat/riff.h @@ -57,6 +57,11 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, int for_asf, int */ #define FF_PUT_WAV_HEADER_SKIP_CHANNELMASK 0x00000002 +/** + * Tell ff_put_wav_header() not to write WAVEFORMATEXTENSIBLE extensions if possible. + */ +#define FF_PUT_WAV_HEADER_FORCE_PCMWAVEFORMAT 0x00000004 + /** * Write WAVEFORMAT header structure. * diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c index ffccfa3d48..4dc8ca6e0f 100644 --- a/libavformat/riffenc.c +++ b/libavformat/riffenc.c @@ -80,9 +80,9 @@ int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, waveformatextensible = (par->channels > 2 && par->channel_layout) || par->channels == 1 && par->channel_layout && par->channel_layout != AV_CH_LAYOUT_MONO || par->channels == 2 && par->channel_layout && par->channel_layout != AV_CH_LAYOUT_STEREO || - par->sample_rate > 48000 || par->codec_id == AV_CODEC_ID_EAC3 || - av_get_bits_per_sample(par->codec_id) > 16; + ((par->sample_rate > 48000 || av_get_bits_per_sample(par->codec_id) > 16) && + !(flags & FF_PUT_WAV_HEADER_FORCE_PCMWAVEFORMAT)); if (waveformatextensible) avio_wl16(pb, 0xfffe); diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c index 2317700be1..bd41d6eeb3 100644 --- a/libavformat/wavenc.c +++ b/libavformat/wavenc.c @@ -83,6 +83,7 @@ typedef struct WAVMuxContext { int peak_block_pos; int peak_ppv; int peak_bps; + int extensible; } WAVMuxContext; #if CONFIG_WAV_MUXER @@ -324,9 +325,10 @@ static int wav_write_header(AVFormatContext *s) } if (wav->write_peak != PEAK_ONLY) { + int flags = !wav->extensible ? FF_PUT_WAV_HEADER_FORCE_PCMWAVEFORMAT : 0; /* format header */ fmt = ff_start_tag(pb, "fmt "); - if (ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0) < 0) { + if (ff_put_wav_header(s, pb, s->streams[0]->codecpar, flags) < 0) { av_log(s, AV_LOG_ERROR, "Codec %s not supported in WAVE format\n", avcodec_get_name(s->streams[0]->codecpar->codec_id)); return AVERROR(ENOSYS); @@ -494,6 +496,7 @@ static const AVOption options[] = { { "peak_block_size", "Number of audio samples used to generate each peak frame.", OFFSET(peak_block_size), AV_OPT_TYPE_INT, { .i64 = 256 }, 0, 65536, ENC }, { "peak_format", "The format of the peak envelope data (1: uint8, 2: uint16).", OFFSET(peak_format), AV_OPT_TYPE_INT, { .i64 = PEAK_FORMAT_UINT16 }, PEAK_FORMAT_UINT8, PEAK_FORMAT_UINT16, ENC }, { "peak_ppv", "Number of peak points per peak value (1 or 2).", OFFSET(peak_ppv), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 2, ENC }, + { "extensible", "Write WAVEFORMATEXTENSIBLE extensions.", OFFSET(extensible), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC }, { NULL }, }; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2021-12-27 8:01 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-12-27 8:01 Tom Yan [this message] 2022-01-23 9:34 Tom Yan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211227080133.340609-1-tom.ty89@gmail.com \ --to=tom.ty89@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git