summaryrefslogtreecommitdiffstats
path: root/audio/filter
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-10 22:01:23 +0100
committerwm4 <wm4@nowhere>2014-11-10 22:02:05 +0100
commit5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1 (patch)
treea3a3ae0ac6ee87449ed780604e55da6dca2f34f2 /audio/filter
parent46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1 (diff)
downloadmpv-5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1.tar.bz2
mpv-5fd8a1e04c725329435e3bead5f11ee3ffb9f1c1.tar.xz
audio: make decoders output refcounted frames
This rewrites the audio decode loop to some degree. Audio filters don't do refcounted frames yet, so af.c contains a hacky "emulation". Remove some of the weird heuristic-heavy code in dec_audio.c. Instead of estimating how much audio we need to filter, we always filter full frames. Maybe this should be adjusted later: in case filtering increases the volume of the audio data, we should try not to buffer too much filter output by reducing the input that is fed at once. For ad_spdif.c and ad_mpg123.c, we don't avoid extra copying yet - it doesn't seem worth the trouble.
Diffstat (limited to 'audio/filter')
-rw-r--r--audio/filter/af.c44
-rw-r--r--audio/filter/af.h4
2 files changed, 38 insertions, 10 deletions
diff --git a/audio/filter/af.c b/audio/filter/af.c
index d396a73ce3..46e577537f 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -28,6 +28,7 @@
#include "options/m_option.h"
#include "options/m_config.h"
+#include "audio/audio_buffer.h"
#include "af.h"
// Static list of filters
@@ -721,24 +722,49 @@ int af_remove_by_label(struct af_stream *s, char *label)
return 1;
}
-/* Filter data chunk through the filters in the list.
- * On success, *data is set to the filtered data/format.
- * Warning: input audio data will be overwritten.
+/* Feed "data" to the chain, and write results to output. "data" needs to be
+ * a refcounted frame, although refcounting is not used yet.
+ * data==NULL means EOF.
*/
-int af_filter(struct af_stream *s, struct mp_audio *data, int flags)
+int af_filter(struct af_stream *s, struct mp_audio *data,
+ struct mp_audio_buffer *output)
{
struct af_instance *af = s->first;
assert(s->initialized > 0);
- assert(mp_audio_config_equals(af->data, data));
+ int flags = 0;
+ int r = 0;
+ struct mp_audio tmp;
+ char dummy[MP_NUM_CHANNELS];
+ if (data) {
+ assert(mp_audio_config_equals(af->data, data));
+ r = mp_audio_make_writeable(data);
+ } else {
+ data = &tmp;
+ *data = *(af->data);
+ mp_audio_set_null_data(data);
+ flags = AF_FILTER_FLAG_EOF;
+ for (int n = 0; n < MP_NUM_CHANNELS; n++)
+ data->planes[n] = &dummy[n];
+ }
+ if (r < 0)
+ goto done;
+ struct mp_audio frame = *data;
+ for (int n = 0; n < MP_NUM_CHANNELS; n++)
+ frame.allocated[n] = NULL;
// Iterate through all filters
while (af) {
- int r = af->filter(af, data, flags);
+ r = af->filter(af, &frame, flags);
if (r < 0)
- return r;
- assert(mp_audio_config_equals(af->data, data));
+ goto done;
+ assert(mp_audio_config_equals(af->data, &frame));
af = af->next;
}
- return 0;
+ mp_audio_buffer_append(output, &frame);
+
+done:
+ if (data != &tmp)
+ talloc_free(data);
+ return r;
}
// Calculate average ratio of filter output samples to input samples.
diff --git a/audio/filter/af.h b/audio/filter/af.h
index 5c7a6c0e7c..682cdb93e3 100644
--- a/audio/filter/af.h
+++ b/audio/filter/af.h
@@ -136,7 +136,9 @@ void af_uninit(struct af_stream *s);
struct af_instance *af_add(struct af_stream *s, char *name, 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);
-int af_filter(struct af_stream *s, struct mp_audio *data, int flags);
+struct mp_audio_buffer;
+int af_filter(struct af_stream *s, struct mp_audio *data,
+ struct mp_audio_buffer *output);
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
void af_control_all(struct af_stream *s, int cmd, void *arg);