summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-10 20:52:30 +0100
committerwm4 <wm4@nowhere>2014-11-10 22:02:05 +0100
commit46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1 (patch)
treefa1c972bfec15114b87aaf045d54355cfb91cdba
parentc1b034f2aacd1c5ada1134125f6a526847c93479 (diff)
downloadmpv-46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1.tar.bz2
mpv-46d6fb9dc1a820b58dd3ffcc155195aea6bb0bd1.tar.xz
audio: add mp_audio_make_writeable()
-rw-r--r--audio/audio.c26
-rw-r--r--audio/audio.h2
2 files changed, 28 insertions, 0 deletions
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);