|
- /*
- * Copyright (c) 2007-2008 Ian Caulfield
- * 2009 Ramiro Polla
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- #include "config.h"
- #include "libavutil/attributes.h"
- #include "mlpdsp.h"
- #include "mlp.h"
-
- static void mlp_filter_channel(int32_t *state, const int32_t *coeff,
- int firorder, int iirorder,
- unsigned int filter_shift, int32_t mask,
- int blocksize, int32_t *sample_buffer)
- {
- int32_t *firbuf = state;
- int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
- const int32_t *fircoeff = coeff;
- const int32_t *iircoeff = coeff + MAX_FIR_ORDER;
- int i;
-
- for (i = 0; i < blocksize; i++) {
- int32_t residual = *sample_buffer;
- unsigned int order;
- int64_t accum = 0;
- int32_t result;
-
- for (order = 0; order < firorder; order++)
- accum += (int64_t) firbuf[order] * fircoeff[order];
- for (order = 0; order < iirorder; order++)
- accum += (int64_t) iirbuf[order] * iircoeff[order];
-
- accum = accum >> filter_shift;
- result = (accum + residual) & mask;
-
- *--firbuf = result;
- *--iirbuf = result - accum;
-
- *sample_buffer = result;
- sample_buffer += MAX_CHANNELS;
- }
- }
-
- void ff_mlp_rematrix_channel(int32_t *samples,
- const int32_t *coeffs,
- const uint8_t *bypassed_lsbs,
- const int8_t *noise_buffer,
- int index,
- unsigned int dest_ch,
- uint16_t blockpos,
- unsigned int maxchan,
- int matrix_noise_shift,
- int access_unit_size_pow2,
- int32_t mask)
- {
- unsigned int src_ch, i;
- int index2 = 2 * index + 1;
- for (i = 0; i < blockpos; i++) {
- int64_t accum = 0;
-
- for (src_ch = 0; src_ch <= maxchan; src_ch++)
- accum += (int64_t) samples[src_ch] * coeffs[src_ch];
-
- if (matrix_noise_shift) {
- index &= access_unit_size_pow2 - 1;
- accum += noise_buffer[index] << (matrix_noise_shift + 7);
- index += index2;
- }
-
- samples[dest_ch] = ((accum >> 14) & mask) + *bypassed_lsbs;
- bypassed_lsbs += MAX_CHANNELS;
- samples += MAX_CHANNELS;
- }
- }
-
- static int32_t (*mlp_select_pack_output(uint8_t *ch_assign,
- int8_t *output_shift,
- uint8_t max_matrix_channel,
- int is32))(int32_t, uint16_t, int32_t (*)[], void *, uint8_t*, int8_t *, uint8_t, int)
- {
- return ff_mlp_pack_output;
- }
-
- int32_t ff_mlp_pack_output(int32_t lossless_check_data,
- uint16_t blockpos,
- int32_t (*sample_buffer)[MAX_CHANNELS],
- void *data,
- uint8_t *ch_assign,
- int8_t *output_shift,
- uint8_t max_matrix_channel,
- int is32)
- {
- unsigned int i, out_ch = 0;
- int32_t *data_32 = data;
- int16_t *data_16 = 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)
- ff_mlpdsp_init_x86(c);
- }
|