Commit 14163700 authored by Tobias Rapp's avatar Tobias Rapp Committed by Michael Niedermayer

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: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 1e75bee3
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "libavutil/dict.h" #include "libavutil/dict.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/timestamp.h" #include "libavutil/timestamp.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavcodec/raw.h" #include "libavcodec/raw.h"
...@@ -58,9 +59,11 @@ typedef struct AVIIndex { ...@@ -58,9 +59,11 @@ typedef struct AVIIndex {
} AVIIndex; } AVIIndex;
typedef struct AVIContext { typedef struct AVIContext {
const AVClass *class;
int64_t riff_start, movi_list, odml_list; int64_t riff_start, movi_list, odml_list;
int64_t frames_hdr_all; int64_t frames_hdr_all;
int riff_id; int riff_id;
int write_channel_mask;
} AVIContext; } AVIContext;
typedef struct AVIStream { typedef struct AVIStream {
...@@ -339,7 +342,7 @@ static int avi_write_header(AVFormatContext *s) ...@@ -339,7 +342,7 @@ static int avi_write_header(AVFormatContext *s)
ff_end_tag(pb, strh); ff_end_tag(pb, strh);
if (enc->codec_type != AVMEDIA_TYPE_DATA) { if (enc->codec_type != AVMEDIA_TYPE_DATA) {
int ret; int ret, flags;
enum AVPixelFormat pix_fmt; enum AVPixelFormat pix_fmt;
strf = ff_start_tag(pb, "strf"); strf = ff_start_tag(pb, "strf");
...@@ -367,7 +370,8 @@ static int avi_write_header(AVFormatContext *s) ...@@ -367,7 +370,8 @@ static int avi_write_header(AVFormatContext *s)
av_get_pix_fmt_name(enc->pix_fmt)); av_get_pix_fmt_name(enc->pix_fmt));
break; break;
case AVMEDIA_TYPE_AUDIO: 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; return ret;
break; break;
default: default:
...@@ -782,6 +786,20 @@ static int avi_write_trailer(AVFormatContext *s) ...@@ -782,6 +786,20 @@ static int avi_write_trailer(AVFormatContext *s)
return res; 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 = { AVOutputFormat ff_avi_muxer = {
.name = "avi", .name = "avi",
.long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"), .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
...@@ -796,4 +814,5 @@ AVOutputFormat ff_avi_muxer = { ...@@ -796,4 +814,5 @@ AVOutputFormat ff_avi_muxer = {
.codec_tag = (const AVCodecTag * const []) { .codec_tag = (const AVCodecTag * const []) {
ff_codec_bmp_tags, ff_codec_wav_tags, 0 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 ...@@ -52,6 +52,11 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t
*/ */
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX 0x00000001 #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. * Write WAVEFORMAT header structure.
* *
......
...@@ -168,8 +168,9 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags) ...@@ -168,8 +168,9 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags)
} }
/* write WAVEFORMATEXTENSIBLE extensions */ /* write WAVEFORMATEXTENSIBLE extensions */
if (waveformatextensible) { if (waveformatextensible) {
int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL || int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
enc->channel_layout < 0x40000; (enc->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
enc->channel_layout < 0x40000);
/* 22 is WAVEFORMATEXTENSIBLE size */ /* 22 is WAVEFORMATEXTENSIBLE size */
avio_wl16(pb, riff_extradata - riff_extradata_start + 22); avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
/* ValidBitsPerSample || SamplesPerBlock || Reserved */ /* ValidBitsPerSample || SamplesPerBlock || Reserved */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment