FFmpeg
Loading...
Searching...
No Matches
apac.c
Go to the documentation of this file.
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
22#include "libavutil/mem.h"
23#include "avcodec.h"
24#include "codec_internal.h"
25#include "decode.h"
26#include "get_bits.h"
27
37
50
52{
53 APACContext *s = avctx->priv_data;
54
55 av_freep(&s->bitstream);
56 s->bitstream_size = 0;
57
58 for (int ch = 0; ch < 2; ch++) {
59 ChContext *c = &s->ch[ch];
60
61 av_audio_fifo_free(c->samples);
62 }
63
64 return 0;
65}
66
68{
69 APACContext *s = avctx->priv_data;
70
71 if (avctx->bits_per_coded_sample > 8)
73 else
75
76 if (avctx->ch_layout.nb_channels < 1 ||
77 avctx->ch_layout.nb_channels > 2 ||
78 avctx->bits_per_coded_sample < 8 ||
79 avctx->bits_per_coded_sample > 16
80 )
82
83 for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
84 ChContext *c = &s->ch[ch];
85
86 c->bit_length = avctx->bits_per_coded_sample;
87 c->block_length = 8;
88 c->have_code = 0;
89 c->samples = av_audio_fifo_alloc(avctx->sample_fmt, 1, 1024);
90 if (!c->samples)
91 return AVERROR(ENOMEM);
92 }
93
94 s->max_framesize = 1024;
95 s->bitstream = av_realloc_f(s->bitstream, s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE, sizeof(*s->bitstream));
96 if (!s->bitstream)
97 return AVERROR(ENOMEM);
98
99 return 0;
100}
101
103{
104 if (get_bits1(gb)) {
105 int code = get_bits(gb, 2);
106
107 switch (code) {
108 case 0:
109 c->bit_length--;
110 break;
111 case 1:
112 c->bit_length++;
113 break;
114 case 2:
115 c->bit_length = get_bits(gb, 5);
116 break;
117 case 3:
118 c->block_length = get_bits(gb, 4);
119 return 1;
120 }
121 }
122
123 return 0;
124}
125
127 int *got_frame_ptr, AVPacket *pkt)
128{
129 APACContext *s = avctx->priv_data;
130 GetBitContext *gb = &s->gb;
131 int ret, n, buf_size, input_buf_size;
132 uint8_t *buf;
133 int nb_samples;
134
135 if (!pkt->size && s->bitstream_size <= 0) {
136 *got_frame_ptr = 0;
137 return 0;
138 }
139
140 buf_size = pkt->size;
141 input_buf_size = buf_size;
142
143 if ((int64_t)s->bitstream_size + buf_size > INT_MAX / (16 * 8))
144 return AVERROR_INVALIDDATA;
145
146 if (s->bitstream_index > 0 && s->bitstream_size > 0) {
147 memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
148 s->bitstream_index = 0;
149 }
150
151 if (s->bitstream_index + s->bitstream_size + buf_size > s->max_framesize) {
152 s->bitstream = av_realloc_f(s->bitstream, s->bitstream_index +
153 s->bitstream_size +
155 sizeof(*s->bitstream));
156 if (!s->bitstream)
157 return AVERROR(ENOMEM);
158 s->max_framesize = s->bitstream_index + s->bitstream_size + buf_size;
159 }
160 if (pkt->data)
161 memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size);
162 buf = &s->bitstream[s->bitstream_index];
163 buf_size += s->bitstream_size;
164 s->bitstream_size = buf_size;
165 memset(buf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
166
167 frame->nb_samples = s->bitstream_size * 16 * 8;
168 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
169 return ret;
170
171 if ((ret = init_get_bits8(gb, buf, buf_size)) < 0)
172 return ret;
173
174 skip_bits(gb, s->skip);
175 s->skip = 0;
176
177 while (get_bits_left(gb) > 0) {
178 for (int ch = s->cur_ch; ch < avctx->ch_layout.nb_channels; ch++) {
179 ChContext *c = &s->ch[ch];
180 int16_t *dst16 = (int16_t *)c->block;
181 uint8_t *dst8 = (uint8_t *)c->block;
182 void *samples[4];
183
184 samples[0] = &c->block[0];
185 if (get_bits_left(gb) < 16 && pkt->size) {
186 s->cur_ch = ch;
187 goto end;
188 }
189
190 if (!c->have_code && get_code(c, gb))
191 get_code(c, gb);
192 c->have_code = 0;
193
194 if (c->block_length <= 0)
195 continue;
196
197 if (c->bit_length < 0 ||
198 c->bit_length > 17) {
199 c->bit_length = avctx->bits_per_coded_sample;
200 s->bitstream_index = 0;
201 s->bitstream_size = 0;
202 return AVERROR_INVALIDDATA;
203 }
204
205 if (get_bits_left(gb) < c->block_length * c->bit_length) {
206 if (pkt->size) {
207 c->have_code = 1;
208 s->cur_ch = ch;
209 goto end;
210 } else {
211 break;
212 }
213 }
214
215 for (int i = 0; i < c->block_length; i++) {
216 int val = get_bits_long(gb, c->bit_length);
217 unsigned delta = (val & 1) ? ~(val >> 1) : (val >> 1);
218 int sample;
219
220 delta += c->last_delta;
221 sample = c->last_sample + delta;
222 c->last_delta = delta;
223 c->last_sample = sample;
224
225 switch (avctx->sample_fmt) {
227 dst16[i] = sample;
228 break;
230 dst8[i] = sample;
231 break;
232 }
233 }
234
235 av_audio_fifo_write(c->samples, samples, c->block_length);
236 }
237
238 s->cur_ch = 0;
239 }
240end:
241 nb_samples = frame->nb_samples;
242 for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
243 nb_samples = FFMIN(av_audio_fifo_size(s->ch[ch].samples), nb_samples);
244
245 frame->nb_samples = nb_samples;
246 for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
247 void *samples[1] = { frame->extended_data[ch] };
248 av_audio_fifo_read(s->ch[ch].samples, samples, nb_samples);
249 }
250
251 s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8);
252 n = get_bits_count(gb) / 8;
253
254 if (nb_samples > 0 || pkt->size)
255 *got_frame_ptr = 1;
256
257 if (s->bitstream_size > 0) {
258 s->bitstream_index += n;
259 s->bitstream_size -= n;
260 return input_buf_size;
261 }
262 return n;
263}
264
266 .p.name = "apac",
267 CODEC_LONG_NAME("Marian's A-pac audio"),
268 .p.type = AVMEDIA_TYPE_AUDIO,
269 .p.id = AV_CODEC_ID_APAC,
270 .priv_data_size = sizeof(APACContext),
271 .init = apac_init,
273 .close = apac_close,
274 .p.capabilities = AV_CODEC_CAP_DELAY |
276 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
277};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_apac_decoder
Definition apac.c:265
Audio FIFO Buffer.
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
long long int64_t
Definition coverity.c:34
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define sample
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_APAC
Definition codec_id.h:552
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition audio_fifo.c:62
int av_audio_fifo_write(AVAudioFifo *af, void *const *data, int nb_samples)
Write data to an AVAudioFifo.
Definition audio_fifo.c:119
int av_audio_fifo_read(AVAudioFifo *af, void *const *data, int nb_samples)
Read data from an AVAudioFifo.
Definition audio_fifo.c:175
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition audio_fifo.c:48
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition audio_fifo.c:222
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition samplefmt.h:64
@ AV_SAMPLE_FMT_U8P
unsigned 8 bits, planar
Definition samplefmt.h:63
static av_cold int apac_close(AVCodecContext *avctx)
Definition apac.c:51
static int get_code(ChContext *c, GetBitContext *gb)
Definition apac.c:102
static av_cold int apac_init(AVCodecContext *avctx)
Definition apac.c:67
static int apac_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *pkt)
Definition apac.c:126
#define av_cold
Definition attributes.h:117
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
const uint8_t * code
Definition spdifenc.c:433
int skip
Definition apac.c:40
int bitstream_size
Definition apac.c:47
GetBitContext gb
Definition apac.c:39
int64_t max_framesize
Definition apac.c:46
int cur_ch
Definition apac.c:42
uint8_t * bitstream
Definition apac.c:45
ChContext ch[2]
Definition apac.c:43
int bitstream_index
Definition apac.c:48
Context for an Audio FIFO Buffer.
Definition audio_fifo.c:37
int nb_channels
Number of channels in this layout.
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition avcodec.h:1564
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
uint8_t block[32 *2]
Definition apac.c:34
int bit_length
Definition apac.c:32
int have_code
Definition apac.c:29
int last_sample
Definition apac.c:30
int block_length
Definition apac.c:33
AVAudioFifo * samples
Definition apac.c:35
int last_delta
Definition apac.c:31
#define av_realloc_f(p, o, n)
#define av_freep(p)
float delta
static double c[64]