FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aac/aacdec_lpd.c
Date: 2024-07-16 12:46:59
Exec Total Coverage
Lines: 0 76 0.0%
Functions: 0 4 0.0%
Branches: 0 66 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2024 Lynne <dev@lynne.ee>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "aacdec_lpd.h"
22 #include "aacdec_usac.h"
23 #include "libavcodec/unary.h"
24
25 const uint8_t ff_aac_lpd_mode_tab[32][4] = {
26 { 0, 0, 0, 0 },
27 { 1, 0, 0, 0 },
28 { 0, 1, 0, 0 },
29 { 1, 1, 0, 0 },
30 { 0, 0, 1, 0 },
31 { 1, 0, 1, 0 },
32 { 0, 1, 1, 0 },
33 { 1, 1, 1, 0 },
34 { 0, 0, 0, 1 },
35 { 1, 0, 0, 1 },
36 { 0, 1, 0, 1 },
37 { 1, 1, 0, 1 },
38 { 0, 0, 1, 1 },
39 { 1, 0, 1, 1 },
40 { 0, 1, 1, 1 },
41 { 1, 1, 1, 1 },
42 { 2, 2, 0, 0 },
43 { 2, 2, 1, 0 },
44 { 2, 2, 0, 1 },
45 { 2, 2, 1, 1 },
46 { 0, 0, 2, 2 },
47 { 1, 0, 2, 2 },
48 { 0, 1, 2, 2 },
49 { 1, 1, 2, 2 },
50 { 2, 2, 2, 2 },
51 { 3, 3, 3, 3 },
52 /* Larger values are reserved, but permit them for resilience */
53 { 0, 0, 0, 0 },
54 { 0, 0, 0, 0 },
55 { 0, 0, 0, 0 },
56 { 0, 0, 0, 0 },
57 { 0, 0, 0, 0 },
58 { 0, 0, 0, 0 },
59 };
60
61 static void parse_qn(GetBitContext *gb, int *qn, int nk_mode, int no_qn)
62 {
63 if (nk_mode == 1) {
64 for (int k = 0; k < no_qn; k++) {
65 qn[k] = get_unary(gb, 0, INT32_MAX); // TODO: find proper ranges
66 if (qn[k])
67 qn[k]++;
68 }
69 return;
70 }
71
72 for (int k = 0; k < no_qn; k++)
73 qn[k] = get_bits(gb, 2) + 2;
74
75 if (nk_mode == 2) {
76 for (int k = 0; k < no_qn; k++) {
77 if (qn[k] > 4) {
78 qn[k] = get_unary(gb, 0, INT32_MAX);;
79 if (qn[k])
80 qn[k] += 4;
81 }
82 }
83 return;
84 }
85
86 for (int k = 0; k < no_qn; k++) {
87 if (qn[k] > 4) {
88 int qn_ext = get_unary(gb, 0, INT32_MAX);;
89 switch (qn_ext) {
90 case 0: qn[k] = 5; break;
91 case 1: qn[k] = 6; break;
92 case 2: qn[k] = 0; break;
93 default: qn[k] = qn_ext + 4; break;
94 }
95 }
96 }
97 }
98
99 static int parse_codebook_idx(GetBitContext *gb, uint32_t *kv,
100 int nk_mode, int no_qn)
101 {
102 int n, nk;
103
104 int qn[2];
105 parse_qn(gb, qn, nk_mode, no_qn);
106
107 for (int k = 0; k < no_qn; k++) {
108 if (qn[k] > 4) {
109 nk = (qn[k] - 3) / 2;
110 n = qn[k] - nk*2;
111 } else {
112 nk = 0;
113 n = qn[k];
114 }
115 }
116
117 skip_bits(gb, 4*n);
118
119 if (nk > 0)
120 for (int i = 0; i < 8; i++)
121 kv[i] = get_bits(gb, nk);
122
123 return 0;
124 }
125
126 int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
127 int use_gain, int len)
128 {
129 int ret;
130 if (use_gain)
131 ce->fac.gain = get_bits(gb, 7);
132
133 for (int i = 0; i < len/8; i++) {
134 ret = parse_codebook_idx(gb, ce->fac.kv[i], 1, 1);
135 if (ret < 0)
136 return ret;
137 }
138
139 return 0;
140 }
141
142 int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
143 AACUsacElemData *ce, GetBitContext *gb)
144 {
145 int k;
146 const uint8_t *mod;
147 int first_ldp_flag;
148
149 ce->ldp.acelp_core_mode = get_bits(gb, 3);
150 ce->ldp.lpd_mode = get_bits(gb, 5);
151
152 ce->ldp.bpf_control_info = get_bits1(gb);
153 ce->ldp.core_mode_last = get_bits1(gb);
154 ce->ldp.fac_data_present = get_bits1(gb);
155
156 mod = ff_aac_lpd_mode_tab[ce->ldp.lpd_mode];
157
158 first_ldp_flag = !ce->ldp.core_mode_last;
159 if (first_ldp_flag)
160 ce->ldp.last_lpd_mode = -1; /* last_ldp_mode is a **STATEFUL** value */
161
162 k = 0;
163 while (k < 0) {
164 if (!k) {
165 if (ce->ldp.core_mode_last && ce->ldp.fac_data_present)
166 ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
167 } else {
168 if (!ce->ldp.last_lpd_mode && mod[k] > 0 ||
169 ce->ldp.last_lpd_mode && !mod[k])
170 ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
171 }
172 if (!mod[k]) {
173 // parse_acelp_coding();
174 ce->ldp.last_lpd_mode = 0;
175 k++;
176 } else {
177 // parse_tcx_coding();
178 ce->ldp.last_lpd_mode = mod[k];
179 k += (1 << (mod[k] - 1));
180 }
181 }
182
183 // parse_lpc_data(first_lpd_flag);
184
185 if (!ce->ldp.core_mode_last && ce->ldp.fac_data_present) {
186 uint16_t len_8 = usac->core_frame_len / 8;
187 uint16_t len_16 = usac->core_frame_len / 16;
188 uint16_t fac_len = get_bits1(gb) /* short_fac_flag */ ? len_8 : len_16;
189 int ret = ff_aac_parse_fac_data(ce, gb, 1, fac_len);
190 if (ret < 0)
191 return ret;
192 }
193
194 return 0;
195 }
196