[FFmpeg-devel] [PATCH 5/6] truehd: break out part of output_data into platform-specific callback.

Ben Avison bavison at riscosopen.org
Wed Mar 19 18:26:20 CET 2014


Verified with profiling that this doesn't have a measurable effect upon
overall performance.
---
 libavcodec/mlpdec.c |   40 +++++++++++++++++++++++-----------------
 libavcodec/mlpdsp.c |   36 ++++++++++++++++++++++++++++++++++++
 libavcodec/mlpdsp.h |   22 ++++++++++++++++++++++
 3 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index 01ded5c..1bbd433 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -363,6 +363,10 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
         m->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
     else
         m->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(m->substream[m->max_decoded_substream].max_matrix_channel,
+                                                           m->avctx->sample_fmt == AV_SAMPLE_FMT_S32,
+                                                           m->substream[m->max_decoded_substream].ch_assign,
+                                                           m->substream[m->max_decoded_substream].output_shift);
 
     m->params_valid = 1;
     for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
@@ -612,6 +616,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
     if (substr == m->max_decoded_substream) {
         m->avctx->channels       = s->max_matrix_channel + 1;
         m->avctx->channel_layout = s->ch_layout;
+        m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->max_matrix_channel,
+                                                               m->avctx->sample_fmt == AV_SAMPLE_FMT_S32,
+                                                               s->ch_assign,
+                                                               s->output_shift);
 
         if (m->avctx->codec_id == AV_CODEC_ID_MLP && m->needs_reordering) {
             if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) ||
@@ -857,9 +865,15 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
                 return ret;
 
     if (s->param_presence_flags & PARAM_OUTSHIFT)
-        if (get_bits1(gbp))
+        if (get_bits1(gbp)) {
             for (ch = 0; ch <= s->max_matrix_channel; ch++)
                 s->output_shift[ch] = get_sbits(gbp, 4);
+            if (substr == m->max_decoded_substream)
+                m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->max_matrix_channel,
+                                                                       m->avctx->sample_fmt == AV_SAMPLE_FMT_S32,
+                                                                       s->ch_assign,
+                                                                       s->output_shift);
+        }
 
     if (s->param_presence_flags & PARAM_QUANTSTEP)
         if (get_bits1(gbp))
@@ -1058,9 +1072,6 @@ static int output_data(MLPDecodeContext *m, unsigned int substr,
 {
     AVCodecContext *avctx = m->avctx;
     SubStream *s = &m->substream[substr];
-    unsigned int i, out_ch = 0;
-    int32_t *data_32;
-    int16_t *data_16;
     int ret;
     int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
 
@@ -1078,19 +1089,14 @@ static int output_data(MLPDecodeContext *m, unsigned int substr,
     frame->nb_samples = s->blockpos;
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
-    data_32 = (int32_t *)frame->data[0];
-    data_16 = (int16_t *)frame->data[0];
-
-    for (i = 0; i < s->blockpos; i++) {
-        for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) {
-            int mat_ch = s->ch_assign[out_ch];
-            int32_t sample = m->sample_buffer[i][mat_ch]
-                          << s->output_shift[mat_ch];
-            s->lossless_check_data ^= (sample & 0xffffff) << mat_ch;
-            if (is32) *data_32++ = sample << 8;
-            else      *data_16++ = sample >> 8;
-        }
-    }
+    s->lossless_check_data = m->dsp.mlp_pack_output(s->lossless_check_data,
+                                                    m->sample_buffer,
+                                                    frame->data[0],
+                                                    s->blockpos,
+                                                    s->max_matrix_channel,
+                                                    is32,
+                                                    s->ch_assign,
+                                                    s->output_shift);
 
     /* Update matrix encoding side data */
     if ((ret = ff_side_data_update_matrix_encoding(frame, s->matrix_encoding)) < 0)
diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c
index 7a359b0..d0769ba 100644
--- a/libavcodec/mlpdsp.c
+++ b/libavcodec/mlpdsp.c
@@ -89,10 +89,46 @@ void ff_mlp_rematrix_channel(int32_t *samples,
     }
 }
 
+static int32_t (*mlp_select_pack_output(uint8_t max_matrix_channel,
+                                        int is32,
+                                        uint8_t *ch_assign,
+                                        int8_t *output_shift))(int32_t, int32_t (*)[], void *, uint16_t, uint8_t, int, uint8_t*, int8_t *)
+{
+    return ff_mlp_pack_output;
+}
+
+int32_t ff_mlp_pack_output(int32_t lossless_check_data,
+                           int32_t (*sample_buffer)[MAX_CHANNELS],
+                           void *data,
+                           uint16_t blockpos,
+                           uint8_t max_matrix_channel,
+                           int is32,
+                           uint8_t *ch_assign,
+                           int8_t *output_shift)
+{
+    unsigned int i, out_ch = 0;
+    int32_t *data_32 = (int32_t *)data;
+    int16_t *data_16 = (int16_t *)data;
+
+    for (i = 0; i < blockpos; i++) {
+        for (out_ch = 0; out_ch <= max_matrix_channel; out_ch++) {
+            int mat_ch = ch_assign[out_ch];
+            int32_t sample = sample_buffer[i][mat_ch]
+                          << output_shift[mat_ch];
+            lossless_check_data ^= (sample & 0xffffff) << mat_ch;
+            if (is32) *data_32++ = sample << 8;
+            else      *data_16++ = sample >> 8;
+        }
+    }
+    return lossless_check_data;
+}
+
 av_cold void ff_mlpdsp_init(MLPDSPContext *c)
 {
     c->mlp_filter_channel = mlp_filter_channel;
     c->mlp_rematrix_channel = ff_mlp_rematrix_channel;
+    c->mlp_select_pack_output = mlp_select_pack_output;
+    c->mlp_pack_output = ff_mlp_pack_output;
     if (ARCH_ARM)
         ff_mlpdsp_init_arm(c);
     if (ARCH_X86)
diff --git a/libavcodec/mlpdsp.h b/libavcodec/mlpdsp.h
index f98e9be..5bc901f 100644
--- a/libavcodec/mlpdsp.h
+++ b/libavcodec/mlpdsp.h
@@ -23,6 +23,7 @@
 #define AVCODEC_MLPDSP_H
 
 #include <stdint.h>
+#include "mlp.h"
 
 void ff_mlp_rematrix_channel(int32_t *samples,
                              const int32_t *coeffs,
@@ -36,6 +37,15 @@ void ff_mlp_rematrix_channel(int32_t *samples,
                              int access_unit_size_pow2,
                              int32_t mask);
 
+int32_t ff_mlp_pack_output(int32_t lossless_check_data,
+                           int32_t (*sample_buffer)[MAX_CHANNELS],
+                           void *data,
+                           uint16_t blockpos,
+                           uint8_t max_matrix_channel,
+                           int is32,
+                           uint8_t *ch_assign,
+                           int8_t *output_shift);
+
 typedef struct MLPDSPContext {
     void (*mlp_filter_channel)(int32_t *state, const int32_t *coeff,
                                int firorder, int iirorder,
@@ -52,6 +62,18 @@ typedef struct MLPDSPContext {
                                  int matrix_noise_shift,
                                  int access_unit_size_pow2,
                                  int32_t mask);
+    int32_t (*(*mlp_select_pack_output)(uint8_t max_matrix_channel,
+                                        int is32,
+                                        uint8_t *ch_assign,
+                                        int8_t *output_shift))(int32_t, int32_t (*)[], void *, uint16_t, uint8_t, int, uint8_t*, int8_t *);
+    int32_t (*mlp_pack_output)(int32_t lossless_check_data,
+                               int32_t (*sample_buffer)[MAX_CHANNELS],
+                               void *data,
+                               uint16_t blockpos,
+                               uint8_t max_matrix_channel,
+                               int is32,
+                               uint8_t *ch_assign,
+                               int8_t *output_shift);
 } MLPDSPContext;
 
 void ff_mlpdsp_init(MLPDSPContext *c);
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list