summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Rapp <t.rapp@noa-audio.com>2015-09-10 14:04:18 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-09-12 14:39:28 +0200
commit141637002767d47154bffaf1463edcfd9445a5ee (patch)
treefb8e639407e7b74e19ed91c80cb278f3b4a9d02e
parent1e75bee3d6031b39a11c69719fdd24871c109f9d (diff)
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>
-rw-r--r--libavformat/avienc.c23
-rw-r--r--libavformat/riff.h5
-rw-r--r--libavformat/riffenc.c5
3 files changed, 29 insertions, 4 deletions
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index a79f156ab2..649961d11c 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -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,
};
diff --git a/libavformat/riff.h b/libavformat/riff.h
index 399c52738f..d6d91ef52d 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -53,6 +53,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.
*
* @param flags a combination of FF_PUT_WAV_HEADER_* constants
diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c
index 85c953f2ef..ceb27f272c 100644
--- a/libavformat/riffenc.c
+++ b/libavformat/riffenc.c
@@ -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 */