📄 qdm2.c
字号:
return value;}static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth){ int value = qdm2_get_vlc (gb, vlc, 0, depth); return (value & 1) ? ((value + 1) >> 1) : -(value >> 1);}/** * QDM2 checksum * * @param data pointer to data to be checksum'ed * @param length data length * @param value checksum value * * @return 0 if checksum is OK */static uint16_t qdm2_packet_checksum (uint8_t *data, int length, int value) { int i; for (i=0; i < length; i++) value -= data[i]; return (uint16_t)(value & 0xffff);}/** * Fills a QDM2SubPacket structure with packet type, size, and data pointer. * * @param gb bitreader context * @param sub_packet packet under analysis */static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet){ sub_packet->type = get_bits (gb, 8); if (sub_packet->type == 0) { sub_packet->size = 0; sub_packet->data = NULL; } else { sub_packet->size = get_bits (gb, 8); if (sub_packet->type & 0x80) { sub_packet->size <<= 8; sub_packet->size |= get_bits (gb, 8); sub_packet->type &= 0x7f; } if (sub_packet->type == 0x7f) sub_packet->type |= (get_bits (gb, 8) << 8); sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data } av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n", sub_packet->type, sub_packet->size, get_bits_count(gb) / 8);}/** * Return node pointer to first packet of requested type in list. * * @param list list of subpackets to be scanned * @param type type of searched subpacket * @return node pointer for subpacket if found, else NULL */static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type){ while (list != NULL && list->packet != NULL) { if (list->packet->type == type) return list; list = list->next; } return NULL;}/** * Replaces 8 elements with their average value. * Called by qdm2_decode_superblock before starting subblock decoding. * * @param q context */static void average_quantized_coeffs (QDM2Context *q){ int i, j, n, ch, sum; n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < n; i++) { sum = 0; for (j = 0; j < 8; j++) sum += q->quantized_coeffs[ch][i][j]; sum /= 8; if (sum > 0) sum--; for (j=0; j < 8; j++) q->quantized_coeffs[ch][i][j] = sum; }}/** * Build subband samples with noise weighted by q->tone_level. * Called by synthfilt_build_sb_samples. * * @param q context * @param sb subband index */static void build_sb_samples_from_noise (QDM2Context *q, int sb){ int ch, j; FIX_NOISE_IDX(q->noise_idx); if (!q->nb_channels) return; for (ch = 0; ch < q->nb_channels; ch++) for (j = 0; j < 64; j++) { q->sb_samples[ch][j * 2][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); q->sb_samples[ch][j * 2 + 1][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); }}/** * Called while processing data from subpackets 11 and 12. * Used after making changes to coding_method array. * * @param sb subband index * @param channels number of channels * @param coding_method q->coding_method[0][0][0] */static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method){ int j,k; int ch; int run, case_val; int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4}; for (ch = 0; ch < channels; ch++) { for (j = 0; j < 64; ) { if((coding_method[ch][sb][j] - 8) > 22) { run = 1; case_val = 8; } else { switch (switchtable[coding_method[ch][sb][j]]) { case 0: run = 10; case_val = 10; break; case 1: run = 1; case_val = 16; break; case 2: run = 5; case_val = 24; break; case 3: run = 3; case_val = 30; break; case 4: run = 1; case_val = 30; break; case 5: run = 1; case_val = 8; break; default: run = 1; case_val = 8; break; } } for (k = 0; k < run; k++) if (j + k < 128) if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) if (k > 0) { SAMPLES_NEEDED //not debugged, almost never used memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t)); memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t)); } j += run; } }}/** * Related to synthesis filter * Called by process_subpacket_10 * * @param q context * @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10 */static void fill_tone_level_array (QDM2Context *q, int flag){ int i, sb, ch, sb_used; int tmp, tab; // This should never happen if (q->nb_channels <= 0) return; for (ch = 0; ch < q->nb_channels; ch++) for (sb = 0; sb < 30; sb++) for (i = 0; i < 8; i++) { if ((tab=coeff_per_sb_for_dequant[q->coeff_per_sb_select][sb]) < (last_coeff[q->coeff_per_sb_select] - 1)) tmp = q->quantized_coeffs[ch][tab + 1][i] * dequant_table[q->coeff_per_sb_select][tab + 1][sb]+ q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; else tmp = q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; if(tmp < 0) tmp += 0xff; q->tone_level_idx_base[ch][sb][i] = (tmp / 256) & 0xff; } sb_used = QDM2_SB_USED(q->sub_sampling); if ((q->superblocktype_2_3 != 0) && !flag) { for (sb = 0; sb < sb_used; sb++) for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < 64; i++) { q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; if (q->tone_level_idx[ch][sb][i] < 0) q->tone_level[ch][sb][i] = 0; else q->tone_level[ch][sb][i] = fft_tone_level_table[0][q->tone_level_idx[ch][sb][i] & 0x3f]; } } else { tab = q->superblocktype_2_3 ? 0 : 1; for (sb = 0; sb < sb_used; sb++) { if ((sb >= 4) && (sb <= 23)) { for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < 64; i++) { tmp = q->tone_level_idx_base[ch][sb][i / 8] - q->tone_level_idx_hi1[ch][sb / 8][i / 8][i % 8] - q->tone_level_idx_mid[ch][sb - 4][i / 8] - q->tone_level_idx_hi2[ch][sb - 4]; q->tone_level_idx[ch][sb][i] = tmp & 0xff; if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) q->tone_level[ch][sb][i] = 0; else q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; } } else { if (sb > 4) { for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < 64; i++) { tmp = q->tone_level_idx_base[ch][sb][i / 8] - q->tone_level_idx_hi1[ch][2][i / 8][i % 8] - q->tone_level_idx_hi2[ch][sb - 4]; q->tone_level_idx[ch][sb][i] = tmp & 0xff; if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) q->tone_level[ch][sb][i] = 0; else q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; } } else { for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < 64; i++) { tmp = q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) q->tone_level[ch][sb][i] = 0; else q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; } } } } } return;}/** * Related to synthesis filter * Called by process_subpacket_11 * c is built with data from subpacket 11 * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples * * @param tone_level_idx * @param tone_level_idx_temp * @param coding_method q->coding_method[0][0][0] * @param nb_channels number of channels * @param c coming from subpacket 11, passed as 8*c * @param superblocktype_2_3 flag based on superblock packet type * @param cm_table_select q->cm_table_select */static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp, sb_int8_array coding_method, int nb_channels, int c, int superblocktype_2_3, int cm_table_select){ int ch, sb, j; int tmp, acc, esp_40, comp; int add1, add2, add3, add4; int64_t multres; // This should never happen if (nb_channels <= 0) return; if (!superblocktype_2_3) { /* This case is untested, no samples available */ SAMPLES_NEEDED for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) { for (j = 1; j < 64; j++) { add1 = tone_level_idx[ch][sb][j] - 10; if (add1 < 0) add1 = 0; add2 = add3 = add4 = 0; if (sb > 1) { add2 = tone_level_idx[ch][sb - 2][j] + tone_level_idx_offset_table[sb][0] - 6; if (add2 < 0) add2 = 0; } if (sb > 0) { add3 = tone_level_idx[ch][sb - 1][j] + tone_level_idx_offset_table[sb][1] - 6; if (add3 < 0) add3 = 0; } if (sb < 29) { add4 = tone_level_idx[ch][sb + 1][j] + tone_level_idx_offset_table[sb][3] - 6; if (add4 < 0) add4 = 0; } tmp = tone_level_idx[ch][sb][j + 1] * 2 - add4 - add3 - add2 - add1; if (tmp < 0) tmp = 0; tone_level_idx_temp[ch][sb][j + 1] = tmp & 0xff; } tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1]; } acc = 0; for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) for (j = 0; j < 64; j++) acc += tone_level_idx_temp[ch][sb][j]; if (acc) tmp = c * 256 / (acc & 0xffff); multres = 0x66666667 * (acc * 10); esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) for (j = 0; j < 64; j++) { comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; if (comp < 0) comp += 0xff; comp /= 256; // signed shift switch(sb) { case 0: if (comp < 30) comp = 30; comp += 15; break; case 1: if (comp < 24) comp = 24; comp += 10; break; case 2: case 3: case 4: if (comp < 16) comp = 16; } if (comp <= 5) tmp = 0; else if (comp <= 10) tmp = 10; else if (comp <= 16) tmp = 16; else if (comp <= 24) tmp = -1; else tmp = 0; coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; } for (sb = 0; sb < 30; sb++) fix_coding_method_array(sb, nb_channels, coding_method); for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) for (j = 0; j < 64; j++) if (sb >= 10) { if (coding_method[ch][sb][j] < 10) coding_method[ch][sb][j] = 10; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -