summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-12 21:47:55 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:47:55 +0200
commite6e5a7b221ef2fcdd5a1982d6fdcb627100447d2 (patch)
tree08b54ef9bb771434fc7fbe9185793503d3ba314c /core
parent6a83ef1552de4a1a71da49e45647ce1a4ce64e53 (diff)
parent48f94311516dc1426644b3e68b2a48c22727e1e7 (diff)
downloadmpv-e6e5a7b221ef2fcdd5a1982d6fdcb627100447d2.tar.bz2
mpv-e6e5a7b221ef2fcdd5a1982d6fdcb627100447d2.tar.xz
Merge branch 'audio_changes'
Conflicts: audio/out/ao_lavc.c
Diffstat (limited to 'core')
-rw-r--r--core/cfg-mplayer.h13
-rw-r--r--core/command.c16
-rw-r--r--core/defaultopts.c8
-rw-r--r--core/m_option.c42
-rw-r--r--core/m_option.h6
-rw-r--r--core/mplayer.c24
-rw-r--r--core/options.h9
7 files changed, 83 insertions, 35 deletions
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 5b30e387c3..baf0820f48 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -175,11 +175,6 @@ const m_option_t mfopts_conf[]={
#include "audio/filter/af.h"
extern struct af_cfg af_cfg; // Audio filter configuration, defined in libmpcodecs/dec_audio.c
-const m_option_t audio_filter_conf[]={
- {"list", &af_cfg.list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
- {"force", &af_cfg.force, CONF_TYPE_INT, CONF_RANGE, 0, 7, NULL},
- {NULL, NULL, 0, 0, 0, 0, NULL}
-};
extern int mp_msg_levels[MSGT_MAX];
extern int mp_msg_level_all;
@@ -281,6 +276,7 @@ const m_option_t msgl_config[]={
};
extern const m_option_t lavc_decode_opts_conf[];
+extern const m_option_t ad_lavc_decode_opts_conf[];
#define OPT_BASE_STRUCT struct MPOpts
@@ -418,7 +414,7 @@ const m_option_t common_opts[] = {
// force video/audio rate:
OPT_DOUBLE("fps", force_fps, CONF_MIN, 0),
OPT_INTRANGE("srate", force_srate, 0, 1000, 8*48000),
- OPT_INTRANGE("channels", audio_output_channels, 0, 1, 8),
+ OPT_CHMAP("channels", audio_output_channels, CONF_MIN, .min = 1),
OPT_AUDIOFORMAT("format", audio_output_format, 0),
OPT_FLOATRANGE("speed", playback_speed, 0, 0.01, 100.0),
@@ -428,15 +424,12 @@ const m_option_t common_opts[] = {
// ignore header-specified delay (dwStart)
OPT_FLAG("ignore-start", ignore_start, 0),
- OPT_FLOATRANGE("a52drc", drc_level, 0, 0, 2),
-
// ------------------------- codec/vfilter options --------------------
// MP3-only: select stereo/left/right
{"stereo", &fakemono, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
{"af*", &af_cfg.list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
- {"af-adv", (void *) audio_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
OPT_SETTINGSLIST("vf*", vf_settings, 0, &vf_obj_list),
@@ -472,6 +465,8 @@ const m_option_t common_opts[] = {
{"lavdopts", (void *) lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
{"lavfdopts", (void *) lavfdopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
+
+ {"ad-lavc", (void *) ad_lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG},
// ------------------------- subtitles options --------------------
OPT_STRINGLIST("sub", sub_name, 0),
diff --git a/core/command.c b/core/command.c
index d9788084db..d8a8882c26 100644
--- a/core/command.c
+++ b/core/command.c
@@ -684,20 +684,10 @@ static int mp_property_channels(m_option_t *prop, int action, void *arg,
return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_PRINT:
- switch (mpctx->sh_audio->channels) {
- case 1:
- *(char **) arg = talloc_strdup(NULL, "mono");
- break;
- case 2:
- *(char **) arg = talloc_strdup(NULL, "stereo");
- break;
- default:
- *(char **) arg = talloc_asprintf(NULL, "%d channels",
- mpctx->sh_audio->channels);
- }
+ *(char **) arg = mp_chmap_to_str(&mpctx->sh_audio->channels);
return M_PROPERTY_OK;
case M_PROPERTY_GET:
- *(int *)arg = mpctx->sh_audio->channels;
+ *(int *)arg = mpctx->sh_audio->channels.num;
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@@ -2319,7 +2309,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
break;
}
af->control(af, AF_CONTROL_COMMAND_LINE, cmd->args[1].v.s);
- af_reinit(sh_audio->afilter, af);
+ af_reinit(sh_audio->afilter);
}
break;
case MP_CMD_SHOW_CHAPTERS:
diff --git a/core/defaultopts.c b/core/defaultopts.c
index b80bea5c1e..3ffc5e2555 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -4,6 +4,7 @@
#include "defaultopts.h"
#include "core/options.h"
#include "audio/mixer.h"
+#include "audio/chmap.h"
void set_default_mplayer_options(struct MPOpts *opts)
{
@@ -72,10 +73,9 @@ void set_default_mplayer_options(struct MPOpts *opts)
.audio_display = 1,
.sub_visibility = 1,
.extension_parsing = 1,
- .audio_output_channels = 2,
+ .audio_output_channels = MP_CHMAP_INIT_STEREO,
.audio_output_format = -1, // AF_FORMAT_UNKNOWN
.playback_speed = 1.,
- .drc_level = 1.,
.movie_aspect = -1.,
.sub_auto = 1,
.osd_bar_visible = 1,
@@ -93,6 +93,10 @@ void set_default_mplayer_options(struct MPOpts *opts)
.workaround_bugs = 1, // autodetect
.error_concealment = 3,
},
+ .ad_lavc_param = {
+ .ac3drc = 1.,
+ .downmix = 1,
+ },
.input = {
.key_fifo_size = 7,
.ar_delay = 200,
diff --git a/core/m_option.c b/core/m_option.c
index a667471407..fcf8cc6a67 100644
--- a/core/m_option.c
+++ b/core/m_option.c
@@ -1604,6 +1604,48 @@ const m_option_type_t m_option_type_afmt = {
.copy = copy_opt,
};
+#include "audio/chmap.h"
+
+static int parse_chmap(const m_option_t *opt, struct bstr name,
+ struct bstr param, void *dst)
+{
+ // min>0: at least min channels, min=0: empty ok, min=-1: invalid ok
+ int min_ch = (opt->flags & M_OPT_MIN) ? opt->min : 1;
+
+ if (bstr_equals0(param, "help")) {
+ mp_chmap_print_help(MSGT_CFGPARSER, MSGL_INFO);
+ return M_OPT_EXIT - 1;
+ }
+
+ if (param.len == 0 && min_ch >= 1)
+ return M_OPT_MISSING_PARAM;
+
+ struct mp_chmap res = {0};
+ if (!mp_chmap_from_str(&res, param)) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Error parsing channel layout: %.*s\n", BSTR_P(param));
+ return M_OPT_INVALID;
+ }
+
+ if ((min_ch > 0 && !mp_chmap_is_valid(&res)) ||
+ (min_ch >= 0 && mp_chmap_is_empty(&res)))
+ {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Invalid channel layout: %.*s\n", BSTR_P(param));
+ return M_OPT_INVALID;
+ }
+
+ *(struct mp_chmap *)dst = res;
+
+ return 1;
+}
+
+const m_option_type_t m_option_type_chmap = {
+ .name = "Audio channels or channel map",
+ .size = sizeof(struct mp_chmap *),
+ .parse = parse_chmap,
+ .copy = copy_opt,
+};
static int parse_timestring(struct bstr str, double *time, char endchar)
{
diff --git a/core/m_option.h b/core/m_option.h
index 0026406569..c94b170424 100644
--- a/core/m_option.h
+++ b/core/m_option.h
@@ -25,6 +25,7 @@
#include "config.h"
#include "core/bstr.h"
+#include "audio/chmap.h"
// m_option allows to parse, print and copy data of various types.
@@ -60,6 +61,7 @@ extern const m_option_type_t m_option_type_afmt;
extern const m_option_type_t m_option_type_color;
extern const m_option_type_t m_option_type_geometry;
extern const m_option_type_t m_option_type_size_box;
+extern const m_option_type_t m_option_type_chmap;
// Callback used by m_option_type_print_func options.
typedef int (*m_opt_func_full_t)(const m_option_t *, const char *, const char *);
@@ -194,6 +196,7 @@ union m_option_value {
struct m_color color;
struct m_geometry geometry;
struct m_geometry size_box;
+ struct mp_chmap chmap;
};
////////////////////////////////////////////////////////////////////////////
@@ -568,6 +571,9 @@ int m_option_required_params(const m_option_t *opt);
#define OPT_AUDIOFORMAT(...) \
OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_afmt)
+#define OPT_CHMAP(...) \
+ OPT_GENERAL(struct mp_chmap, __VA_ARGS__, .type = &m_option_type_chmap)
+
#define M_CHOICES(choices) \
.priv = (void *)&(const struct m_opt_choice_alternatives[]){ \
diff --git a/core/mplayer.c b/core/mplayer.c
index 89d463daa1..361d3d5466 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -330,7 +330,7 @@ static void print_file_properties(struct MPContext *mpctx, const char *filename)
mp_msg(MSGT_IDENTIFY, MSGL_INFO,
"ID_AUDIO_RATE=%d\n", mpctx->sh_audio->samplerate);
mp_msg(MSGT_IDENTIFY, MSGL_INFO,
- "ID_AUDIO_NCH=%d\n", mpctx->sh_audio->channels);
+ "ID_AUDIO_NCH=%d\n", mpctx->sh_audio->channels.num);
start_pts = ds_get_next_pts(mpctx->sh_audio->ds);
}
if (video_start_pts != MP_NOPTS_VALUE) {
@@ -1700,6 +1700,12 @@ void reinit_audio_chain(struct MPContext *mpctx)
mpctx->ao = ao_create(opts, mpctx->input);
mpctx->ao->samplerate = opts->force_srate;
mpctx->ao->format = opts->audio_output_format;
+ // Automatic downmix
+ if (mp_chmap_is_stereo(&opts->audio_output_channels) &&
+ !mp_chmap_is_stereo(&mpctx->sh_audio->channels))
+ {
+ mp_chmap_from_channels(&mpctx->ao->channels, 2);
+ }
}
ao = mpctx->ao;
@@ -1716,6 +1722,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
if (!ao->initialized) {
ao->buffersize = opts->ao_buffersize;
ao->encode_lavc_ctx = mpctx->encode_lavc_ctx;
+ mp_chmap_remove_useless_channels(&ao->channels,
+ &opts->audio_output_channels);
ao_init(ao, opts->audio_driver_list);
if (!ao->initialized) {
mp_tmsg(MSGT_CPLAYER, MSGL_ERR,
@@ -1723,12 +1731,10 @@ void reinit_audio_chain(struct MPContext *mpctx)
goto init_error;
}
ao->buffer.start = talloc_new(ao);
- mp_msg(MSGT_CPLAYER, MSGL_INFO,
- "AO: [%s] %dHz %dch %s (%d bytes per sample)\n",
- ao->driver->info->short_name,
- ao->samplerate, ao->channels,
- af_fmt2str_short(ao->format),
- af_fmt2bits(ao->format) / 8);
+ char *s = mp_audio_fmt_to_str(ao->samplerate, &ao->channels, ao->format);
+ mp_msg(MSGT_CPLAYER, MSGL_INFO, "AO: [%s] %s\n",
+ ao->driver->info->short_name, s);
+ talloc_free(s);
mp_msg(MSGT_CPLAYER, MSGL_V, "AO: Description: %s\nAO: Author: %s\n",
ao->driver->info->name, ao->driver->info->author);
if (strlen(ao->driver->info->comment) > 0)
@@ -2295,7 +2301,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
ptsdiff = written_pts - mpctx->sh_video->pts - mpctx->delay
- mpctx->audio_delay;
bytes = ptsdiff * bps;
- bytes -= bytes % (ao->channels * af_fmt2bits(ao->format) / 8);
+ bytes -= bytes % (ao->channels.num * af_fmt2bits(ao->format) / 8);
// ogg demuxers give packets without timing
if (written_pts <= 1 && sh_audio->pts == MP_NOPTS_VALUE) {
@@ -2364,7 +2370,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
bool partial_fill = false;
sh_audio_t * const sh_audio = mpctx->sh_audio;
bool modifiable_audio_format = !(ao->format & AF_FORMAT_SPECIAL_MASK);
- int unitsize = ao->channels * af_fmt2bits(ao->format) / 8;
+ int unitsize = ao->channels.num * af_fmt2bits(ao->format) / 8;
if (mpctx->paused)
playsize = 1; // just initialize things (audio pts at least)
diff --git a/core/options.h b/core/options.h
index 9905397f0e..11286bf883 100644
--- a/core/options.h
+++ b/core/options.h
@@ -155,12 +155,11 @@ typedef struct MPOpts {
double force_fps;
- int audio_output_channels;
+ struct mp_chmap audio_output_channels;
int audio_output_format;
int force_srate;
int dtshd;
float playback_speed;
- float drc_level;
struct m_obj_settings *vf_settings;
float movie_aspect;
int flip;
@@ -210,6 +209,12 @@ typedef struct MPOpts {
char *avopt;
} lavc_param;
+ struct ad_lavc_param {
+ float ac3drc;
+ int downmix;
+ char *avopt;
+ } ad_lavc_param;
+
struct lavfdopts {
int probesize;
int probescore;