https://wiki.multimedia.cx/api.php?action=feedcontributions&user=71.198.76.184&feedformat=atom
MultimediaWiki - User contributions [en]
2024-03-28T19:24:33Z
User contributions
MediaWiki 1.39.5
https://wiki.multimedia.cx/index.php?title=Reconstructing_AAC_CPE&diff=2747
Reconstructing AAC CPE
2006-03-13T00:37:08Z
<p>71.198.76.184: /* pns_decode() */ fill in the algorithm</p>
<hr />
<div>''Part of [[Understanding AAC]]''<br />
<br />
This page describes the process of reconstructing [[PCM]] data based on the [[Decoding AAC CPE|decoded CPE parameters]] in an AAC bitstream. For the moment, this description focuses on what is necessary to reconstruct low complexity (LC) profile data.<br />
<br />
== Reconstruction Process ==<br />
specrec.c:reconstruct_channel_pair()<br />
+-specrec.c:allocate_channel_pair()<br />
+-specrec.c:inverse_quantization()<br />
+-specrec.c:apply_scalefactors()<br />
+-specrec.c:quant_to_spec()<br />
+-pns.c:pns_decode()<br />
+-ms.c:ms_decode()<br />
+-is.c:is_decode()<br />
+-ic_predict.c:ic_prediction() (main profile)<br />
+-ic_predict.c:pns_reset_pred_state() (main profile)<br />
+-(processing that is specific LTP & LD profiles)<br />
+-tns.c:tns_decode_frame()<br />
+-drc.c:drc_decode()<br />
+-filtbank.c:ifilter_bank()<br />
+-filtbank.c:imdct_long()<br />
+-mdct.c:faad_imdct()<br />
+-ssr.c:ssr_decode()<br />
+-lt_predict.c:lt_update_state()<br />
+-sbr_dec.c:sbrDecodeInit()<br />
+-sbr_dec.c:sbrDecodeCoupleFrame()<br />
<br />
== reconstruct_channel_pair(2 ic_streams, 2 spec_data arrays(16 bit ints)) ==<br />
declare 2 1024-element float arrays for spectral coefficients (spec_coeff1 and spec_coeff2)<br />
inverse_quantization(spec_coeff1, spec_data1)<br />
inverse_quantization(spec_coeff2, spec_data2)<br />
apply_scalefactors(ics1, spec_coeff1)<br />
apply_scalefactors(ics2, spec_coeff2)<br />
if ics1.window_sequence is EIGHT_SHORT_SEQUENCE (2)<br />
quant_to_spec(ics1, spec_coeff1)<br />
if ics2.window_sequence is EIGHT_SHORT_SEQUENCE (2)<br />
quant_to_spec(ics2, spec_coeff2)<br />
if ics1.ms_mask_present<br />
pns_decode(ics1, ics2, spec_coef1, spec_coeff2)<br />
else<br />
pns_decode(ics1, spec_coef1)<br />
pns_decode(ics2, spec_coef2)<br />
ms_decode(ics1, ics2, spec_coef1, spec_coef2)<br />
is_decode(ics1, ics2, spec_coef1, spec_coef2)<br />
''// main profile decoding''<br />
''// LTP decoding''<br />
tns_decode(ics1, spec_coeff1)<br />
tns_decode(ics2, spec_coeff2)<br />
''// DRC stuff''<br />
ifilter_bank(ics1, spec_coeff1)<br />
ifilter_bank(ics2, spec_coeff2)<br />
save window shape for next frame (I thought frames were independent)<br />
''// LTP stuff''<br />
''// SBR stuff''<br />
<br />
== allocate_channel_pair() ==<br />
This function mostly contains considerations for non-LC decoding modes. Need to revisit the mechanics of this later.<br />
<br />
== inverse_quantization(real spec_coeff[1024], int16 spec_data[1024]) ==<br />
Perform inverse non-linear quantization of spectral coefficients, converting from int -> real in the process. Can this be effectively parallelized via SIMD?<br />
foreach i in 0..1023<br />
spec_coeff[i] = abs(spec_data[i])<sup>4/3</sup><br />
if (spec_data[i] < 0)<br />
spec_coeff[i] = -spec_coeff[i]<br />
<br />
== apply_scalefactors(ic_string ics, real spec_coeff[1024]) ==<br />
nshort = frame_length (1024) / 8<br />
groups = 0<br />
foreach g in 0..ics.num_window_groups - 1<br />
k = 0<br />
foreach scalefactor_band in 0..ics.max_scalefactor_bands - 1<br />
top = ics.section_scalefactor_band_offset[g][scalefactor_band + 1]<br />
if (ics.scalefactors[g][scalefactor_band] < 0) OR (ics.scalefactors[g][scalefactor_band] > 255)<br />
exponent = fraction = 0<br />
else<br />
exponent = ics.scalefactors[g][scalefactor_band] >> 2<br />
fraction = ics.scalefactors[g][scalefactor_band] & 3<br />
while (k < top)<br />
spec_coeff[k + (groups * nshort) + 0] *= pow2sf_tab[exponent]<br />
spec_coeff[k + (groups * nshort) + 0] *= pow2_table[fraction]<br />
spec_coeff[k + (groups * nshort) + 1] *= pow2sf_tab[exponent]<br />
spec_coeff[k + (groups * nshort) + 1] *= pow2_table[fraction]<br />
spec_coeff[k + (groups * nshort) + 2] *= pow2sf_tab[exponent]<br />
spec_coeff[k + (groups * nshort) + 2] *= pow2_table[fraction]<br />
spec_coeff[k + (groups * nshort) + 3] *= pow2sf_tab[exponent]<br />
spec_coeff[k + (groups * nshort) + 3] *= pow2_table[fraction]<br />
k += 4<br />
groups += ics.window_group_length[g]<br />
pow2sf_tab[] is defined as:<br />
foreach i in -25..38<br />
pow2sf_tab[i] = 2<sup>i</sup><br />
pow2_table[] is defined as:<br />
foreach i in 0..3<br />
pow2_table[i] = 2<sup>i/4</sup><br />
<br />
== quant_to_spec(ic_stream ics, real spec_coeff[1024]) ==<br />
Comment from FAAD2:<br />
For ONLY_LONG_SEQUENCE windows (num_window_groups = 1,<br />
window_group_length[0] = 1) the spectral data is in ascending spectral<br />
order.<br />
For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the<br />
grouping in the following manner:<br />
- Groups are ordered sequentially<br />
- Within a group, a scalefactor band consists of the spectral data of all<br />
grouped SHORT_WINDOWs for the associated scalefactor window band. To<br />
clarify via example, the length of a group is in the range of one to eight<br />
SHORT_WINDOWs.<br />
- If there are eight groups each with length one (num_window_groups = 8,<br />
window_group_length[0..7] = 1), the result is a sequence of eight spectra,<br />
each in ascending spectral order.<br />
- If there is only one group with length eight (num_window_groups = 1,<br />
window_group_length[0] = 8), the result is that spectral data of all eight<br />
SHORT_WINDOWs is interleaved by scalefactor window bands.<br />
- Within a scalefactor window band, the coefficients are in ascending<br />
spectral order.<br />
Algorithm:<br />
allocate a temporary spectral data array: temp_spec[1024]<br />
k = gindex = 0<br />
foreach g in 0..ics.num_window_groups - 1<br />
j = gincrease = 0<br />
window_increment = ics.scalefactor_window_band_offset[ics.num_scalefactor_window_bands]<br />
foreach scalefactor_band in 0..ics.num_scalefactor_window_bands - 1 <br />
width = ics.scalefactor_window_band_offset[scalefactor_band + 1] -<br />
ics.scalefactor_window_band[scalefactor_band]<br />
foreach window in 0..ics.window_group_length[g] - 1<br />
foreach bin in 0..width - 1, step 4<br />
temp_spec[gindex + (window * window_increment) + j + bin + 0] = spec_coeff[k + 0]<br />
temp_spec[gindex + (window * window_increment) + j + bin + 1] = spec_coeff[k + 1]<br />
temp_spec[gindex + (window * window_increment) + j + bin + 2] = spec_coeff[k + 2]<br />
temp_spec[gindex + (window * window_increment) + j + bin + 3] = spec_coeff[k + 3]<br />
gincrease += 4<br />
k += 4<br />
j += width<br />
gindex + gincrease<br />
copy temp_spec -> spec_coeff<br />
<br />
== pns_decode(ic_stream ics1, ic_stream ics2, real spec_coeff1[1024], real spec_coeff2[1024], bool channel_pair) ==<br />
pns = perceptual noise substitution<br />
<br />
group = 0<br />
nshort = frame_length / 8 (frame_length is usually 1024)<br />
foreach g in ics1.num_window_groups - 1<br />
foreach b in ics1.window_group_length[g] - 1<br />
foreach scalefactor_band in 0..ics1.max_scalefactor_bands - 1<br />
if ics1.scalefactor_band_codebook[group][scalefactor_band] == NOISE_HCB (13)<br />
/* LTP and PNS are not allowed in the same band and PNS takes precedence;<br />
* thus, disable LTP for this band */<br />
ics1.ltp.long_used[scalefactor_band] = 0<br />
ics1.ltp2.long_used[scalefactor_band] = 0<br />
/* disable predictors for bands using PNS */<br />
ics1.pred.prediction_used[scalefactor_band] = 0<br />
offset = ics1.scalefactor_window_band_offset[scalefactor_band]<br />
size = ics1.scalefactor_window_band_offset[scalefactor_band + 1] - offset<br />
generate_random_vector(&spec_coeff1[(group * nshort) + offset], ics1.scalefactors[g][scalefactor_band], size)<br />
if channel_pair AND ics2.scalefactor_band_codebook[g][scalefactor_band] == NOISE_HCB (13)<br />
if (ics1.midside_mask_present == 1 AND ics1.midside_used[g][scalefactor_band]) OR ics1.midside_mask_present == 2<br />
offset = ics2.scalefactor_window_band_offset[scalefactor_band]<br />
size = ics2.scalefactor_window_band_offset[scalefactor_band + 1] - offset<br />
foreach c in 0..size - 1<br />
spec_coeff2[(group * nshort) + offset + c] = spec_coeff1[(group * nshort) + offset + c]<br />
else<br />
/* LTP and PNS are not allowed in the same band and PNS takes precedence;<br />
* thus, disable LTP for this band */<br />
ics2.ltp.long_used[scalefactor_band] = 0<br />
ics2.ltp2.long_used[scalefactor_band] = 0<br />
/* disable predictors for bands using PNS */<br />
ics2.pred.prediction_used[scalefactor_band] = 0<br />
offset = ics2.scalefactor_window_band_offset[scalefactor_band]<br />
size = ics2.scalefactor_window_band_offset[scalefactor_band + 1] - offset<br />
generate_random_vector(&spec_coeff2[(group * nshort) + offset], ics2.scalefactors[g][scalefactor_band], size)<br />
group++<br />
<br />
== ms_decode() ==<br />
<br />
== is_decode() ==<br />
<br />
== ic_prediction() ==<br />
<br />
== pns_reset_pred_state() ==<br />
<br />
== tns_decode_frame() ==<br />
<br />
== drc_decode() ==<br />
<br />
== ifilter_bank() ==<br />
<br />
== imdct_long() ==<br />
In low complexity mode, this function simply calls down to faad_imdct(). If LD is enabled, there is some more processing beforehand.<br />
<br />
== faad_imdct(real *in, real *out) ==<br />
This comment appears in FAAD2's mdct.c file header:<br />
<br />
"Fast (I)MDCT Implementation using (I)FFT ((Inverse) Fast Fourier Transform) and consists of three steps: pre-(I)FFT complex multiplication, complex (I)FFT, post-(I)FFT complex multiplication."<br />
<br />
This function is apparently a good candidate for SIMD optimization.<br />
<br />
== ssr_decode() ==<br />
<br />
== lt_update_state() ==<br />
<br />
== sbrDecodeInit() ==<br />
<br />
== sbrDecodeCoupleFrame() ==</div>
71.198.76.184
https://wiki.multimedia.cx/index.php?title=AAC_Huffman_Tables&diff=2709
AAC Huffman Tables
2006-03-11T22:52:48Z
<p>71.198.76.184: </p>
<hr />
<div>''Part of [[Understanding AAC]]''<br />
<br />
These Huffman tables are formatted in a manner conducive to being included in [[FFmpeg]].<br />
<br />
== AAC Huffman Table 1 ==<br />
<br />
== AAC Huffman Table 2 ==<br />
<br />
== AAC Huffman Table 3 ==<br />
static const unsigned short aac_huffman_table_quad_3[][6] = {<br />
/* codeword, code length, 4 data points */<br />
{ 0x0, 1, 0, 0, 0, 0 },<br />
{ 0x8, 4, 1, 0, 0, 0 },<br />
{ 0x9, 4, 0, 0, 0, 1 },<br />
{ 0xA, 4, 0, 1, 0, 0 },<br />
{ 0xB, 4, 0, 0, 1, 0 },<br />
{ 0x18, 5, 1, 1, 0, 0 },<br />
{ 0x19, 5, 0, 0, 1, 1 },<br />
{ 0x34, 6, 0, 1, 1, 0 },<br />
{ 0x35, 6, 0, 1, 0, 1 },<br />
{ 0x36, 6, 1, 0, 1, 0 },<br />
{ 0x37, 6, 0, 1, 1, 1 },<br />
{ 0x38, 6, 1, 0, 0, 1 },<br />
{ 0x39, 6, 1, 1, 1, 0 },<br />
{ 0x74, 7, 1, 1, 1, 1 },<br />
{ 0x75, 7, 1, 0, 1, 1 },<br />
{ 0x76, 7, 1, 1, 0, 1 },<br />
{ 0xEE, 8, 2, 0, 0, 0 },<br />
{ 0xEF, 8, 0, 0, 0, 2 },<br />
{ 0xF0, 8, 0, 0, 1, 2 },<br />
{ 0xF1, 8, 2, 1, 0, 0 },<br />
{ 0xF2, 8, 1, 2, 1, 0 },<br />
{ 0x1E6, 9, 0, 0, 2, 1 },<br />
{ 0x1E7, 9, 0, 1, 2, 1 },<br />
{ 0x1E8, 9, 1, 2, 0, 0 },<br />
{ 0x1E9, 9, 0, 1, 1, 2 },<br />
{ 0x1EA, 9, 2, 1, 1, 0 },<br />
{ 0x1EB, 9, 0, 0, 2, 0 },<br />
{ 0x1EC, 9, 0, 2, 1, 0 },<br />
{ 0x1ED, 9, 0, 1, 2, 0 },<br />
{ 0x1EE, 9, 0, 2, 0, 0 },<br />
{ 0x1EF, 9, 0, 1, 0, 2 },<br />
{ 0x1F0, 9, 2, 0, 1, 0 },<br />
{ 0x1F1, 9, 1, 2, 1, 1 },<br />
{ 0x1F2, 9, 0, 2, 1, 1 },<br />
{ 0x1F3, 9, 1, 1, 2, 0 },<br />
{ 0x1F4, 9, 1, 1, 2, 1 },<br />
{ 0x3EA, 10, 1, 2, 0, 1 },<br />
{ 0x3EB, 10, 1, 0, 2, 0 },<br />
{ 0x3EC, 10, 1, 0, 2, 1 },<br />
{ 0x3ED, 10, 0, 2, 0, 1 },<br />
{ 0x3EE, 10, 2, 1, 1, 1 },<br />
{ 0x3EF, 10, 1, 1, 1, 2 },<br />
{ 0x3F0, 10, 2, 1, 0, 1 },<br />
{ 0x3F1, 10, 1, 0, 1, 2 },<br />
{ 0x3F2, 10, 0, 0, 2, 2 },<br />
{ 0x3F3, 10, 0, 1, 2, 2 },<br />
{ 0x3F4, 10, 2, 2, 1, 0 },<br />
{ 0x3F5, 10, 1, 2, 2, 0 },<br />
{ 0x3F6, 10, 1, 0, 0, 2 },<br />
{ 0x3F7, 10, 2, 0, 0, 1 },<br />
{ 0x3F8, 10, 0, 2, 2, 1 },<br />
{ 0x7F2, 11, 2, 2, 0, 0 },<br />
{ 0x7F3, 11, 1, 2, 2, 1 },<br />
{ 0x7F4, 11, 1, 1, 0, 2 },<br />
{ 0x7F5, 11, 2, 0, 1, 1 },<br />
{ 0x7F6, 11, 1, 1, 2, 2 },<br />
{ 0x7F7, 11, 2, 2, 1, 1 },<br />
{ 0x7F8, 11, 0, 2, 2, 0 },<br />
{ 0x7F9, 11, 0, 2, 1, 2 },<br />
{ 0xFF4, 12, 1, 0, 2, 2 },<br />
{ 0xFF5, 12, 2, 2, 0, 1 },<br />
{ 0xFF6, 12, 2, 1, 2, 0 },<br />
{ 0xFF7, 12, 2, 2, 2, 0 },<br />
{ 0xFF8, 12, 0, 2, 2, 2 },<br />
{ 0xFF9, 12, 2, 2, 2, 1 },<br />
{ 0xFFA, 12, 2, 1, 2, 1 },<br />
{ 0xFFB, 12, 1, 2, 1, 2 },<br />
{ 0xFFC, 12, 1, 2, 2, 2 },<br />
{ 0x1FFA, 13, 0, 2, 0, 2 },<br />
{ 0x1FFB, 13, 2, 0, 2, 0 },<br />
{ 0x1FFC, 13, 1, 2, 0, 2 },<br />
{ 0x3FFA, 14, 2, 0, 2, 1 },<br />
{ 0x3FFB, 14, 2, 1, 1, 2 },<br />
{ 0x3FFC, 14, 2, 1, 0, 2 },<br />
{ 0x7FFA, 15, 2, 2, 2, 2 },<br />
{ 0x7FFB, 15, 2, 2, 1, 2 },<br />
{ 0x7FFC, 15, 2, 1, 2, 2 },<br />
{ 0x7FFD, 15, 2, 0, 1, 2 },<br />
{ 0x7FFE, 15, 2, 0, 0, 2 },<br />
{ 0xFFFE, 16, 2, 2, 0, 2 },<br />
{ 0xFFFF, 16, 2, 0, 2, 2 },<br />
};<br />
<br />
== AAC Huffman Table 4 ==<br />
<br />
== AAC Huffman Table 5 ==<br />
static const unsigned short aac_huffman_table_pair_5[][4] = {<br />
/* codeword, code length, 2 data points */<br />
{ 0x0, 1, 0, 0 },<br />
{ 0x8, 4, -1, 0 },<br />
{ 0x9, 4, 1, 0 },<br />
{ 0xA, 4, 0, 1 },<br />
{ 0xB, 4, 0, -1 },<br />
{ 0x18, 5, 1, -1 },<br />
{ 0x19, 5, -1, 1 },<br />
{ 0x1A, 5, -1, -1 },<br />
{ 0x1B, 5, 1, 1 },<br />
{ 0x70, 7, -2, 0 },<br />
{ 0x71, 7, 0, 2 },<br />
{ 0x72, 7, 2, 0 },<br />
{ 0x73, 7, 0, -2 },<br />
{ 0xE8, 8, -2, -1 },<br />
{ 0xE9, 8, 2, 1 },<br />
{ 0xEA, 8, -1, -2 },<br />
{ 0xEB, 8, 1, 2 },<br />
{ 0xEC, 8, -2, 1 },<br />
{ 0xED, 8, 2, -1 },<br />
{ 0xEE, 8, -1, 2 },<br />
{ 0xEF, 8, 1, -2 },<br />
{ 0xF0, 8, -3, 0 },<br />
{ 0xF1, 8, 3, 0 },<br />
{ 0xF2, 8, 0, -3 },<br />
{ 0xF3, 8, 0, 3 },<br />
{ 0x1E8, 9, -3, -1 },<br />
{ 0x1E9, 9, 1, 3 },<br />
{ 0x1EA, 9, 3, 1 },<br />
{ 0x1EB, 9, -1, -3 },<br />
{ 0x1EC, 9, -3, 1 },<br />
{ 0x1ED, 9, 3, -1 },<br />
{ 0x1EE, 9, 1, -3 },<br />
{ 0x1EF, 9, -1, 3 },<br />
{ 0x1F0, 9, -2, 2 },<br />
{ 0x1F1, 9, 2, 2 },<br />
{ 0x1F2, 9, -2, -2 },<br />
{ 0x1F3, 9, 2, -2 },<br />
{ 0x3E8, 10, -3, -2 },<br />
{ 0x3E9, 10, 3, -2 },<br />
{ 0x3EA, 10, -2, 3 },<br />
{ 0x3EB, 10, 2, -3 },<br />
{ 0x3EC, 10, 3, 2 },<br />
{ 0x3ED, 10, 2, 3 },<br />
{ 0x3EE, 10, -3, 2 },<br />
{ 0x3EF, 10, -2, -3 },<br />
{ 0x3F0, 10, 0, -4 },<br />
{ 0x3F1, 10, -4, 0 },<br />
{ 0x3F2, 10, 4, 1 },<br />
{ 0x3F3, 10, 4, 0 },<br />
{ 0x7E8, 11, -4, -1 },<br />
{ 0x7E9, 11, 0, 4 },<br />
{ 0x7EA, 11, 4, -1 },<br />
{ 0x7EB, 11, -1, -4 },<br />
{ 0x7EC, 11, 1, 4 },<br />
{ 0x7ED, 11, -1, 4 },<br />
{ 0x7EE, 11, -4, 1 },<br />
{ 0x7EF, 11, 1, -4 },<br />
{ 0x7F0, 11, 3, -3 },<br />
{ 0x7F1, 11, -3, -3 },<br />
{ 0x7F2, 11, -3, 3 },<br />
{ 0x7F3, 11, -2, 4 },<br />
{ 0x7F4, 11, -4, -2 },<br />
{ 0x7F5, 11, 4, 2 },<br />
{ 0x7F6, 11, 2, -4 },<br />
{ 0x7F7, 11, 2, 4 },<br />
{ 0x7F8, 11, 3, 3 },<br />
{ 0x7F9, 11, -4, 2 },<br />
{ 0xFF4, 12, -2, -4 },<br />
{ 0xFF5, 12, 4, -2 },<br />
{ 0xFF6, 12, 3, -4 },<br />
{ 0xFF7, 12, -4, -3 },<br />
{ 0xFF8, 12, -4, 3 },<br />
{ 0xFF9, 12, 3, 4 },<br />
{ 0xFFA, 12, -3, 4 },<br />
{ 0xFFB, 12, 4, 3 },<br />
{ 0xFFC, 12, 4, -3 },<br />
{ 0xFFD, 12, -3, -4 },<br />
{ 0x1FFC, 13, 4, -4 },<br />
{ 0x1FFD, 13, -4, 4 },<br />
{ 0x1FFE, 13, 4, 4 },<br />
{ 0x1FFF, 13, -4, -4 },<br />
};<br />
<br />
== AAC Huffman Table 6 ==<br />
<br />
== AAC Huffman Table 7 ==<br />
static const unsigned short aac_huffman_table_pair_7[][4] = {<br />
/* codeword, code length, 2 data points */<br />
{ 0x0, 1, 0, 0 },<br />
{ 0x4, 3, 1, 0 },<br />
{ 0x5, 3, 0, 1 },<br />
{ 0xC, 4, 1, 1 },<br />
{ 0x34, 6, 2, 1 },<br />
{ 0x35, 6, 1, 2 },<br />
{ 0x36, 6, 2, 0 },<br />
{ 0x37, 6, 0, 2 },<br />
{ 0x70, 7, 3, 1 },<br />
{ 0x71, 7, 1, 3 },<br />
{ 0x72, 7, 2, 2 },<br />
{ 0x73, 7, 3, 0 },<br />
{ 0x74, 7, 0, 3 },<br />
{ 0xEA, 8, 2, 3 },<br />
{ 0xEB, 8, 3, 2 },<br />
{ 0xEC, 8, 1, 4 },<br />
{ 0xED, 8, 4, 1 },<br />
{ 0xEE, 8, 1, 5 },<br />
{ 0xEF, 8, 5, 1 },<br />
{ 0xF0, 8, 3, 3 },<br />
{ 0xF1, 8, 2, 4 },<br />
{ 0xF2, 8, 0, 4 },<br />
{ 0xF3, 8, 4, 0 },<br />
{ 0x1E8, 9, 4, 2 },<br />
{ 0x1E9, 9, 2, 5 },<br />
{ 0x1EA, 9, 5, 2 },<br />
{ 0x1EB, 9, 0, 5 },<br />
{ 0x1EC, 9, 6, 1 },<br />
{ 0x1ED, 9, 5, 0 },<br />
{ 0x1EE, 9, 1, 6 },<br />
{ 0x1EF, 9, 4, 3 },<br />
{ 0x1F0, 9, 3, 5 },<br />
{ 0x1F1, 9, 3, 4 },<br />
{ 0x1F2, 9, 5, 3 },<br />
{ 0x1F3, 9, 2, 6 },<br />
{ 0x1F4, 9, 6, 2 },<br />
{ 0x1F5, 9, 1, 7 },<br />
{ 0x3EC, 10, 3, 6 },<br />
{ 0x3ED, 10, 0, 6 },<br />
{ 0x3EE, 10, 6, 0 },<br />
{ 0x3EF, 10, 4, 4 },<br />
{ 0x3F0, 10, 7, 1 },<br />
{ 0x3F1, 10, 4, 5 },<br />
{ 0x3F2, 10, 7, 2 },<br />
{ 0x3F3, 10, 5, 4 },<br />
{ 0x3F4, 10, 6, 3 },<br />
{ 0x3F5, 10, 2, 7 },<br />
{ 0x3F6, 10, 7, 3 },<br />
{ 0x3F7, 10, 6, 4 },<br />
{ 0x3F8, 10, 5, 5 },<br />
{ 0x3F9, 10, 4, 6 },<br />
{ 0x3FA, 10, 3, 7 },<br />
{ 0x7F6, 11, 7, 0 },<br />
{ 0x7F7, 11, 0, 7 },<br />
{ 0x7F8, 11, 6, 5 },<br />
{ 0x7F9, 11, 5, 6 },<br />
{ 0x7FA, 11, 7, 4 },<br />
{ 0x7FB, 11, 4, 7 },<br />
{ 0x7FC, 11, 5, 7 },<br />
{ 0x7FD, 11, 7, 5 },<br />
{ 0xFFC, 12, 7, 6 },<br />
{ 0xFFD, 12, 6, 6 },<br />
{ 0xFFE, 12, 6, 7 },<br />
{ 0xFFF, 12, 7, 7 },<br />
};<br />
<br />
== AAC Huffman Table 8 ==<br />
<br />
== AAC Huffman Table 9 ==<br />
static const unsigned short aac_huffman_table_pair_9[][4] = {<br />
/* codeword, code length, 2 data points */<br />
{ 0x0, 1, 0, 0 },<br />
{ 0x4, 3, 1, 0 },<br />
{ 0x5, 3, 0, 1 },<br />
{ 0xC, 4, 1, 1 },<br />
{ 0x34, 6, 2, 1 },<br />
{ 0x35, 6, 1, 2 },<br />
{ 0x36, 6, 2, 0 },<br />
{ 0x37, 6, 0, 2 },<br />
{ 0x70, 7, 3, 1 },<br />
{ 0x71, 7, 2, 2 },<br />
{ 0x72, 7, 1, 3 },<br />
{ 0xE6, 8, 3, 0 },<br />
{ 0xE7, 8, 0, 3 },<br />
{ 0xE8, 8, 2, 3 },<br />
{ 0xE9, 8, 3, 2 },<br />
{ 0xEA, 8, 1, 4 },<br />
{ 0xEB, 8, 4, 1 },<br />
{ 0xEC, 8, 2, 4 },<br />
{ 0xED, 8, 1, 5 },<br />
{ 0x1DC, 9, 4, 2 },<br />
{ 0x1DD, 9, 3, 3 },<br />
{ 0x1DE, 9, 0, 4 },<br />
{ 0x1DF, 9, 4, 0 },<br />
{ 0x1E0, 9, 5, 1 },<br />
{ 0x1E1, 9, 2, 5 },<br />
{ 0x1E2, 9, 1, 6 },<br />
{ 0x1E3, 9, 3, 4 },<br />
{ 0x1E4, 9, 5, 2 },<br />
{ 0x1E5, 9, 6, 1 },<br />
{ 0x1E6, 9, 4, 3 },<br />
{ 0x3CE, 10, 0, 5 },<br />
{ 0x3CF, 10, 2, 6 },<br />
{ 0x3D0, 10, 5, 0 },<br />
{ 0x3D1, 10, 1, 7 },<br />
{ 0x3D2, 10, 3, 5 },<br />
{ 0x3D3, 10, 1, 8 },<br />
{ 0x3D4, 10, 8, 1 },<br />
{ 0x3D5, 10, 4, 4 },<br />
{ 0x3D6, 10, 5, 3 },<br />
{ 0x3D7, 10, 6, 2 },<br />
{ 0x3D8, 10, 7, 1 },<br />
{ 0x3D9, 10, 0, 6 },<br />
{ 0x3DA, 10, 8, 2 },<br />
{ 0x3DB, 10, 2, 8 },<br />
{ 0x3DC, 10, 3, 6 },<br />
{ 0x3DD, 10, 2, 7 },<br />
{ 0x3DE, 10, 4, 5 },<br />
{ 0x3DF, 10, 9, 1 },<br />
{ 0x3E0, 10, 1, 9 },<br />
{ 0x3E1, 10, 7, 2 },<br />
{ 0x7C4, 11, 6, 0 },<br />
{ 0x7C5, 11, 5, 4 },<br />
{ 0x7C6, 11, 6, 3 },<br />
{ 0x7C7, 11, 8, 3 },<br />
{ 0x7C8, 11, 0, 7 },<br />
{ 0x7C9, 11, 9, 2 },<br />
{ 0x7CA, 11, 3, 8 },<br />
{ 0x7CB, 11, 4, 6 },<br />
{ 0x7CC, 11, 3, 7 },<br />
{ 0x7CD, 11, 0, 8 },<br />
{ 0x7CE, 11, 10, 1 },<br />
{ 0x7CF, 11, 6, 4 },<br />
{ 0x7D0, 11, 2, 9 },<br />
{ 0x7D1, 11, 5, 5 },<br />
{ 0x7D2, 11, 8, 0 },<br />
{ 0x7D3, 11, 7, 0 },<br />
{ 0x7D4, 11, 7, 3 },<br />
{ 0x7D5, 11, 10, 2 },<br />
{ 0x7D6, 11, 9, 3 },<br />
{ 0x7D7, 11, 8, 4 },<br />
{ 0x7D8, 11, 1, 10 },<br />
{ 0x7D9, 11, 7, 4 },<br />
{ 0x7DA, 11, 6, 5 },<br />
{ 0x7DB, 11, 5, 6 },<br />
{ 0x7DC, 11, 4, 8 },<br />
{ 0x7DD, 11, 4, 7 },<br />
{ 0x7DE, 11, 3, 9 },<br />
{ 0x7DF, 11, 11, 1 },<br />
{ 0x7E0, 11, 5, 8 },<br />
{ 0x7E1, 11, 9, 0 },<br />
{ 0x7E2, 11, 8, 5 },<br />
{ 0xFC6, 12, 10, 3 },<br />
{ 0xFC7, 12, 2, 10 },<br />
{ 0xFC8, 12, 0, 9 },<br />
{ 0xFC9, 12, 11, 2 },<br />
{ 0xFCA, 12, 9, 4 },<br />
{ 0xFCB, 12, 6, 6 },<br />
{ 0xFCC, 12, 12, 1 },<br />
{ 0xFCD, 12, 4, 9 },<br />
{ 0xFCE, 12, 8, 6 },<br />
{ 0xFCF, 12, 1, 11 },<br />
{ 0xFD0, 12, 9, 5 },<br />
{ 0xFD1, 12, 10, 4 },<br />
{ 0xFD2, 12, 5, 7 },<br />
{ 0xFD3, 12, 7, 5 },<br />
{ 0xFD4, 12, 2, 11 },<br />
{ 0xFD5, 12, 1, 12 },<br />
{ 0xFD6, 12, 12, 2 },<br />
{ 0xFD7, 12, 11, 3 },<br />
{ 0xFD8, 12, 3, 10 },<br />
{ 0xFD9, 12, 5, 9 },<br />
{ 0xFDA, 12, 6, 7 },<br />
{ 0xFDB, 12, 8, 7 },<br />
{ 0xFDC, 12, 11, 4 },<br />
{ 0xFDD, 12, 0, 10 },<br />
{ 0xFDE, 12, 7, 6 },<br />
{ 0xFDF, 12, 12, 3 },<br />
{ 0xFE0, 12, 10, 0 },<br />
{ 0xFE1, 12, 10, 5 },<br />
{ 0xFE2, 12, 4, 10 },<br />
{ 0xFE3, 12, 6, 8 },<br />
{ 0xFE4, 12, 2, 12 },<br />
{ 0xFE5, 12, 9, 6 },<br />
{ 0xFE6, 12, 9, 7 },<br />
{ 0xFE7, 12, 4, 11 },<br />
{ 0xFE8, 12, 11, 0 },<br />
{ 0xFE9, 12, 6, 9 },<br />
{ 0xFEA, 12, 3, 11 },<br />
{ 0xFEB, 12, 5, 10 },<br />
{ 0x1FD8, 13, 8, 8 },<br />
{ 0x1FD9, 13, 7, 8 },<br />
{ 0x1FDA, 13, 12, 5 },<br />
{ 0x1FDB, 13, 3, 12 },<br />
{ 0x1FDC, 13, 11, 5 },<br />
{ 0x1FDD, 13, 7, 7 },<br />
{ 0x1FDE, 13, 12, 4 },<br />
{ 0x1FDF, 13, 11, 6 },<br />
{ 0x1FE0, 13, 10, 6 },<br />
{ 0x1FE1, 13, 4, 12 },<br />
{ 0x1FE2, 13, 7, 9 },<br />
{ 0x1FE3, 13, 5, 11 },<br />
{ 0x1FE4, 13, 0, 11 },<br />
{ 0x1FE5, 13, 12, 6 },<br />
{ 0x1FE6, 13, 6, 10 },<br />
{ 0x1FE7, 13, 12, 0 },<br />
{ 0x1FE8, 13, 10, 7 },<br />
{ 0x1FE9, 13, 5, 12 },<br />
{ 0x1FEA, 13, 7, 10 },<br />
{ 0x1FEB, 13, 9, 8 },<br />
{ 0x1FEC, 13, 0, 12 },<br />
{ 0x1FED, 13, 11, 7 },<br />
{ 0x1FEE, 13, 8, 9 },<br />
{ 0x1FEF, 13, 9, 9 },<br />
{ 0x1FF0, 13, 10, 8 },<br />
{ 0x1FF1, 13, 7, 11 },<br />
{ 0x1FF2, 13, 12, 7 },<br />
{ 0x1FF3, 13, 6, 11 },<br />
{ 0x1FF4, 13, 8, 11 },<br />
{ 0x1FF5, 13, 11, 8 },<br />
{ 0x1FF6, 13, 7, 12 },<br />
{ 0x1FF7, 13, 6, 12 },<br />
{ 0x3FF0, 14, 8, 10 },<br />
{ 0x3FF1, 14, 10, 9 },<br />
{ 0x3FF2, 14, 8, 12 },<br />
{ 0x3FF3, 14, 9, 10 },<br />
{ 0x3FF4, 14, 9, 11 },<br />
{ 0x3FF5, 14, 9, 12 },<br />
{ 0x3FF6, 14, 10, 11 },<br />
{ 0x3FF7, 14, 12, 9 },<br />
{ 0x3FF8, 14, 10, 10 },<br />
{ 0x3FF9, 14, 11, 9 },<br />
{ 0x3FFA, 14, 12, 8 },<br />
{ 0x3FFB, 14, 11, 10 },<br />
{ 0x3FFC, 14, 12, 10 },<br />
{ 0x3FFD, 14, 12, 11 },<br />
{ 0x7FFC, 15, 10, 12 },<br />
{ 0x7FFD, 15, 11, 11 },<br />
{ 0x7FFE, 15, 11, 12 },<br />
{ 0x7FFF, 15, 12, 12 },<br />
};<br />
<br />
== AAC Huffman Table 10 ==<br />
<br />
== AAC Huffman Table 11 ==</div>
71.198.76.184
https://wiki.multimedia.cx/index.php?title=VC-1&diff=2263
VC-1
2006-02-15T06:11:45Z
<p>71.198.76.184: add cursory data description details</p>
<hr />
<div>* FOURCCs: WMV3, WMV9<br />
* Company: [[Microsoft]]<br />
<br />
Old specs can be found here: [http://jovian.com/files/C24.008-VC9-Spec-CD1.pdf]<br />
<br />
VC-1 is the codec microsoft is pushing for SMPTE standard. VC-1 is what wmv9 became and specs for it can be found here:<br />
<br />
VC-1 Compressed Video Bitstream Format and Decoding Process [http://www.smpte.org/smpte_store/standards/pdf/s421m.pdf]<br />
<br />
VC-1 Bitstream Transport Encodings (specs for placing VC-1 in MPEG-2 Program and Transport streams) [http://www.smpte.org/smpte_store/standards/pdf/rp227.pdf]<br />
<br />
VC-1 Decoder and Bitstream Conformance [http://www.smpte.org/smpte_store/standards/pdf/rp228.pdf]<br />
<br />
Googling for VC1_reference_decoder_release6.zip might turn up sources for the reference decoder.<br />
<br />
== Data Format ==<br />
<br />
This description assumes that the data to be decoded in WMV3 data coming in from a [[Microsoft Advanced Streaming Format|Microsoft ASF]] file. The video data should be packaged with "extradata" which is attached to the end of a [[BITMAPINFOHEADER]] structure and transported in the ASF file. The format of the extradata is as follows:<br />
<br />
2 bits VC-1 Profile<br />
if (profile == 3)<br />
3 bits Profile level<br />
2 bits Chroma format (SRD does not care)<br />
3 bits VC1_BITS_FRMRTQ_POSTPROC (? SRD does not care)<br />
5 bits VC1_BITS_BITRTQ_POSTPROC (? SRD does not care)<br />
1 bit VC1_BITS_POSTPROCFLAG (? SRD does not care)<br />
12 bits Encoded width (actual width = (w + 1) * 2)<br />
12 bits Encoded height (actual height = (h + 1) * 2)<br />
<br />
There are 4 VC-1 profiles:<br />
<br />
* 0 simple profile<br />
* 1 main profile<br />
* 2 reserved<br />
* 3 advanced profile<br />
<br />
If profile is advanced, the extradata carries a lot of setup information. For simple and main profiles, the relevant setup data is established outside of the decoder, e.g., the BITMAPINFO header of a Microsoft ASF file. This information provides the width and height that the decoder uses to set up its state.<br />
<br />
The decoder computes the macroblock width and height as the ceiling of each dimension divided by 16:<br />
<br />
macroblock_width = (frame_width + 15) / 16<br />
macroblock_height = (frame_height + 15) / 16<br />
<br />
The total number of macroblocks in a frame is defined as:<br />
<br />
total_macroblocks = macroblock_width * macroblock_height<br />
<br />
If the level is marked as unknown during the initialization process, figure out what level the video belongs at. This is determined by the number of macroblocks in combination with the profile. The relevant table is vc1gentab.c:vc1GENTAB_LevelLimits<nowiki>[][]</nowiki>. The profile/level combination defines the following limits:<br />
<br />
max macroblocks/second<br />
max macroblocks/frame<br />
max peak transmission rate in kbps<br />
max buffer size in multiples of 16 kbits<br />
motion vector range<br />
<br />
SRD maintains the following information about each macroblock:<br />
<br />
macroblock type, contains the following attributes:<br />
(attribute 1)<br />
intra<br />
1 MV<br />
2 MV<br />
4 MV<br />
<br />
(attribute 2)<br />
direct macroblock<br />
forward prediction<br />
backward prediction<br />
forward and backward prediction<br />
<br />
(attribute 3)<br />
MVs apply to fields<br />
bottom different than top<br />
field transform<br />
<br />
AC prediction status, one of the following attributes:<br />
AC prediction off<br />
AC prediction on<br />
no blocks can be predicted<br />
<br />
Block type, one of the following types:<br />
8x8 inter-coded<br />
8x4 inter-coded<br />
4x8 inter-coded<br />
4x4 inter-coded<br />
intra-coded, no AC prediction<br />
intra-coded, AC prediction from top values<br />
intra-coded, AC prediction from left values<br />
<br />
flag indicating whether overlap filter is active for this macroblock<br />
flag indicating whether macroblock is motion predicted only (no residual)<br />
byte indicating coded block pattern which indicates which of the 6<br />
sub-blocks are coded<br />
<br />
Quantizer information, this includes:<br />
quantizer step in the range 1..31<br />
quantizer half step, either 0 or 1<br />
flag indicating uniform or non-uniform quantizer<br />
<br />
Information for each of the 6 constituent blocks in the macroblock:<br />
block type (same choices as the macroblock attributes)<br />
flag indicating non-zero AC coeffs for intra, non-zero AC/DC for inter<br />
union between an intra block structure and an inter block structure<br />
intra structure:<br />
number of zero/non-zero AC coeffs<br />
quantized DC coeff<br />
quantized AC top row for prediction (7 values)<br />
quantized AC left column for prediction (7 values)<br />
bottom 2 rows (16 values) kept for overlap smoothing<br />
inter structure:<br />
number of zero/non-zero AC coeffs for 4 sub-blocks (Y blocks?)<br />
forward and backward motion vector structures, each includes:<br />
hybrid prediction mode, one of the following attributes:<br />
predict from left<br />
predict from top<br />
no hybrid prediction<br />
(x,y) motion vectors for each of the 4 Y blocks<br />
(x,y) differential motion vectors in 1/4 pel units<br />
(note: I am a little confused as to why each of the 6 sub-blocks stores the motion vector data for the entire macroblock)<br />
<br />
The initializer then needs to computer how much space to allocate for each reference frame. The size of a frame determined by frame width and height, encoding profile, and interlacing. This size is used to allocate space for 4 different frames:<br />
<br />
reference new (new/current I/P frame)<br />
reference old (old I/P reference frame)<br />
reference B (reconstructed B frame)<br />
reference NoIC (B reference before intensity compensation was applied)<br />
<br />
Further, the initializer allocates space for 7 different bitplanes. Each bitplanes has 1 flag per each macroblock as enumerated by the max macroblocks per frame for the profile/level. The bitplanes are:<br />
<br />
ACPRED<br />
SKIPMB<br />
MVTYPEMB<br />
DIRECTMB<br />
OVERFLAGS<br />
FORWARDMB<br />
FIELDTX<br />
<br />
Allocate space for motion vector history. The number of entries in this array is macroblock_width * (macroblock_height + 1) (extra height is for interlaced field). Each entry is a motion vector history structure which contains the 4 Y block motion vectors for a particular macroblock. The individual motion<br />
vector structures are the same as in the intra structure which provides hybrid prediction, motion vectors, and diff MVs (again, 4 for each block?).<br />
<br />
And that's it for the SRD "requirements gathering" process (vc1dec.c:vc1DEC_DecoderRequirements()). The function returns the number of bytes needed for the decoder's internal state. The client app is expected<br />
to allocate enough space for this state.<br />
<br />
Next is the vc1dec.c:vc1DEC_DecoderInitialise() function. This sets up the positions and structures contained within the memory pool allocated for space.<br />
<br />
Next is the vc1dec.c:vc1DEC_DecodeSequence() function which unpacks the sequence layer:<br />
<br />
2 bits profile<br />
if (profile is simple or main)<br />
2 bits VC1_BITS_RES_SM (? SRD does not care)<br />
if (profile is advanced)<br />
3 bits level of advanced profile<br />
2 bits chroma format (note that only format 1, YUV 4:2:0 is defined)<br />
3 bits QFrameRateForPostProc ("see standard", SRD does not use)<br />
5 bits QBitRateForPostProc ("see standard", SRD does not use)<br />
if (profile is simple or main)<br />
1 bit loop filter flag<br />
1 bit reserved, should be 0<br />
1 bit multiresolution coding flag<br />
1 bit reserved, should be 1, SRD calls it "RES_FASTTX"<br />
1 bit fast U/V motion compensation<br />
note: must be 1 in simple profile<br />
1 bit extended motion vectors<br />
note: must be 0 in simple profile<br />
2 bits macroblock dequantization<br />
1 bit variable sized transform<br />
1 bit reserved, should be 0, SRD calls it "RES_TRANSTAB"<br />
1 bit overlapped transform flag<br />
1 bit sync marker flag<br />
1 bit range reduction flag<br />
3 bits maximum number of consecutive B frames<br />
2 bits quantizer<br />
if (profile is advanced)<br />
1 bit post processing flag<br />
12 bits max coded width (actual width = (w + 1) * 2)<br />
12 bits max coded height (actual height = (h + 1) * 2)<br />
1 bit pulldown flag<br />
1 bit interlaced<br />
1 bit frame counter flag<br />
1 bit frame interpolation flag<br />
if (profile is advanced)<br />
[lots more stuff to be filled in when advanced profile is needed]<br />
if (profile is simple or main)<br />
1 bit reserved, should be 1, SRD calls it "RES_RTM_FLAG"<br />
<br />
Finally, it is time to decode an actual frame (referred to as "unpacking the picture layer"). The decode process iterates through however many fields comprise the frame (1 or 2).<br />
<br />
Choose from among 5 different zigzag table sets depending on profile and interlacing:<br />
<br />
if (picture format is interlaced frame)<br />
choose set 4<br />
if (picture is intra)<br />
choose set 0<br />
else<br />
if (profile is simple or main)<br />
choose set 1<br />
else<br />
if (picture format is progressive)<br />
choose set 2<br />
else<br />
choose set 3<br />
'''(unfinished)'''<br />
... there is a lot more logic dealing with frame accounting; let's skip to the real meat: macroblock decoding! ...<br />
<br />
Decode a macroblock:<br />
set the macroblock overlap filter flag, coding type, quantizer and halfstep<br />
parameters to the same as the picture<br />
clear the skipped flag<br />
set the CBP to 0 (no coded blocks)<br />
choose the quantizer (long list of logic, see<br />
vc1iquant.c:vc1IQUANT_ChooseQuantizer())<br />
for each of the 6 sub-blocks, set coded field to 0, clear down all MV data<br />
decide on non-uniform quantizer<br />
<br />
unpack an I or BI macroblock:<br />
<br />
'''(unfinished)'''<br />
<br />
[[Category:Video Codecs]]</div>
71.198.76.184
https://wiki.multimedia.cx/index.php?title=DosBox_Capture_Codec&diff=2262
DosBox Capture Codec
2006-02-15T05:29:46Z
<p>71.198.76.184: some more ZMBV doc</p>
<hr />
<div>* FourCC: ZMBV<br />
* Samples: [http://multimedia.cx/samples/zmbv/ http://multimedia.cx/samples/zmbv/]<br />
<br />
This is a codec added to the [http://dosbox.sourceforge.net DosBox] project to capture screen data (like Vmware [[VMNC]]).<br />
<br />
This codec employs ZLIB compression and has intraframes and delta frames. Delta frames seem to have blocks either copied from the previous frame or XOR'ed with some block from the previous frame.<br />
<br />
The [[FourCC]] for this codec is ZMBV which ostensibly stands for Zip Motion Blocks Video. The data is most commonly stored in [[Microsoft Audio/Video Interleaved|AVI]] files.<br />
<br />
== Data Format ==<br />
<br />
The first byte of a ZMBV data chunk contains the following flags:<br />
<br />
bits 7-2 undefined<br />
bit 1 palette change<br />
bit 0 1 = intraframe, 0 = interframe<br />
<br />
If the frame is an intra frame as indicated by bit 0 of byte 0, the next 6 bytes in the data chunk are formatted as follows:<br />
<br />
byte 1 major version<br />
byte 2 minor version<br />
byte 3 compression type (0 = uncompressed, 1 = zlib-compressed)<br />
byte 4 video format<br />
byte 5 block width<br />
byte 6 block height<br />
<br />
Presently, the only valid major/minor version pair is 0/1. A block width or height of 0 is invalid. These are the video modes presently defined:<br />
<br />
0 none<br />
1 1 bit/pixel, palettized<br />
2 2 bits/pixel, palettized<br />
3 4 bits/pixel, palettized<br />
4 8 bits/pixel, palettized<br />
5 15 bits/pixel<br />
6 16 bits/pixel<br />
7 24 bits/pixel<br />
8 32 bits/pixel<br />
<br />
Presently, it seems that only modes 4 (8 bpp) and 7 (24 bpp) are supported.<br />
<br />
If the compression type is 1, the remainder of the data chunk is compressed using the standard zlib package. Decompress the data before proceeding with the next step. Otherwise, proceed to the next step.<br />
<br />
If bit 1 of the frame header (palette change) is set then the first 768 bytes of the uncompressed data represent 256 red-green-blue palette triplets. Each component is one byte and ranges from 0..255.<br />
<br />
Next, if the frame is intracoded, the remaining uncompressed data at this point represents the entire frame. If the frame is intercoded then the remainder of the data is coded using blocks and XOR'ing.<br />
<br />
'''NOT FINISHED'''<br />
<br />
[[Category:Video Codecs]]</div>
71.198.76.184