/* ----------------------------------------------------------------------- */ struct Descriptor *parse_short_smoothing_buffer(struct TS_bits *bits, unsigned tag, unsigned len) { struct Descriptor_short_smoothing_buffer *ssbd ; unsigned byte ; int end_buff_len ; ssbd = (struct Descriptor_short_smoothing_buffer *)malloc( sizeof(*ssbd) ) ; memset(ssbd,0,sizeof(*ssbd)); //== Parse data == INIT_LIST_HEAD(&ssbd->next); ssbd->descriptor_tag = tag ; // already extracted by parse_desc() ssbd->descriptor_length = len ; // already extracted by parse_desc() ssbd->sb_size = bits_get(bits, 2) ; ssbd->sb_leak_rate = bits_get(bits, 6) ; end_buff_len = bits_len_calc(bits, -(ssbd->descriptor_length - 1)) ; ssbd->DVB_reserved[0] = 0 ; for (byte=0; (bits->buff_len > end_buff_len) && (byte < MAX_DVB_RESERVED_LEN); ++byte) { ssbd->DVB_reserved[byte] = bits_get(bits, 8) ; ssbd->DVB_reserved[byte+1] = 0 ; } return (struct Descriptor *)ssbd ; }
/* ----------------------------------------------------------------------- */ struct Descriptor *parse_s2_satellite_delivery_system(struct TS_bits *bits, unsigned tag, unsigned len) { struct Descriptor_s2_satellite_delivery_system *ssdsd ; unsigned byte ; int end_buff_len ; ssdsd = (struct Descriptor_s2_satellite_delivery_system *)malloc( sizeof(*ssdsd) ) ; memset(ssdsd,0,sizeof(*ssdsd)); //== Parse data == INIT_LIST_HEAD(&ssdsd->next); ssdsd->descriptor_tag = tag ; // already extracted by parse_desc() ssdsd->descriptor_length = len ; // already extracted by parse_desc() ssdsd->scrambling_sequence_selector = bits_get(bits, 1) ; ssdsd->multiple_input_stream_flag = bits_get(bits, 1) ; ssdsd->backwards_compatibility_indicator = bits_get(bits, 1) ; bits_skip(bits, 5) ; if (ssdsd->scrambling_sequence_selector == 0x1 ) { bits_skip(bits, 6) ; ssdsd->scrambling_sequence_index = bits_get(bits, 18) ; } if (ssdsd->multiple_input_stream_flag == 0x1 ) { ssdsd->input_stream_identifier = bits_get(bits, 8) ; } return (struct Descriptor *)ssdsd ; }
int read_pat_section(TSTEST* ctx, PACKET* pctx, struct mpegts_section_header* sec_header) { BITS* b = pctx->b; struct mpegts_program_association_section_header pat_header; pat_header.transport_stream_id = bits_get(b, 16); pat_header.reserved = bits_get(b, 2); pat_header.version_number = bits_get(b, 5); pat_header.current_next_indicator = bits_getbit(b); pat_header.section_number = bits_get(b, 8); pat_header.last_section_number = bits_get(b, 8); int i, table_size = sec_header->section_length - 5 - 4; pat_header.count = table_size / 4; for(i = 0; i < pat_header.count; i++) { struct mpegts_program_association_section_entry e; e.program_number = bits_get(b, 16); e.reserved = bits_get(b, 3); e.program_map_PID = bits_get(b, 13); pidmap_register(ctx, e.program_map_PID, read_section); printf("PAT: PROG:%04x => PMT:%04x\n", e.program_number, e.program_map_PID); } return 0; }
/* ----------------------------------------------------------------------- */ struct Descriptor *parse_bouquet_name(struct TS_bits *bits, unsigned tag, unsigned len) { struct Descriptor_bouquet_name *bnd ; unsigned byte ; int end_buff_len ; bnd = (struct Descriptor_bouquet_name *)malloc( sizeof(*bnd) ) ; memset(bnd,0,sizeof(*bnd)); //== Parse data == INIT_LIST_HEAD(&bnd->next); bnd->descriptor_tag = tag ; // already extracted by parse_desc() bnd->descriptor_length = len ; // already extracted by parse_desc() end_buff_len = bits_len_calc(bits, -bnd->descriptor_length) ; bnd->descriptor[0] = 0 ; for (byte=0; (bits->buff_len > end_buff_len) && (byte < MAX_DESCRIPTOR_LEN); ++byte) { bnd->descriptor[byte] = bits_get(bits, 8) ; bnd->descriptor[byte+1] = 0 ; } return (struct Descriptor *)bnd ; }
static void parse_lbr_parameters(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; // Size of LBR component in extension substream asset->lbr_size = bits_get(&exss->bits, 14) + 1; // LBR sync word present flag if (bits_get1(&exss->bits)) // LBR sync distance bits_skip(&exss->bits, 2); }
unsigned int octstr_get_bits(octstr_t *s, long pos, int n) { int len; len = (pos + n) / 8 + ((pos + n) % 8 > 0 ? 1 : 0); if( s->len >= len ) { return bits_get(s->s, pos, n); } return 0; }
int main(int argc, char *argv[]) { long id; char name[NAME_LEN]; char rasdial[RAS_LEN]; memset(name,'\0',NAME_LEN); memset(rasdial,'\0',RAS_LEN); Bits bits; int ret = bits_init(&bits,LEN); if(-1 == ret){ fprintf(stderr,"bits_init error %s %d\n",__FILE__,__LINE__); } FILE *save; save = fopen("random_save.txt","a+"); if(NULL == save){ fprintf(stderr,"open random_save.text failed\n"); exit(1); } long times=0; long count=0; srand((int)time(0)); do{ id = rand(); id = ((id<<4) + rand()) % LEN; if(!bits_get(&bits,id)) { bits_set(&bits,id); } else { printf("Repeat times %ld\n",++count); continue; } if (LEN-1 == times){ printf("Have try all size=%ld\n",times); goto EXIT; } sprintf(name,"TYT010%03ld",id); sprintf(rasdial,"rasdial pppoe %s 8888\n",name); printf("times=%ld %s",++times,rasdial); ret = system(rasdial); }while(0 != ret); EXIT: bits_destroy(&bits); fprintf(save,"times=%ld %s",times,rasdial); printf("Final Rpeat times %ld\n",count); return 0; }
int read_section(TSTEST* ctx, PACKET* pctx) { struct mpegts_section_header sec_header; BITS* b = pctx->b; uint8_t* body; uint8_t* body_end; body = bits_getptr(b); sec_header.table_id = bits_get(b, 8); sec_header.section_syntax_indicator = bits_getbit(b); sec_header.zero = bits_getbit(b); sec_header.b2_reserved = bits_get(b, 2); sec_header.section_length = bits_get(b, 12); print_section_header(&sec_header); switch(sec_header.table_id) { case TABLE_ID_PAT: // PAT read_pat_section(ctx, pctx, &sec_header); break; case TABLE_ID_PMT: // PMT read_pmt_section(ctx, pctx, &sec_header); break; } body_end = bits_getptr(b); uint32_t crc_read, crc; crc = crc32(body, body_end - body); crc_read = bits_get(b, 32); printf("CRC: %s (%08x/%08x)\n", (crc == crc_read) ? "[OK]" : "[NG]", crc_read, crc); return 0; }
static void parse_xll_parameters(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; // Size of XLL data in extension substream asset->xll_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; // XLL sync word present flag asset->xll_sync_present = bits_get1(&exss->bits); if (asset->xll_sync_present) { // Peak bit rate smoothing buffer size bits_skip(&exss->bits, 4); // Number of bits for XLL decoding delay int xll_delay_nbits = bits_get(&exss->bits, 5) + 1; // Initial XLL decoding delay in frames asset->xll_delay_nframes = bits_get(&exss->bits, xll_delay_nbits); // Number of bytes offset to XLL sync asset->xll_sync_offset = bits_get(&exss->bits, exss->exss_size_nbits); } else { asset->xll_delay_nframes = 0; asset->xll_sync_offset = 0; } }
/* ----------------------------------------------------------------------- */ struct Descriptor *parse_short_event(struct TS_bits *bits, unsigned tag, unsigned len) { struct Descriptor_short_event *sed ; unsigned byte ; int end_buff_len ; sed = (struct Descriptor_short_event *)malloc( sizeof(*sed) ) ; memset(sed,0,sizeof(*sed)); //== Parse data == INIT_LIST_HEAD(&sed->next); sed->descriptor_tag = tag ; // already extracted by parse_desc() sed->descriptor_length = len ; // already extracted by parse_desc() sed->ISO_639_language_code = bits_get(bits, 24) ; sed->event_name_length = bits_get(bits, 8) ; end_buff_len = bits_len_calc(bits, -sed->event_name_length) ; sed->event_name[0] = 0 ; for (byte=0; (bits->buff_len > end_buff_len) && (byte < MAX_EVENT_NAME_LEN); ++byte) { sed->event_name[byte] = bits_get(bits, 8) ; sed->event_name[byte+1] = 0 ; } sed->text_length = bits_get(bits, 8) ; end_buff_len = bits_len_calc(bits, -sed->text_length) ; sed->text[0] = 0 ; for (byte=0; (bits->buff_len > end_buff_len) && (byte < MAX_TEXT_LEN); ++byte) { sed->text[byte] = bits_get(bits, 8) ; sed->text[byte+1] = 0 ; } return (struct Descriptor *)sed ; }
/* ----------------------------------------------------------------------- */ void parse_dit(struct TS_reader *tsreader, struct TS_state *tsstate, struct TS_bits *bits, Section_handler handler, struct Section_decode_flags *flags) { struct Section_discontinuity_information dit ; struct list_head *item, *safe; unsigned byte ; int end_buff_len ; //== Parse data == dit.table_id = bits_get(bits, 8) ; dit.section_syntax_indicator = bits_get(bits, 1) ; bits_skip(bits, 1) ; bits_skip(bits, 2) ; dit.section_length = bits_get(bits, 12) ; dit.transition_flag = bits_get(bits, 1) ; bits_skip(bits, 7) ; //== Call handler == if (handler) handler(tsreader, tsstate, (struct Section *)&dit, tsreader->user_data) ; //== Tidy up == }
DCADEC_API int dcadec_frame_parse_header(const uint8_t *data, size_t *size) { struct bitstream bits; uint8_t header[DCADEC_FRAME_HEADER_SIZE]; size_t header_size, frame_size; int ret; if (!data || !size) return -DCADEC_EINVAL; if ((ret = dcadec_frame_convert_bitstream(header, &header_size, data, DCADEC_FRAME_HEADER_SIZE)) < 0) return ret; bits_init(&bits, header, header_size); switch (bits_get(&bits, 32)) { case SYNC_WORD_CORE: { bool normal_frame = bits_get1(&bits); int deficit_samples = bits_get(&bits, 5) + 1; int npcmblocks; if (normal_frame && deficit_samples != 32) return -DCADEC_ENOSYNC; bits_skip1(&bits); npcmblocks = bits_get(&bits, 7) + 1; if ((npcmblocks & 7) && (npcmblocks < 6 || normal_frame)) return -DCADEC_ENOSYNC; frame_size = bits_get(&bits, 14) + 1; if (frame_size < 96) return -DCADEC_ENOSYNC; if (ret & DCADEC_BITSTREAM_BE14) *size = frame_size * 8 / 14 * 2; else *size = frame_size; return DCADEC_FRAME_TYPE_CORE; } case SYNC_WORD_EXSS: { bool wide_hdr; bits_skip(&bits, 10); wide_hdr = bits_get1(&bits); header_size = bits_get(&bits, 8 + 4 * wide_hdr) + 1; if ((header_size & 3) || header_size < DCADEC_FRAME_HEADER_SIZE) return -DCADEC_ENOSYNC; frame_size = bits_get(&bits, 16 + 4 * wide_hdr) + 1; if ((frame_size & 3) || frame_size < header_size) return -DCADEC_ENOSYNC; *size = frame_size; return DCADEC_FRAME_TYPE_EXSS; } default: return -DCADEC_ENOSYNC; } }
char M128_DIO_fgt(char LSByte, char Mask, char shift, char *Data) { if(LSByte<100||LSByte>106) return 1; else if(shift>7) return 2; volatile uint8_t *PORT; volatile uint8_t *DDR; volatile uint8_t *PIN; switch(LSByte) { case 100: PORT = &PORTA; DDR = &DDRA; PIN = &PINA; break; case 101: PORT = &PORTB; DDR = &DDRB; PIN = &PINB; break; case 102: PORT = &PORTC; DDR = &DDRC; PIN = &PINC; break; case 103: PORT = &PORTD; DDR = &DDRD; PIN = &PIND; break; case 104: PORT = &PORTE; DDR = &DDRE; PIN = &PINE; break; case 105: PORT = &PORTF; DDR = &DDRF; PIN = &PINF; break; case 106: PORT = &PORTG; DDR = &DDRG; PIN = &PING; break; default: return 1; } *Data = bits_get(*PIN,Mask,shift); // *Data=(*PIN&(Mask))>>shift; return 0; }
int parse_adaptation_field(BITS* b, struct mpegts_header* header, struct mpegts_adaptation_field* af) { memset(af, 0, sizeof *af); if(!HAS_AF(header)) { return 0; } af->adaptation_field_length = bits_get(b, 8); if(af->adaptation_field_length == 0) { return 0; } af->discontinuity_indicator = bits_getbit(b); af->random_access_indicator = bits_getbit(b); af->elementary_stream_priority_indicator = bits_getbit(b); af->PCR_flag = bits_getbit(b); af->OPCR_flag = bits_getbit(b); af->splicing_point_flag = bits_getbit(b); af->transport_private_data_flag = bits_getbit(b); af->adaptation_field_extension_flag = bits_getbit(b); if(af->PCR_flag) { af->program_clock_reference_extension = bits_get(b, 9); af->pcr_reserved = bits_get(b, 6); af->program_clock_reference_base = bits_get(b, 33); } if(af->OPCR_flag) { af->original_program_clock_reference_extension = bits_get(b, 9); af->opcr_reserved = bits_get(b, 6); af->original_program_clock_reference_base = bits_get(b, 33); } if(af->splicing_point_flag) { af->splice_countdown = bits_get(b, 8); } if(af->transport_private_data_flag) { int i; af->transport_private_data_length = bits_get(b, 8); for(i = 0; i < af->transport_private_data_length; i++) { af->private_data_byte[i] = bits_get(b, 8); } } if(af->adaptation_field_extension_flag) { af->adaptation_field_extension_length = bits_get(b, 8); af->ltw_flag = bits_getbit(b); af->piecewise_rate_flag = bits_getbit(b); af->seamless_splice_flag = bits_getbit(b); af->afe_reserved = bits_get(b, 5); if(af->ltw_flag) { af->ltw_valid_flag = bits_getbit(b); af->ltw_offset = bits_get(b, 15); } if(af->piecewise_rate_flag) { af->pr_reserved = bits_get(b, 2); af->piecewise_rate = bits_get(b, 22); } if(af->seamless_splice_flag) { af->splice_type = bits_get(b, 4); af->DTS_next_AU_h = bits_get(b, 3); af->marker_bit_h = bits_getbit(b); af->DTS_next_AU_m = bits_get(b, 15); af->marker_bit_m = bits_getbit(b); af->DTS_next_AU_l = bits_get(b, 15); af->marker_bit_l = bits_getbit(b); } } return 0; }
int read_pmt_section(TSTEST* ctx, PACKET* pctx, struct mpegts_section_header* sec_header) { BITS* b = pctx->b; struct mpegts_program_map_section_header pmt_header; int i, j; pmt_header.program_number = bits_get(b, 16); pmt_header.reserved1 = bits_get(b, 2); pmt_header.version_number = bits_get(b, 5); pmt_header.current_next_indicator = bits_getbit(b); pmt_header.section_number = bits_get(b, 8); pmt_header.last_section_number = bits_get(b, 8); pmt_header.reserved2 = bits_get(b, 3); pmt_header.PCR_PID = bits_get(b, 13); pmt_header.reserved3 = bits_get(b, 4); pmt_header.program_info_length = bits_get(b, 12); for(i = 0; i < pmt_header.program_info_length; i++) { // 捨てる bits_get(b, 8); } int table_size = sec_header->section_length - 9 - pmt_header.program_info_length - 4; for(i = 0; i < table_size; ) { struct mpegts_program_map_section_entry e; e.stream_type = bits_get(b, 8); e.reserved1 = bits_get(b, 3); e.elementary_PID = bits_get(b, 13); e.reserved2 = bits_get(b, 4); e.ES_info_length = bits_get(b, 12); for(j = 0; j < e.ES_info_length; j++) { bits_get(b, 8); } printf("PMT: STR:%02x => PID:%04x\n", e.stream_type, e.elementary_PID); i += 5 + e.ES_info_length; } return 0; }
static int parse_descriptor(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; int i, j, ret, descr_pos = exss->bits.index; // Size of audio asset descriptor in bytes int descr_size = bits_get(&exss->bits, 9) + 1; // Audio asset identifier asset->asset_index = bits_get(&exss->bits, 3); // // Per stream static metadata // if (exss->static_fields_present) { // Asset type descriptor presence if (bits_get1(&exss->bits)) // Asset type descriptor bits_skip(&exss->bits, 4); // Language descriptor presence if (bits_get1(&exss->bits)) // Language descriptor bits_skip(&exss->bits, 24); // Additional textual information presence if (bits_get1(&exss->bits)) { // Byte size of additional text info int text_size = bits_get(&exss->bits, 10) + 1; // Additional textual information string bits_skip(&exss->bits, text_size * 8); } // PCM bit resolution asset->pcm_bit_res = bits_get(&exss->bits, 5) + 1; // Maximum sample rate asset->max_sample_rate = exss_sample_rates[bits_get(&exss->bits, 4)]; // Total number of channels asset->nchannels_total = bits_get(&exss->bits, 8) + 1; // One to one map channel to speakers asset->one_to_one_map_ch_to_spkr = bits_get1(&exss->bits); if (asset->one_to_one_map_ch_to_spkr) { // Embedded stereo flag if (asset->nchannels_total > 2) asset->embedded_stereo = bits_get1(&exss->bits); // Embedded 6 channels flag if (asset->nchannels_total > 6) asset->embedded_6ch = bits_get1(&exss->bits); // Speaker mask enabled flag asset->spkr_mask_enabled = bits_get1(&exss->bits); int spkr_mask_nbits = 0; if (asset->spkr_mask_enabled) { // Number of bits for speaker activity mask spkr_mask_nbits = (bits_get(&exss->bits, 2) + 1) << 2; // Loudspeaker activity mask asset->spkr_mask = bits_get(&exss->bits, spkr_mask_nbits); } // Number of speaker remapping sets int spkr_remap_nsets = bits_get(&exss->bits, 3); if (spkr_remap_nsets && !spkr_mask_nbits) { exss_err("Speaker mask disabled yet there are remapping sets"); return -DCADEC_EBADDATA; } // Standard loudspeaker layout mask int nspeakers[8]; for (i = 0; i < spkr_remap_nsets; i++) nspeakers[i] = count_chs_for_mask(bits_get(&exss->bits, spkr_mask_nbits)); for (i = 0; i < spkr_remap_nsets; i++) { // Number of channels to be decoded for speaker remapping int nch_for_remaps = bits_get(&exss->bits, 5) + 1; for (j = 0; j < nspeakers[i]; j++) { // Decoded channels to output speaker mapping mask int remap_ch_mask = bits_get(&exss->bits, nch_for_remaps); // Loudspeaker remapping codes int ncodes = dca_popcount(remap_ch_mask); bits_skip(&exss->bits, ncodes * 5); } } } else { asset->embedded_stereo = false; asset->embedded_6ch = false; asset->spkr_mask_enabled = false; asset->spkr_mask = 0; // Representation type asset->representation_type = bits_get(&exss->bits, 3); } } // // DRC, DNC and mixing metadata // // Dynamic range coefficient presence flag bool drc_present = bits_get1(&exss->bits); // Code for dynamic range coefficient if (drc_present) bits_skip(&exss->bits, 8); // Dialog normalization presence flag if (bits_get1(&exss->bits)) // Dialog normalization code bits_skip(&exss->bits, 5); // DRC for stereo downmix if (drc_present && asset->embedded_stereo) bits_skip(&exss->bits, 8); // Mixing metadata presence flag if (exss->mix_metadata_enabled && bits_get1(&exss->bits)) { // External mixing flag bits_skip1(&exss->bits); // Post mixing / replacement gain adjustment bits_skip(&exss->bits, 6); // DRC prior to mixing if (bits_get(&exss->bits, 2) == 3) // Custom code for mixing DRC bits_skip(&exss->bits, 8); else // Limit for mixing DRC bits_skip(&exss->bits, 3); // Scaling type for channels of main audio // Scaling parameters of main audio if (bits_get1(&exss->bits)) for (i = 0; i < exss->nmixoutconfigs; i++) bits_skip(&exss->bits, 6 * exss->nmixoutchs[i]); else bits_skip(&exss->bits, 6 * exss->nmixoutconfigs); int nchannels_dmix = asset->nchannels_total; if (asset->embedded_6ch) nchannels_dmix += 6; if (asset->embedded_stereo) nchannels_dmix += 2; for (i = 0; i < exss->nmixoutconfigs; i++) { for (j = 0; j < nchannels_dmix; j++) { if (!exss->nmixoutchs[i]) { exss_err("Invalid speaker layout mask for mixing configuration"); return -DCADEC_EBADDATA; } // Mix output mask int mix_map_mask = bits_get(&exss->bits, exss->nmixoutchs[i]); // Mixing coefficients int nmixcoefs = dca_popcount(mix_map_mask); bits_skip(&exss->bits, 6 * nmixcoefs); } } } // // Decoder navigation data // // Coding mode for the asset asset->coding_mode = bits_get(&exss->bits, 2); // Coding components used in asset switch (asset->coding_mode) { case 0: // Coding mode that may contain multiple coding components asset->extension_mask = bits_get(&exss->bits, 12); if (asset->extension_mask & EXSS_CORE) { // Size of core component in extension substream asset->core_size = bits_get(&exss->bits, 14) + 1; // Core sync word present flag if (bits_get1(&exss->bits)) // Core sync distance bits_skip(&exss->bits, 2); } if (asset->extension_mask & EXSS_XBR) // Size of XBR extension in extension substream asset->xbr_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_XXCH) // Size of XXCH extension in extension substream asset->xxch_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_X96) // Size of X96 extension in extension substream asset->x96_size = bits_get(&exss->bits, 12) + 1; if (asset->extension_mask & EXSS_LBR) parse_lbr_parameters(asset); if (asset->extension_mask & EXSS_XLL) parse_xll_parameters(asset); if (asset->extension_mask & EXSS_RSV1) bits_skip(&exss->bits, 16); if (asset->extension_mask & EXSS_RSV2) bits_skip(&exss->bits, 16); break; case 1: // Loss-less coding mode without CBR component asset->extension_mask = EXSS_XLL; parse_xll_parameters(asset); break; case 2: // Low bit rate mode asset->extension_mask = EXSS_LBR; parse_lbr_parameters(asset); break; case 3: // Auxiliary coding mode asset->extension_mask = 0; // Size of auxiliary coded data bits_skip(&exss->bits, 14); // Auxiliary codec identification bits_skip(&exss->bits, 8); // Aux sync word present flag if (bits_get1(&exss->bits)) // Aux sync distance bits_skip(&exss->bits, 3); break; } if (asset->extension_mask & EXSS_XLL) // DTS-HD stream ID asset->hd_stream_id = bits_get(&exss->bits, 3); // One to one mixing flag // Per channel main audio scaling flag // Main audio scaling codes // Decode asset in secondary decoder flag // Revision 2 DRC metadata // Reserved // Zero pad if ((ret = bits_seek(&exss->bits, descr_pos + descr_size * 8)) < 0) exss_err("Read past end of asset descriptor"); return ret; }
int exss_parse(struct exss_parser *exss, uint8_t *data, int size) { int i, j, ret; bits_init(&exss->bits, data, size); // Extension substream sync word bits_skip(&exss->bits, 32); // User defined bits bits_skip(&exss->bits, 8); // Extension substream index exss->exss_index = bits_get(&exss->bits, 2); // Flag indicating short or long header size bool wide_hdr = bits_get1(&exss->bits); // Extension substream header length int header_size = bits_get(&exss->bits, 8 + 4 * wide_hdr) + 1; // Check CRC if ((ret = bits_check_crc(&exss->bits, 32 + 8, header_size * 8)) < 0) { exss_err("Invalid EXSS header checksum"); return ret; } exss->exss_size_nbits = 16 + 4 * wide_hdr; // Number of bytes of extension substream exss->exss_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; if (exss->exss_size > size) { exss_err("Packet too short for EXSS frame"); return -DCADEC_EBADDATA; } // Per stream static fields presence flag exss->static_fields_present = bits_get1(&exss->bits); if (exss->static_fields_present) { // Reference clock code bits_skip(&exss->bits, 2); // Extension substream frame duration bits_skip(&exss->bits, 3); // Timecode presence flag if (bits_get1(&exss->bits)) { // Timecode data bits_skip(&exss->bits, 32); bits_skip(&exss->bits, 4); } // Number of defined audio presentations exss->npresents = bits_get(&exss->bits, 3) + 1; // Number of audio assets in extension substream exss->nassets = bits_get(&exss->bits, 3) + 1; // Reject unsupported features for now if (exss->npresents > 1 || exss->nassets > 1) { exss_err_once("Multiple audio presentations " "and/or assets are not supported"); return -DCADEC_ENOSUP; } // Active extension substream mask for audio presentation int active_exss_mask[8]; for (i = 0; i < exss->npresents; i++) active_exss_mask[i] = bits_get(&exss->bits, exss->exss_index + 1); // Active audio asset mask for (i = 0; i < exss->npresents; i++) for (j = 0; j <= exss->exss_index; j++) if (active_exss_mask[i] & (1 << j)) bits_skip(&exss->bits, 8); // Mixing metadata enable flag exss->mix_metadata_enabled = bits_get1(&exss->bits); if (exss->mix_metadata_enabled) { // Mixing metadata adjustment level bits_skip(&exss->bits, 2); // Number of bits for mixer output speaker activity mask int spkr_mask_nbits = (bits_get(&exss->bits, 2) + 1) << 2; // Number of mixing configurations exss->nmixoutconfigs = bits_get(&exss->bits, 2) + 1; // Speaker layout mask for mixer output channels for (i = 0; i < exss->nmixoutconfigs; i++) exss->nmixoutchs[i] = count_chs_for_mask(bits_get(&exss->bits, spkr_mask_nbits)); } } else { exss->npresents = 1; exss->nassets = 1; } // Reallocate assets if (ta_zalloc_fast(exss, &exss->assets, exss->nassets, sizeof(struct exss_asset)) < 0) return -DCADEC_ENOMEM; // Size of encoded asset data in bytes int offset = header_size; for (i = 0; i < exss->nassets; i++) { exss->assets[i].asset_offset = offset; exss->assets[i].asset_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; offset += exss->assets[i].asset_size; if (offset > exss->exss_size) { exss_err("Asset out of bounds"); return -DCADEC_EBADDATA; } } // Audio asset descriptor for (i = 0; i < exss->nassets; i++) { exss->assets[i].parser = exss; if ((ret = parse_descriptor(&exss->assets[i])) < 0) return ret; if ((ret = set_exss_offsets(&exss->assets[i])) < 0) { exss_err("Invalid extension size in asset descriptor"); return ret; } } // Backward compatible core present // Backward compatible core substream index // Backward compatible core asset index // Reserved // Byte align // CRC16 of extension substream header if ((ret = bits_seek(&exss->bits, header_size * 8)) < 0) exss_err("Read past end of EXSS header"); return ret; }
static int parse_dmix_coeffs(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int m, n; if (chs->primary_chset) { m = dmix_primary_nch[chs->dmix_type]; n = chs->nchannels; } else { m = chs->dmix_m; n = chs->nchannels + 2; // Two extra columns for scales } // Reallocate downmix coefficients matrix if (ta_zalloc_fast(xll->chset, &chs->dmix_coeff, m * n, sizeof(int)) < 0) return -DCADEC_ENOMEM; if (chs->primary_chset) { chs->dmix_scale = NULL; chs->dmix_scale_inv = NULL; } else { chs->dmix_scale = chs->dmix_coeff + m * chs->nchannels; chs->dmix_scale_inv = chs->dmix_coeff + m * (chs->nchannels + 1); } int *coeff_ptr = chs->dmix_coeff; for (int i = 0; i < m; i++) { int scale_inv = 0; // Downmix scale // Only for non-primary channel sets if (!chs->primary_chset) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; enforce(index >= 40 && index < dca_countof(dmix_table), "Invalid downmix scale index"); int scale = dmix_table[index]; scale_inv = dmix_table_inv[index - 40]; chs->dmix_scale[i] = (scale ^ sign) - sign; chs->dmix_scale_inv[i] = (scale_inv ^ sign) - sign; } else { chs->dmix_scale[i] = 0; chs->dmix_scale_inv[i] = 0; } } // Downmix coefficients for (int j = 0; j < chs->nchannels; j++) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; enforce(index < dca_countof(dmix_table), "Invalid downmix coefficient index"); int coeff = dmix_table[index]; if (!chs->primary_chset) // Multiply by |InvDmixScale| to get |UndoDmixScale| coeff = mul16(scale_inv, coeff); // Convert sign *coeff_ptr++ = (coeff ^ sign) - sign; } else { *coeff_ptr++ = 0; } } }
static int parse_dmix_coeffs(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int m, n; if (chs->primary_chset) { m = dmix_primary_nch[chs->dmix_type]; n = chs->nchannels; } else { m = chs->dmix_m; n = chs->nchannels + 2; // Two extra columns for scales } // Reallocate downmix coefficients buffer if (ta_zalloc_fast(xll->chset, &chs->dmix_coeff, m * n * 2, sizeof(int)) < 0) return -DCADEC_ENOMEM; // Setup buffer pointers for current and previous frame bool valid = (chs->dmix_coeffs_signature == XLL_DMIX_SIGNATURE(chs)); chs->dmix_coeff_cur = chs->dmix_coeff + m * n * chs->dmix_coeffs_parity; chs->dmix_coeff_pre = chs->dmix_coeff + m * n * (chs->dmix_coeffs_parity ^ valid); if (chs->primary_chset) { chs->dmix_scale_cur = chs->dmix_scale_pre = NULL; chs->dmix_scale_inv_cur = chs->dmix_scale_inv_pre = NULL; } else { chs->dmix_scale_cur = chs->dmix_coeff_cur + m * chs->nchannels; chs->dmix_scale_pre = chs->dmix_coeff_pre + m * chs->nchannels; chs->dmix_scale_inv_cur = chs->dmix_coeff_cur + m * (chs->nchannels + 1); chs->dmix_scale_inv_pre = chs->dmix_coeff_pre + m * (chs->nchannels + 1); } int *coeff_ptr = chs->dmix_coeff_cur; for (int i = 0; i < m; i++) { int scale_inv = 0; // Downmix scale // Only for non-primary channel sets if (!chs->primary_chset) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; if (index < 40 || index >= dca_countof(dmix_table)) { xll_err("Invalid downmix scale index"); return -DCADEC_EBADDATA; } int scale = dmix_table[index]; scale_inv = dmix_table_inv[index - 40]; chs->dmix_scale_cur[i] = (scale ^ sign) - sign; chs->dmix_scale_inv_cur[i] = (scale_inv ^ sign) - sign; } else { chs->dmix_scale_cur[i] = 0; chs->dmix_scale_inv_cur[i] = 0; } } // Downmix coefficients for (int j = 0; j < chs->nchannels; j++) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; if (index >= dca_countof(dmix_table)) { xll_err("Invalid downmix coefficient index"); return -DCADEC_EBADDATA; } int coeff = dmix_table[index]; if (!chs->primary_chset) // Multiply by |InvDmixScale| to get |UndoDmixScale| coeff = mul16(scale_inv, coeff); // Convert sign *coeff_ptr++ = (coeff ^ sign) - sign; } else { *coeff_ptr++ = 0; } } }