xref: /third_party/ffmpeg/libavcodec/mlpdsp.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2007-2008 Ian Caulfield
3cabdff1aSopenharmony_ci *               2009 Ramiro Polla
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "config.h"
23cabdff1aSopenharmony_ci#include "libavutil/attributes.h"
24cabdff1aSopenharmony_ci#include "mlpdsp.h"
25cabdff1aSopenharmony_ci#include "mlp.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_cistatic void mlp_filter_channel(int32_t *state, const int32_t *coeff,
28cabdff1aSopenharmony_ci                               int firorder, int iirorder,
29cabdff1aSopenharmony_ci                               unsigned int filter_shift, int32_t mask,
30cabdff1aSopenharmony_ci                               int blocksize, int32_t *sample_buffer)
31cabdff1aSopenharmony_ci{
32cabdff1aSopenharmony_ci    int32_t *firbuf = state;
33cabdff1aSopenharmony_ci    int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
34cabdff1aSopenharmony_ci    const int32_t *fircoeff = coeff;
35cabdff1aSopenharmony_ci    const int32_t *iircoeff = coeff + MAX_FIR_ORDER;
36cabdff1aSopenharmony_ci    int i;
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci    for (i = 0; i < blocksize; i++) {
39cabdff1aSopenharmony_ci        int32_t residual = *sample_buffer;
40cabdff1aSopenharmony_ci        unsigned int order;
41cabdff1aSopenharmony_ci        int64_t accum = 0;
42cabdff1aSopenharmony_ci        int32_t result;
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci        for (order = 0; order < firorder; order++)
45cabdff1aSopenharmony_ci            accum += (int64_t) firbuf[order] * fircoeff[order];
46cabdff1aSopenharmony_ci        for (order = 0; order < iirorder; order++)
47cabdff1aSopenharmony_ci            accum += (int64_t) iirbuf[order] * iircoeff[order];
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci        accum  = accum >> filter_shift;
50cabdff1aSopenharmony_ci        result = (accum + residual) & mask;
51cabdff1aSopenharmony_ci
52cabdff1aSopenharmony_ci        *--firbuf = result;
53cabdff1aSopenharmony_ci        *--iirbuf = result - accum;
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ci        *sample_buffer = result;
56cabdff1aSopenharmony_ci        sample_buffer += MAX_CHANNELS;
57cabdff1aSopenharmony_ci    }
58cabdff1aSopenharmony_ci}
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_civoid ff_mlp_rematrix_channel(int32_t *samples,
61cabdff1aSopenharmony_ci                             const int32_t *coeffs,
62cabdff1aSopenharmony_ci                             const uint8_t *bypassed_lsbs,
63cabdff1aSopenharmony_ci                             const int8_t *noise_buffer,
64cabdff1aSopenharmony_ci                             int index,
65cabdff1aSopenharmony_ci                             unsigned int dest_ch,
66cabdff1aSopenharmony_ci                             uint16_t blockpos,
67cabdff1aSopenharmony_ci                             unsigned int maxchan,
68cabdff1aSopenharmony_ci                             int matrix_noise_shift,
69cabdff1aSopenharmony_ci                             int access_unit_size_pow2,
70cabdff1aSopenharmony_ci                             int32_t mask)
71cabdff1aSopenharmony_ci{
72cabdff1aSopenharmony_ci    unsigned int src_ch, i;
73cabdff1aSopenharmony_ci    int index2 = 2 * index + 1;
74cabdff1aSopenharmony_ci    for (i = 0; i < blockpos; i++) {
75cabdff1aSopenharmony_ci        int64_t accum = 0;
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci        for (src_ch = 0; src_ch <= maxchan; src_ch++)
78cabdff1aSopenharmony_ci            accum += (int64_t) samples[src_ch] * coeffs[src_ch];
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci        if (matrix_noise_shift) {
81cabdff1aSopenharmony_ci            index &= access_unit_size_pow2 - 1;
82cabdff1aSopenharmony_ci            accum += noise_buffer[index] * (1 << (matrix_noise_shift + 7));
83cabdff1aSopenharmony_ci            index += index2;
84cabdff1aSopenharmony_ci        }
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci        samples[dest_ch] = ((accum >> 14) & mask) + *bypassed_lsbs;
87cabdff1aSopenharmony_ci        bypassed_lsbs += MAX_CHANNELS;
88cabdff1aSopenharmony_ci        samples += MAX_CHANNELS;
89cabdff1aSopenharmony_ci    }
90cabdff1aSopenharmony_ci}
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_cistatic int32_t (*mlp_select_pack_output(uint8_t *ch_assign,
93cabdff1aSopenharmony_ci                                        int8_t *output_shift,
94cabdff1aSopenharmony_ci                                        uint8_t max_matrix_channel,
95cabdff1aSopenharmony_ci                                        int is32))(int32_t, uint16_t, int32_t (*)[], void *, uint8_t*, int8_t *, uint8_t, int)
96cabdff1aSopenharmony_ci{
97cabdff1aSopenharmony_ci    return ff_mlp_pack_output;
98cabdff1aSopenharmony_ci}
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ciint32_t ff_mlp_pack_output(int32_t lossless_check_data,
101cabdff1aSopenharmony_ci                           uint16_t blockpos,
102cabdff1aSopenharmony_ci                           int32_t (*sample_buffer)[MAX_CHANNELS],
103cabdff1aSopenharmony_ci                           void *data,
104cabdff1aSopenharmony_ci                           uint8_t *ch_assign,
105cabdff1aSopenharmony_ci                           int8_t *output_shift,
106cabdff1aSopenharmony_ci                           uint8_t max_matrix_channel,
107cabdff1aSopenharmony_ci                           int is32)
108cabdff1aSopenharmony_ci{
109cabdff1aSopenharmony_ci    unsigned int i, out_ch = 0;
110cabdff1aSopenharmony_ci    int32_t *data_32 = data;
111cabdff1aSopenharmony_ci    int16_t *data_16 = data;
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci    for (i = 0; i < blockpos; i++) {
114cabdff1aSopenharmony_ci        for (out_ch = 0; out_ch <= max_matrix_channel; out_ch++) {
115cabdff1aSopenharmony_ci            int mat_ch = ch_assign[out_ch];
116cabdff1aSopenharmony_ci            int32_t sample = sample_buffer[i][mat_ch] *
117cabdff1aSopenharmony_ci                          (1U << output_shift[mat_ch]);
118cabdff1aSopenharmony_ci            lossless_check_data ^= (sample & 0xffffff) << mat_ch;
119cabdff1aSopenharmony_ci            if (is32)
120cabdff1aSopenharmony_ci                *data_32++ = sample * 256U;
121cabdff1aSopenharmony_ci            else
122cabdff1aSopenharmony_ci                *data_16++ = sample >> 8;
123cabdff1aSopenharmony_ci        }
124cabdff1aSopenharmony_ci    }
125cabdff1aSopenharmony_ci    return lossless_check_data;
126cabdff1aSopenharmony_ci}
127cabdff1aSopenharmony_ci
128cabdff1aSopenharmony_ciav_cold void ff_mlpdsp_init(MLPDSPContext *c)
129cabdff1aSopenharmony_ci{
130cabdff1aSopenharmony_ci    c->mlp_filter_channel = mlp_filter_channel;
131cabdff1aSopenharmony_ci    c->mlp_rematrix_channel = ff_mlp_rematrix_channel;
132cabdff1aSopenharmony_ci    c->mlp_select_pack_output = mlp_select_pack_output;
133cabdff1aSopenharmony_ci    c->mlp_pack_output = ff_mlp_pack_output;
134cabdff1aSopenharmony_ci#if ARCH_ARM
135cabdff1aSopenharmony_ci    ff_mlpdsp_init_arm(c);
136cabdff1aSopenharmony_ci#elif ARCH_X86
137cabdff1aSopenharmony_ci    ff_mlpdsp_init_x86(c);
138cabdff1aSopenharmony_ci#endif
139cabdff1aSopenharmony_ci}
140