summaryrefslogtreecommitdiffstats
path: root/audio/aframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/aframe.c')
-rw-r--r--audio/aframe.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/audio/aframe.c b/audio/aframe.c
index cb5d412f98..bc43bc98d2 100644
--- a/audio/aframe.c
+++ b/audio/aframe.c
@@ -520,6 +520,56 @@ bool mp_aframe_set_silence(struct mp_aframe *f, int offset, int samples)
return true;
}
+bool mp_aframe_reverse(struct mp_aframe *f)
+{
+ int format = mp_aframe_get_format(f);
+ size_t bps = af_fmt_to_bytes(format);
+ if (!af_fmt_is_pcm(format) || bps > 16)
+ return false;
+
+ uint8_t **d = mp_aframe_get_data_rw(f);
+ if (!d)
+ return false;
+
+ int planes = mp_aframe_get_planes(f);
+ int samples = mp_aframe_get_size(f);
+ int channels = mp_aframe_get_channels(f);
+ size_t sstride = mp_aframe_get_sstride(f);
+
+ int plane_samples = channels;
+ if (af_fmt_is_planar(format))
+ plane_samples = 1;
+
+ for (int p = 0; p < planes; p++) {
+ for (int n = 0; n < samples / 2; n++) {
+ int s1_offset = n * sstride;
+ int s2_offset = (samples - 1 - n) * sstride;
+ for (int c = 0; c < plane_samples; c++) {
+ // Nobody said it'd be fast.
+ char tmp[16];
+ uint8_t *s1 = d[p] + s1_offset + c * bps;
+ uint8_t *s2 = d[p] + s2_offset + c * bps;
+ memcpy(tmp, s2, bps);
+ memcpy(s2, s1, bps);
+ memcpy(s1, tmp, bps);
+ }
+ }
+ }
+
+ return true;
+}
+
+int mp_aframe_approx_byte_size(struct mp_aframe *frame)
+{
+ // God damn, AVFrame is too fucking annoying. Just go with the size that
+ // allocating a new frame would use.
+ int planes = mp_aframe_get_planes(frame);
+ size_t sstride = mp_aframe_get_sstride(frame);
+ int samples = frame->av_frame->nb_samples;
+ int plane_size = MP_ALIGN_UP(sstride * MPMAX(samples, 1), 32);
+ return plane_size * planes + sizeof(*frame);
+}
+
struct mp_aframe_pool {
AVBufferPool *avpool;
int element_size;