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