📄 qdm2.c
字号:
/**
* Process subpacket 10 if not null, else
*
* @param q context
* @param node pointer to node with packet
* @param length packet length in bits
*/
static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node, int length)
{
GetBitContext gb;
init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8));
if (length != 0) {
init_tone_level_dequantization(q, &gb, length);
fill_tone_level_array(q, 1);
} else {
fill_tone_level_array(q, 0);
}
}
/**
* Process subpacket 11
*
* @param q context
* @param node pointer to node with packet
* @param length packet length in bit
*/
static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node, int length)
{
GetBitContext gb;
init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8));
if (length >= 32) {
int c = get_bits (&gb, 13);
if (c > 3)
fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method,
q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select);
}
synthfilt_build_sb_samples(q, &gb, length, 0, 8);
}
/**
* Process subpacket 12
*
* @param q context
* @param node pointer to node with packet
* @param length packet length in bits
*/
static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node, int length)
{
GetBitContext gb;
init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8));
synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling));
}
/*
* Process new subpackets for synthesis filter
*
* @param q context
* @param list list with synthesis filter packets (list D)
*/
static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list)
{
QDM2SubPNode *nodes[4];
nodes[0] = qdm2_search_subpacket_type_in_list(list, 9);
if (nodes[0] != NULL)
process_subpacket_9(q, nodes[0]);
nodes[1] = qdm2_search_subpacket_type_in_list(list, 10);
if (nodes[1] != NULL)
process_subpacket_10(q, nodes[1], nodes[1]->packet->size << 3);
else
process_subpacket_10(q, NULL, 0);
nodes[2] = qdm2_search_subpacket_type_in_list(list, 11);
if (nodes[0] != NULL && nodes[1] != NULL && nodes[2] != NULL)
process_subpacket_11(q, nodes[2], (nodes[2]->packet->size << 3));
else
process_subpacket_11(q, NULL, 0);
nodes[3] = qdm2_search_subpacket_type_in_list(list, 12);
if (nodes[0] != NULL && nodes[1] != NULL && nodes[3] != NULL)
process_subpacket_12(q, nodes[3], (nodes[3]->packet->size << 3));
else
process_subpacket_12(q, NULL, 0);
}
/*
* Decode superblock, fill packet lists.
*
* @param q context
*/
static void qdm2_decode_super_block (QDM2Context *q)
{
GetBitContext gb;
QDM2SubPacket header, *packet;
int i, packet_bytes, sub_packet_size, sub_packets_D;
unsigned int next_index = 0;
memset(q->tone_level_idx_hi1, 0, sizeof(q->tone_level_idx_hi1));
memset(q->tone_level_idx_mid, 0, sizeof(q->tone_level_idx_mid));
memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2));
q->sub_packets_B = 0;
sub_packets_D = 0;
average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8]
init_get_bits(&gb, q->compressed_data, q->compressed_size*8);
qdm2_decode_sub_packet_header(&gb, &header);
if (header.type < 2 || header.type >= 8) {
q->has_errors = 1;
av_log(NULL,AV_LOG_ERROR,"bad superblock type\n");
return;
}
q->superblocktype_2_3 = (header.type == 2 || header.type == 3);
packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8);
init_get_bits(&gb, header.data, header.size*8);
if (header.type == 2 || header.type == 4 || header.type == 5) {
int csum = 257 * get_bits(&gb, 8) + 2 * get_bits(&gb, 8);
csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum);
if (csum != 0) {
q->has_errors = 1;
av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n");
return;
}
}
q->sub_packet_list_B[0].packet = NULL;
q->sub_packet_list_D[0].packet = NULL;
for (i = 0; i < 6; i++)
if (--q->fft_level_exp[i] < 0)
q->fft_level_exp[i] = 0;
for (i = 0; packet_bytes > 0; i++) {
int j;
q->sub_packet_list_A[i].next = NULL;
if (i > 0) {
q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i];
/* seek to next block */
init_get_bits(&gb, header.data, header.size*8);
skip_bits(&gb, next_index*8);
if (next_index >= header.size)
break;
}
/* decode subpacket */
packet = &q->sub_packets[i];
qdm2_decode_sub_packet_header(&gb, packet);
next_index = packet->size + get_bits_count(&gb) / 8;
sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2;
if (packet->type == 0)
break;
if (sub_packet_size > packet_bytes) {
if (packet->type != 10 && packet->type != 11 && packet->type != 12)
break;
packet->size += packet_bytes - sub_packet_size;
}
packet_bytes -= sub_packet_size;
/* add subpacket to 'all subpackets' list */
q->sub_packet_list_A[i].packet = packet;
/* add subpacket to related list */
if (packet->type == 8) {
SAMPLES_NEEDED_2("packet type 8");
return;
} else if (packet->type >= 9 && packet->type <= 12) {
/* packets for MPEG Audio like Synthesis Filter */
QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet);
} else if (packet->type == 13) {
for (j = 0; j < 6; j++)
q->fft_level_exp[j] = get_bits(&gb, 6);
} else if (packet->type == 14) {
for (j = 0; j < 6; j++)
q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2);
} else if (packet->type == 15) {
SAMPLES_NEEDED_2("packet type 15")
return;
} else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) {
/* packets for FFT */
QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet);
}
} // Packet bytes loop
/* **************************************************************** */
if (q->sub_packet_list_D[0].packet != NULL) {
process_synthesis_subpackets(q, q->sub_packet_list_D);
q->do_synth_filter = 1;
} else if (q->do_synth_filter) {
process_subpacket_10(q, NULL, 0);
process_subpacket_11(q, NULL, 0);
process_subpacket_12(q, NULL, 0);
}
/* **************************************************************** */
}
static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet,
int offset, int duration, int channel,
int exp, int phase)
{
if (q->fft_coefs_min_index[duration] < 0)
q->fft_coefs_min_index[duration] = q->fft_coefs_index;
q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet);
q->fft_coefs[q->fft_coefs_index].channel = channel;
q->fft_coefs[q->fft_coefs_index].offset = offset;
q->fft_coefs[q->fft_coefs_index].exp = exp;
q->fft_coefs[q->fft_coefs_index].phase = phase;
q->fft_coefs_index++;
}
static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b)
{
int channel, stereo, phase, exp;
int local_int_4, local_int_8, stereo_phase, local_int_10;
int local_int_14, stereo_exp, local_int_20, local_int_28;
int n, offset;
local_int_4 = 0;
local_int_28 = 0;
local_int_20 = 2;
local_int_8 = (4 - duration);
local_int_10 = 1 << (q->group_order - duration - 1);
offset = 1;
while (1) {
if (q->superblocktype_2_3) {
while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) {
offset = 1;
if (n == 0) {
local_int_4 += local_int_10;
local_int_28 += (1 << local_int_8);
} else {
local_int_4 += 8*local_int_10;
local_int_28 += (8 << local_int_8);
}
}
offset += (n - 2);
} else {
offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2);
while (offset >= (local_int_10 - 1)) {
offset += (1 - (local_int_10 - 1));
local_int_4 += local_int_10;
local_int_28 += (1 << local_int_8);
}
}
if (local_int_4 >= q->group_size)
return;
local_int_14 = (offset >> local_int_8);
if (q->nb_channels > 1) {
channel = get_bits1(gb);
stereo = get_bits1(gb);
} else {
channel = 0;
stereo = 0;
}
exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2);
exp += q->fft_level_exp[fft_level_index_table[local_int_14]];
exp = (exp < 0) ? 0 : exp;
phase = get_bits(gb, 3);
stereo_exp = 0;
stereo_phase = 0;
if (stereo) {
stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1));
stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1));
if (stereo_phase < 0)
stereo_phase += 8;
}
if (q->frequency_range > (local_int_14 + 1)) {
int sub_packet = (local_int_20 + local_int_28);
qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase);
if (stereo)
qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase);
}
offset++;
}
}
static void qdm2_decode_fft_packets (QDM2Context *q)
{
int i, j, min, max, value, type, unknown_flag;
GetBitContext gb;
if (q->sub_packet_list_B[0].packet == NULL)
return;
/* reset minimum indices for FFT coefficients */
q->fft_coefs_index = 0;
for (i=0; i < 5; i++)
q->fft_coefs_min_index[i] = -1;
/* process subpackets ordered by type, largest type first */
for (i = 0, max = 256; i < q->sub_packets_B; i++) {
QDM2SubPacket *packet;
/* find subpacket with largest type less than max */
for (j = 0, min = 0, packet = NULL; j < q->sub_packets_B; j++) {
value = q->sub_packet_list_B[j].packet->type;
if (value > min && value < max) {
min = value;
packet = q->sub_packet_list_B[j].packet;
}
}
max = min;
/* check for errors (?) */
if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16]))
return;
/* decode FFT tones */
init_get_bits (&gb, packet->data, packet->size*8);
if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16])
unknown_flag = 1;
else
unknown_flag = 0;
type = packet->type;
if ((type >= 17 && type < 24) || (type >= 33 && type < 40)) {
int duration = q->sub_sampling + 5 - (type & 15);
if (duration >= 0 && duration < 4)
qdm2_fft_decode_tones(q, duration, &gb, unknown_flag);
} else if (type == 31) {
for (j=0; j < 4; j++)
qdm2_fft_decode_tones(q, j, &gb, unknown_flag);
} else if (type == 46) {
for (j=0; j < 6; j++)
q->fft_level_exp[j] = get_bits(&gb, 6);
for (j=0; j < 4; j++)
qdm2_fft_decode_tones(q, j, &gb, unknown_flag);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -