Skip to content

Commit

Permalink
avformat/avienc: add muxer option "write_channel_mask"
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
t-rapp authored and michaelni committed Sep 12, 2015
1 parent 1e75bee commit 1416370
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
23 changes: 21 additions & 2 deletions libavformat/avienc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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 {
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)"),
Expand All @@ -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,
};
5 changes: 5 additions & 0 deletions libavformat/riff.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
5 changes: 3 additions & 2 deletions libavformat/riffenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 1416370

Please sign in to comment.