/src/ffmpeg/libavcodec/apac.c
Line | Count | Source |
1 | | /* |
2 | | * APAC audio decoder |
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 "libavutil/audio_fifo.h" |
22 | | #include "libavutil/mem.h" |
23 | | #include "avcodec.h" |
24 | | #include "codec_internal.h" |
25 | | #include "decode.h" |
26 | | #include "get_bits.h" |
27 | | |
28 | | typedef struct ChContext { |
29 | | int have_code; |
30 | | int last_sample; |
31 | | int last_delta; |
32 | | int bit_length; |
33 | | int block_length; |
34 | | uint8_t block[32 * 2]; |
35 | | AVAudioFifo *samples; |
36 | | } ChContext; |
37 | | |
38 | | typedef struct APACContext { |
39 | | GetBitContext gb; |
40 | | int skip; |
41 | | |
42 | | int cur_ch; |
43 | | ChContext ch[2]; |
44 | | |
45 | | uint8_t *bitstream; |
46 | | int64_t max_framesize; |
47 | | int bitstream_size; |
48 | | int bitstream_index; |
49 | | } APACContext; |
50 | | |
51 | | static av_cold int apac_close(AVCodecContext *avctx) |
52 | 829 | { |
53 | 829 | APACContext *s = avctx->priv_data; |
54 | | |
55 | 829 | av_freep(&s->bitstream); |
56 | 829 | s->bitstream_size = 0; |
57 | | |
58 | 2.48k | for (int ch = 0; ch < 2; ch++) { |
59 | 1.65k | ChContext *c = &s->ch[ch]; |
60 | | |
61 | 1.65k | av_audio_fifo_free(c->samples); |
62 | 1.65k | } |
63 | | |
64 | 829 | return 0; |
65 | 829 | } |
66 | | |
67 | | static av_cold int apac_init(AVCodecContext *avctx) |
68 | 829 | { |
69 | 829 | APACContext *s = avctx->priv_data; |
70 | | |
71 | 829 | if (avctx->bits_per_coded_sample > 8) |
72 | 556 | avctx->sample_fmt = AV_SAMPLE_FMT_S16P; |
73 | 273 | else |
74 | 273 | avctx->sample_fmt = AV_SAMPLE_FMT_U8P; |
75 | | |
76 | 829 | if (avctx->ch_layout.nb_channels < 1 || |
77 | 829 | avctx->ch_layout.nb_channels > 2 || |
78 | 768 | avctx->bits_per_coded_sample < 8 || |
79 | 729 | avctx->bits_per_coded_sample > 16 |
80 | 829 | ) |
81 | 129 | return AVERROR_INVALIDDATA; |
82 | | |
83 | 1.66k | for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) { |
84 | 960 | ChContext *c = &s->ch[ch]; |
85 | | |
86 | 960 | c->bit_length = avctx->bits_per_coded_sample; |
87 | 960 | c->block_length = 8; |
88 | 960 | c->have_code = 0; |
89 | 960 | c->samples = av_audio_fifo_alloc(avctx->sample_fmt, 1, 1024); |
90 | 960 | if (!c->samples) |
91 | 0 | return AVERROR(ENOMEM); |
92 | 960 | } |
93 | | |
94 | 700 | s->max_framesize = 1024; |
95 | 700 | s->bitstream = av_realloc_f(s->bitstream, s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE, sizeof(*s->bitstream)); |
96 | 700 | if (!s->bitstream) |
97 | 0 | return AVERROR(ENOMEM); |
98 | | |
99 | 700 | return 0; |
100 | 700 | } |
101 | | |
102 | | static int get_code(ChContext *c, GetBitContext *gb) |
103 | 104M | { |
104 | 104M | if (get_bits1(gb)) { |
105 | 399k | int code = get_bits(gb, 2); |
106 | | |
107 | 399k | switch (code) { |
108 | 79.8k | case 0: |
109 | 79.8k | c->bit_length--; |
110 | 79.8k | break; |
111 | 72.1k | case 1: |
112 | 72.1k | c->bit_length++; |
113 | 72.1k | break; |
114 | 179k | case 2: |
115 | 179k | c->bit_length = get_bits(gb, 5); |
116 | 179k | break; |
117 | 68.4k | case 3: |
118 | 68.4k | c->block_length = get_bits(gb, 4); |
119 | 68.4k | return 1; |
120 | 399k | } |
121 | 399k | } |
122 | | |
123 | 104M | return 0; |
124 | 104M | } |
125 | | |
126 | | static int apac_decode(AVCodecContext *avctx, AVFrame *frame, |
127 | | int *got_frame_ptr, AVPacket *pkt) |
128 | 368k | { |
129 | 368k | APACContext *s = avctx->priv_data; |
130 | 368k | GetBitContext *gb = &s->gb; |
131 | 368k | int ret, n, buf_size, input_buf_size; |
132 | 368k | uint8_t *buf; |
133 | 368k | int nb_samples; |
134 | | |
135 | 368k | if (!pkt->size && s->bitstream_size <= 0) { |
136 | 257 | *got_frame_ptr = 0; |
137 | 257 | return 0; |
138 | 257 | } |
139 | | |
140 | 368k | buf_size = pkt->size; |
141 | 368k | input_buf_size = buf_size; |
142 | | |
143 | 368k | if ((int64_t)s->bitstream_size + buf_size > INT_MAX / (16 * 8)) |
144 | 0 | return AVERROR_INVALIDDATA; |
145 | | |
146 | 368k | if (s->bitstream_index > 0) { |
147 | 46.6k | if (s->bitstream_size > 0) |
148 | 43.5k | memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); |
149 | 46.6k | s->bitstream_index = 0; |
150 | 46.6k | } |
151 | | |
152 | 368k | if (s->bitstream_index + s->bitstream_size + buf_size > s->max_framesize) { |
153 | 38.1k | s->bitstream = av_realloc_f(s->bitstream, s->bitstream_index + |
154 | 38.1k | s->bitstream_size + |
155 | 38.1k | buf_size + AV_INPUT_BUFFER_PADDING_SIZE, |
156 | 38.1k | sizeof(*s->bitstream)); |
157 | 38.1k | if (!s->bitstream) |
158 | 0 | return AVERROR(ENOMEM); |
159 | 38.1k | s->max_framesize = s->bitstream_index + s->bitstream_size + buf_size; |
160 | 38.1k | } |
161 | 368k | if (pkt->data) |
162 | 367k | memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size); |
163 | 368k | buf = &s->bitstream[s->bitstream_index]; |
164 | 368k | buf_size += s->bitstream_size; |
165 | 368k | s->bitstream_size = buf_size; |
166 | 368k | memset(buf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); |
167 | | |
168 | 368k | frame->nb_samples = s->bitstream_size * 16 * 8; |
169 | 368k | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
170 | 37.7k | return ret; |
171 | | |
172 | 330k | if ((ret = init_get_bits8(gb, buf, buf_size)) < 0) |
173 | 0 | return ret; |
174 | | |
175 | 330k | skip_bits(gb, s->skip); |
176 | 330k | s->skip = 0; |
177 | | |
178 | 101M | while (get_bits_left(gb) > 0) { |
179 | 205M | for (int ch = s->cur_ch; ch < avctx->ch_layout.nb_channels; ch++) { |
180 | 104M | ChContext *c = &s->ch[ch]; |
181 | 104M | int16_t *dst16 = (int16_t *)c->block; |
182 | 104M | uint8_t *dst8 = (uint8_t *)c->block; |
183 | 104M | void *samples[4]; |
184 | | |
185 | 104M | samples[0] = &c->block[0]; |
186 | 104M | if (get_bits_left(gb) < 16 && pkt->size) { |
187 | 55.3k | s->cur_ch = ch; |
188 | 55.3k | goto end; |
189 | 55.3k | } |
190 | | |
191 | 104M | if (!c->have_code && get_code(c, gb)) |
192 | 59.2k | get_code(c, gb); |
193 | 104M | c->have_code = 0; |
194 | | |
195 | 104M | if (c->block_length <= 0) |
196 | 1.16M | continue; |
197 | | |
198 | 103M | if (c->bit_length < 0 || |
199 | 103M | c->bit_length > 17) { |
200 | 7.58k | c->bit_length = avctx->bits_per_coded_sample; |
201 | 7.58k | s->bitstream_index = 0; |
202 | 7.58k | s->bitstream_size = 0; |
203 | 7.58k | return AVERROR_INVALIDDATA; |
204 | 7.58k | } |
205 | | |
206 | 103M | if (get_bits_left(gb) < c->block_length * c->bit_length) { |
207 | 274k | if (pkt->size) { |
208 | 264k | c->have_code = 1; |
209 | 264k | s->cur_ch = ch; |
210 | 264k | goto end; |
211 | 264k | } else { |
212 | 9.78k | break; |
213 | 9.78k | } |
214 | 274k | } |
215 | | |
216 | 1.63G | for (int i = 0; i < c->block_length; i++) { |
217 | 1.53G | int val = get_bits_long(gb, c->bit_length); |
218 | 1.53G | unsigned delta = (val & 1) ? ~(val >> 1) : (val >> 1); |
219 | 1.53G | int sample; |
220 | | |
221 | 1.53G | delta += c->last_delta; |
222 | 1.53G | sample = c->last_sample + delta; |
223 | 1.53G | c->last_delta = delta; |
224 | 1.53G | c->last_sample = sample; |
225 | | |
226 | 1.53G | switch (avctx->sample_fmt) { |
227 | 1.50G | case AV_SAMPLE_FMT_S16P: |
228 | 1.50G | dst16[i] = sample; |
229 | 1.50G | break; |
230 | 29.0M | case AV_SAMPLE_FMT_U8P: |
231 | 29.0M | dst8[i] = sample; |
232 | 29.0M | break; |
233 | 1.53G | } |
234 | 1.53G | } |
235 | | |
236 | 103M | av_audio_fifo_write(c->samples, samples, c->block_length); |
237 | 103M | } |
238 | | |
239 | 100M | s->cur_ch = 0; |
240 | 100M | } |
241 | 323k | end: |
242 | 323k | nb_samples = frame->nb_samples; |
243 | 672k | for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) |
244 | 349k | nb_samples = FFMIN(av_audio_fifo_size(s->ch[ch].samples), nb_samples); |
245 | | |
246 | 323k | frame->nb_samples = nb_samples; |
247 | 672k | for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) { |
248 | 349k | void *samples[1] = { frame->extended_data[ch] }; |
249 | 349k | av_audio_fifo_read(s->ch[ch].samples, samples, nb_samples); |
250 | 349k | } |
251 | | |
252 | 323k | s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8); |
253 | 323k | n = get_bits_count(gb) / 8; |
254 | | |
255 | 323k | if (nb_samples > 0 || pkt->size) |
256 | 322k | *got_frame_ptr = 1; |
257 | | |
258 | 323k | if (s->bitstream_size > 0) { |
259 | 323k | s->bitstream_index += n; |
260 | 323k | s->bitstream_size -= n; |
261 | 323k | return input_buf_size; |
262 | 323k | } |
263 | 0 | return n; |
264 | 323k | } |
265 | | |
266 | | const FFCodec ff_apac_decoder = { |
267 | | .p.name = "apac", |
268 | | CODEC_LONG_NAME("Marian's A-pac audio"), |
269 | | .p.type = AVMEDIA_TYPE_AUDIO, |
270 | | .p.id = AV_CODEC_ID_APAC, |
271 | | .priv_data_size = sizeof(APACContext), |
272 | | .init = apac_init, |
273 | | FF_CODEC_DECODE_CB(apac_decode), |
274 | | .close = apac_close, |
275 | | .p.capabilities = AV_CODEC_CAP_DELAY | |
276 | | AV_CODEC_CAP_DR1, |
277 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
278 | | }; |