summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-12 22:26:59 +0100
committerwm4 <wm4@nowhere>2013-11-12 23:35:33 +0100
commitcc5083cfe00e6872d0b52b6be917b80582c64e52 (patch)
tree18f8fb23046d670b208ec16f91db69fbb4b3d5dc /audio
parente1656d369af03d24d8c0008910c805a29a0c27ec (diff)
downloadmpv-cc5083cfe00e6872d0b52b6be917b80582c64e52.tar.bz2
mpv-cc5083cfe00e6872d0b52b6be917b80582c64e52.tar.xz
mp_audio: use av_malloc (cargo cult for libav*)
libav* is generally freaking horrible, and might do bad things if the data pointer passed to it are not aligned. One way to be sure that the alignment is correct is allocating all pointers using av_malloc(). It's possible that this is not needed at all, though. For now it might be better to keep this, since the mp_audio code is intended to replace another buffer in dec_audio.c, which is currently av_malloc() allocated. The original reason why this uses av_malloc() is apparently because libavcodec used to directly encode into mplayer buffers, which is not the case anymore, and thus (probably) doesn't make sense anymore. (The commit subject uses the word "cargo cult", after all.)
Diffstat (limited to 'audio')
-rw-r--r--audio/audio.c30
-rw-r--r--audio/audio.h3
2 files changed, 30 insertions, 3 deletions
diff --git a/audio/audio.c b/audio/audio.c
index ace455f123..2a67e22e5e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -17,6 +17,8 @@
#include <assert.h>
+#include <libavutil/mem.h>
+
#include "mpvcore/mp_common.h"
#include "mpvcore/mp_talloc.h"
#include "audio.h"
@@ -110,6 +112,16 @@ void mp_audio_set_null_data(struct mp_audio *mpa)
mpa->samples = 0;
}
+static void mp_audio_destructor(void *ptr)
+{
+ struct mp_audio *mpa = ptr;
+ for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
+ // Note: don't free if not allocated by mp_audio_realloc
+ if (mpa->allocated[n])
+ av_free(mpa->planes[n]);
+ }
+}
+
/* Reallocate the data stored in mpa->planes[n] so that enough samples are
* available on every plane. The previous data is kept (for the smallest
* common number of samples before/after resize).
@@ -129,12 +141,24 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
assert(samples >= 0);
int size = MPMAX(samples * mpa->sstride, 1);
for (int n = 0; n < mpa->num_planes; n++) {
- mpa->planes[n] = talloc_realloc_size(mpa, mpa->planes[n], size);
+ if (size != mpa->allocated[n]) {
+ // Note: av_realloc() can't be used (see libavutil doxygen)
+ void *new = av_malloc(size);
+ if (!new)
+ abort();
+ if (mpa->allocated[n])
+ memcpy(new, mpa->planes[n], MPMIN(mpa->allocated[n], size));
+ av_free(mpa->planes[n]);
+ mpa->planes[n] = new;
+ mpa->allocated[n] = size;
+ }
}
for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
- talloc_free(mpa->planes[n]);
+ av_free(mpa->planes[n]);
mpa->planes[n] = NULL;
+ mpa->allocated[n] = 0;
}
+ talloc_set_destructor(mpa, mp_audio_destructor);
}
// Like mp_audio_realloc(), but only reallocate if the audio grows in size.
@@ -154,7 +178,7 @@ int mp_audio_get_allocated_size(struct mp_audio *mpa)
{
int size = 0;
for (int n = 0; n < mpa->num_planes; n++) {
- int s = talloc_get_size(mpa->planes[n]) / mpa->sstride;
+ int s = mpa->allocated[n] / mpa->sstride;
size = n == 0 ? s : MPMIN(size, s);
}
return size;
diff --git a/audio/audio.h b/audio/audio.h
index b5cae0c83c..54ac2d5aac 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -36,6 +36,9 @@ struct mp_audio {
int spf; // sub-samples per sample on each plane
int num_planes; // number of planes
int bps; // size of sub-samples (af_fmt2bits(format) / 8)
+
+ // private
+ int allocated[MP_NUM_CHANNELS]; // use mp_audio_get_allocated_size()
};
void mp_audio_set_format(struct mp_audio *mpa, int format);