FFmpeg: libavcodec/atrac3plusdec.c Source File
Go to the documentation of this file. 1 /*
2 * ATRAC3+ compatible decoder
3 *
4 * Copyright (c) 2010-2013 Maxim Poliakovski
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * Sony ATRAC3+ compatible decoder.
26 *
27 * Container formats used to store its data:
28 * RIFF WAV (.at3) and Sony OpenMG (.oma, .aa3).
29 *
30 * Technical description of this codec can be found here:
31 * http://wiki.multimedia.cx/index.php?title=ATRAC3plus
32 *
33 * Kudos to Benjamin Larsson and Michael Karcher
34 * for their precious technical help!
35 */
36
37 #include <stdint.h>
38 #include <string.h>
39
51
53 { 0, },
54 { 0, 1, },
55 { 0, 1, 2, },
56 { 0, 1, 2, 3, },
57 { 0, },
58 { 0, 1, 2, 4, 5, 3, },
59 { 0, 1, 2, 4, 5, 6, 3, },
60 { 0, 1, 2, 4, 5, 6, 7, 3, },
61 };
62
66
71
77
79
84
86 {
88
91
94
95 return 0;
96 }
97
100 {
102 memset(
ctx->channel_blocks, 0,
sizeof(
ctx->channel_blocks));
103
106 case 1:
108 ctx->num_channel_blocks = 1;
110 break;
111 case 2:
113 ctx->num_channel_blocks = 1;
115 break;
116 case 3:
118 ctx->num_channel_blocks = 2;
121 break;
122 case 4:
124 ctx->num_channel_blocks = 3;
128 break;
129 case 6:
131 ctx->num_channel_blocks = 4;
136 break;
137 case 7:
139 ctx->num_channel_blocks = 5;
145 break;
146 case 8:
148 ctx->num_channel_blocks = 5;
154 break;
155 default:
157 "Unsupported channel count: %d!\n",
channels);
159 }
160
162
163 return 0;
164 }
165
167 {
170 }
171
173 {
178
182 }
183
184 /* initialize IPQF */
185 scale = 32.0 / 32768.0;
190
196
198
201
204
205 if (!
ctx->ch_units || !
ctx->fdsp) {
207 }
208
209 for (
i = 0;
i <
ctx->num_channel_blocks;
i++) {
210 for (ch = 0; ch < 2; ch++) {
211 ctx->ch_units[
i].channels[ch].ch_num = ch;
212 ctx->ch_units[
i].channels[ch].wnd_shape = &
ctx->ch_units[
i].channels[ch].wnd_shape_hist[0][0];
213 ctx->ch_units[
i].channels[ch].wnd_shape_prev = &
ctx->ch_units[
i].channels[ch].wnd_shape_hist[1][0];
214 ctx->ch_units[
i].channels[ch].gain_data = &
ctx->ch_units[
i].channels[ch].gain_data_hist[0][0];
215 ctx->ch_units[
i].channels[ch].gain_data_prev = &
ctx->ch_units[
i].channels[ch].gain_data_hist[1][0];
216 ctx->ch_units[
i].channels[ch].tones_info = &
ctx->ch_units[
i].channels[ch].tones_info_hist[0][0];
217 ctx->ch_units[
i].channels[ch].tones_info_prev = &
ctx->ch_units[
i].channels[ch].tones_info_hist[1][0];
218 }
219
220 ctx->ch_units[
i].waves_info = &
ctx->ch_units[
i].wave_synth_hist[0];
221 ctx->ch_units[
i].waves_info_prev = &
ctx->ch_units[
i].wave_synth_hist[1];
222 }
223
225
227
228 return 0;
229 }
230
233 int num_channels,
235 {
236 int i, sb, ch,
qu, nspeclines, RNG_index;
239 /* calculate RNG table index for each subband */
241
243 for (ch = 0; ch < num_channels; ch++)
245 return;
246 }
247
251
253 sb_RNG_index[sb] = RNG_index & 0x3FC;
254
255 /* inverse quant and power compensation */
256 for (ch = 0; ch < num_channels; ch++) {
257 /* clear channel's residual spectrum */
259
265
269 for (
i = 0;
i < nspeclines;
i++)
271 }
272 }
273
276 sb_RNG_index[sb], sb);
277 }
278
285 }
286
287 /* flip coefficients' sign if requested */
291 }
292 }
293 }
294
297 {
298 int ch, sb;
299
300 for (ch = 0; ch < num_channels; ch++) {
302 /* inverse transform and windowing */
308
309 /* gain compensation and overlapping */
317 }
318
319 /* zero unused subbands in both output and overlapping buffers */
321 0,
326 0,
330
331 /* resynthesize and add tonal signal */
338 &
ctx->time_buf[ch][sb * 128]);
339 }
340 }
341
342 /* subband synthesis and acoustic signal output */
345 &
ctx->outp_buf[ch][0]);
346 }
347
348 /* swap window shape and gain control buffers. */
349 for (ch = 0; ch < num_channels; ch++) {
356 }
357
359 }
360
362 int *got_frame_ptr,
AVPacket *avpkt)
363 {
365 int i,
ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process;
366 float **samples_p = (
float **)
frame->extended_data;
367
371
374
378 }
379
385 }
386 if (ch_block >=
ctx->num_channel_blocks ||
387 ctx->channel_blocks[ch_block] != ch_unit_id) {
389 "Frame data doesn't match channel configuration!\n");
391 }
392
393 ctx->ch_units[ch_block].unit_type = ch_unit_id;
394 channels_to_process = ch_unit_id + 1;
395
397 &
ctx->ch_units[ch_block],
398 channels_to_process,
399 avctx)) < 0)
401
403 channels_to_process, avctx);
405 channels_to_process, avctx);
406
407 for (
i = 0;
i < channels_to_process;
i++)
408 memcpy(samples_p[
ctx->channel_map[out_ch_index +
i]],
ctx->outp_buf[
i],
410
411 ch_block++;
412 out_ch_index += channels_to_process;
413 }
414
415 *got_frame_ptr = 1;
416
418 }
419
421 .
p.
name =
"atrac3plus",
431 };
432
434 .
p.
name =
"atrac3plusal",
435 CODEC_LONG_NAME(
"ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"),
444 };
Atrac3pWaveSynthParams * waves_info
const uint8_t * channel_map
channel layout map
void ff_atrac3p_init_dsp_static(void)
Initialize sine waves synthesizer and ff_sine_* tables.
@ AV_SAMPLE_FMT_FLTP
float, planar
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
static int get_bits_left(GetBitContext *gb)
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
Atrac3pWavesData * tones_info_prev
#define AV_CHANNEL_LAYOUT_STEREO
int num_wavs
number of sine waves in the group
AtracGCContext gainc_ctx
gain compensation context
static av_cold int atrac3p_decode_close(AVCodecContext *avctx)
static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, int num_channels, AVCodecContext *avctx)
This structure describes decoded (raw) audio or video data.
Atrac3pIPQFChannelCtx ipqf_ctx[2]
void ff_atrac3p_generate_tones(Atrac3pChanUnitCtx *ch_unit, AVFloatDSPContext *fdsp, int ch_num, int sb, float *out)
Synthesize sine waves for a particular subband.
Atrac3pChanUnitCtx * ch_units
global channel units
static av_cold void atrac3p_init_static(void)
void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, AVFloatDSPContext *fdsp, int ch_index, float *sp, int rng_index, int sb_num)
Perform power compensation aka noise dithering.
uint8_t negate_coeffs[ATRAC3P_SUBBANDS]
1 - subband-wise IMDCT coefficients negation
float mdct_buf[2][ATRAC3P_FRAME_SAMPLES]
output of the IMDCT
int nb_channels
Number of channels in this layout.
static int atrac3p_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
#define ATRAC3P_FRAME_SAMPLES
@ CH_UNIT_EXTENSION
unit containing extension information
uint8_t * wnd_shape
IMDCT window shape for current frame.
static av_cold void close(AVCodecParserContext *s)
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
AVCodec p
The public AVCodec.
static void decode_residual_spectrum(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, float out[2][ATRAC3P_FRAME_SAMPLES], int num_channels, AVCodecContext *avctx)
AVChannelLayout ch_layout
Audio channel layout.
static av_cold int set_channel_params(ATRAC3PContext *ctx, AVCodecContext *avctx)
int flags
AV_CODEC_FLAG_*.
av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, int loc_scale)
Initialize gain compensation context.
#define AV_CHANNEL_LAYOUT_SURROUND
static av_cold int atrac3p_decode_init(AVCodecContext *avctx)
const float ff_atrac3p_sf_tab[64]
static int ff_thread_once(char *control, void(*routine)(void))
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
float outp_buf[2][ATRAC3P_FRAME_SAMPLES]
int used_quant_units
number of quant units with coded spectrum
#define AV_CHANNEL_LAYOUT_4POINT0
@ AV_TX_FLOAT_MDCT
Standard MDCT with a sample data type of float, double or int32_t, respectively.
#define FF_CODEC_DECODE_CB(func)
#define AV_CHANNEL_LAYOUT_7POINT1
@ CH_UNIT_MONO
unit containing one coded channel
int num_coded_subbands
number of subbands with coded spectrum
Gain compensation context structure.
static const uint8_t channel_map[8][8]
const uint16_t ff_atrac3p_qu_to_spec_pos[33]
Map quant unit number to its position in the spectrum.
Atrac3pWaveSynthParams * waves_info_prev
#define CODEC_LONG_NAME(str)
const float ff_atrac3p_mant_tab[8]
@ AV_TX_FULL_IMDCT
Performs a full inverse MDCT rather than leaving out samples that can be derived through symmetry.
@ CH_UNIT_TERMINATOR
unit sequence terminator
void ff_atrac3p_ipqf(AVTXContext *dct_ctx, av_tx_fn dct_fn, Atrac3pIPQFChannelCtx *hist, const float *in, float *out)
Subband synthesis filter based on the polyphase quadrature (pseudo-QMF) filter bank.
int num_channel_blocks
number of channel blocks
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static unsigned int get_bits1(GetBitContext *s)
AtracGainInfo * gain_data_prev
gain control data for previous frame
int16_t spectrum[2048]
decoded IMDCT spectrum
uint8_t channel_blocks[5]
channel configuration descriptor
Gain control parameters for one subband.
Atrac3pWavesData * tones_info
Atrac3pChanParams channels[2]
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int(* init)(AVBSFContext *ctx)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
AVTXContext * ipqf_dct_ctx
IDCT context used by IPQF.
An AVChannelLayout holds information about the channel layout of audio data.
#define DECLARE_ALIGNED(n, t, v)
const FFCodec ff_atrac3pal_decoder
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
av_cold void ff_atrac3p_init_vlcs(void)
Initialize VLC tables for bitstream parsing.
enum AVSampleFormat sample_fmt
audio sample format
int qu_sf_idx[32]
array of scale factor indexes for each quant unit
@ CH_UNIT_STEREO
unit containing two jointly-coded channels
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
float time_buf[2][ATRAC3P_FRAME_SAMPLES]
output of the gain compensation
int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx)
Decode bitstream data of a channel unit.
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
#define AV_CHANNEL_LAYOUT_6POINT1_BACK
#define i(width, name, range_min, range_max)
int unit_type
unit type (mono/stereo)
const char * name
Name of the codec implementation.
void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, AVTXContext *mdct_ctx, av_tx_fn mdct_fn, float *pIn, float *pOut, int wind_id, int sb)
Regular IMDCT and windowing without overlapping, with spectrum reversal in the odd subbands.
void * av_calloc(size_t nmemb, size_t size)
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs.
#define FFSWAP(type, a, b)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
float prev_buf[2][ATRAC3P_FRAME_SAMPLES]
overlapping buffer
int tones_present
1 - tones info present
uint8_t swap_channels[ATRAC3P_SUBBANDS]
1 - perform subband-wise channel swapping
main external API structure.
void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, AtracGainInfo *gc_now, AtracGainInfo *gc_next, int num_samples, float *out)
Apply gain compensation and perform the MDCT overlapping part.
Parameters of a group of sine waves.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
uint8_t * wnd_shape_prev
IMDCT window shape for previous frame.
#define ATRAC3P_SUBBAND_SAMPLES
number of samples per subband
const FFCodec ff_atrac3p_decoder
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
#define AV_CHANNEL_LAYOUT_MONO
static void scale(int *out, const int *in, const int w, const int h, const int shift)
This structure stores compressed data.
#define ATRAC3P_SUBBANDS
Global unit sizes.
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
#define AV_CHANNEL_LAYOUT_5POINT1_BACK
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int qu_wordlen[32]
array of word lengths for each quant unit
AtracGainInfo * gain_data
gain control data for next frame
float samples[2][ATRAC3P_FRAME_SAMPLES]
quantized MDCT spectrum
Generated on Sat Oct 18 2025 19:21:52 for FFmpeg by
doxygen
1.8.17