/***************************************************************************** * dvbpsi_DecodeNetworkNameDr *****************************************************************************/ dvbpsi_network_name_dr_t* dvbpsi_DecodeNetworkNameDr( dvbpsi_descriptor_t * p_descriptor) { dvbpsi_network_name_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x40)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Allocate memory */ p_decoded = (dvbpsi_network_name_dr_t*)calloc(1, sizeof(dvbpsi_network_name_dr_t)); if (!p_decoded) return NULL; /* Decode data */ p_decoded->i_name_length = p_descriptor->i_length; if (p_decoded->i_name_length > 255) p_decoded->i_name_length = 255; if (p_decoded->i_name_length) memcpy(p_decoded->i_name_byte, p_descriptor->p_data, p_decoded->i_name_length); p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_decode_mpeg_private_data_dr *****************************************************************************/ dvbpsi_mpeg_private_data_dr_t * dvbpsi_decode_mpeg_private_data_dr( dvbpsi_descriptor_t * p_descriptor) { dvbpsi_mpeg_private_data_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x0f)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if (p_descriptor->i_length != 4) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_mpeg_private_data_dr_t*)malloc(sizeof(dvbpsi_mpeg_private_data_dr_t)); if (!p_decoded) return NULL; p_decoded->i_private_data = ((uint32_t)(p_descriptor->p_data[0]) << 24) | ((uint32_t)(p_descriptor->p_data[1]) << 16) | ((uint32_t)(p_descriptor->p_data[2]) << 8) | p_descriptor->p_data[3]; p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
dvbpsi_mpeg_sl_dr_t* dvbpsi_decode_mpeg_sl_dr( dvbpsi_descriptor_t * p_descriptor) { dvbpsi_mpeg_sl_dr_t * p_decoded; /* check the tag. */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x1e)) return NULL; /* don't decode twice. */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* all descriptors of this type have two bytes of payload. */ if (p_descriptor->i_length != 2) return NULL; p_decoded = malloc(sizeof(*p_decoded)); if (!p_decoded) return NULL; p_decoded->i_es_id = ((p_descriptor->p_data[0] & 0xff) << 8) | p_descriptor->p_data[1]; p_descriptor->p_decoded = p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_DecodeCUEIDr *****************************************************************************/ dvbpsi_cuei_dr_t * dvbpsi_DecodeCUEIDr(dvbpsi_descriptor_t * p_descriptor) { /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x8a)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if (p_descriptor->i_length == 0x01) return NULL; /* Allocate memory */ dvbpsi_cuei_dr_t *p_decoded; p_decoded = (dvbpsi_cuei_dr_t*)malloc(sizeof(dvbpsi_cuei_dr_t)); if (!p_decoded) return NULL; /* cue_stream_type according to: SCTE 35 2004 - p15 - table 6.3 * cue_stream_type PID usage * 0x00 splice_insert, splice_null, splice_schedule * 0x01 All Commands * 0x02 Segmentation * 0x03 Tiered Splicing * 0x04 Tiered Segmentation * 0x05 - 0x7f Reserved * 0x80 - 0xff User Defined */ p_decoded->i_cue_stream_type = p_descriptor->p_data[0]; p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_decode_dvb_subtitling_dr *****************************************************************************/ dvbpsi_dvb_subtitling_dr_t * dvbpsi_decode_dvb_subtitling_dr( dvbpsi_descriptor_t * p_descriptor) { int i_subtitles_number; dvbpsi_dvb_subtitling_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x59)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Decode data and check the length */ if (p_descriptor->i_length < 3) return NULL; if (p_descriptor->i_length % 8) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_dvb_subtitling_dr_t*)malloc(sizeof(dvbpsi_dvb_subtitling_dr_t)); if (!p_decoded) return NULL; i_subtitles_number = p_descriptor->i_length / 8; if (i_subtitles_number > DVBPSI_SUBTITLING_DR_MAX) i_subtitles_number = DVBPSI_SUBTITLING_DR_MAX; p_decoded->i_subtitles_number = i_subtitles_number; for (int i = 0; i < i_subtitles_number; i++) { memcpy(p_decoded->p_subtitle[i].i_iso6392_language_code, p_descriptor->p_data + 8 * i, 3); p_decoded->p_subtitle[i].i_subtitling_type = p_descriptor->p_data[8 * i + 3]; p_decoded->p_subtitle[i].i_composition_page_id = ((uint16_t)(p_descriptor->p_data[8 * i + 4]) << 8) | p_descriptor->p_data[8 * i + 5]; p_decoded->p_subtitle[i].i_ancillary_page_id = ((uint16_t)(p_descriptor->p_data[8 * i + 6]) << 8) | p_descriptor->p_data[8 * i + 7]; } p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_DecodeAc3AudioDr *****************************************************************************/ dvbpsi_ac3_audio_dr_t *dvbpsi_DecodeAc3AudioDr(dvbpsi_descriptor_t *p_descriptor) { dvbpsi_ac3_audio_dr_t *p_decoded; uint8_t * buf = p_descriptor->p_data; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x81)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Check length */ if (p_descriptor->i_length < 3) return NULL; p_decoded = (dvbpsi_ac3_audio_dr_t*)calloc(1, sizeof(dvbpsi_ac3_audio_dr_t)); if (!p_decoded) return NULL; p_descriptor->p_decoded = (void*)p_decoded; p_decoded->i_sample_rate_code = 0x07 & (buf[0] >> 5); p_decoded->i_bsid = 0x1f & buf[0]; p_decoded->i_bit_rate_code = 0x3f & (buf[1] >> 2); p_decoded->i_surround_mode = 0x03 & buf[1]; p_decoded->i_bsmod = 0x07 & (buf[2] >> 5); p_decoded->i_num_channels = 0x0f & (buf[2] >> 1); p_decoded->b_full_svc = 0x01 & buf[2]; buf += 3; if (buf == p_descriptor->p_data + p_descriptor->i_length) return p_decoded; p_decoded->i_lang_code = buf[0]; buf++; if (buf == p_descriptor->p_data + p_descriptor->i_length) return p_decoded; if (!p_decoded->i_num_channels) { p_decoded->i_lang_code2 = buf[0]; buf++; } if (buf == p_descriptor->p_data + p_descriptor->i_length) return p_decoded; if (p_decoded->i_bsmod < 2) { p_decoded->i_mainid = 0x07 & (buf[0] >> 5); p_decoded->i_priority = 0x03 & (buf[0] >> 3); } else
/***************************************************************************** * dvbpsi_DecodeVBIDataDr *****************************************************************************/ dvbpsi_vbi_dr_t * dvbpsi_DecodeVBIDataDr( dvbpsi_descriptor_t * p_descriptor) { /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x45)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Check the length */ if (p_descriptor->i_length < 3) return NULL; if (p_descriptor->i_length % 2) return NULL; /* */ dvbpsi_vbi_dr_t * p_decoded; uint8_t i_services_number = p_descriptor->i_length / 2; if (i_services_number > DVBPSI_VBI_DR_MAX) i_services_number = DVBPSI_VBI_DR_MAX; /* Allocate memory */ p_decoded = (dvbpsi_vbi_dr_t*)malloc(sizeof(dvbpsi_vbi_dr_t)); if (!p_decoded) return NULL; p_decoded->i_services_number = i_services_number; for (uint8_t i = 0; i < i_services_number; i++) { uint8_t i_lines = 0, i_data_service_id; i_data_service_id = ((uint8_t)(p_descriptor->p_data[3 * i + 2 + i_lines])); p_decoded->p_services[i].i_data_service_id = i_data_service_id; i_lines = ((uint8_t)(p_descriptor->p_data[3 * i + 3])); p_decoded->p_services[i].i_lines = i_lines; for (uint8_t n = 0; n < i_lines; n++) { if( (i_data_service_id >= 0x01) && (i_data_service_id <= 0x07) ) { p_decoded->p_services[i].p_lines[n].i_parity = ((uint8_t)((p_descriptor->p_data[3 * i + 3 + n])&0x20)>>5); p_decoded->p_services[i].p_lines[n].i_line_offset = ((uint8_t)(p_descriptor->p_data[3 * i + 3 + n])&0x1f); } } }
/***************************************************************************** * dvbpsi_DecodeAACDr *****************************************************************************/ dvbpsi_aac_dr_t *dvbpsi_DecodeAACDr(dvbpsi_descriptor_t *p_descriptor) { /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x7c)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if (p_descriptor->i_length == 0x01) return NULL; /* Allocate memory */ dvbpsi_aac_dr_t *p_decoded; p_decoded = (dvbpsi_aac_dr_t*)calloc(1, sizeof(dvbpsi_aac_dr_t)); if (!p_decoded) return NULL; /* AAC Audio descriptor * ETSI EN 300 468 V1.13.1 (2012-04) Annex H */ p_decoded->i_profile_and_level = dvbpsi_aac_profile_and_level_lookup(p_descriptor->p_data[0]); if (p_descriptor->i_length > 1) p_decoded->b_type = ((p_descriptor->p_data[1]>>7) == 0x01); if (p_decoded->b_type) p_decoded->i_type = dvbpsi_aac_type_lookup(p_descriptor->p_data[2]); /* Keep additional info bytes field */ if (p_descriptor->i_length > 1) { uint8_t i_info_length = p_descriptor->i_length - (p_decoded->b_type ? 3 : 2); dvbpsi_aac_dr_t *p_tmp = realloc(p_decoded, sizeof(dvbpsi_aac_dr_t) + i_info_length); if (!p_tmp) { free(p_decoded); return NULL; } p_decoded->p_additional_info = ((uint8_t*)p_tmp + sizeof(dvbpsi_aac_dr_t)); p_decoded->i_additional_info_length = i_info_length; uint8_t i_data = p_decoded->b_type ? 3 : 2; uint8_t *p = &p_descriptor->p_data[i_data]; memcpy(&p_decoded->p_additional_info, p, i_info_length); } p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_DecodeServiceLocationDr *****************************************************************************/ dvbpsi_service_location_dr_t * dvbpsi_DecodeServiceLocationDr (dvbpsi_descriptor_t * p_descriptor) { dvbpsi_service_location_dr_t *p_decoded; uint8_t *buf = p_descriptor->p_data; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0xa1)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Check length */ if ((p_descriptor->i_length - 3) % 6) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_service_location_dr_t *) malloc (sizeof (dvbpsi_service_location_dr_t)); if (!p_decoded) return NULL; memset (p_decoded, 0, sizeof (dvbpsi_service_location_dr_t)); p_descriptor->p_decoded = (void *) p_decoded; p_decoded->i_pcr_pid = ((uint16_t) (buf[0] & 0x1f) << 8) | buf[1]; p_decoded->i_number_elements = buf[2]; buf += 3; for (int i = 0; i < p_decoded->i_number_elements; i++) { dvbpsi_service_location_element_t *p_element = &p_decoded->elements[i]; p_element->i_stream_type = buf[0]; p_element->i_elementary_pid = ((uint16_t) (buf[1] & 0x1f) << 8) | buf[2]; memcpy (p_element->i_iso_639_code, &buf[3], 3); buf += 6; } return p_decoded; }
/***************************************************************************** * dvbpsi_DecodeParentalRatingDr *****************************************************************************/ dvbpsi_parental_rating_dr_t * dvbpsi_DecodeParentalRatingDr( dvbpsi_descriptor_t * p_descriptor) { /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x55)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Decode data and check the length */ if(p_descriptor->i_length % 4) return NULL; /* Allocate memory */ dvbpsi_parental_rating_dr_t * p_decoded; p_decoded = (dvbpsi_parental_rating_dr_t*)malloc(sizeof(dvbpsi_parental_rating_dr_t)); if (!p_decoded) return NULL; int i_ratings_number = p_descriptor->i_length / 4; if (i_ratings_number > DVBPSI_PARENTAL_RATING_DR_MAX) i_ratings_number = DVBPSI_PARENTAL_RATING_DR_MAX; p_decoded->i_ratings_number = i_ratings_number; for (int i = 0; i < i_ratings_number; i++) { p_decoded->p_parental_rating[i].i_country_code = ((uint32_t)p_descriptor->p_data[4 * i] << 16) | ((uint32_t)p_descriptor->p_data[4 * i + 1] << 8) | p_descriptor->p_data[4 * i + 2]; p_decoded->p_parental_rating[i].i_rating = p_descriptor->p_data[4 * i + 3]; } p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_decode_mpeg_iso639_dr *****************************************************************************/ dvbpsi_mpeg_iso639_dr_t * dvbpsi_decode_mpeg_iso639_dr(dvbpsi_descriptor_t * p_descriptor) { dvbpsi_mpeg_iso639_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x0a)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if ((p_descriptor->i_length < 1) || (p_descriptor->i_length % 4 != 0)) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_mpeg_iso639_dr_t*)malloc(sizeof(dvbpsi_mpeg_iso639_dr_t)); if (!p_decoded) return NULL; p_decoded->i_code_count = p_descriptor->i_length / 4; if (p_decoded->i_code_count > 64) p_decoded->i_code_count = 64; int i = 0; while( i < p_decoded->i_code_count ) { p_decoded->code[i].iso_639_code[0] = p_descriptor->p_data[i*4]; p_decoded->code[i].iso_639_code[1] = p_descriptor->p_data[i*4+1]; p_decoded->code[i].iso_639_code[2] = p_descriptor->p_data[i*4+2]; p_decoded->code[i].i_audio_type = p_descriptor->p_data[i*4+3]; i++; } p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_decode_dvb_terr_deliv_sys_dr *****************************************************************************/ dvbpsi_dvb_terr_deliv_sys_dr_t * dvbpsi_decode_dvb_terr_deliv_sys_dr( dvbpsi_descriptor_t * p_descriptor) { /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x5a)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Allocate memory */ dvbpsi_dvb_terr_deliv_sys_dr_t * p_decoded; p_decoded = (dvbpsi_dvb_terr_deliv_sys_dr_t*)malloc(sizeof(dvbpsi_dvb_terr_deliv_sys_dr_t)); if (!p_decoded) return NULL; /* Decode data */ p_decoded->i_centre_frequency = (uint32_t)(p_descriptor->p_data[0] << 24) | (uint32_t)(p_descriptor->p_data[1] << 16) | (uint32_t)(p_descriptor->p_data[2] << 8) | (uint32_t)(p_descriptor->p_data[3]); p_decoded->i_bandwidth = (p_descriptor->p_data[4] >> 5) & 0x07; p_decoded->i_priority = (p_descriptor->p_data[4] >> 4) & 0x01; p_decoded->i_time_slice_indicator = (p_descriptor->p_data[4] >> 3) & 0x01; p_decoded->i_mpe_fec_indicator = (p_descriptor->p_data[4] >> 2) & 0x01; p_decoded->i_constellation = (p_descriptor->p_data[5] >> 6) & 0x03; p_decoded->i_hierarchy_information = (p_descriptor->p_data[5] >> 3) & 0x07; p_decoded->i_code_rate_hp_stream = p_descriptor->p_data[5] & 0x07; p_decoded->i_code_rate_lp_stream = (p_descriptor->p_data[6] >> 5) & 0x07; p_decoded->i_guard_interval = (p_descriptor->p_data[6] >> 3) & 0x03; p_decoded->i_transmission_mode = (p_descriptor->p_data[6] >> 1) & 0x03; p_decoded->i_other_frequency_flag = p_descriptor->p_data[6] & 0x01; p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_decode_mpeg_vstream_dr *****************************************************************************/ dvbpsi_mpeg_vstream_dr_t * dvbpsi_decode_mpeg_vstream_dr(dvbpsi_descriptor_t * p_descriptor) { dvbpsi_mpeg_vstream_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x02)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; /* Allocate memory */ p_decoded = (dvbpsi_mpeg_vstream_dr_t*)malloc(sizeof(dvbpsi_mpeg_vstream_dr_t)); if(!p_decoded) return NULL; /* Decode data and check the length */ p_decoded->b_mpeg2 = !((p_descriptor->p_data[0] & 0x04) ? true : false); if( (!p_decoded->b_mpeg2 && (p_descriptor->i_length != 1)) || (p_decoded->b_mpeg2 && (p_descriptor->i_length != 3))) { free(p_decoded); return NULL; } p_decoded->b_multiple_frame_rate = (p_descriptor->p_data[0] & 0x80) ? true : false; p_decoded->i_frame_rate_code = (p_descriptor->p_data[0] & 0x78) >> 3; p_decoded->b_constrained_parameter = (p_descriptor->p_data[0] & 0x02) ? true : false; p_decoded->b_still_picture = (p_descriptor->p_data[0] & 0x01) ? true : false; if(p_decoded->b_mpeg2) { p_decoded->i_profile_level_indication = p_descriptor->p_data[1]; p_decoded->i_chroma_format = (p_descriptor->p_data[2] & 0xc0) >> 6; p_decoded->b_frame_rate_extension = (p_descriptor->p_data[2] & 0x20) ? true : false; }
/***************************************************************************** * dvbpsi_DecodeCADr *****************************************************************************/ dvbpsi_ca_dr_t * dvbpsi_DecodeCADr(dvbpsi_descriptor_t * p_descriptor) { dvbpsi_ca_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x09)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if (p_descriptor->i_length < 4) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_ca_dr_t*)malloc(sizeof(dvbpsi_ca_dr_t)); if (!p_decoded) return NULL; p_decoded->i_ca_system_id = ((uint16_t)(p_descriptor->p_data[0]) << 8) | p_descriptor->p_data[1]; p_decoded->i_ca_pid = ((uint16_t)(p_descriptor->p_data[2] & 0x1f) << 8) | p_descriptor->p_data[3]; p_decoded->i_private_length = p_descriptor->i_length - 4; if (p_decoded->i_private_length > 251) p_decoded->i_private_length = 251; if (p_decoded->i_private_length) memcpy(p_decoded->i_private_data, p_descriptor->p_data + 4, p_decoded->i_private_length); p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }
/***************************************************************************** * dvbpsi_DecodeCAIdentifierDr *****************************************************************************/ dvbpsi_ca_identifier_dr_t * dvbpsi_DecodeCAIdentifierDr(dvbpsi_descriptor_t *p_descriptor) { dvbpsi_ca_identifier_dr_t * p_decoded; /* Check the tag */ if (!dvbpsi_CanDecodeAsDescriptor(p_descriptor, 0x53)) return NULL; /* Don't decode twice */ if (dvbpsi_IsDescriptorDecoded(p_descriptor)) return p_descriptor->p_decoded; if (p_descriptor->i_length < 1) return NULL; /* Allocate memory */ p_decoded = (dvbpsi_ca_identifier_dr_t*)calloc(1, sizeof(dvbpsi_ca_identifier_dr_t)); if (!p_decoded) return NULL; int i_number = p_descriptor->i_length / 2; if (i_number > DVBPSI_CA_SYSTEM_ID_DR_MAX) i_number = DVBPSI_CA_SYSTEM_ID_DR_MAX; p_decoded->i_number = i_number; for (int i = 0; i < i_number; i++) { /* TODO: decode CA system identifier values */ p_decoded->p_system[i].i_ca_system_id = p_descriptor->p_data[2 * i] << 8; p_decoded->p_system[i].i_ca_system_id |= p_descriptor->p_data[2 * i + 1]; } p_descriptor->p_decoded = (void*)p_decoded; return p_decoded; }