mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-04 13:53:26 +00:00
avformat/avienc: add muxer option "write_channel_mask"
Allow writing an empty channel mask into the wave format header. Useful if the input file contains an unknown channel layout. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
1e75bee3d6
commit
1416370027
@ -34,6 +34,7 @@
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/timestamp.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavcodec/raw.h"
|
||||
|
||||
@ -58,9 +59,11 @@ typedef struct AVIIndex {
|
||||
} AVIIndex;
|
||||
|
||||
typedef struct AVIContext {
|
||||
const AVClass *class;
|
||||
int64_t riff_start, movi_list, odml_list;
|
||||
int64_t frames_hdr_all;
|
||||
int riff_id;
|
||||
int write_channel_mask;
|
||||
} AVIContext;
|
||||
|
||||
typedef struct AVIStream {
|
||||
@ -339,7 +342,7 @@ static int avi_write_header(AVFormatContext *s)
|
||||
ff_end_tag(pb, strh);
|
||||
|
||||
if (enc->codec_type != AVMEDIA_TYPE_DATA) {
|
||||
int ret;
|
||||
int ret, flags;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
|
||||
strf = ff_start_tag(pb, "strf");
|
||||
@ -367,7 +370,8 @@ static int avi_write_header(AVFormatContext *s)
|
||||
av_get_pix_fmt_name(enc->pix_fmt));
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if ((ret = ff_put_wav_header(pb, enc, 0)) < 0)
|
||||
flags = (avi->write_channel_mask == 0) ? FF_PUT_WAV_HEADER_SKIP_CHANNELMASK : 0;
|
||||
if ((ret = ff_put_wav_header(pb, enc, flags)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
@ -782,6 +786,20 @@ static int avi_write_trailer(AVFormatContext *s)
|
||||
return res;
|
||||
}
|
||||
|
||||
#define OFFSET(x) offsetof(AVIContext, x)
|
||||
#define ENC AV_OPT_FLAG_ENCODING_PARAM
|
||||
static const AVOption options[] = {
|
||||
{ "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const AVClass avi_muxer_class = {
|
||||
.class_name = "AVI muxer",
|
||||
.item_name = av_default_item_name,
|
||||
.option = options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
AVOutputFormat ff_avi_muxer = {
|
||||
.name = "avi",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
|
||||
@ -796,4 +814,5 @@ AVOutputFormat ff_avi_muxer = {
|
||||
.codec_tag = (const AVCodecTag * const []) {
|
||||
ff_codec_bmp_tags, ff_codec_wav_tags, 0
|
||||
},
|
||||
.priv_class = &avi_muxer_class,
|
||||
};
|
||||
|
@ -52,6 +52,11 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t
|
||||
*/
|
||||
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX 0x00000001
|
||||
|
||||
/**
|
||||
* Tell ff_put_wav_header() to write an empty channel mask.
|
||||
*/
|
||||
#define FF_PUT_WAV_HEADER_SKIP_CHANNELMASK 0x00000002
|
||||
|
||||
/**
|
||||
* Write WAVEFORMAT header structure.
|
||||
*
|
||||
|
@ -168,8 +168,9 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags)
|
||||
}
|
||||
/* write WAVEFORMATEXTENSIBLE extensions */
|
||||
if (waveformatextensible) {
|
||||
int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
|
||||
enc->channel_layout < 0x40000;
|
||||
int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
|
||||
(enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
|
||||
enc->channel_layout < 0x40000);
|
||||
/* 22 is WAVEFORMATEXTENSIBLE size */
|
||||
avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
|
||||
/* ValidBitsPerSample || SamplesPerBlock || Reserved */
|
||||
|
Loading…
Reference in New Issue
Block a user