summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-13 20:14:25 +0100
committerwm4 <wm4@nowhere>2015-01-13 20:14:25 +0100
commit97becbc31bfd6acb76f584eaf65c1546d6fbcc8b (patch)
tree2296fed4fd1d1da2d0b493b635bdd006e71c6fce
parent0bbd65b09cb80ee6a822b27a53e7ddfd5d249cf2 (diff)
downloadmpv-97becbc31bfd6acb76f584eaf65c1546d6fbcc8b.tar.bz2
mpv-97becbc31bfd6acb76f584eaf65c1546d6fbcc8b.tar.xz
audio: add some utility functions for refcounted frames
Used in the following commits.
-rw-r--r--audio/audio.c68
-rw-r--r--audio/audio.h6
2 files changed, 64 insertions, 10 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 93e9f1814b..57eb9ca20f 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -227,6 +227,14 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset,
}
}
+// Copy fields that describe characteristics of the audio frame, but which are
+// not part of the core format (format/channels/rate), and not part of the
+// data (samples).
+void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src)
+{
+ // nothing yet
+}
+
// Set data to the audio after the given number of samples (i.e. slice it).
void mp_audio_skip_samples(struct mp_audio *data, int samples)
{
@@ -238,28 +246,40 @@ 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)
+// Return false if the frame data is shared, true otherwise.
+// Will return true for non-refcounted frames.
+bool mp_audio_is_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) {
+ return ok;
+}
+
+static void mp_audio_steal_data(struct mp_audio *dst, struct mp_audio *src)
+{
+ talloc_set_destructor(dst, mp_audio_destructor);
+ mp_audio_destructor(dst);
+ *dst = *src;
+ talloc_set_destructor(src, NULL);
+ talloc_free(src);
+}
+
+// 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)
+{
+ if (!mp_audio_is_writeable(data)) {
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);
+ mp_audio_steal_data(data, new);
}
return 0;
}
@@ -370,3 +390,31 @@ struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
}
return new;
}
+
+// Return a copy of the given frame.
+// Returns NULL on error.
+struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
+ struct mp_audio *frame)
+{
+ struct mp_audio *new = mp_audio_pool_get(pool, frame, frame->samples);
+ if (new) {
+ mp_audio_copy(new, 0, frame, 0, new->samples);
+ mp_audio_copy_attributes(new, frame);
+ }
+ return new;
+}
+
+// Exactly like mp_audio_make_writeable(), but get the data from the pool.
+int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
+ struct mp_audio *data)
+{
+ if (mp_audio_is_writeable(data))
+ return 0;
+ struct mp_audio *new = mp_audio_pool_get(pool, data, data->samples);
+ if (!new)
+ return -1;
+ mp_audio_copy(new, 0, data, 0, data->samples);
+ mp_audio_copy_attributes(new, data);
+ mp_audio_steal_data(data, new);
+ return 0;
+}
diff --git a/audio/audio.h b/audio/audio.h
index e2346ee0aa..39ceb00705 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -66,8 +66,10 @@ void mp_audio_fill_silence(struct mp_audio *mpa, int start, int length);
void mp_audio_copy(struct mp_audio *dst, int dst_offset,
struct mp_audio *src, int src_offset, int length);
+void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src);
void mp_audio_skip_samples(struct mp_audio *data, int samples);
+bool mp_audio_is_writeable(struct mp_audio *data);
int mp_audio_make_writeable(struct mp_audio *data);
struct AVFrame;
@@ -76,5 +78,9 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent);
struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
const struct mp_audio *fmt, int samples);
+struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
+ struct mp_audio *frame);
+int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
+ struct mp_audio *frame);
#endif