History

audio: add global options for resampler defaults

This is part of trying to get rid of --af-defaults, and the af resample filter. It requires a complicated mechanism to set the defaults on the resample filter for backwards compatibility.

wm4 committed 8 years ago

Commit 6d4b4c01 parent 23edaf412 files · +116 −30Browse files

Unified · Split

12 files
  1. DOCS/interface-changes.rst +2 −0
  2. DOCS/man/options.rst +38 −10
  3. audio/aconverter.c +20 −8
  4. audio/aconverter.h +3 −1
  5. audio/filter/af.c +2 −1
  6. audio/filter/af.h +2 −0
  7. audio/filter/af_lavrresample.c +26 −0
  8. options/m_config.c +12 −5
  9. options/m_config.h +0 −3
  10. options/m_option.h +5 −0
  11. options/options.c +4 −1
  12. options/options.h +2 −1
DOCS/interface-changes.rst+2−0
@@ -25,6 +25,8 @@ Interface changes · 24 unmodified lines
25 - fix --external-files: strictly never select any tracks from them, unless25 - fix --external-files: strictly never select any tracks from them, unless
26 explicitly selected (this may or may not be expected)26 explicitly selected (this may or may not be expected)
27 - --ytdl is now always enabled, even for libmpv27 - --ytdl is now always enabled, even for libmpv
28 - add a number of --audio-resample-* options, which should from now on be
29 used instead of --af-defaults=lavrresample:...
28 --- mpv 0.28.0 ---30 --- mpv 0.28.0 ---
29 - rename --hwdec=mediacodec option to mediacodec-copy, to reflect31 - rename --hwdec=mediacodec option to mediacodec-copy, to reflect
30 conventions followed by other hardware video decoding APIs32 conventions followed by other hardware video decoding APIs
DOCS/man/options.rst+38−10
@@ -1441,16 +1441,6 @@ Audio · 1440 unmodified lines
1441 want. For example, most A/V receivers connected via HDMI and that can1441 want. For example, most A/V receivers connected via HDMI and that can
1442 do 7.1 would be served by: ``--audio-channels=7.1,5.1,stereo``1442 do 7.1 would be served by: ``--audio-channels=7.1,5.1,stereo``
1443 1443
1444``--audio-normalize-downmix=<yes|no>``
1445 Enable/disable normalization if surround audio is downmixed to stereo
1446 (default: no). If this is disabled, downmix can cause clipping. If it's
1447 enabled, the output might be too silent. It depends on the source audio.
1448
1449 Technically, this changes the ``normalize`` suboption of the
1450 ``lavrresample`` audio filter, which performs the downmixing.
1451
1452 If downmix happens outside of mpv for some reason, this has no effect.
1453
1454``--audio-display=<no|attachment>``1444``--audio-display=<no|attachment>``
1455 Setting this option to ``attachment`` (default) will display image1445 Setting this option to ``attachment`` (default) will display image
1456 attachments (e.g. album cover art) when playing audio files. It will1446 attachments (e.g. album cover art) when playing audio files. It will
@@ -3453,6 +3443,44 @@ Software Scaler · 1996 unmodified lines
3453``--sws-cvs=<v>``3443``--sws-cvs=<v>``
3454 Software scaler chroma vertical shifting. See ``--sws-scaler``.3444 Software scaler chroma vertical shifting. See ``--sws-scaler``.
3455 3445
3446Audio Resampler
3447---------------
3448
3449This controls the default options of any resampling done by mpv (but not within
3450libavfilter, within the system audio API resampler, or any other places).
3451
3452It also sets the defaults for the ``lavrresample`` audio filter.
3453
3454``--audio-resample-filter-size=<length>``
3455 Length of the filter with respect to the lower sampling rate. (default:
3456 16)
3457
3458``--audio-resample-phase-shift=<count>``
3459 Log2 of the number of polyphase entries. (..., 10->1024, 11->2048,
3460 12->4096, ...) (default: 10->1024)
3461
3462``--audio-resample-cutoff=<cutoff>``
3463 Cutoff frequency (0.0-1.0), default set depending upon filter length.
3464
3465``--audio-resample-linear=<yes|no>``
3466 If set then filters will be linearly interpolated between polyphase
3467 entries. (default: no)
3468
3469``--audio-normalize-downmix=<yes|no>``
3470 Enable/disable normalization if surround audio is downmixed to stereo
3471 (default: no). If this is disabled, downmix can cause clipping. If it's
3472 enabled, the output might be too quiet. It depends on the source audio.
3473
3474 Technically, this changes the ``normalize`` suboption of the
3475 ``lavrresample`` audio filter, which performs the downmixing.
3476
3477 If downmix happens outside of mpv for some reason, or in the decoder
3478 (decoder downmixing), or in the audio output (system mixer), this has no
3479 effect.
3480
3481``--audio-swresample-o=<string>``
3482 Set AVOptions on the SwrContext or AVAudioResampleContext. These should
3483 be documented by FFmpeg or Libav.
3456 3484
3457Terminal3485Terminal
3458--------3486--------
audio/aconverter.c+20−8
@@ -86,6 +86,23 @@ struct mp_aconverter { · 85 unmodified lines
86 bool output_eof; // queued output EOF86 bool output_eof; // queued output EOF
87};87};
88 88
89#define OPT_BASE_STRUCT struct mp_resample_opts
90const struct m_sub_options resample_config = {
91 .opts = (const m_option_t[]) {
92 OPT_INTRANGE("audio-resample-filter-size", filter_size, 0, 0, 32),
93 OPT_INTRANGE("audio-resample-phase-shift", phase_shift, 0, 0, 30),
94 OPT_FLAG("audio-resample-linear", linear, 0),
95 OPT_DOUBLE("audio-resample-cutoff", cutoff, M_OPT_RANGE,
96 .min = 0, .max = 1),
97 OPT_FLAG("audio-normalize-downmix", normalize, 0),
98 OPT_KEYVALUELIST("audio-swresample-o", avopts, 0),
99 {0}
100 },
101 .size = sizeof(struct mp_resample_opts),
102 .defaults = &(const struct mp_resample_opts)MP_RESAMPLE_OPTS_DEF,
103 .change_flags = UPDATE_AUDIO,
104};
105
89#if HAVE_LIBAVRESAMPLE106#if HAVE_LIBAVRESAMPLE
90static double get_delay(struct mp_aconverter *p)107static double get_delay(struct mp_aconverter *p)
91{108{
@@ -211,12 +228,7 @@ static bool configure_lavrr(struct mp_aconverter *p, bool verbose) · 119 unmodified lines
211 cutoff = MPMAX(1.0 - 6.5 / (p->opts->filter_size + 8), 0.80);228 cutoff = MPMAX(1.0 - 6.5 / (p->opts->filter_size + 8), 0.80);
212 av_opt_set_double(p->avrctx, "cutoff", cutoff, 0);229 av_opt_set_double(p->avrctx, "cutoff", cutoff, 0);
213 230
214 int global_normalize;
215 mp_read_option_raw(p->global, "audio-normalize-downmix", &m_option_type_flag,
216 &global_normalize);
217 int normalize = p->opts->normalize;231 int normalize = p->opts->normalize;
218 if (normalize < 0)
219 normalize = global_normalize;
220#if HAVE_LIBSWRESAMPLE232#if HAVE_LIBSWRESAMPLE
221 av_opt_set_double(p->avrctx, "rematrix_maxval", normalize ? 1 : 1000, 0);233 av_opt_set_double(p->avrctx, "rematrix_maxval", normalize ? 1 : 1000, 0);
222#else234#else
@@ -628,9 +640,9 @@ struct mp_aconverter *mp_aconverter_create(struct mpv_global *global, · 405 unmodified lines
628 p->log = log;640 p->log = log;
629 p->global = global;641 p->global = global;
630 642
631 static const struct mp_resample_opts defs = MP_RESAMPLE_OPTS_DEF;643 p->opts = opts;
632 644 if (!p->opts)
633 p->opts = opts ? opts : &defs;645 p->opts = mp_get_config_group(p, global, &resample_config);
634 646
635 p->reorder_buffer = mp_aframe_pool_create(p);647 p->reorder_buffer = mp_aframe_pool_create(p);
636 p->out_pool = mp_aframe_pool_create(p);648 p->out_pool = mp_aframe_pool_create(p);
audio/aconverter.h+3−1
@@ -23,9 +23,11 @@ struct mp_resample_opts { · 22 unmodified lines
23 .filter_size = 16, \23 .filter_size = 16, \
24 .cutoff = 0.0, \24 .cutoff = 0.0, \
25 .phase_shift = 10, \25 .phase_shift = 10, \
26 .normalize = -1, \26 .normalize = 0, \
27 }27 }
28 28
29extern const struct m_sub_options resample_config;
30
29struct mp_aconverter *mp_aconverter_create(struct mpv_global *global,31struct mp_aconverter *mp_aconverter_create(struct mpv_global *global,
30 struct mp_log *log,32 struct mp_log *log,
31 const struct mp_resample_opts *opts);33 const struct mp_resample_opts *opts);
audio/filter/af.c+2−1
@@ -63,6 +63,7 @@ static bool get_desc(struct m_obj_desc *dst, int index) · 62 unmodified lines
63 .priv_size = af->priv_size,63 .priv_size = af->priv_size,
64 .priv_defaults = af->priv_defaults,64 .priv_defaults = af->priv_defaults,
65 .options = af->options,65 .options = af->options,
66 .set_defaults = af->set_defaults,
66 .p = af,67 .p = af,
67 };68 };
68 return true;69 return true;
@@ -170,7 +171,7 @@ static struct af_instance *af_create(struct af_stream *s, char *name, · 101 unmodified lines
170 .out_pool = mp_audio_pool_create(af),171 .out_pool = mp_audio_pool_create(af),
171 };172 };
172 struct m_config *config =173 struct m_config *config =
173 m_config_from_obj_desc_and_args(af, s->log, NULL, &desc,174 m_config_from_obj_desc_and_args(af, s->log, s->global, &desc,
174 name, s->opts->af_defs, args);175 name, s->opts->af_defs, args);
175 if (!config)176 if (!config)
176 goto error;177 goto error;
audio/filter/af.h+2−0
@@ -52,6 +52,8 @@ struct af_info { · 51 unmodified lines
52 int priv_size;52 int priv_size;
53 const void *priv_defaults;53 const void *priv_defaults;
54 const struct m_option *options;54 const struct m_option *options;
55 // For m_obj_desc.set_defaults
56 void (*set_defaults)(struct mpv_global *global, void *p);
55};57};
56 58
57// Linked list of audio filters59// Linked list of audio filters
audio/filter/af_lavrresample.c+26−0
@@ -32,6 +32,7 @@ · 31 unmodified lines
32 32
33#include "common/av_common.h"33#include "common/av_common.h"
34#include "common/msg.h"34#include "common/msg.h"
35#include "options/m_config.h"
35#include "options/m_option.h"36#include "options/m_option.h"
36#include "audio/filter/af.h"37#include "audio/filter/af.h"
37#include "audio/fmt-conversion.h"38#include "audio/fmt-conversion.h"
@@ -42,6 +43,7 @@ struct af_resample { · 4 unmodified lines
42 int allow_detach;43 int allow_detach;
43 double playback_speed;44 double playback_speed;
44 struct mp_resample_opts opts;45 struct mp_resample_opts opts;
46 int global_normalize;
45 struct mp_aconverter *converter;47 struct mp_aconverter *converter;
46};48};
47 49
@@ -142,11 +144,34 @@ static int af_open(struct af_instance *af) · 94 unmodified lines
142 af->filter_frame = filter;144 af->filter_frame = filter;
143 af->filter_out = filter_out;145 af->filter_out = filter_out;
144 146
147 if (s->opts.normalize < 0)
148 s->opts.normalize = s->global_normalize;
149
145 s->converter = mp_aconverter_create(af->global, af->log, &s->opts);150 s->converter = mp_aconverter_create(af->global, af->log, &s->opts);
146 151
147 return AF_OK;152 return AF_OK;
148}153}
149 154
155static void set_defaults(struct mpv_global *global, void *p)
156{
157 struct af_resample *s = p;
158
159 struct mp_resample_opts *opts = &s->opts;
160
161 struct mp_resample_opts *src_opts =
162 mp_get_config_group(s, global, &resample_config);
163
164 s->global_normalize = src_opts->normalize;
165
166 assert(!opts->avopts); // we don't set a default value, so it must be NULL
167
168 *opts = *src_opts;
169
170 opts->avopts = NULL;
171 struct m_option dummy = {.type = &m_option_type_keyvalue_list};
172 m_option_copy(&dummy, &opts->avopts, &src_opts->avopts);
173}
174
150#define OPT_BASE_STRUCT struct af_resample175#define OPT_BASE_STRUCT struct af_resample
151 176
152const struct af_info af_info_lavrresample = {177const struct af_info af_info_lavrresample = {
@@ -170,4 +195,5 @@ const struct af_info af_info_lavrresample = { · 17 unmodified lines
170 OPT_KEYVALUELIST("o", opts.avopts, 0),195 OPT_KEYVALUELIST("o", opts.avopts, 0),
171 {0}196 {0}
172 },197 },
198 .set_defaults = set_defaults,
173};199};
options/m_config.c+12−5
@@ -194,11 +194,18 @@ struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log, · 193 unmodified lines
194 return config;194 return config;
195}195}
196 196
197struct m_config *m_config_from_obj_desc(void *talloc_ctx, struct mp_log *log,197static struct m_config *m_config_from_obj_desc(void *talloc_ctx,
198 struct m_obj_desc *desc)198 struct mp_log *log,
199 struct mpv_global *global,
200 struct m_obj_desc *desc)
199{201{
200 return m_config_new(talloc_ctx, log, desc->priv_size, desc->priv_defaults,202 struct m_config *c =
201 desc->options);203 m_config_new(talloc_ctx, log, desc->priv_size, desc->priv_defaults,
204 desc->options);
205 c->global = global;
206 if (desc->set_defaults && c->global)
207 desc->set_defaults(c->global, c->optstruct);
208 return c;
202}209}
203 210
204// Like m_config_from_obj_desc(), but don't allocate option struct.211// Like m_config_from_obj_desc(), but don't allocate option struct.
@@ -260,7 +267,7 @@ struct m_config *m_config_from_obj_desc_and_args(void *ta_parent, · 55 unmodified lines
260 struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc,267 struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc,
261 const char *name, struct m_obj_settings *defaults, char **args)268 const char *name, struct m_obj_settings *defaults, char **args)
262{269{
263 struct m_config *config = m_config_from_obj_desc(ta_parent, log, desc);270 struct m_config *config = m_config_from_obj_desc(ta_parent, log, global, desc);
264 271
265 for (int n = 0; defaults && defaults[n].name; n++) {272 for (int n = 0; defaults && defaults[n].name; n++) {
266 struct m_obj_settings *entry = &defaults[n];273 struct m_obj_settings *entry = &defaults[n];
options/m_config.h+0−3
@@ -123,9 +123,6 @@ struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log, · 122 unmodified lines
123// mpv_global. Expected to be called at early init on the main m_config.123// mpv_global. Expected to be called at early init on the main m_config.
124void m_config_create_shadow(struct m_config *config);124void m_config_create_shadow(struct m_config *config);
125 125
126struct m_config *m_config_from_obj_desc(void *talloc_ctx, struct mp_log *log,
127 struct m_obj_desc *desc);
128
129struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx,126struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx,
130 struct mp_log *log,127 struct mp_log *log,
131 struct m_obj_desc *desc);128 struct m_obj_desc *desc);
options/m_option.h+5−0
@@ -32,6 +32,7 @@ typedef struct m_option m_option_t; · 31 unmodified lines
32struct m_config;32struct m_config;
33struct mp_log;33struct mp_log;
34struct mpv_node;34struct mpv_node;
35struct mpv_global;
35 36
36///////////////////////////// Options types declarations ////////////////////37///////////////////////////// Options types declarations ////////////////////
37 38
@@ -129,6 +130,10 @@ struct m_obj_desc { · 91 unmodified lines
129 bool hidden;130 bool hidden;
130 // Callback to print custom help if "help" is passed131 // Callback to print custom help if "help" is passed
131 void (*print_help)(struct mp_log *log);132 void (*print_help)(struct mp_log *log);
133 // Callback that allows you to override the static default values. The
134 // pointer p points to the struct described by options/priv_size, with
135 // priv_defaults already applied. You can write to it to set any defaults.
136 void (*set_defaults)(struct mpv_global *global, void *p);
132 // Set by m_obj_list_find(). If the requested name is an old alias, this137 // Set by m_obj_list_find(). If the requested name is an old alias, this
133 // is set to the old name (while the name field uses the new name).138 // is set to the old name (while the name field uses the new name).
134 const char *replaced_name;139 const char *replaced_name;
options/options.c+4−1
@@ -94,6 +94,8 @@ extern const struct m_sub_options angle_conf; · 93 unmodified lines
94extern const struct m_sub_options cocoa_conf;94extern const struct m_sub_options cocoa_conf;
95extern const struct m_sub_options android_conf;95extern const struct m_sub_options android_conf;
96 96
97extern const struct m_sub_options resample_config;
98
97static const struct m_sub_options screenshot_conf = {99static const struct m_sub_options screenshot_conf = {
98 .opts = image_writer_opts,100 .opts = image_writer_opts,
99 .size = sizeof(struct image_writer_opts),101 .size = sizeof(struct image_writer_opts),
@@ -474,7 +476,6 @@ const m_option_t mp_opts[] = { · 374 unmodified lines
474 OPT_INTRANGE("audio-samplerate", force_srate, UPDATE_AUDIO, 1000, 16*48000),476 OPT_INTRANGE("audio-samplerate", force_srate, UPDATE_AUDIO, 1000, 16*48000),
475 OPT_CHANNELS("audio-channels", audio_output_channels, UPDATE_AUDIO),477 OPT_CHANNELS("audio-channels", audio_output_channels, UPDATE_AUDIO),
476 OPT_AUDIOFORMAT("audio-format", audio_output_format, UPDATE_AUDIO),478 OPT_AUDIOFORMAT("audio-format", audio_output_format, UPDATE_AUDIO),
477 OPT_FLAG("audio-normalize-downmix", audio_normalize, UPDATE_AUDIO),
478 OPT_DOUBLE("speed", playback_speed, M_OPT_RANGE, .min = 0.01, .max = 100.0),479 OPT_DOUBLE("speed", playback_speed, M_OPT_RANGE, .min = 0.01, .max = 100.0),
479 480
480 OPT_FLAG("audio-pitch-correction", pitch_correction, 0),481 OPT_FLAG("audio-pitch-correction", pitch_correction, 0),
@@ -691,6 +692,8 @@ const m_option_t mp_opts[] = { · 210 unmodified lines
691 692
692 OPT_STRING("record-file", record_file, M_OPT_FILE),693 OPT_STRING("record-file", record_file, M_OPT_FILE),
693 694
695 OPT_SUBSTRUCT("", resample_opts, resample_config, 0),
696
694 OPT_SUBSTRUCT("", input_opts, input_config, 0),697 OPT_SUBSTRUCT("", input_opts, input_config, 0),
695 698
696 OPT_SUBSTRUCT("", vo, vo_sub_opts, 0),699 OPT_SUBSTRUCT("", vo, vo_sub_opts, 0),
options/options.h+2−1
@@ -275,7 +275,6 @@ typedef struct MPOpts { · 274 unmodified lines
275 275
276 struct m_channels audio_output_channels;276 struct m_channels audio_output_channels;
277 int audio_output_format;277 int audio_output_format;
278 int audio_normalize;
279 int force_srate;278 int force_srate;
280 double playback_speed;279 double playback_speed;
281 int pitch_correction;280 int pitch_correction;
@@ -331,6 +330,8 @@ typedef struct MPOpts { · 49 unmodified lines
331 330
332 int wingl_dwm_flush;331 int wingl_dwm_flush;
333 332
333 struct mp_resample_opts *resample_opts;
334
334 struct gl_video_opts *gl_video_opts;335 struct gl_video_opts *gl_video_opts;
335 struct angle_opts *angle_opts;336 struct angle_opts *angle_opts;
336 struct opengl_opts *opengl_opts;337 struct opengl_opts *opengl_opts;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t