FFmpeg
|
wmapro decoder implementation Wmapro is an MDCT based codec comparable to wma standard or AAC. The decoding therefore consists of the following steps: More...
#include <inttypes.h>
#include "libavutil/audio_fifo.h"
#include "libavutil/tx.h"
#include "libavutil/ffmath.h"
#include "libavutil/float_dsp.h"
#include "libavutil/intfloat.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
#include "get_bits.h"
#include "internal.h"
#include "put_bits.h"
#include "wmaprodata.h"
#include "sinewin.h"
#include "wma.h"
#include "wma_common.h"
Go to the source code of this file.
Data Structures | |
struct | WMAProChannelCtx |
frame specific decoder context for a single channel More... | |
struct | WMAProChannelGrp |
channel group for channel transformations More... | |
struct | WMAProDecodeCtx |
main decoder context More... | |
struct | XMADecodeCtx |
Functions | |
static av_cold void | dump_context (WMAProDecodeCtx *s) |
helper function to print the most important members of the context More... | |
static av_cold int | decode_end (WMAProDecodeCtx *s) |
Uninitialize the decoder and free all resources. More... | |
static av_cold int | wmapro_decode_end (AVCodecContext *avctx) |
static av_cold int | get_rate (AVCodecContext *avctx) |
static av_cold void | decode_init_static (void) |
static av_cold int | decode_init (WMAProDecodeCtx *s, AVCodecContext *avctx, int num_stream) |
Initialize the decoder. More... | |
static av_cold int | wmapro_decode_init (AVCodecContext *avctx) |
Initialize the decoder. More... | |
static int | decode_subframe_length (WMAProDecodeCtx *s, int offset) |
Decode the subframe length. More... | |
static int | decode_tilehdr (WMAProDecodeCtx *s) |
Decode how the data in the frame is split into subframes. More... | |
static void | decode_decorrelation_matrix (WMAProDecodeCtx *s, WMAProChannelGrp *chgroup) |
Calculate a decorrelation matrix from the bitstream parameters. More... | |
static int | decode_channel_transform (WMAProDecodeCtx *s) |
Decode channel transformation parameters. More... | |
static int | decode_coeffs (WMAProDecodeCtx *s, int c) |
Extract the coefficients from the bitstream. More... | |
static int | decode_scale_factors (WMAProDecodeCtx *s) |
Extract scale factors from the bitstream. More... | |
static void | inverse_channel_transform (WMAProDecodeCtx *s) |
Reconstruct the individual channel data. More... | |
static void | wmapro_window (WMAProDecodeCtx *s) |
Apply sine window and reconstruct the output buffer. More... | |
static int | decode_subframe (WMAProDecodeCtx *s) |
Decode a single subframe (block). More... | |
static int | decode_frame (WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) |
Decode one WMA frame. More... | |
static int | remaining_bits (WMAProDecodeCtx *s, GetBitContext *gb) |
Calculate remaining input buffer length. More... | |
static void | save_bits (WMAProDecodeCtx *s, GetBitContext *gb, int len, int append) |
Fill the bit reservoir with a (partial) frame. More... | |
static int | decode_packet (AVCodecContext *avctx, WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) |
static int | wmapro_decode_packet (AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) |
Decode a single WMA packet. More... | |
static int | xma_decode_packet (AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) |
static av_cold int | xma_decode_init (AVCodecContext *avctx) |
static av_cold int | xma_decode_end (AVCodecContext *avctx) |
static void | flush (WMAProDecodeCtx *s) |
static void | wmapro_flush (AVCodecContext *avctx) |
Clear decoder buffers (for seeking). More... | |
static void | xma_flush (AVCodecContext *avctx) |
Variables | |
static VLC | sf_vlc |
scale factor DPCM vlc More... | |
static VLC | sf_rl_vlc |
scale factor run length vlc More... | |
static VLC | vec4_vlc |
4 coefficients per symbol More... | |
static VLC | vec2_vlc |
2 coefficients per symbol More... | |
static VLC | vec1_vlc |
1 coefficient per symbol More... | |
static VLC | coef_vlc [2] |
coefficient run length vlc codes More... | |
static float | sin64 [33] |
sine table for decorrelation More... | |
const FFCodec | ff_wmapro_decoder |
wmapro decoder More... | |
const FFCodec | ff_xma1_decoder |
const FFCodec | ff_xma2_decoder |
wmapro decoder implementation Wmapro is an MDCT based codec comparable to wma standard or AAC. The decoding therefore consists of the following steps:
The compressed wmapro bitstream is split into individual packets. Every such packet contains one or more wma frames. The compressed frames may have a variable length and frames may cross packet boundaries. Common to all wmapro frames is the number of samples that are stored in a frame. The number of samples and a few other decode flags are stored as extradata that has to be passed to the decoder.
The wmapro frames themselves are again split into a variable number of subframes. Every subframe contains the data for 2^N time domain samples where N varies between 7 and 12.
Example wmapro bitstream (in samples):
The frame layouts for the individual channels of a wma frame does not need to be the same.
However, if the offsets and lengths of several subframes of a frame are the same, the subframes of the channels can be grouped. Every group may then use special coding techniques like M/S stereo coding to improve the compression ratio. These channel transformations do not need to be applied to a whole subframe. Instead, they can also work on individual scale factor bands (see below). The coefficients that carry the audio signal in the frequency domain are transmitted as huffman-coded vectors with 4, 2 and 1 elements. In addition to that, the encoder can switch to a runlevel coding scheme by transmitting subframe_length / 128 zero coefficients.
Before the audio signal can be converted to the time domain, the coefficients have to be rescaled and inverse quantized. A subframe is therefore split into several scale factor bands that get scaled individually. Scale factors are submitted for every frame but they might be shared between the subframes of a channel. Scale factors are initially DPCM-coded. Once scale factors are shared, the differences are transmitted as runlevel codes. Every subframe length and offset combination in the frame layout shares a common quantization factor that can be adjusted for every channel by a modifier. After the inverse quantization, the coefficients get processed by an IMDCT. The resulting values are then windowed with a sine window and the first half of the values are added to the second half of the output from the previous subframe in order to reconstruct the output samples.
Definition in file wmaprodec.c.
#define WMAPRO_MAX_CHANNELS 8 |
current decoder limitations
max number of handled channels
Definition at line 112 of file wmaprodec.c.
#define MAX_SUBFRAMES 32 |
max number of subframes per channel
Definition at line 113 of file wmaprodec.c.
#define MAX_BANDS 29 |
max number of scale factor bands
Definition at line 114 of file wmaprodec.c.
#define MAX_FRAMESIZE 32768 |
maximum compressed frame size
Definition at line 115 of file wmaprodec.c.
#define XMA_MAX_STREAMS 8 |
Definition at line 116 of file wmaprodec.c.
#define XMA_MAX_CHANNELS_STREAM 2 |
Definition at line 117 of file wmaprodec.c.
#define XMA_MAX_CHANNELS (XMA_MAX_STREAMS * XMA_MAX_CHANNELS_STREAM) |
Definition at line 118 of file wmaprodec.c.
#define WMAPRO_BLOCK_MIN_BITS 6 |
log2 of min block size
Definition at line 120 of file wmaprodec.c.
#define WMAPRO_BLOCK_MAX_BITS 13 |
log2 of max block size
Definition at line 121 of file wmaprodec.c.
#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) |
minimum block size
Definition at line 122 of file wmaprodec.c.
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) |
maximum block size
Definition at line 123 of file wmaprodec.c.
#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) |
possible block sizes
Definition at line 124 of file wmaprodec.c.
#define VLCBITS 9 |
Definition at line 127 of file wmaprodec.c.
#define SCALEVLCBITS 8 |
Definition at line 128 of file wmaprodec.c.
#define VEC4MAXDEPTH ((HUFF_VEC4_MAXBITS+VLCBITS-1)/VLCBITS) |
Definition at line 129 of file wmaprodec.c.
#define VEC2MAXDEPTH ((HUFF_VEC2_MAXBITS+VLCBITS-1)/VLCBITS) |
Definition at line 130 of file wmaprodec.c.
#define VEC1MAXDEPTH ((HUFF_VEC1_MAXBITS+VLCBITS-1)/VLCBITS) |
Definition at line 131 of file wmaprodec.c.
#define SCALEMAXDEPTH ((HUFF_SCALE_MAXBITS+SCALEVLCBITS-1)/SCALEVLCBITS) |
Definition at line 132 of file wmaprodec.c.
#define SCALERLMAXDEPTH ((HUFF_SCALE_RL_MAXBITS+VLCBITS-1)/VLCBITS) |
Definition at line 133 of file wmaprodec.c.
|
static |
helper function to print the most important members of the context
s | context |
Definition at line 266 of file wmaprodec.c.
Referenced by decode_init().
|
static |
Uninitialize the decoder and free all resources.
avctx | codec context |
Definition at line 285 of file wmaprodec.c.
Referenced by wmapro_decode_end(), and xma_decode_end().
|
static |
Definition at line 297 of file wmaprodec.c.
|
static |
Definition at line 306 of file wmaprodec.c.
Referenced by decode_init().
|
static |
calculate sine values for the decorrelation matrix
Definition at line 321 of file wmaprodec.c.
Referenced by decode_init().
|
static |
Initialize the decoder.
avctx | codec context |
dump the extradata
generic init
frame info
get frame len
subframe info
init previous block len
extract lfe channel position
calculate number of scale factor bands and their offsets for every possible block size
Scale factors can be shared between blocks of different size as every block has a different scale factor band layout. The matrix sf_offsets is needed to find the correct scale factor.
init MDCT, FIXME: only init needed sizes
init MDCT windows: simple sine window
calculate subwoofer cutoff values
Definition at line 358 of file wmaprodec.c.
Referenced by wmapro_decode_init(), and xma_decode_init().
|
static |
Initialize the decoder.
avctx | codec context |
Definition at line 601 of file wmaprodec.c.
|
static |
Decode the subframe length.
s | context |
offset | sample offset in the frame |
no need to read from the bitstream when only one length is possible
1 bit indicates if the subframe is of maximum length
sanity check the length
Definition at line 614 of file wmaprodec.c.
Referenced by decode_tilehdr().
|
static |
Decode how the data in the frame is split into subframes.
Every WMA frame contains the encoded data for a fixed number of samples per channel. The data for every channel might be split into several subframes. This function will reconstruct the list of subframes for every channel.
If the subframes are not evenly split, the algorithm estimates the channels with the lowest number of total samples. Afterwards, for each of these channels a bit is read from the bitstream that indicates if the channel contains a subframe with the next subframe size that is going to be read from the bitstream or not. If a channel contains such a subframe, the subframe size gets added to the channel's subframe list. The algorithm repeats these steps until the frame is properly divided between the individual channels.
s | context |
< sum of samples for all currently known subframes of a channel
< flag indicating if a channel contains the current subframe
< number of channels that contain the current subframe
< flag indicating that all channels use the same subframe offsets and sizes
< smallest sum of samples (channels with this length will be processed first)
reset tiling information
loop until the frame data is split between the subframes
check which channels contain the subframe
get subframe length, subframe_len == 0 is not allowed
add subframes to the individual channels and find new min_channel_len
Definition at line 665 of file wmaprodec.c.
Referenced by decode_frame().
|
static |
Calculate a decorrelation matrix from the bitstream parameters.
s | codec context |
chgroup | channel group for which the matrix needs to be calculated |
Definition at line 756 of file wmaprodec.c.
Referenced by decode_channel_transform().
|
static |
Decode channel transformation parameters.
s | codec context |
in the one channel case channel transforms are pointless
decode channel mask
decode transform type
cos(pi/4)
FIXME: more than 6 coupled channels not supported
decode transform on / off
transform can be enabled for individual bands
Definition at line 806 of file wmaprodec.c.
Referenced by decode_subframe().
|
static |
Extract the coefficients from the bitstream.
s | codec context |
c | current channel number |
decode vector coefficients (consumes up to 167 bits per iteration for 4 vector coded large values)
decode sign
switch to run level mode when subframe_len / 128 zeros were found in a row
decode run level coded coefficients
Definition at line 920 of file wmaprodec.c.
Referenced by decode_subframe().
|
static |
Extract scale factors from the bitstream.
s | codec context |
should never consume more than 5344 bits MAX_CHANNELS * (1 + MAX_BANDS * 23)
resample scale factors for the new block size as the scale factors might need to be resampled several times before some new values are transmitted, a backup of the last transmitted scale factors is kept in saved_scale_factors
decode DPCM coded scale factors
run level decode differences to the resampled factors
swap buffers
calculate new scale factor maximum
Definition at line 1026 of file wmaprodec.c.
Referenced by decode_subframe().
|
static |
Reconstruct the individual channel data.
s | codec context |
multichannel decorrelation
multiply values with the decorrelation_matrix
Definition at line 1119 of file wmaprodec.c.
Referenced by decode_subframe().
|
static |
Apply sine window and reconstruct the output buffer.
s | codec context |
Definition at line 1174 of file wmaprodec.c.
Referenced by decode_subframe().
|
static |
Decode a single subframe (block).
s | codec context |
reset channel context and find the next block offset and size == the next block of the channel with the smallest number of decoded samples
get a list of all channels that contain the estimated block
subtract already processed samples
and count if there are multiple subframes that match our profile
check if the frame will be complete after processing the estimated block
calculate number of scale factor bands and their offsets
configure the decoder for the current subframe
skip extended header if any
no idea for what the following bit is used
decode number of vector coded coefficients
decode quantization step
decode quantization step modifiers for every channel
decode scale factors
parse coefficients
reconstruct the per channel data
inverse quantization and rescaling
apply imdct (imdct_half == DCTIV with reverse)
window and overlapp-add
handled one subframe
Definition at line 1204 of file wmaprodec.c.
Referenced by decode_frame().
|
static |
Decode one WMA frame.
s | codec context |
get frame length
decode tile information
read postproc transform
read drc info
reset subframe states
decode all subframes
copy samples to the output buffer
reuse second half of the IMDCT output for the next frame
FIXME: not sure if this is always an error
skip the rest of the frame data
decode trailer bit
Definition at line 1445 of file wmaprodec.c.
Referenced by decode_packet().
|
static |
Calculate remaining input buffer length.
s | codec context |
gb | bitstream reader context |
Definition at line 1558 of file wmaprodec.c.
Referenced by decode_packet().
|
static |
Fill the bit reservoir with a (partial) frame.
s | codec context |
gb | bitstream reader context |
len | length of the partial frame |
append | decides whether to reset the buffer or not |
when the frame data does not need to be concatenated, the input buffer is reset and additional bits from the previous frame are copied and skipped later so that a fast byte copy is possible
Definition at line 1570 of file wmaprodec.c.
Referenced by decode_packet().
|
static |
Must output remaining samples after stream end. WMAPRO 5.1 created by XWMA encoder don't though (maybe only 1/2ch streams need it).
clean output buffer and copy last IMDCT samples
sanity check for the buffer length
parse packet header
get number of bits that need to be added to the previous frame
check for packet loss
append the previous frame data to the remaining data from the previous packet to create a full frame
decode the cross packet frame if it is valid
reset number of saved bits so that the decoder does not start to decode incomplete frames in the s->len_prefix == 0 case
when the frames do not have a length prefix, we don't know the compressed length of the individual frames however, we know what part of a new packet belongs to the previous frame therefore we save the incoming packet first, then we append the "previous frame" data from the next packet so that we get a buffer that only contains full frames
save the rest of the data so that it can be decoded with the next packet
Definition at line 1617 of file wmaprodec.c.
Referenced by wmapro_decode_packet(), and xma_decode_packet().
|
static |
Decode a single WMA packet.
avctx | codec context |
data | the output buffer |
avpkt | input packet |
Definition at line 1817 of file wmaprodec.c.
|
static |
Definition at line 1833 of file wmaprodec.c.
|
static |
Definition at line 1954 of file wmaprodec.c.
|
static |
Definition at line 2024 of file wmaprodec.c.
|
static |
reset output buffer as a part of it is used during the windowing of a new frame
Definition at line 2043 of file wmaprodec.c.
Referenced by wmapro_flush(), and xma_flush().
|
static |
Clear decoder buffers (for seeking).
avctx | codec context |
Definition at line 2061 of file wmaprodec.c.
|
static |
Definition at line 2068 of file wmaprodec.c.
|
static |
scale factor DPCM vlc
Definition at line 135 of file wmaprodec.c.
Referenced by decode_init_static(), and decode_scale_factors().
|
static |
scale factor run length vlc
Definition at line 136 of file wmaprodec.c.
Referenced by decode_init_static(), and decode_scale_factors().
|
static |
4 coefficients per symbol
Definition at line 137 of file wmaprodec.c.
Referenced by decode_coeffs(), and decode_init_static().
|
static |
2 coefficients per symbol
Definition at line 138 of file wmaprodec.c.
Referenced by decode_coeffs(), and decode_init_static().
|
static |
1 coefficient per symbol
Definition at line 139 of file wmaprodec.c.
Referenced by decode_coeffs(), and decode_init_static().
|
static |
coefficient run length vlc codes
Definition at line 140 of file wmaprodec.c.
Referenced by decode_coeffs(), and decode_init_static().
|
static |
sine table for decorrelation
Definition at line 141 of file wmaprodec.c.
Referenced by decode_decorrelation_matrix(), and decode_init_static().
const FFCodec ff_wmapro_decoder |
wmapro decoder
Definition at line 2088 of file wmaprodec.c.
const FFCodec ff_xma1_decoder |
Definition at line 2104 of file wmaprodec.c.
const FFCodec ff_xma2_decoder |
Definition at line 2120 of file wmaprodec.c.