summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-04-07 21:23:23 +0200
committerwm4 <wm4@nowhere>2015-04-07 21:24:22 +0200
commit579c4dac34546357a5fd1dfd67712df6a5930bf6 (patch)
tree917ea7531726635db21fb5c327f13acfd8352368 /audio
parente98ab5e596b003b68e44e8c94b5e393e52ed6b6b (diff)
downloadmpv-579c4dac34546357a5fd1dfd67712df6a5930bf6.tar.bz2
mpv-579c4dac34546357a5fd1dfd67712df6a5930bf6.tar.xz
audio: change a detail about filter insertion
The af_add() function has a problem: if the inserted filter returns AF_DETACH during init, the function will have a dangling pointer. Until now this was avoided by making sure none of the used filters actually return AF_DETACH, but it's getting infeasible. Solve this by requiring passing an unique label to af_add(), which is then used instead of the pointer.
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af.c17
-rw-r--r--audio/filter/af.h3
-rw-r--r--audio/mixer.c4
3 files changed, 14 insertions, 10 deletions
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 2889e87bb7..48f6d58868 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -689,8 +689,14 @@ int af_init(struct af_stream *s)
to the stream s. The filter will be inserted somewhere nice in the
list of filters. The return value is a pointer to the new filter,
If the filter couldn't be added the return value is NULL. */
-struct af_instance *af_add(struct af_stream *s, char *name, char **args)
+struct af_instance *af_add(struct af_stream *s, char *name, char *label,
+ char **args)
{
+ assert(label);
+
+ if (af_find_by_label(s, label))
+ return NULL;
+
struct af_instance *new;
// Insert the filter somewhere nice
if (af_is_conversion_filter(s->first->next))
@@ -699,17 +705,14 @@ struct af_instance *af_add(struct af_stream *s, char *name, char **args)
new = af_prepend(s, s->first->next, name, args);
if (!new)
return NULL;
+ new->label = talloc_strdup(new, label);
// Reinitalize the filter list
if (af_reinit(s) != AF_OK) {
- af_remove(s, new);
- if (af_reinit(s) != AF_OK) {
- af_uninit(s);
- af_init(s);
- }
+ af_remove_by_label(s, label);
return NULL;
}
- return new;
+ return af_find_by_label(s, label);
}
struct af_instance *af_find_by_label(struct af_stream *s, char *label)
diff --git a/audio/filter/af.h b/audio/filter/af.h
index 4c67208123..65a30f7dd1 100644
--- a/audio/filter/af.h
+++ b/audio/filter/af.h
@@ -141,7 +141,8 @@ struct af_stream *af_new(struct mpv_global *global);
void af_destroy(struct af_stream *s);
int af_init(struct af_stream *s);
void af_uninit(struct af_stream *s);
-struct af_instance *af_add(struct af_stream *s, char *name, char **args);
+struct af_instance *af_add(struct af_stream *s, char *name, char *label,
+ char **args);
int af_remove_by_label(struct af_stream *s, char *label);
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
diff --git a/audio/mixer.c b/audio/mixer.c
index 0eb9c86453..7ae7ed458d 100644
--- a/audio/mixer.c
+++ b/audio/mixer.c
@@ -135,7 +135,7 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
if (gain == 1.0)
return;
MP_VERBOSE(mixer, "Inserting volume filter.\n");
- if (!(af_add(mixer->af, "volume", NULL)
+ if (!(af_add(mixer->af, "volume", "softvol", NULL)
&& af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
MP_ERR(mixer, "No volume control available.\n");
}
@@ -222,7 +222,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
if (val == 0)
return;
- if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
+ if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
MP_ERR(mixer, "No balance control available.\n");
return;
}