summaryrefslogtreecommitdiffstats
path: root/audio/audio.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-10 18:45:24 +0100
committerwm4 <wm4@nowhere>2014-11-10 22:02:04 +0100
commit0b26d8c66639c1e12035448eb2feadcf067dc056 (patch)
treeffdec8d6fd854810385530a87a5afe82b90f2e20 /audio/audio.c
parent5d46e44160fe9ab6a922b594d10f2e4e70242ab7 (diff)
downloadmpv-0b26d8c66639c1e12035448eb2feadcf067dc056.tar.bz2
mpv-0b26d8c66639c1e12035448eb2feadcf067dc056.tar.xz
audio: add function to convert AVFrame to mp_audio references
This is somewhat duplicated from ad_lavc.c and af_lavfi.c, but will eventually be used by both.
Diffstat (limited to 'audio/audio.c')
-rw-r--r--audio/audio.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 725658070e..3d93f7d4c4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -21,9 +21,12 @@
#include <assert.h>
#include <libavutil/buffer.h>
+#include <libavutil/frame.h>
+#include <libavutil/version.h>
#include "talloc.h"
#include "common/common.h"
+#include "fmt-conversion.h"
#include "audio.h"
static void update_redundant_info(struct mp_audio *mpa)
@@ -239,6 +242,51 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
data->samples -= samples;
}
+struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
+{
+ struct mp_audio *new = talloc_zero(NULL, struct mp_audio);
+ talloc_set_destructor(new, mp_audio_destructor);
+
+ mp_audio_set_format(new, af_from_avformat(avframe->format));
+
+ struct mp_chmap lavc_chmap;
+ mp_chmap_from_lavc(&lavc_chmap, avframe->channel_layout);
+
+#if LIBAVUTIL_VERSION_MICRO >= 100
+ // FFmpeg being special again
+ if (lavc_chmap.num != avframe->channels)
+ mp_chmap_from_channels(&lavc_chmap, avframe->channels);
+#endif
+
+ new->rate = avframe->sample_rate;
+
+ mp_audio_set_channels(new, &lavc_chmap);
+
+ // If we can't handle the format (e.g. too many channels), bail out.
+ if (!mp_audio_config_valid(new) || avframe->nb_extended_buf)
+ goto fail;
+
+ for (int n = 0; n < AV_NUM_DATA_POINTERS; n++) {
+ if (!avframe->buf[n])
+ break;
+ if (n >= MP_NUM_CHANNELS)
+ goto fail;
+ new->allocated[n] = av_buffer_ref(avframe->buf[n]);
+ if (!new->allocated[n])
+ goto fail;
+ }
+
+ for (int n = 0; n < new->num_planes; n++)
+ new->planes[n] = avframe->data[n];
+ new->samples = avframe->nb_samples;
+
+ return new;
+
+fail:
+ talloc_free(new);
+ return NULL;
+}
+
struct mp_audio_pool {
AVBufferPool *avpool;
int element_size;