From 46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 10 Nov 2014 20:52:30 +0100 Subject: [PATCH] audio: add mp_audio_make_writeable() --- audio/audio.c | 26 ++++++++++++++++++++++++++ audio/audio.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/audio/audio.c b/audio/audio.c index ed07c4dc91..7721fa4d0b 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -244,6 +244,32 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples) data->samples -= samples; } +// Make sure the frame owns the audio data, and if not, copy the data. +// Return negative value on failure (which means it can't be made writeable). +// Non-refcounted frames are always considered writeable. +int mp_audio_make_writeable(struct mp_audio *data) +{ + bool ok = true; + for (int n = 0; n < MP_NUM_CHANNELS; n++) { + if (data->allocated[n]) + ok &= av_buffer_is_writable(data->allocated[n]); + } + if (!ok) { + struct mp_audio *new = talloc(NULL, struct mp_audio); + *new = *data; + mp_audio_set_null_data(new); // use format only + mp_audio_realloc(new, data->samples); + new->samples = data->samples; + mp_audio_copy(new, 0, data, 0, data->samples); + // "Transfer" the reference. + mp_audio_destructor(data); + *data = *new; + talloc_set_destructor(new, NULL); + talloc_free(new); + } + return 0; +} + struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe) { struct mp_audio *new = talloc_zero(NULL, struct mp_audio); diff --git a/audio/audio.h b/audio/audio.h index 63c37ac03c..0b092867ca 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -68,6 +68,8 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset, struct mp_audio *src, int src_offset, int length); void mp_audio_skip_samples(struct mp_audio *data, int samples); +int mp_audio_make_writeable(struct mp_audio *data); + struct AVFrame; struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);