/**************************************************************************** *_Copyright (c) 2009 DST Technologies Inc. All Rights Reserved. * * Filename: dsthalPsiDvbSi.c * Author: Junku Park (hwatk@dstreamtech.com) * Description: Monitor and parse DVB-SI tables. * ***************************************************************************/ #include "dsthalcommon.h" #include "dstoslayer.h" #include "dsthalerror.h" #include #include #include #include "dsthalPsiMemChain.h" #include "dsthalPsiBitBuffer.h" #include "dsthalPsiMpegSi.h" #include "dsthalPsiDvbSi.h" #ifdef DMALLOC #include #endif /****************************************************************************** * Global variable declaration ******************************************************************************/ /****************************************************************************** * Imported variable declaration ******************************************************************************/ extern DHL_PSI_HANDLE gPsiHandle; extern DHL_RESULT GetMpegDescriptor (DS_U8 *descriptors, DS_U16 len, DS_U8 tag, DS_U16 instance, DS_U8 **descriptor); /****************************************************************************** * Imported function declaration ******************************************************************************/ extern void hal_cbPSISyncEventProc ( PSIEvent event , DHL_TBL_HANDLE hTblHandle , DS_U32 userParam ); /****************************************************************************** * Local definitions ******************************************************************************/ #define checkMemoryError(p) if (p == NULL) {err = DHL_FAIL_OUT_OF_RESOURCE ; goto ParseExit;} #define MEM_LIMIT 0x00004000 /* 16k */ //#define MEM_EIT_LIMIT 0x00010000 /* 64k */ #define SEGMENT_TABLE_MODE 0xFF #define SEGMENT_EAGER_MODE 0x80 /****************************************************************************** * Local typedefs ******************************************************************************/ /****************************************************************************** * Local variables declaration ******************************************************************************/ /****************************************************************************** * Local function prototypes ******************************************************************************/ static void DHL_PSI_ParseEventGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_event_group_descriptor_t **pp_event_grp); void DHL_PSI_ParseNetworkNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_network_name, DS_U8 *p_length); void DHL_PSI_ParseServiceListDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_list_descriptor_t **pp_service_list); void DHL_PSI_ParseServiceDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_descriptor_t **pp_service_desc); void DHL_PSI_ParseShortEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_short_event_descriptor_t **pp_short_event); void DHL_PSI_ParseExtendedEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_extended_event_descriptor_t **pp_extended_event); void DHL_PSI_DecodeDate(DS_U16 date_in_mjd, DS_U16 *p_year, DS_U8 *p_month, DS_U8 *p_day); static void DHL_PSI_ParseParentalRatingDescriptorEx (DS_U8* p, memId_t memId, dvb_parental_rating_descriptor_t **pp_desc); void DHL_PSI_ParseLocalTimeOffsetDescriptor( DS_U8 *p, int numItems, dvb_local_time_t *p_desc ); static int DHL_PSI_ParseTSInformationDescriptor(DS_U8* p, memId_t memId, arib_ts_information_descriptor_t **pp_ts_info); static int DHL_PSI_ParseSystemManagementDescriptor(DS_U8* p, DS_U16* p_system_management_id); void DHL_PSI_ParseBouquetNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_bouquet_name, DS_U8 *p_length); void DHL_PSI_ParseHierarchicalTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_hierarchical_transmission_descriptor_t **pp_hierarchical_transmission ); void DHL_PSI_ParseDigitalCopyControlDescriptor(DS_U8* p, memId_t memId, arib_digital_copy_control_descriptor_t **pp_digital_copy_control); void DHL_PSI_ParseNetworkIdentificationDescriptor( DS_U8 *p, memId_t memId, arib_network_identification_descriptor_t **pp_network_identification ); void DHL_PSI_ParsePartialTSTimeDescriptor( DS_U8 *p, memId_t memId, arib_partialTS_time_descriptor_t **pp_partialTS_time ); void DHL_PSI_ParseAudioComponentDescriptor( DS_U8 *p, memId_t memId, arib_audio_component_descriptor_t **pp_audio_component ); void DHL_PSI_ParseHyperlinkDescriptor( DS_U8 *p, memId_t memId, arib_hyperlink_descriptor_t **pp_hyperlink ); void DHL_PSI_ParseTargetRegionDescriptor( DS_U8 *p, memId_t memId, arib_target_region_descriptor_t **pp_target_region ); void DHL_PSI_ParseDataContentDescriptor( DS_U8 *p, memId_t memId, arib_data_content_descriptor_t **pp_data_content ); void DHL_PSI_ParseVideoDecodeControlDescriptor( DS_U8 *p, memId_t memId, arib_video_decode_control_descriptor_t **pp_video_decode_control ); void DHL_PSI_ParseLogoTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_logo_transmission_descriptor_t **pp_logo_transmission ); void DHL_PSI_ParseBasicLocalEventDescriptor( DS_U8 *p, memId_t memId, arib_basic_local_event_descriptor_t **pp_basic_local_event ); void DHL_PSI_ParseReferenceDescriptor( DS_U8 *p, memId_t memId, arib_reference_descriptor_t **pp_reference ); void DHL_PSI_ParseNodeRelationDescriptor( DS_U8 *p, memId_t memId, arib_node_relation_descriptor_t **pp_node_relation ); void DHL_PSI_ParseShortNodeInformationDescriptor( DS_U8 *p, memId_t memId, arib_short_node_information_descriptor_t **pp_short_node_information ); void DHL_PSI_ParseSTCReferenceDescriptor( DS_U8 *p, memId_t memId, arib_stc_reference_descriptor_t **pp_stc_reference ); void DHL_PSI_ParseSeriesDescriptor( DS_U8 *p, memId_t memId, arib_series_descriptor_t **pp_series ); void DHL_PSI_ParseSIParameterDescriptor( DS_U8 *p, memId_t memId, arib_si_parameter_descriptor_t **pp_si_parameter ); void DHL_PSI_ParseBroadcasterNameDescriptor(DS_U8 *p, memId_t memId, DS_U8 **pp_broadcaster_name, DS_U8 *p_length); void DHL_PSI_ParseComponentGroupDescriptor( DS_U8 *p, memId_t memId, arib_component_group_descriptor_t **pp_component_group ); void DHL_PSI_ParseSIPrimeTSDescriptor( DS_U8 *p, memId_t memId, arib_si_prime_ts_descriptor_t **pp_si_prime_ts ); void DHL_PSI_ParseBoardInformationDescriptor( DS_U8 *p, memId_t memId, arib_board_information_descriptor_t **pp_board_information ); void DHL_PSI_ParseLDTLinkageDescriptor( DS_U8 *p, memId_t memId, arib_ldt_linkage_descriptor_t **pp_ldt_linkage ); void DHL_PSI_ParseConnectedTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_connected_transmission_descriptor_t **pp_connected_tx ); void DHL_PSI_ParseContentAvailabilityDescriptor( DS_U8 *p, memId_t memId, arib_content_availability_descriptor_t **pp_content_availability ); void DHL_PSI_ParseConditionalPlaybackDescriptor( DS_U8 *p, memId_t memId, arib_conditional_playback_descriptor_t **pp_conditional_playback ); void DHL_PSI_ParseTerrestrialDeliverySystemDescriptor( DS_U8 *p, memId_t memId, arib_terrestrial_delivery_system_descriptor_t **pp_terrestrial_delivery_system ); void DHL_PSI_ParsePartialReceptionDescriptor(DS_U8 *p, memId_t memId, DS_U16 **pp_partial_reception, DS_U8 *p_length); void DHL_PSI_ParseEmergencyInformationDescriptor(DS_U8 *p_desc, memId_t memId, arib_emergency_information_descriptor_t **pp_emergency_info); void DHL_PSI_ParseDataComponentDescriptor(DS_U8 *p_desc, memId_t memId, arib_data_component_descriptor_t **pp_data_component); void DHL_PSI_ParseExtendedBroadcasterDescriptor(DS_U8 *p_desc, memId_t memId, arib_extended_broadcaster_descriptor_t **pp_ex_broad); void DHL_PSI_ParseServiceGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_service_group_descriptor_t **pp_service_grp); void DHL_PSI_ParseDownloadContentDescriptor(DS_U8 *p, memId_t memId, arib_download_content_descriptor_t **pp_download); static DS_U32 _ConvertMJD2UTC(DS_U16 Mjd, DS_U32 TimeInBCD); void DHL_PSI_Dump(DS_U8 *p_desc, int length) { int i; for(i=0; inum_transport_stream = numStreams; if ( numStreams ) { p_nit->transport_streams = (transport_stream_t *)memChainAlloc(memId,sizeof(transport_stream_t)*numStreams); checkMemoryError(p_nit->transport_streams); } else { p_nit->transport_streams = (transport_stream_t *)NULL; } /* * Now fill-out all the remaining fields over the all sections. */ index = 0; p_nit->network_descriptors = (DS_U8 *)NULL; p_ts = p_nit->transport_streams; for (i = 0; i < numSections; ++i) { DS_U8 last_section_number; int network_id; p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; network_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF; last_section_number = p[SECTION_NUM_LAST]; p_nit->b_system_management_id = DS_FALSE; if (i == 0) { /* First section */ p_nit->network_id = network_id; p_nit->version_number = version_number; //p_nit->current_next_indicator = current_next_indicator; p_nit->section_number = p[SECTION_NUM]; p_nit->last_section_number = last_section_number; /* * CONFIRM ME: Is network_descriptor is same on each sections? */ if ( p_nit->network_descriptors == (DS_U8 *)NULL && network_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_nit->network_descriptor_length = network_descriptor_length; p_nit->network_descriptors = (DS_U8 *)memChainAlloc(memId, network_descriptor_length); memcpy( p_nit->network_descriptors, &p[10], network_descriptor_length); err=GetMpegDescriptor( p_nit->network_descriptors, network_descriptor_length, DVB_TAG_network_name_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseNetworkNameDescriptor( p_desc, memId, &(p_nit->p_network_name), &(p_nit->network_name_length) ); } else { p_nit->p_network_name = (DS_U8 *)NULL; p_nit->network_name_length = 0; } p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_nit->network_descriptors, network_descriptor_length, ARIB_TAG_system_management_descriptor, 0, &p_desc ); if ( p_desc && !err ) { if ( DHL_PSI_ParseSystemManagementDescriptor( p_desc, &p_nit->system_management_id ) == 0 ) p_nit->b_system_management_id = DS_TRUE; } } } else { if (p_nit->network_id != network_id) printf("NIT: Inconsistent network_id (0x%x, 0x%x)\n", p_nit->network_id, network_id); if (p_nit->version_number != version_number) printf("NIT: inconsistent version_number (0x%x, 0x%x)\n", p_nit->version_number, version_number); if (p_nit->network_descriptor_length != network_descriptor_length) printf("NIT: Inconsistent network_descriptor_length (0x%x, 0x%x)\n", p_nit->network_descriptor_length, network_descriptor_length ); if (p_nit->last_section_number != last_section_number ) printf("NIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_nit->last_section_number, last_section_number); } transport_loop_length = ((p[10+network_descriptor_length]<<8) + p[11+network_descriptor_length]) & 0xFFF; if (!p_ts && transport_loop_length) { printf("NIT: transport_loop_length is not NULL, but transport_streams is NULL.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } p = §ionArr[i][12+network_descriptor_length]; for(k=0; ktransport_stream_id = transport_stream_id; p_ts->original_network_id = original_network_id; p_ts->transport_descriptor_length = transport_descriptor_length; if ( transport_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_ts->transport_descriptors = (DS_U8 *)memChainAlloc( memId, transport_descriptor_length ); if ( !(p_ts->transport_descriptors) ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseExit; } memcpy( p_ts->transport_descriptors, &p[k+6], transport_descriptor_length ); /* * Parse Service List descriptor */ err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length, DVB_TAG_service_list_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc ) { DHL_PSI_ParseServiceListDescriptor( p_desc, memId, &(p_ts->p_service_list) ); } else { p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL; } /* * Parse TS information descriptor. */ p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length, ARIB_TAG_ts_information_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc ) { DHL_PSI_ParseTSInformationDescriptor( p_desc, memId, &(p_ts->p_ts_info) ); } else { p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL; } } else { p_ts->transport_descriptors = (DS_U8 *)NULL; p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL; p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL; } k += 6+transport_descriptor_length; p_ts++; } } err = DHL_OK; *(((memId_t *)p_nit)-1) = memId; *pp_nit = p_nit; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbNit( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_NIT **pp_nit, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n"); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbNit(sysInfo, _TRUE_ /* current */, _FALSE_ /* not eager */, b_actual, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { #ifdef PSI_DGB printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut); #endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("DHL_PSI_GetPAT : procData.err = %d \n", err ); goto done2; } err = DHL_PSI_ParseDvbNit(procData.desc->sectPtr, b_actual, pp_nit); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbNit( DVB_NIT *p_nit ) { DHL_RESULT err = DHL_OK; transport_stream_t *p_ts; int i; if (!p_nit) return (err); printf("NIT (Network Information Table)\n"); printf(" network_id: 0x%04X\n", p_nit->network_id); printf(" version_number: %d\n", p_nit->version_number); printf(" section_number: %d\n", p_nit->section_number); printf(" last_section_number: %d\n", p_nit->last_section_number); if ( p_nit->p_network_name ) printf(" network_name: %s\n", p_nit->p_network_name); else printf(" network_name: (not found)\n"); printf(" network_descriptor_length: %d\n", p_nit->network_descriptor_length ); printf(" network_descriptors\n"); DHL_PSI_Dump(p_nit->network_descriptors, p_nit->network_descriptor_length); if ( p_nit->b_system_management_id ) printf(" system_management_id: 0x%04X\n", p_nit->system_management_id ); else printf(" NO system_management_id!\n"); printf(" num_transport_stream: %d\n", p_nit->num_transport_stream); p_ts = p_nit->transport_streams; for (i=0; inum_transport_stream; i++) { printf(" transport_stream %d\n", i); printf(" transport_stream_id: 0x%04X\n", p_ts->transport_stream_id); printf(" original_network_id: 0x%04X\n", p_ts->original_network_id); if ( p_ts->p_service_list ) { int n; dvb_service_t *p_service = p_ts->p_service_list->p_service; printf(" service_list (%d)\n", p_ts->p_service_list->numServices); for(n=0; np_service_list->numServices; n++) { printf(" service #%d: service_id 0x%04X, service_type 0x%02X\n", n, p_service->service_id, p_service->service_type); p_service++; } } if ( p_ts->p_ts_info ) { arib_ts_information_descriptor_t *p_ts_info = p_ts->p_ts_info; printf(" TS_info.remote_control_key_id = %d\n", p_ts_info->remote_control_key_id); if ( p_ts_info->ts_name_length && p_ts_info->ts_name ) { int n; #ifndef CONV_TO_ASCII #define CONV_TO_ASCII(x) ( ((x) >= ' ' && (x) <= '~') ? (x) : '.' ) #endif printf(" TS_info.ts_name = "); for (n=0; nts_name_length; n++) printf("%c", CONV_TO_ASCII(p_ts_info->ts_name[n])); printf("\n"); printf(" TS_info.ts_name = "); for (n=0; nts_name_length; n++) printf("%02X ", p_ts_info->ts_name[n]); printf("\n"); } if ( p_ts_info->transmission_type_count ) { int n; arib_transmission_type_t *p_tx_type = p_ts_info->transmission_type; for (n=0; ntransmission_type_count; n++) { printf(" TS_info.tx_type[%d].type: 0x%02X (%s-%s) See ARIB TR-B14 Table 3\n", n, p_tx_type->transmission_type_info, ((p_tx_type->transmission_type_info>>6)&3) == 0 ? "Type A" : ((p_tx_type->transmission_type_info>>6)&3) == 1 ? "Type B" : ((p_tx_type->transmission_type_info>>6)&3) == 2 ? "Type C" :"Reserved", ((p_tx_type->transmission_type_info>>4)&3) == 0 ? "64QAM" : ((p_tx_type->transmission_type_info>>4)&3) == 1 ? "16QAM" : ((p_tx_type->transmission_type_info>>4)&3) == 2 ? "QPSK" : "Reserved"); if ( p_tx_type->number_of_service && p_tx_type->service_id ) { int k; printf(" TS_info.tx_type[%d].service_id list\n", n); for (k=0; knumber_of_service; k++) { printf(" 0x%04X\n", p_tx_type->service_id[k]); } } p_tx_type++; } } } printf(" transport_descriptor_length: 0x%04X\n", p_ts->transport_descriptor_length); DHL_PSI_Dump(p_ts->transport_descriptors, p_ts->transport_descriptor_length); p_ts++; } return (err); } #if 0 ___Service_Description_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbSdt( DHL_PSI_HANDLE sysInfo, DS_BOOL current_next_indicator, DS_BOOL eager, DS_BOOL b_actual, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err=DHL_OK; if ((err = DD_PSI_GetTIDPSIMask (&pref, b_actual ? DVB_TID_service_description_section_actual : DVB_TID_service_description_section_other, current_next_indicator))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid(sysInfo, DVB_PID_SDT, eager ? eagerTableMode : tableMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, MAX_PSI_SECTIONS, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbSdt(DS_U8 **sectionArr, DS_BOOL b_actual, dvb_sdt_t **pp_sdt) { DHL_RESULT err = DHL_OK; int i, k; int numChannels; int numSections; int index; const DS_U8 *p; int len; dvb_sdt_t *p_sdt = NULL; int version_number; DS_BOOL current_next_indicator; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; dvb_sdt_service_t *p_service; if (sectionArr == NULL || (pp_sdt == NULL)) { return (DHL_FAIL_NULL_POINTER); } if (sectionArr[0] == NULL) { return (DHL_FAIL_NULL_POINTER); } else { numSections = get_last_section_number(sectionArr[0]) + 1; } /* now verify all other sections are present */ for (i=1; inumServices = numChannels; if ( numChannels ) { p_sdt->services = (dvb_sdt_service_t *)memChainAlloc(memId,sizeof(dvb_sdt_service_t)*numChannels); checkMemoryError(p_sdt->services); } else { p_sdt->services = (dvb_sdt_service_t *)NULL; } /* * Now fill-out all the remaining fields over the all sections. */ index = 0; p_service = p_sdt->services; for (i = 0; i < numSections; ++i) { DS_U16 original_network_id; DS_U16 transport_stream_id; DS_U8 last_section_number; int service_length; p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; transport_stream_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; original_network_id = ((p[8]<<8) + p[9]); last_section_number = p[SECTION_NUM_LAST]; if (i == 0) { /* First section */ p_sdt->transport_stream_id = transport_stream_id; p_sdt->version_number = version_number; p_sdt->original_network_id = original_network_id; p_sdt->section_number = p[SECTION_NUM]; p_sdt->last_section_number = last_section_number; /* * CONFIRM ME: Is network_descriptor is same on each sections? */ } else { if (p_sdt->transport_stream_id != transport_stream_id) printf("SDT: Inconsistent transport_stream_id (0x%x, 0x%x)\n", p_sdt->transport_stream_id, transport_stream_id); if (p_sdt->version_number != version_number) printf("SDT: Inconsistent version_number (0x%x, 0x%x)\n", p_sdt->version_number, version_number); if (p_sdt->original_network_id != original_network_id ) printf("SDT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_sdt->original_network_id, original_network_id ); if (p_sdt->last_section_number != last_section_number ) printf("SDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_sdt->last_section_number, last_section_number); } service_length = len - 8; if ( service_length < 5 ) { /* No service available for this section. */ continue; } p = §ionArr[i][11]; for(k=0; (k+5+4)service_id = ((p[k+0]<<8)+p[k+1]); p_service->EIT_user_defined_flags = (p[k+2]>>2) & 0x07; p_service->EIT_schedule_flag = (p[k+2] & 0x02) ? DS_TRUE : DS_FALSE; p_service->EIT_present_following_flag = (p[k+2] & 0x01) ? DS_TRUE : DS_FALSE; p_service->running_status = (p[k+3]>>5) & 0x07; p_service->free_CA_mode = ((p[k+3]>>4) & 0x01) ? DS_TRUE : DS_FALSE; p_service->descriptor_length = ((p[k+3]<<8)+p[k+4]) & 0xFFF; p_service->descriptors = (DS_U8 *)NULL; p_service->p_service_desc = (dvb_service_descriptor_t *)NULL; p_service->logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL; if ( p_service->descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_service->descriptors = (DS_U8 *)memChainAlloc( memId, p_service->descriptor_length ); if ( !(p_service->descriptors) ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseExit; } memcpy( p_service->descriptors, &p[k+5], p_service->descriptor_length ); // // Parse service_descriptor if available. // err=GetMpegDescriptor( p_service->descriptors, p_service->descriptor_length, DVB_TAG_service_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && err == DHL_OK ) { p_service->p_service_desc = (dvb_service_descriptor_t *)NULL; DHL_PSI_ParseServiceDescriptor( p_desc, memId, &(p_service->p_service_desc) ); } // // Parse service_descriptor if available. // err=GetMpegDescriptor( p_service->descriptors, p_service->descriptor_length, ARIB_TAG_logo_transmission_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && err == DHL_OK ) { p_service->logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL; DHL_PSI_ParseLogoTransmissionDescriptor( p_desc, memId, &(p_service->logo_tx_desc) ); } } k += 5+p_service->descriptor_length; p_service++; if ( index++ > numChannels ) { printf("SDT: Inconsistent number of services.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } } } err = DHL_OK; *(((memId_t *)p_sdt)-1) = memId; *pp_sdt = p_sdt; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbSdt( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_SDT **pp_sdt, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbSdt(sysInfo, _TRUE_ /* current */, _FALSE_ /* not eager */, b_actual, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { printf("%s: DHL_PSI_MonitorDvbSdt()=0x%02X\n", __func__, err); goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { //#ifdef PSI_DGB printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut); //#endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("%s: procData.err = %d\n", __func__, err ); goto done2; } err = DHL_PSI_ParseDvbSdt(procData.desc->sectPtr, b_actual, pp_sdt); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbSdt( DVB_SDT *p_sdt ) { DHL_RESULT err=DHL_OK; dvb_sdt_service_t *p_service; int i; if (!p_sdt) return err; p_service = p_sdt->services; printf("SDT (Service Description Table)\n"); printf(" transport_stream_id: 0x%04X\n", p_sdt->transport_stream_id); printf(" version_number: %d\n", p_sdt->version_number); printf(" section_number: %d\n", p_sdt->section_number); printf(" last_section_number: %d\n", p_sdt->last_section_number); printf(" original_network_id: 0x%04X\n\n", p_sdt->original_network_id); if ( !p_service ) return (err); for (i=0; inumServices; i++) { printf("Service #%d\n", i ); printf(" service_id: 0x%04X\n", p_service->service_id); printf(" EIT_user_defined_flags: %d\n", p_service->EIT_user_defined_flags); printf(" EIT_schedule_flag: %s (%d)\n", p_service->EIT_schedule_flag ? "TRUE" : "FALSE", p_service->EIT_schedule_flag); printf(" EIT_present_following_flag: %s (%d)\n", p_service->EIT_present_following_flag ? "TRUE" : "FALSE", p_service->EIT_present_following_flag); printf(" running_status: %d\n", p_service->running_status); printf(" free_CA_mode: %d\n", p_service->free_CA_mode); DHL_PSI_Dump(p_service->descriptors, p_service->descriptor_length); if ( p_service->logo_tx_desc ) { arib_logo_transmission_descriptor_t *p_logo; p_logo = p_service->logo_tx_desc; printf(" logo_transmission_descriptor\n"); if ( p_logo->logo_transmission_type == 0x1 ) { printf(" logo_id: 0x%04X\n", p_logo->logo_id); printf(" logo_version: 0x%04X\n", p_logo->logo_version); printf(" download_data_id: 0x%04X\n", p_logo->download_data_id); } else if ( p_logo->logo_transmission_type == 0x2 ) { printf(" logo_id: 0x%04X\n", p_logo->logo_id); } else if ( p_logo->logo_transmission_type == 0x3 ) { printf(" logo_char: %s\n", p_logo->logo_char); } } if ( p_service->p_service_desc ) { printf(" service_type: 0x%02X\n", p_service->p_service_desc->service_type); printf(" provider_name: %s\n", p_service->p_service_desc->p_provider_name); printf(" service_name : %s\n", p_service->p_service_desc->p_service_name); } p_service++; } return (err); } #if 0 ___Event_Information_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbEitEx( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DS_U16 eit_pid, DS_U8 scheduleTableId, DS_U16 service_id, DS_U8 segment_number, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err=DHL_OK; DS_U8 tableId = DVB_TID_event_information_section_actual_present; /* * If b_schedule is TRUE, then schedule_table_id shall be valid one. */ if ( scheduleTableId ) { tableId = scheduleTableId; } else { if ( b_actual ) tableId = DVB_TID_event_information_section_actual_present; else tableId = DVB_TID_event_information_section_other_present; } if ( segment_number == SEGMENT_TABLE_MODE || segment_number == SEGMENT_EAGER_MODE ) { if ((err = DD_PSI_GetExTIDPSIMask(&pref, tableId, service_id, 1))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } } else { if ((err = DD_PSI_GetDvbEitMask(&pref, tableId, service_id, segment_number, 1))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } } if ((err = DD_PSI_MonitorPSIPid(sysInfo, eit_pid ? eit_pid : DVB_PID_EIT, SEGMENT_TABLE_MODE == segment_number ? segmentTableMode : SEGMENT_EAGER_MODE == segment_number ? segmentEagerMode : segmentOnlyMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/4096, MAX_PSI_SECTIONS, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } if ( segment_number != SEGMENT_TABLE_MODE && segment_number != SEGMENT_EAGER_MODE && *returnPSICtl ) { DD_PSI_SetSegmentNumber(*returnPSICtl, segment_number); } return(err); } DHL_RESULT DHL_PSI_MonitorDvbEit( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DS_U16 eit_pid, DS_U8 scheduleTableId, DS_U16 service_id, PSIUpdateMode updateMode, PSIMode psiMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { int mode=0; switch(psiMode) { case segmentTableMode: mode = SEGMENT_TABLE_MODE; break; case segmentEagerMode: mode = SEGMENT_EAGER_MODE; break; default: printf("|%s| ERROR!! Invalid mode (%d)\n", __func__, psiMode); return DHL_FAIL; } return DHL_PSI_MonitorDvbEitEx( sysInfo, b_actual, eit_pid, scheduleTableId, service_id, mode, updateMode, eventProc, userParam, returnPSICtl ); } DHL_RESULT DHL_PSI_ParseDvbEitEx(DS_U8 **sectionArr, DS_BOOL b_actual, int i_section_mode, DS_U8 scheduleTableId, DS_U32 prefLangCode, DVB_EIT **pp_eit) { DHL_RESULT err = DHL_OK; int i, k; int numEvents; int numSections; int index; const DS_U8 *p; int len; dvb_eit_t *p_eit = NULL; DS_BOOL current_next_indicator; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; DS_U8 expectedTableId; dvb_eit_event_t *p_event; DS_BOOL b_first = DS_TRUE; DS_BOOL b_exist = DS_FALSE; int instance; if (sectionArr == NULL || (pp_eit == NULL)) { return (DHL_FAIL_NULL_POINTER); } if ( i_section_mode ) { numSections = i_section_mode; } else { if (sectionArr[0] == NULL) { //return (DHL_FAIL_NULL_POINTER); numSections = 256; } else { numSections = get_last_section_number(sectionArr[0]) + 1; } } /* now verify all other sections are present */ for (b_exist=DS_FALSE, i=0; inumEvents = numEvents; if ( numEvents ) { p_eit->eit_events = (dvb_eit_event_t *)memChainAlloc(memId,sizeof(dvb_eit_event_t)*numEvents); checkMemoryError(p_eit->eit_events); } else { p_eit->eit_events = (dvb_eit_event_t *)NULL; } /* * Now fill-out all the remaining fields over the all sections. */ index = 0; p_event = p_eit->eit_events; b_first = 0; for (i = 0; i < numSections; ++i) { DS_U16 service_id; DS_U8 version_number; DS_U8 last_section_number; DS_U8 segment_last_section_number; DS_U8 table_id; DS_U16 transport_stream_id; DS_U16 original_network_id; DS_U8 last_table_id; int event_length; if( sectionArr[i] == NULL ) { /* Skip null pointer section. */ //printf("skip %d section due to NULL.\n", i); continue; } p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; service_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; last_section_number = p[SECTION_NUM_LAST]; table_id = p[SECTION_TID]; transport_stream_id = ((p[8]<<8) + p[9]); original_network_id = ((p[10]<<8) + p[11]); segment_last_section_number = p[12]; last_table_id = p[13]; if (b_first == 0) { //DHL_PSI_Dump( (DS_U8 *)p, 32 ); /* First section */ p_eit->table_id = table_id; p_eit->service_id = service_id; p_eit->version_number = version_number; p_eit->section_number = p[6]; p_eit->last_section_number = last_section_number; p_eit->segment_last_section_number = segment_last_section_number; p_eit->transport_stream_id = transport_stream_id; p_eit->original_network_id = original_network_id; p_eit->last_table_id = last_table_id; b_first = 1; } else { if (p_eit->table_id != table_id) printf("EIT: Inconsistent table_id (0x%x, 0x%x)\n", p_eit->table_id, table_id); if (p_eit->service_id != service_id) printf("EIT: Inconsistent service_id (0x%x, 0x%x)\n", p_eit->service_id, service_id); if (p_eit->version_number != version_number) printf("EIT: Inconsistent version_number (0x%x, 0x%x)\n", p_eit->version_number, version_number); if (p_eit->last_section_number != last_section_number ) printf("EIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_eit->last_section_number, last_section_number); #if 0 /* Don't need to check this. */ if (p_eit->segment_last_section_number != segment_last_section_number ) printf("EIT: Inconsistent segment_last_section_number (0x%x, 0x%x)\n", p_eit->segment_last_section_number, segment_last_section_number); #endif if (p_eit->transport_stream_id != transport_stream_id) printf("EIT: Inconsistent transport_stream_id (0x%x, 0x%x)\n", p_eit->transport_stream_id, transport_stream_id); if (p_eit->original_network_id != original_network_id ) printf("EIT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_eit->original_network_id, original_network_id ); if (p_eit->last_table_id != last_table_id ) printf("EIT: Inconsistent last_table_id (0x%x, 0x%x)\n", p_eit->last_table_id, last_table_id ); } event_length = len - 14 - 4; if ( event_length < 12 ) { /* No service available for this section. */ continue; } p = §ionArr[i][14]; for(k=0; (k+12+4)event_id = (p[k+0]<<8)+p[k+1]; p_event->start_date = (p[k+2]<<8)+p[k+3]; p_event->start_time = (p[k+4]<<16)+(p[k+5]<<8)+p[k+6]; p_event->duration = (p[k+7]<<16)+(p[k+8]<<8)+p[k+9]; p_event->start_time_utc = _ConvertMJD2UTC(p_event->start_date, p_event->start_time); p_event->duration_in_sec = _ConvertMJD2UTC(0, p_event->duration); p_event->running_status = (p[k+10]>>5) & 0x07; p_event->free_CA_mode = (p[k+10]>>4) & 0x01; descriptor_length = p_event->descriptor_length = ((p[k+10]<<8)+p[k+11]) & 0xFFF; p_event->descriptor_length = 0; p_event->descriptors = (DS_U8 *)NULL; if ( descriptor_length ) { DS_U8 *p_desc_sect = (DS_U8 *)&p[k+12]; DS_U8 *p_desc = (DS_U8 *)NULL; DS_U8 langCode[3]; #if 0 p_event->descriptors = (UINT8 *)memChainAlloc( memId, descriptor_length ); if ( !(p_event->descriptors) ) { err = outOfCPUMemoryError; goto ParseExit; } memcpy( p_event->descriptors, &p[k+12], descriptor_length ); #endif { /* * ShortEventDescriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse. */ dvb_short_event_descriptor_t *pp_short_event[MAX_SHORT_EVENTS]; p_event->pp_short_event = (dvb_short_event_descriptor_t **)NULL; memset( pp_short_event, 0, sizeof(dvb_short_event_descriptor_t *)*MAX_SHORT_EVENTS ); instance = 0; do { p_desc = (DS_U8 *)NULL; if ( prefLangCode ) { langCode[0] = (prefLangCode>>16) & 0xFF; langCode[1] = (prefLangCode>>8) & 0xFF; langCode[2] = (prefLangCode>>0) & 0xFF; err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, DVB_TAG_short_event_descriptor, 2/*Offset to ISO_639_language_code*/, langCode, 3/*Langcode=3byte*/, instance, &p_desc ); } else { err=GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_short_event_descriptor, instance, &p_desc ); } if (p_desc && err == DHL_OK) { DHL_PSI_ParseShortEventDescriptor( p_desc, memId, prefLangCode, &pp_short_event[instance] ); instance++; } } while (p_desc && err == DHL_OK && instance < MAX_SHORT_EVENTS); if (instance) { /* * ãÀº ¼ö ¸¸Å­ pointer¸¦ º¹»çÇϰí, count¸¦ ¼³Á¤. */ p_event->pp_short_event = (dvb_short_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t *) * instance); checkMemoryError(p_event->pp_short_event); memcpy( p_event->pp_short_event, pp_short_event, sizeof(dvb_short_event_descriptor_t *) * instance ); } p_event->numShortEvents = instance; } { /* * extended_event_descriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse. */ dvb_extended_event_descriptor_t *pp_extended_event[MAX_EXTENDED_EVENTS]; p_event->pp_extended_event = (dvb_extended_event_descriptor_t **)NULL; memset( pp_extended_event, 0, sizeof(dvb_extended_event_descriptor_t *) * MAX_EXTENDED_EVENTS ); instance = 0; do { p_desc = (DS_U8 *)NULL; if ( prefLangCode ) { err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, DVB_TAG_extended_event_descriptor, 3/*Offset to ISO_639_language_code*/, langCode, 3/*Langcode=3byte*/, instance, &p_desc ); } else { err=GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_extended_event_descriptor, instance, &p_desc ); } if (p_desc && err == DHL_OK) { DHL_PSI_ParseExtendedEventDescriptor( p_desc, memId, prefLangCode, &pp_extended_event[instance] ); instance++; } } while (p_desc && err == DHL_OK && instance < MAX_EXTENDED_EVENTS); /* * ãÀº ¼ö ¸¸Å­ pointer¸¦ º¹»çÇϰí, count¸¦ ¼³Á¤. */ if (instance) { p_event->pp_extended_event = (dvb_extended_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t *) * instance); checkMemoryError(p_event->pp_extended_event); memcpy( p_event->pp_extended_event, pp_extended_event, instance * sizeof(dvb_extended_event_descriptor_t *) ); } p_event->numExtendedEvents = instance; } { /* * Find Parental_Rating descriptor. */ dvb_parental_rating_descriptor_t *pp_pr_desc[MAX_RATINGS]; p_event->pp_pr_desc = (dvb_parental_rating_descriptor_t **)NULL; memset( pp_pr_desc, 0, sizeof(dvb_parental_rating_descriptor_t *) * MAX_RATINGS ); instance = 0; do { p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_parental_rating_descriptor, instance, &p_desc ); if (p_desc && err == DHL_OK) { DHL_PSI_ParseParentalRatingDescriptorEx( p_desc, memId, &pp_pr_desc[instance] ); instance++; } } while (p_desc && err == DHL_OK && instance < MAX_RATINGS); if (instance) { p_event->pp_pr_desc = (dvb_parental_rating_descriptor_t **)memChainAlloc(memId, sizeof(dvb_parental_rating_descriptor_t *) * instance); checkMemoryError(p_event->pp_pr_desc); memcpy( p_event->pp_pr_desc, pp_pr_desc, sizeof(dvb_parental_rating_descriptor_t *) * instance ); } p_event->numParentalRating = instance; } /* * Find Event Group descriptor. */ p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_desc_sect, descriptor_length, ARIB_TAG_event_group_descriptor, 0, /* only find first one. */ &p_desc ); if (p_desc && err == DHL_OK) DHL_PSI_ParseEventGroupDescriptor( p_desc, memId, &p_event->p_event_group ); { /* * Find Audio component descriptor. */ arib_audio_component_descriptor_t *pp_audio_component[MAX_AUDIO_COMPONENT]; p_event->pp_audio_component = (arib_audio_component_descriptor_t **)NULL; memset( pp_audio_component, 0, sizeof(arib_audio_component_descriptor_t *) * MAX_AUDIO_COMPONENT ); instance = 0; do { p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_desc_sect, descriptor_length, ARIB_TAG_audio_component_descriptor, instance, &p_desc ); if (p_desc && err == DHL_OK) { DHL_PSI_ParseAudioComponentDescriptor( p_desc, memId, &pp_audio_component[instance] ); instance++; } } while (p_desc && err == DHL_OK && instance < MAX_AUDIO_COMPONENT); if (instance) { p_event->pp_audio_component = (arib_audio_component_descriptor_t **)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t *) * instance); checkMemoryError(p_event->pp_audio_component); memcpy( p_event->pp_audio_component, pp_audio_component, sizeof(arib_audio_component_descriptor_t *) * instance ); } p_event->numAudioComponent = instance; } { // // Data component descriptor // arib_data_content_descriptor_t *pp_data_content[MAX_CAPTION_ES]; p_event->pp_data_content = (arib_data_content_descriptor_t **)NULL; memset( pp_data_content, 0, sizeof(arib_data_content_descriptor_t *) * MAX_CAPTION_ES ); instance = 0; langCode[0] = 0x00; langCode[1] = 0x08; do { p_desc = (DS_U8 *)NULL; err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, ARIB_TAG_data_content_descriptor, 2/*Offset to data_component_id*/, langCode/*=0x0008*/, 2/*Langcode=3byte*/, instance, &p_desc ); if (p_desc && err == DHL_OK) { DHL_PSI_ParseDataContentDescriptor( p_desc, memId, &pp_data_content[instance] ); instance++; } } while (p_desc && err == DHL_OK && instance < MAX_CAPTION_ES); if (instance) { p_event->pp_data_content = (arib_data_content_descriptor_t **)memChainAlloc( memId, sizeof(arib_data_content_descriptor_t *) * instance ); checkMemoryError(p_event->pp_data_content); memcpy( p_event->pp_data_content, pp_data_content, sizeof(arib_data_content_descriptor_t *) * instance ); } p_event->numDataContent = instance; } } else { p_event->descriptors = (DS_U8 *)NULL; p_event->numShortEvents = 0; p_event->numExtendedEvents = 0; p_event->numParentalRating = 0; p_event->numAudioComponent = 0; p_event->numDataContent = 0; p_event->p_event_group = (arib_event_group_descriptor_t *)NULL; //p_event->pp_audio_component = (arib_audio_component_descriptor_t **)NULL; } k += 12+descriptor_length; p_event++; if ( index++ > numEvents ) { printf("EIT: Inconsistent number of events.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } } } err = DHL_OK; *(((memId_t *)p_eit)-1) = memId; *pp_eit = p_eit; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_ParseDvbEit(DS_U8 **sectionArr, DS_BOOL b_actual, DS_U8 scheduleTableId, DVB_EIT **pp_eit) { return DHL_PSI_ParseDvbEitEx(sectionArr, b_actual, 0, scheduleTableId, 0, pp_eit ); } DHL_RESULT DHL_PSI_GetDvbEitEx( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DS_U8 scheduleTableId, DS_U16 service_id, DS_U8 segment_number, DVB_EIT **pp_eit, int timeOut ) { DHL_RESULT err = DHL_OK; PSIContext_t *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbEitEx(sysInfo, b_actual, 0, scheduleTableId, service_id, segment_number, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, (DHL_PSI_HANDLE *)&returnPSICtl))) { printf("%s: DHL_PSI_MonitorDvbEit()=0x%02X\n", __func__, err); goto done; } printf("returnPSICtl->segment_number: %d\n", returnPSICtl->segment_number); //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { //#ifdef PSI_DGB printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut); //#endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("%s: procData.err = %d\n", __func__, err ); goto done2; } if ( procData.desc ) err = DHL_PSI_ParseDvbEit(procData.desc->sectPtr, b_actual, scheduleTableId, pp_eit); else err = DHL_FAIL; done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_GetDvbEit( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DS_U8 scheduleTableId, DS_U16 service_id, DVB_EIT **pp_eit, int timeOut ) { return DHL_PSI_GetDvbEitEx( sysInfo, b_actual, scheduleTableId, service_id, 0xFF, pp_eit, timeOut ); } static const char BitUnmap[256] = { -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; static const char BitCount[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, }; static int getFirstBit(DS_U32 bitmap) { int k; union { DS_U32 ul; DS_U8 uc[4]; } u; if (!bitmap) return -1; u.ul = bitmap; for (k=0; k<4; k++) { if ( BitUnmap[u.uc[k]] >= 0 ) return ((k*8)+BitUnmap[u.uc[k]]); } return -1; } int getBitCount(DS_U32 bitmap) { int k, cnt; union { DS_U32 ul; DS_U8 uc[4]; } u; u.ul = bitmap; for (cnt=0,k=0; k<4; k++) cnt += BitCount[u.uc[k]]; return cnt; } int getBitCountEx(DS_U32 bitmap, int n) { int k, cnt; union { DS_U32 ul; DS_U8 uc[4]; } u; for(k=n; k<32; k++) bitmap &= ~(1<desc = NULL; /*for safety.*/ } else { procData->desc = desc; } procData->err = err; if( procData->hEvent ) { //AtiCore_EventSet((ACL_HANDLE)(procData->hEvent)); OS_GiveSemaphore(procData->hEvent); #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : set procData->hEvent.\r\n"); #endif } break; case psiSectionReceived: { DS_S32 segment_number, segment_count; int i; P_DS_U8 p[8]; segment_number = segment_count = -1; memset(p, 0, sizeof(p)); err = DD_PSI_GetLastReceivedSegment( hTblHandle, DS_FALSE, &segment_number, &segment_count, p ); if (err || (segment_number <0) || (segment_count < 0)) { printf("ERROR!! DD_PSI_GetLastReceivedSegment() = %d, (%d/%d)\n", err, (int)segment_number, (int)segment_count); return; } if ( procData->exist_segment_map & (1<desc = NULL; procData->newly_received_map |= (1<last_segment_number = segment_count; for (i=0; i<8; i++) procData->section_data[i] = p[i]; procData->err = err; if( procData->hEvent ) { //AtiCore_EventSet((ACL_HANDLE)(procData->hEvent)); OS_GiveSemaphore(procData->hEvent); } break; } default: break; } } DHL_RESULT DHL_PSI_GetDvbEitEager( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DS_U8 scheduleTableId, DS_U16 service_id, DS_U32 exist_segment_map, P_DVB_EIT *pp_eitPtr, int timeOut ) { DHL_RESULT err = DHL_OK; PSIContext_t *returnPSICtl = NULL; PSIEagerEventData_t procData; DS_U32 endTime = OS_GetTickCount() + timeOut/10; DS_U32 temp_received_map; int res = 0; int current_segment=0; int received_count=0; //memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); procData.newly_received_map = 0; procData.processed_map = 0; procData.last_segment_number = -1; procData.exist_segment_map = exist_segment_map; if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbEitEx(sysInfo, b_actual, 0, scheduleTableId, service_id, SEGMENT_EAGER_MODE, psiOneShot, cbPsiEagerFunction, (DS_U32)&procData, (DHL_PSI_HANDLE *)&returnPSICtl))) { printf("%s: DHL_PSI_MonitorDvbEit()=0x%02X\n", __func__, err); goto done; } //printf("returnPSICtl->segment_number: %d\n", returnPSICtl->segment_number); do { //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { //#ifdef PSI_DGB printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut); //#endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("%s: procData.err = %d\n", __func__, err ); goto done2; } /* * FIX ME: ¾Æ·¡¿¡¼­ Event¸¦ ó¸®Çϱâ Àü¿¡, Çѹø ´õ Event°¡ ¿À¸é ¹®Á¦°¡ ¹ß»ýÇÔ. * => BITMAPÀ¸·Î º¯°æÇÏ¿© ¹®Á¦ ÇØ°áµÊ. */ temp_received_map = procData.newly_received_map; current_segment = getFirstBit(temp_received_map & (~procData.processed_map)); if (procData.desc) { err = DHL_PSI_ParseDvbEit(procData.desc->sectPtr, b_actual, scheduleTableId, &pp_eitPtr[0]); goto done2; } else if (current_segment >= 0) { //err = DHL_PSI_ParseDvbEit(procData.section_data, b_actual, scheduleTableId, &pp_eitPtr[1+procData.current_section_number]); err = DHL_PSI_ParseDvbEitEx(&procData.section_data[0], b_actual, 8, scheduleTableId, 0, &pp_eitPtr[1+current_segment]); procData.processed_map |= (1< %d (segment_count: %d/%ld)\n", temp_received_map, procData.processed_map, current_segment, received_count, procData.last_segment_number); printf("total count: %d\n", getBitCountEx( temp_received_map | procData.exist_segment_map, procData.last_segment_number )); if ( procData.last_segment_number <= received_count ) goto done2; } else { printf("%s| ERROR!! Both desc and section_number is invalid!\n", __func__); } } while ( OS_GetTickCount() < endTime ); if ( OS_GetTickCount() > endTime ) err = DHL_FAIL_TIMEOUT; done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbEit( DVB_EIT *p_eit ) { DHL_RESULT err=DHL_OK; int i; dvb_eit_event_t *p_event; DS_U16 y; DS_U8 m, d; dvb_short_event_descriptor_t *p_short_event; dvb_extended_event_descriptor_t *p_extended_event; printf("EIT (Event Information Table)\n"); printf(" service_id: 0x%04X\n", p_eit->service_id); printf(" version_number: 0x%02X\n", p_eit->version_number); printf(" section # (%d/%d)\n", p_eit->section_number, p_eit->last_section_number); printf(" segment_last_section_number: %d\n", p_eit->segment_last_section_number); printf(" transport_stream_id: 0x%04X\n", p_eit->transport_stream_id); printf(" original_network_id: 0x%04X\n", p_eit->original_network_id); printf(" last_table_id: 0x%02X\n", p_eit->last_table_id); printf("Number of events: %d\n", p_eit->numEvents); p_event = p_eit->eit_events; for (i=0; inumEvents; i++) { int idx; printf(" Event #%d\n", i); printf(" event_id: 0x%04X\n", p_event->event_id); DHL_PSI_DecodeDate(p_event->start_date, &y, &m, &d); printf(" start_date: (0x%04X) %4d/%02d/%02d %02X:%02X:%02X\n", p_event->start_date, y, m, d, (DS_U16)((p_event->start_time>>16)&0xFF), (DS_U16)((p_event->start_time>>8)&0xFF), (DS_U16)((p_event->start_time)&0xFF)); printf(" duration: %02X:%02X:%02X\n", (DS_U16)((p_event->duration>>16)&0xFF), (DS_U16)((p_event->duration>>8)&0xFF), (DS_U16)(p_event->duration)&0xFF); printf(" running_status: %d\n", p_event->running_status); printf(" free_CA_mode: %s (%d)\n", p_event->free_CA_mode ? "Free" : "Scrambled", p_event->free_CA_mode); if (p_event->p_event_group) { arib_event_t *p_grp_event; arib_other_event_t *p_other_event; int idx; printf(" Event_Group> GroupType: 0x%X\n", p_event->p_event_group->group_type); p_grp_event = p_event->p_event_group->p_event; for (idx=0; idxp_event_group->numEvents; idx++) { printf(" EventGroup%d: Service_Id 0x%04X Event_Id 0x%04X\n", idx, p_grp_event->service_id, p_grp_event->event_id); p_grp_event++; } p_other_event = p_event->p_event_group->p_other_event; for (idx=0; idxp_event_group->numOtherNetworkEvents; idx++) { printf(" OtherEventGroup%d: ONID 0x%04X TSID 0x%04X Service_Id 0x%04X Event_Id 0x%04X\n", idx, p_other_event->original_network_id, p_other_event->transport_stream_id, p_other_event->service_id, p_other_event->event_id); p_other_event++; } } for (idx=0; idxnumParentalRating; idx++) { int idxRatings; dvb_parental_rating_descriptor_t *p_pr_desc=p_event->pp_pr_desc[idx]; dvb_parental_rating_entry_t *p_ratings; printf("\n Parental Rating %d...\n", idx); p_ratings = p_pr_desc->p_ratings; for (idxRatings=0; idxRatingsi_num_ratings; idxRatings++) { printf(" Country_Code: %c%c%c ", (DS_U8)((p_ratings->country_code>>16)&0xFF), (DS_U8)((p_ratings->country_code>>8)&0xFF), (DS_U8)((p_ratings->country_code>>0)&0xFF)); printf(" Rating_value: 0x%x\n", p_ratings->rating_value); p_ratings++; } } for (idx=0; idxnumAudioComponent; idx++) { arib_audio_component_descriptor_t *p_audio_component; p_audio_component = p_event->pp_audio_component[idx]; printf(" AUDIO #%d\n", idx); printf(" stream_content: 0x%02X\n", p_audio_component->stream_content); printf(" component_type: 0x%02X\n", p_audio_component->component_type); printf(" component_tag : 0x%02X\n", p_audio_component->component_tag); printf(" stream_type : 0x%02X\n", p_audio_component->stream_type); printf(" ES_multi_lingu: 0x%02X\n", p_audio_component->ES_multi_lingual_flag); printf(" Sampling_rate: 0x%02X\n", p_audio_component->sampling_rate); printf(" ISO_639_language_code : 0x%06lX (%c%c%c)\n", p_audio_component->ISO_639_language_code, (DS_U8)((p_audio_component->ISO_639_language_code>>16)&0xFF), (DS_U8)((p_audio_component->ISO_639_language_code>>8)&0xFF), (DS_U8)((p_audio_component->ISO_639_language_code>>0)&0xFF)); printf(" ISO_639_language_code_2 : 0x%06lX (%c%c%c)\n", p_audio_component->ISO_639_language_code_2, (DS_U8)((p_audio_component->ISO_639_language_code_2>>16)&0xFF), (DS_U8)((p_audio_component->ISO_639_language_code_2>>8)&0xFF), (DS_U8)((p_audio_component->ISO_639_language_code_2>>0)&0xFF)); } for (idx=0; idxnumDataContent; idx++) { arib_data_content_descriptor_t *p_data_content; p_data_content = p_event->pp_data_content[idx]; printf(" DATA_CONTENT %d\n", idx); printf(" data_component_id: 0x%04X\n", p_data_content->data_component_id); printf(" entry_component: 0x%04X\n", p_data_content->entry_component); if ( p_data_content->selector_length && p_data_content->selector_byte ) { int k; printf(" Selector_byte: "); for (k=0; kselector_length; k++) printf("%02X ", p_data_content->selector_byte[k]); printf("\n"); } printf(" ISO_639_lang_code: %c%c%c\n", (DS_U8)((p_data_content->ISO_639_language_code>>16)&0xFF), (DS_U8)((p_data_content->ISO_639_language_code>>8)&0xFF), (DS_U8)((p_data_content->ISO_639_language_code>>0)&0xFF)); } for (idx=0; idxnumShortEvents; idx++) { p_short_event = p_event->pp_short_event[idx]; if (p_short_event) { printf("\n Short_event%d: %c%c%c\n", idx, (DS_U8)((p_short_event->ISO_639_language_code>>16)&0xFF), (DS_U8)((p_short_event->ISO_639_language_code>>8)&0xFF), (DS_U8)((p_short_event->ISO_639_language_code>>0)&0xFF)); if (p_short_event->event_name_length && p_short_event->p_event_name) printf(" Event_Name: %s\n", p_short_event->p_event_name); else printf(" Event_Name: NULL\n"); if (p_short_event->text_length && p_short_event->p_text) printf(" Text: %s\n", p_short_event->p_text); else printf(" Text: NULL\n"); } else { printf(" Why it's NULL????? %d\n", idx); } } for (idx=0; idxnumExtendedEvents; idx++) { p_extended_event = p_event->pp_extended_event[idx]; if (p_extended_event) { dvb_ext_event_item_t *p_ext_item; int j; printf("\n Extended_event%d: %c%c%c\n", idx, (DS_U8)((p_extended_event->ISO_639_language_code>>16)&0xFF), (DS_U8)((p_extended_event->ISO_639_language_code>>8)&0xFF), (DS_U8)((p_extended_event->ISO_639_language_code>>0)&0xFF)); printf(" descriptor #: (%d/%d)\n", p_extended_event->descriptor_number, p_extended_event->last_descriptor_number); p_ext_item = p_extended_event->items; for (j=0; jnumItems; j++) { if (p_ext_item->item_description_length && p_ext_item->p_item_description) { printf(" item_description: %s\n", p_ext_item->p_item_description); } if (p_ext_item->item_length && p_ext_item->p_item_char) { printf(" item: %s\n", p_ext_item->p_item_char); } p_ext_item++; } if (p_extended_event->text_length && p_extended_event->p_text) printf(" Text: %s\n", p_extended_event->p_text); else printf(" Text: NULL\n"); } } p_event++; } return (err); } #if 0 ___Time_Data_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbTdt( DHL_PSI_HANDLE sysInfo, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err=DHL_OK; if ((err = DD_PSI_GetTIDPSISimpleMask (&pref, DVB_TID_time_date_section))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid(sysInfo, DVB_PID_TDT, privateMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, 1, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbTdt(DS_U8 *sectionArr, dvb_tdt_t **pp_tdt) { DHL_RESULT err = DHL_OK; const DS_U8 *p; int len; dvb_tdt_t *p_tdt = NULL; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; if (sectionArr == NULL || (pp_tdt == NULL)) { return (DHL_FAIL_NULL_POINTER); } p = sectionArr; if ( p[SECTION_TID] != DVB_TID_time_date_section ) { /* * This thing isn't a PAT. Stop right here. */ printf("TDT: Bad table ID. (0x%02X)\n", p[SECTION_TID]); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } if ((p[SECTION_LEN_HI] & 0x80) != 0x00) { printf("TDT: section_syntax_indicator set\n"); } len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; if ( len < 8 ) { err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } /* create the memChain */ err = memChainCreate(&memId,&memSetup); if (err) { goto ParseExit; } p_tdt = (dvb_tdt_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_tdt_t)+sizeof(memId_t))) + 1); checkMemoryError(p_tdt); p_tdt->date = (p[3]<<8)+p[4]; p_tdt->time = (p[5]<<16)+(p[6]<<8)+p[7]; err = DHL_OK; *(((memId_t *)p_tdt)-1) = memId; *pp_tdt = p_tdt; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbTdt( DHL_PSI_HANDLE sysInfo, DVB_TDT **pp_tdt, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbTdt(sysInfo, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { printf("%s: DHL_PSI_MonitorDvbTdt()=0x%02X\n", __func__, err); goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { //#ifdef PSI_DGB printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut); //#endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("%s: procData.err = %d\n", __func__, err ); goto done2; } err = DHL_PSI_ParseDvbTdt(procData.desc->sectPtr[0], pp_tdt); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbTdt(DVB_TDT *p_tdt) { DHL_RESULT err = DHL_OK; DS_U16 y; DS_U8 m, d; if (!p_tdt) return (err); printf("TDT (Time Date Table)\n"); y=m=d=0; DHL_PSI_DecodeDate(p_tdt->date, &y, &m, &d); printf(" Date: 0x%04X (%d/%d/%d)\n", p_tdt->date, y, m, d ); printf(" Time: %02X:%02X:%02X\n", (DS_U16)((p_tdt->time>>16)&0xFFFF), (DS_U16)((p_tdt->time>>8)&0xFF), (DS_U16)((p_tdt->time & 0xFF))); return (err); } #if 0 ___Time_Offset_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbTot( DHL_PSI_HANDLE sysInfo, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err=DHL_OK; if ((err = DD_PSI_GetTIDPSISimpleMask (&pref, DVB_TID_time_offset_section))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid(sysInfo, DVB_PID_TOT, privateMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, 1, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); //PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbTot(DS_U8 *sectionArr, dvb_tot_t **pp_tot) { DHL_RESULT err = DHL_OK; const DS_U8 *p; int len, descriptor_length; dvb_tot_t *p_tot = NULL; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; if (sectionArr == NULL || (pp_tot == NULL)) { return (DHL_FAIL_NULL_POINTER); } p = sectionArr; if ( p[SECTION_TID] != DVB_TID_time_offset_section ) { /* * This thing isn't a TDT. Stop right here. */ printf("TOT: Bad table ID. (0x%02X)\n", p[SECTION_TID]); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } if ((p[SECTION_LEN_HI] & 0x80) != 0x00) { printf("TOT: section_syntax_indicator set\n"); } len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; if ( len < 8 ) { err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } /* create the memChain */ err = memChainCreate(&memId,&memSetup); if (err) { goto ParseExit; } p_tot = (dvb_tot_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_tot_t)+sizeof(memId_t))) + 1); checkMemoryError(p_tot); p_tot->date = (p[3]<<8)+p[4]; p_tot->time = (p[5]<<16)+(p[6]<<8)+p[7]; p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)NULL; p_tot->descriptor_length = 0; p_tot->descriptors = (DS_U8 *)NULL; if ( len >= 11 ) { DS_U8 *p_desc = (DS_U8 *)NULL; dvb_local_time_t *p_lt; int numLocaltime; descriptor_length = ((p[8]<<8)+p[9]) & 0xFFF; if ( descriptor_length > 1024 ) { printf("TOT: too long descriptor length %d\n", descriptor_length); goto NoDescExit; } /* * Counts number of local_time. */ err=GetMpegDescriptor( (DS_U8 *)&p[10], descriptor_length, DVB_TAG_local_time_offset_descriptor, 0, &p_desc ); if (err==DHL_OK && p_desc) { numLocaltime = p_desc[1] / 13; if (numLocaltime <= 0) goto NoDescExit; p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)memChainAlloc(memId, sizeof(dvb_local_time_offset_descriptor_t)); checkMemoryError(p_tot->p_lto); p_lt = p_tot->p_lto->p_local_time = (dvb_local_time_t *)memChainAlloc(memId, sizeof(dvb_local_time_t)*numLocaltime); checkMemoryError(p_tot->p_lto->p_local_time); p_tot->p_lto->i_num_local_time = numLocaltime; DHL_PSI_ParseLocalTimeOffsetDescriptor( p_desc, numLocaltime, p_lt ); } else { printf("TOT: cannot find local_time_offset descriptor.\n"); } } NoDescExit: err = DHL_OK; *(((memId_t *)p_tot)-1) = memId; *pp_tot = p_tot; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbTot( DHL_PSI_HANDLE sysInfo, DVB_TOT **pp_tot, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (UINT32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semTot0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbTot(sysInfo, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { printf("%s: DHL_PSI_MonitorDvbTot()=0x%02X\n", __func__, err); goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { //#ifdef PSI_DGB printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut); //#endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("%s: procData.err = %d\n", __func__, err ); goto done2; } err = DHL_PSI_ParseDvbTot(procData.desc->sectPtr[0], pp_tot); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbTot(DVB_TOT *p_tot) { DHL_RESULT err = DHL_OK; DS_U16 y; DS_U8 m, d; int i; dvb_local_time_t *p_lt; if (!p_tot) return (err); printf("TOT (Time Offset Table)\n"); y=m=d=0; DHL_PSI_DecodeDate(p_tot->date, &y, &m, &d); printf(" Date: 0x%04X (%d/%d/%d)\n", p_tot->date, y, m, d ); printf(" Time: %02X:%02X:%02X\n", (DS_U16)((p_tot->time>>16)&0xFFFF), (DS_U16)((p_tot->time>>8)&0xFF), (DS_U16)((p_tot->time & 0xFF))); if (p_tot->p_lto) { printf(" Number of local time: %d\n", p_tot->p_lto->i_num_local_time); p_lt = p_tot->p_lto->p_local_time; for (i=0; ip_lto->i_num_local_time; i++) { printf("\n #%d\n", i); printf(" Country_code: 0x%06lX, Region_id: %d, Local_time_offset: %c0x%04X\n", p_lt->country_code, p_lt->country_region_id, p_lt->local_time_offset_polarity ? '-' : '+', p_lt->local_time_offset); y=m=d=0; DHL_PSI_DecodeDate(p_lt->time_of_change_date, &y, &m, &d); printf(" Time_of_change: 0x%04X (%d/%d/%d)\n", p_lt->time_of_change_date, y, m, d); printf(" Time_of_change: %02X:%02X:%02X\n", (DS_U16)((p_lt->time_of_change_time>>16)&0xFFFF), (DS_U16)((p_lt->time_of_change_time>>8)&0xFF), (DS_U16)((p_lt->time_of_change_time & 0xFF))); printf(" next_time_offset: 0x%04X\n", p_lt->next_time_offset); p_lt++; } } return (err); } #if 0 ___Broadcaster_Information_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbBit( DHL_PSI_HANDLE sysInfo, DS_BOOL current_next_indicator, DS_BOOL eager, // DS_BOOL b_actual, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err; if ((err = DD_PSI_GetTIDPSIMask (&pref, DVB_TID_broadcaster_information_section, current_next_indicator))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid( sysInfo, DVB_PID_BIT, eager ? eagerTableMode : tableMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, MAX_PSI_SECTIONS, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbBit(DS_U8 **sectionArr, dvb_bit_t **pp_bit) { DHL_RESULT err = DHL_OK; int i, k; int len, lenBroadcaster; int numBroadcaster; int numSections; int index; const DS_U8 *p; dvb_bit_t *p_bit = NULL; int version_number; int first_descriptor_length; DS_BOOL current_next_indicator; DS_BOOL broadcast_view_propriety; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; broadcaster_t *p_broadcaster; if ((sectionArr == NULL) || (pp_bit == NULL)) { return (DHL_FAIL_NULL_POINTER); } if (sectionArr[0] == NULL) { return (DHL_FAIL_NULL_POINTER); } else { numSections = get_last_section_number(sectionArr[0]) + 1; } /* now verify all other sections are present */ for (i=1; i> 4) & 0x1); first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF; lenBroadcaster = len - (7+first_descriptor_length+4); p = §ionArr[i][10+first_descriptor_length]; for ( k=0 ; k < lenBroadcaster ; ) { int broadcaster_id; int broadcaster_descriptor_length; broadcaster_id = p[k+0]; broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF; if ( broadcaster_id ) numBroadcaster++; k += 3+broadcaster_descriptor_length; } } /* create the memChain */ err = memChainCreate(&memId,&memSetup); if (err) { goto ParseExit; } p_bit = (dvb_bit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_bit_t)+sizeof(memId_t))) + 1); checkMemoryError(p_bit); p_bit->num_broadcaster = numBroadcaster; if ( numBroadcaster > 0 ) { p_bit->broadcaster = (broadcaster_t *)memChainAlloc(memId,sizeof(broadcaster_t)*numBroadcaster); checkMemoryError(p_bit->broadcaster); } else { p_bit->broadcaster = (broadcaster_t *)NULL; } /* * Now fill-out all the remaining fields over the all sections. */ index = 0; p_bit->first_descriptors = (DS_U8 *)NULL; p_broadcaster = p_bit->broadcaster; for (i = 0 ; i < numSections ; ++i) { DS_U8 last_section_number; int original_network_id; p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; // lenth + 3 ( p[0] (TID) + p[1] + p[2] ) original_network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF; last_section_number = p[SECTION_NUM_LAST]; if (i == 0) { /* First section */ p_bit->original_network_id = original_network_id; p_bit->version_number = version_number; p_bit->section_number = p[SECTION_NUM]; p_bit->last_section_number = last_section_number; if ( p_bit->first_descriptors == (DS_U8 *)NULL && first_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_bit->first_descriptor_length = first_descriptor_length; p_bit->first_descriptors = (DS_U8 *)memChainAlloc(memId, first_descriptor_length); memcpy(p_bit->first_descriptors, &p[10], first_descriptor_length); /* * Parse SI Parameter Descriptor */ err = GetMpegDescriptor( p_bit->first_descriptors, first_descriptor_length, ARIB_TAG_si_parameter_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_bit->p_si_parameter)); } else { // printf("BIT: cannot find si_parameter descriptor.\n"); p_bit->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL; } } } else { if (p_bit->original_network_id != original_network_id) printf("BIT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_bit->original_network_id, original_network_id); if (p_bit->version_number != version_number) printf("BIT: inconsistent version_number (0x%x, 0x%x)\n", p_bit->version_number, version_number); if (p_bit->first_descriptor_length != first_descriptor_length) printf("BIT: Inconsistent first_descriptor_length (0x%x, 0x%x)\n", p_bit->first_descriptor_length, first_descriptor_length ); if (p_bit->last_section_number != last_section_number ) printf("BIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_bit->last_section_number, last_section_number); } lenBroadcaster = len - first_descriptor_length - 4 - 3 - 7; if ( !p_broadcaster && lenBroadcaster ) { printf("BIT: broadcaster length is not NULL, but broadcaster is NULL.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } p = §ionArr[i][10+first_descriptor_length]; for ( k = 0 ; k < lenBroadcaster ; ) { int broadcaster_id; int broadcaster_descriptor_length; broadcaster_id = p[k+0]; broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF; p_broadcaster->broadcaster_id = broadcaster_id; p_broadcaster->broadcaster_descriptor_length = broadcaster_descriptor_length; if ( broadcaster_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_broadcaster->broadcaster_descriptors = (DS_U8 *)memChainAlloc(memId, broadcaster_descriptor_length); if ( !(p_broadcaster->broadcaster_descriptors) ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseExit; } memcpy(p_broadcaster->broadcaster_descriptors, &p[k+3], broadcaster_descriptor_length); /* * Parse Extended Broadcaster Descriptor */ err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors, broadcaster_descriptor_length, ARIB_TAG_extended_broadcaster_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseExtendedBroadcasterDescriptor(p_desc, memId, &(p_broadcaster->p_ex_broad)); } else { // printf("BIT: cannot find extended_broadcaster descriptor.\n"); p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)NULL; } p_desc = (DS_U8 *)NULL; /* * Parse SI Parameter Descriptor */ err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors, broadcaster_descriptor_length, ARIB_TAG_si_parameter_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_broadcaster->p_si_parameter)); } else { // printf("BIT: cannot find si_parameter descriptor.\n"); p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL; } } else { p_broadcaster->broadcaster_descriptors = (DS_U8 *)NULL; p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)NULL; p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL; } k += 3+broadcaster_descriptor_length; p_broadcaster++; } } err = DHL_OK; *(((memId_t *)p_bit)-1) = memId; printf("p_bit = 0x%x\n",(int)memId); *pp_bit = p_bit; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbBit( DHL_PSI_HANDLE sysInfo, DVB_BIT **pp_bit, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n"); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbBit( sysInfo, _TRUE_, _FALSE_, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { #ifdef PSI_DGB printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut); #endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("DHL_PSI_GetPAT : procData.err = %d \n", err ); goto done2; } err = DHL_PSI_ParseDvbBit(procData.desc->sectPtr, pp_bit); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbBit( DVB_BIT *p_bit ) { DHL_RESULT err = DHL_OK; broadcaster_t *p_broadcaster; int i, j, k, l, m, n, o, p; if (!p_bit) return (err); printf("BIT (Broadcaster Information Table)\n"); printf(" original_network_id: 0x%04X\n", p_bit->original_network_id); printf(" version_number: %d\n", p_bit->version_number); printf(" section_number: %d\n", p_bit->section_number); printf(" last_section_number: %d\n", p_bit->last_section_number); printf(" first_descriptor_length: %d\n", p_bit->first_descriptor_length); printf(" first_descriptors\n"); DHL_PSI_Dump(p_bit->first_descriptors, p_bit->first_descriptor_length); if ( p_bit->p_si_parameter ) { arib_si_parameter_descriptor_t *p_si_parameter; arib_table_description_t *table_description; p_si_parameter = p_bit->p_si_parameter; table_description = p_si_parameter->table_description; printf("SI parameter descriptor\n"); printf(" parameter_version: 0x%02X\n", p_si_parameter->parameter_version); printf(" update_time: 0x%04X\n", p_si_parameter->update_time); if ( p_si_parameter->numTable > 0 ) { for ( i=0 ; i < p_si_parameter->numTable ; i++ ) { printf(" table_id: 0x%02X\n", table_description->table_id); printf(" table_description_length: %d\n", table_description->table_description_length); for ( j=0 ; j < table_description->table_description_length ; j++ ) { printf(" table_description_byte: 0x%02X\n", table_description->table_description_byte[j]); } table_description++; } } } p_broadcaster = p_bit->broadcaster; for ( i=0 ; i < p_bit->num_broadcaster ; i++ ) { printf(" broadcaster %d\n", p_bit->num_broadcaster); printf(" broadcaster_id: 0x%02X\n", p_broadcaster->broadcaster_id); if ( p_broadcaster->broadcaster_descriptor_length ) { for ( j=0 ; j < p_broadcaster->broadcaster_descriptor_length ; ) { if ( p_broadcaster->p_ex_broad ) { arib_extended_broadcaster_descriptor_t *p_ex; p_ex = p_broadcaster->p_ex_broad; printf("Extend Broadcaster descriptor\n"); printf(" broadcaster_type: 0x%02X\n", p_ex->broadcaster_type); j += 3; if ( p_ex->broadcaster_type == 0x1 ) { printf(" terrestrial_broadcaster_id: 0x%04X\n", p_ex->terrestrial_broadcaster_id); if ( p_ex->num_affiliation_id > 0 ) { for ( k=0 ; k < p_ex->num_affiliation_id ; k++ ) { printf(" affiliation_id: 0x%02X\n", p_ex->affiliation_id[k]); // p_ex->affiliation_id++; } } if ( p_ex->num_broadcaster_id ) { for ( l=0 ; l < p_ex->num_broadcaster_id ; l++ ) { printf(" original_network_id: 0x%04X\n", p_ex->origin_network_id[l]); printf(" broadcaster_id: 0x%02X\n", p_ex->broadcaster_id[l]); // p_ex->origin_network_id++; // p_ex->broadcaster_id++; } } j += 3+(p_ex->num_affiliation_id)+(p_ex->num_broadcaster_id*3); } else if ( p_ex->broadcaster_type == 0x2 ) { printf(" terrestrial_sound_broadcaster_id: 0x%04X\n", p_ex->terrestrial_broadcaster_id); if ( p_ex->num_affiliation_id ) { for ( m=0 ; m < p_ex->num_affiliation_id ; m++ ) { printf(" sound_broadcaster_affiliation_id: 0x%02X\n", p_ex->affiliation_id[m]); // p_ex->affiliation_id++; } } if ( p_ex->num_broadcaster_id ) { for ( n=0 ; n < p_ex->num_broadcaster_id ; n++ ) { printf(" original_network_id: 0x%04X\n", p_ex->origin_network_id[n]); printf(" broadcaster_id: 0x%02X\n", p_ex->broadcaster_id[n]); // p_ex->origin_network_id++; // p_ex->broadcaster_id++; } } j += 3+(p_ex->num_affiliation_id)+(p_ex->num_broadcaster_id*3); } } if ( p_broadcaster->p_si_parameter ) { arib_si_parameter_descriptor_t *broad_si_parameter; arib_table_description_t *broad_table_description; broad_si_parameter = p_broadcaster->p_si_parameter; broad_table_description = broad_si_parameter->table_description; printf("SI parameter descriptor\n"); printf(" parameter_version: 0x%02X\n", broad_si_parameter->parameter_version); printf(" update_time: 0x%04X\n", broad_si_parameter->update_time); j += 5; if ( broad_si_parameter->numTable > 0 ) { for ( o=0 ; o < broad_si_parameter->numTable ; o++ ) { printf(" table_id: 0x%02X\n", broad_table_description->table_id); printf(" table_description_length: %d\n", broad_table_description->table_description_length); for ( p=0 ; p < broad_table_description->table_description_length ; p++ ) { printf(" table_description_byte: 0x%02X\n", broad_table_description->table_description_byte[p]); } j += 2+(broad_table_description->table_description_length); broad_table_description++; } } } } } printf(" broadcaster_descriptor_length: %d\n", p_broadcaster->broadcaster_descriptor_length); DHL_PSI_Dump(p_broadcaster->broadcaster_descriptors, p_broadcaster->broadcaster_descriptor_length); p_broadcaster++; } return (err); } #if 0 ___Bouquet_Association_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbBat( DHL_PSI_HANDLE sysInfo, DS_BOOL current_next_indicator, DS_BOOL eager, DS_BOOL b_actual, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err; if ((err = DD_PSI_GetTIDPSIMask (&pref, DVB_TID_bouquet_association_section, current_next_indicator))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid(sysInfo, DVB_PID_BAT, eager ? eagerTableMode : tableMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, MAX_PSI_SECTIONS, eventProc, userParam, returnPSICtl))) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbBat( DS_U8 **sectionArr, DS_BOOL b_actual, dvb_bat_t **pp_bat ) { DHL_RESULT err = DHL_OK; int i, k; int numStreams; int numSections; int index; const DS_U8 *p; int len; dvb_bat_t *p_bat = NULL; int version_number; int bouquet_descriptor_length; int transport_loop_length; DS_BOOL current_next_indicator; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; transport_stream_t *p_ts; if (sectionArr == NULL || (pp_bat == NULL)) { return (DHL_FAIL_NULL_POINTER); } if (sectionArr[0] == NULL) { return (DHL_FAIL_NULL_POINTER); } else { numSections = get_last_section_number(sectionArr[0]) + 1; } /* now verify all other sections are present */ for (i=1; inum_transport_stream = numStreams; if ( numStreams ) { p_bat->transport_streams = (transport_stream_t *)memChainAlloc(memId,sizeof(transport_stream_t)*numStreams); checkMemoryError(p_bat->transport_streams); } else { p_bat->transport_streams = (transport_stream_t *)NULL; } /* * Now fill-out all the remaining fields over the all sections. */ index = 0; p_bat->bouquet_descriptors = (DS_U8 *)NULL; p_ts = p_bat->transport_streams; for (i = 0; i < numSections; ++i) { DS_U8 last_section_number; int bouquet_id; p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; bouquet_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; bouquet_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF; last_section_number = p[SECTION_NUM_LAST]; if (i == 0) { /* First section */ p_bat->bouquet_id = bouquet_id; p_bat->version_number = version_number; p_bat->section_number = p[SECTION_NUM]; p_bat->last_section_number = last_section_number; if ( p_bat->bouquet_descriptors == (DS_U8 *)NULL && bouquet_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_bat->bouquet_descriptor_length = bouquet_descriptor_length; p_bat->bouquet_descriptors = (DS_U8 *)memChainAlloc(memId, bouquet_descriptor_length); memcpy( p_bat->bouquet_descriptors, &p[10], bouquet_descriptor_length); err=GetMpegDescriptor( p_bat->bouquet_descriptors, bouquet_descriptor_length, DVB_TAG_bouquet_name_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseBouquetNameDescriptor( p_desc, memId, &(p_bat->p_bouquet_name), &(p_bat->bouquet_name_length) ); } else { p_bat->p_bouquet_name = (DS_U8 *)NULL; p_bat->bouquet_name_length = 0; } } } else { if (p_bat->bouquet_id != bouquet_id) printf("BAT: Inconsistent bouquet_id (0x%x, 0x%x)\n", p_bat->bouquet_id, bouquet_id); if (p_bat->version_number != version_number) printf("BAT: inconsistent version_number (0x%x, 0x%x)\n", p_bat->version_number, version_number); if (p_bat->bouquet_descriptor_length != bouquet_descriptor_length) printf("BAT: Inconsistent bouquet_descriptor_length (0x%x, 0x%x)\n", p_bat->bouquet_descriptor_length, bouquet_descriptor_length ); if (p_bat->last_section_number != last_section_number ) printf("BAT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_bat->last_section_number, last_section_number); } transport_loop_length = ((p[10+bouquet_descriptor_length]<<8) + p[11+bouquet_descriptor_length]) & 0xFFF; if (!p_ts && transport_loop_length) { printf("BAT: transport_loop_length is not NULL, but transport_streams is NULL.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } p = §ionArr[i][12+bouquet_descriptor_length]; for(k=0; ktransport_stream_id = transport_stream_id; p_ts->original_network_id = original_network_id; p_ts->transport_descriptor_length = transport_descriptor_length; if ( transport_descriptor_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_ts->transport_descriptors = (DS_U8 *)memChainAlloc( memId, transport_descriptor_length ); if ( !(p_ts->transport_descriptors) ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseExit; } memcpy( p_ts->transport_descriptors, &p[k+6], transport_descriptor_length ); /* * Parse Service List descriptor */ err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length, DVB_TAG_service_list_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc ) { DHL_PSI_ParseServiceListDescriptor( p_desc, memId, &(p_ts->p_service_list) ); } else { p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL; } /* * Parse TS information descriptor. */ p_desc = (DS_U8 *)NULL; err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length, ARIB_TAG_ts_information_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc ) { DHL_PSI_ParseTSInformationDescriptor( p_desc, memId, &(p_ts->p_ts_info) ); } else { p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL; } } else { p_ts->transport_descriptors = (DS_U8 *)NULL; p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL; p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL; } k += 6+transport_descriptor_length; p_ts++; } } err = DHL_OK; *(((memId_t *)p_bat)-1) = memId; *pp_bat = p_bat; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbBat( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_BAT **pp_bat, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n"); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbBat(sysInfo, _TRUE_ /* current */, _FALSE_ /* not eager */, b_actual, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { #ifdef PSI_DGB printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut); #endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("DHL_PSI_GetPAT : procData.err = %d \n", err ); goto done2; } err = DHL_PSI_ParseDvbBat(procData.desc->sectPtr, b_actual, pp_bat); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbBat( DVB_BAT *p_bat ) { DHL_RESULT err = DHL_OK; transport_stream_t *p_ts; int i; if (!p_bat) return (err); printf("BAT (Bouquet Association Table)\n"); printf(" bouquet_id: 0x%04X\n", p_bat->bouquet_id); printf(" version_number: %d\n", p_bat->version_number); printf(" section_number: %d\n", p_bat->section_number); printf(" last_section_number: %d\n", p_bat->last_section_number); if ( p_bat->p_bouquet_name ) printf(" bouquet_name: %s\n", p_bat->p_bouquet_name); else printf(" bouquet_name: (not found)\n"); printf(" bouquet_descriptor_length: %d\n", p_bat->bouquet_descriptor_length ); printf(" bouquet_descriptors\n"); DHL_PSI_Dump(p_bat->bouquet_descriptors, p_bat->bouquet_descriptor_length); printf(" num_transport_stream: %d\n", p_bat->num_transport_stream); p_ts = p_bat->transport_streams; for (i=0; inum_transport_stream; i++) { printf(" transport_stream %d\n", i); printf(" transport_stream_id: 0x%04X\n", p_ts->transport_stream_id); printf(" original_network_id: 0x%04X\n", p_ts->original_network_id); if ( p_ts->p_service_list ) { int n; dvb_service_t *p_service = p_ts->p_service_list->p_service; printf(" service_list (%d)\n", p_ts->p_service_list->numServices); for(n=0; np_service_list->numServices; n++) { printf(" service #%d: service_id 0x%04X, service_type 0x%02X\n", n, p_service->service_id, p_service->service_type); p_service++; } } if ( p_ts->p_ts_info ) { arib_ts_information_descriptor_t *p_ts_info = p_ts->p_ts_info; printf(" TS_info.remote_control_key_id = %d\n", p_ts_info->remote_control_key_id); if ( p_ts_info->ts_name_length && p_ts_info->ts_name ) { int n; #ifndef CONV_TO_ASCII #define CONV_TO_ASCII(x) ( ((x) >= ' ' && (x) <= '~') ? (x) : '.' ) #endif printf(" TS_info.ts_name = "); for (n=0; nts_name_length; n++) printf("%c", CONV_TO_ASCII(p_ts_info->ts_name[n])); printf("\n"); } if ( p_ts_info->transmission_type_count ) { int n; arib_transmission_type_t *p_tx_type = p_ts_info->transmission_type; for (n=0; ntransmission_type_count; n++) { printf(" TS_info.tx_type[%d].type: 0x%02X (%s-%s) See ARIB TR-B14 Table 3\n", n, p_tx_type->transmission_type_info, ((p_tx_type->transmission_type_info>>6)&3) == 0 ? "Type A" : ((p_tx_type->transmission_type_info>>6)&3) == 1 ? "Type B" : ((p_tx_type->transmission_type_info>>6)&3) == 2 ? "Type C" :"Reserved", ((p_tx_type->transmission_type_info>>4)&3) == 0 ? "64QAM" : ((p_tx_type->transmission_type_info>>4)&3) == 1 ? "16QAM" : ((p_tx_type->transmission_type_info>>4)&3) == 2 ? "QPSK" : "Reserved"); if ( p_tx_type->number_of_service && p_tx_type->service_id ) { int k; printf(" TS_info.tx_type[%d].service_id list\n", n); for (k=0; knumber_of_service; k++) { printf(" 0x%04X\n", p_tx_type->service_id[k]); } } p_tx_type++; } } } printf(" transport_descriptor_length: 0x%04X\n", p_ts->transport_descriptor_length); DHL_PSI_Dump(p_ts->transport_descriptors, p_ts->transport_descriptor_length); p_ts++; } return (err); } #if 0 ___Common_Data_Table___() #endif DHL_RESULT DHL_PSI_MonitorDvbCdt( DHL_PSI_HANDLE sysInfo, DS_BOOL current_next_indicator, DS_BOOL eager, // DS_BOOL b_actual, PSIUpdateMode updateMode, PSIEventProc_f eventProc, DS_U32 userParam, DHL_TBL_HANDLE *returnPSICtl) { PSIMask_t *pref; DHL_RESULT err; if ((err = DD_PSI_GetTIDPSIMask ( &pref, DVB_TID_common_data_section, current_next_indicator))) { printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err); return(err); } if ((err = DD_PSI_MonitorPSIPid( sysInfo, DVB_PID_CDT, eager ? eagerTableMode : tableMode, updateMode, pref, /*MAX_PSI_MPEG_DATA*/1024, MAX_PSI_SECTIONS, eventProc, userParam, returnPSICtl)) ) { printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err); PSI_Free(pref); } return(err); } DHL_RESULT DHL_PSI_ParseDvbCdt(DS_U8 **sectionArr, dvb_cdt_t **pp_cdt) { DHL_RESULT err = DHL_OK; int i, k; DS_U16 *numDatas; int lenDatas; int numSections; int index; const DS_U8 *p; int len, slen; dvb_cdt_t *p_cdt = NULL; int version_number; int descriptors_loop_length; DS_BOOL current_next_indicator; memId_t memId = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; data_module_byte_t *p_data; if (sectionArr == NULL || (pp_cdt == NULL)) { return (DHL_FAIL_NULL_POINTER); } if (sectionArr[0] == NULL) { return (DHL_FAIL_NULL_POINTER); } else { numSections = get_last_section_number(sectionArr[0]) + 1; } /* now verify all other sections are present */ for (i=1; idescriptors = (DS_U8 *)NULL; for (i = 0; i < numSections; ++i) { DS_U8 last_section_number; int download_data_id; int original_network_id; int data_type; p = §ionArr[i][0]; len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; download_data_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]); version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT; current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0; original_network_id = ((p[8]<<8) + p[9]); data_type = p[10]; descriptors_loop_length = ((p[11]<<8) + p[12]) & 0xFFF; last_section_number = p[SECTION_NUM_LAST]; if ( numDatas[i] ) { p_cdt[i].num_Datas = numDatas[i]; p_cdt[i].data_module_byte = (data_module_byte_t *)memChainAlloc(memId,sizeof(data_module_byte_t)*numDatas[i]); } p_cdt[i].download_data_id = download_data_id; p_cdt[i].version_number = version_number; p_cdt[i].last_section_number = last_section_number; p_cdt[i].original_network_id = original_network_id; p_cdt[i].data_type = data_type; #if 0 // // Junku/091211 // Logo transmission descriptor´Â CDT°¡ ¾Æ´Ñ SDT¿¡ Á¸ÀçÇÏ´Â descriptor. // if ( p_cdt[i].descriptors == (DS_U8 *)NULL && descriptors_loop_length ) { DS_U8 *p_desc = (DS_U8 *)NULL; p_cdt[i].descriptors_loop_length = descriptors_loop_length; p_cdt[i].descriptors = (DS_U8 *)memChainAlloc(memId, descriptors_loop_length); memcpy( p_cdt[i].descriptors, &p[13], descriptors_loop_length); err=GetMpegDescriptor( p_cdt[i].descriptors, descriptors_loop_length, ARIB_TAG_logo_transmission_descriptor, 0, /* only find first one. */ &p_desc ); if ( p_desc && !err ) { DHL_PSI_ParseLogoTransmissionDescriptor( p_desc, memId, &(p_cdt[i].logo_tx_desc)); } else { p_cdt[i].logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL; } } #endif if ( i > 0 ) { if (p_cdt[i].download_data_id != download_data_id) printf("CDT: Inconsistent download_data_id (0x%x, 0x%x)\n", p_cdt->download_data_id, download_data_id); if (p_cdt[i].version_number != version_number) printf("CDT: inconsistent version_number (0x%x, 0x%x)\n", p_cdt->version_number, version_number); if (p_cdt[i].original_network_id != original_network_id) printf("CDT: Inconsistent network_descriptor_length (0x%x, 0x%x)\n", p_cdt->original_network_id, original_network_id); if (p_cdt[i].data_type != data_type) printf("CDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_cdt->data_type, data_type); if (p_cdt[i].last_section_number != last_section_number) printf("CDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_cdt->last_section_number, last_section_number); } lenDatas = len - (10 + descriptors_loop_length + 4 + 3); p = §ionArr[i][13+descriptors_loop_length]; if ( !p_data && lenDatas ) { printf("CDT: data_module_byte length is not NULL, but data_module_byte is NULL.\n"); err = DHL_FAIL_INVALID_TABLEID; goto ParseExit; } p_data = p_cdt[i].data_module_byte; p = §ionArr[i][13+descriptors_loop_length]; for( k=0 ; k < lenDatas ; ) { int logo_type; int logo_id; int logo_version; int data_size; logo_type = p[k+0]; logo_id = ((p[k+1]<<8) + p[k+2]) & 0x1FF; logo_version = ((p[k+3]<<8) + p[k+4]) & 0xFFF; data_size = (p[k+5]<<8) + p[k+6]; p_data->logo_type = logo_type; p_data->logo_id = logo_id; p_data->logo_version = logo_version; p_data->data_size = data_size; if ( p_data->data_size ) { p_data->data_byte = (DS_U8 *)memChainAlloc(memId, data_size); if ( !(p_data->data_byte) ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseExit; } memcpy(p_data->data_byte, &p[k+7], data_size); } else { p_data->data_byte = (DS_U8 *)NULL; } k += 7+data_size; p_data++; } } err = DHL_OK; *(((memId_t *)p_cdt)-1) = memId; *pp_cdt = p_cdt; memId = 0; /* Don't delete below */ ParseExit: if (memId) { /* delete the patSection memory */ memChainDestroy(memId); } return(err); } DHL_RESULT DHL_PSI_GetDvbCdt( DHL_PSI_HANDLE sysInfo, DVB_CDT **pp_cdt, int timeOut ) { DHL_RESULT err = DHL_OK; void *returnPSICtl = NULL; PSIEventProcData_t procData; int res = 0; procData.desc = NULL; procData.err = (DS_U32)DHL_OK; /*creae a no-name , non-signaled event.*/ //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ )); procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 ); if (procData.hEvent == (OS_SEMAPHORE_ID)0) { printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n"); return DHL_FAIL_OUT_OF_RESOURCE; } if ((err = DHL_PSI_MonitorDvbCdt(sysInfo, _TRUE_ /* current */, _FALSE_ /* not eager */, // b_actual, psiOneShot, hal_cbPSISyncEventProc, (DS_U32)&procData, &returnPSICtl))) { goto done; } //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut ); res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut ); if (res != 0) { #ifdef PSI_DGB printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut); #endif #ifdef PSI_DBG printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n"); #endif err = DHL_FAIL_TIMEOUT; goto done2; } if ((err = (DHL_RESULT)(procData.err))) { printf("DHL_PSI_GetPAT : procData.err = %d \n", err ); goto done2; } err = DHL_PSI_ParseDvbCdt(procData.desc->sectPtr, pp_cdt); done2: DHL_PSI_CancelMonitor(returnPSICtl); if( procData.desc ) DD_PSI_FreePSIData(procData.desc); done: if(procData.hEvent) { OS_DeleteSemaphore(procData.hEvent); } return(err); } DHL_RESULT DHL_PSI_PrintDvbCdt( DVB_CDT *p_cdt ) { DHL_RESULT err = DHL_OK; data_module_byte_t *p_data; int numSections; int i, j, k; if (!p_cdt) return (err); numSections = p_cdt->last_section_number + 1; printf("CDT (Common Data Table)\n"); for ( i=0 ; i < numSections ; i++ ) { printf(" download_data_id: 0x%04X\n", p_cdt[i].download_data_id); printf(" version_number: %d\n", p_cdt[i].version_number); printf(" section_number: %d\n", i); printf(" last_section_number: %d\n", p_cdt[i].last_section_number); printf(" original_network_id: 0x%04X\n", p_cdt[i].original_network_id); printf(" data_type: 0x%02X\n", p_cdt[i].data_type); printf(" descriptors_loop_length: %d\n", p_cdt[i].descriptors_loop_length ); if ( p_cdt[i].descriptors_loop_length ) { printf(" descriptors\n\n"); DHL_PSI_Dump(p_cdt[i].descriptors, p_cdt[i].descriptors_loop_length); } else printf("CDT: descriptors is NULL.\n\n"); #if 0 if ( p_cdt[i].logo_tx_desc ) { arib_logo_transmission_descriptor_t *p_logo; p_logo = p_cdt[i].logo_tx_desc; printf(" logo_transmission_descriptor\n"); if ( p_logo->logo_transmission_type == 0x1 ) { printf(" logo_id: 0x%04X\n", p_logo->logo_id); printf(" logo_version: 0x%04X\n", p_logo->logo_version); printf(" download_data_id: 0x%04X\n", p_logo->download_data_id); } else if ( p_logo->logo_transmission_type == 0x2 ) { printf(" logo_id: 0x%04X\n", p_logo->logo_id); } else if ( p_logo->logo_transmission_type == 0x3 ) { printf(" logo_char: %s\n", p_logo->logo_char); } } #endif printf(" num_data_module_byte: %d\n", p_cdt[i].num_Datas); p_data = p_cdt[i].data_module_byte; for ( j=0 ; j < p_cdt->num_Datas ; j++ ) { printf(" logo_type: 0x%02X\n", p_data->logo_type); printf(" logo_id: 0x%02X\n", p_data->logo_id); printf(" logo_version: 0x%04X\n", p_data->logo_version); printf(" data_size: %d\n", p_data->data_size); for ( k=0 ; k < p_data->data_size ; k++ ) { printf(" data_byte[%d]: 0x%02X\n", k, p_data->data_byte[k]); // p_data->data_byte++; } p_data++; } printf("\n"); } return (err); } #if 0 ___Descriptors___() #endif static void DHL_PSI_ParseEventGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_event_group_descriptor_t **pp_event_grp) { DS_U8 *p = p_desc; arib_event_group_descriptor_t *p_event_grp; arib_event_t *p_event; arib_other_event_t *p_other_event; int i, len, off; // int numEvent; if (!p_desc || !pp_event_grp || !memId) return; len = p_desc[1]; if (len<5) return; p_event_grp = (arib_event_group_descriptor_t *)memChainAlloc(memId, sizeof(arib_event_group_descriptor_t)); p_event_grp->group_type = (p[2] >> 4) & 0x0F; p_event_grp->numEvents = p[2]&0x0F; off = 3 /*3=descriptor_tag+length+group_type + event_cnt*/; if ( p_event_grp->numEvents ) { p_event = p_event_grp->p_event = (arib_event_t *)memChainAlloc(memId, sizeof(arib_event_t) * p_event_grp->numEvents); for (i=0; inumEvents && off <= (len+2); i++) { p_event->service_id = (p[0+off]<<8)+p[1+off]; p_event->event_id = (p[2+off]<<8)+p[3+off]; off += 4; p_event++; } } p_event_grp->numOtherNetworkEvents = 0; if ( p_event_grp->group_type == 4 || p_event_grp->group_type == 5 ) { p_event_grp->numOtherNetworkEvents = (len-off-2)/8; if (p_event_grp->numOtherNetworkEvents) { p_other_event = p_event_grp->p_other_event = (arib_other_event_t *)memChainAlloc(memId, sizeof(arib_other_event_t) * p_event_grp->numOtherNetworkEvents); for (i=0; inumOtherNetworkEvents; i++) { p_other_event->original_network_id = (p[0+off]<<8)+p[1+off]; p_other_event->transport_stream_id = (p[2+off]<<8)+p[3+off]; p_other_event->service_id = (p[4+off]<<8)+p[5+off]; p_other_event->event_id = (p[6+off]<<8)+p[7+off]; off += 8; p_other_event++; } } } *pp_event_grp = p_event_grp; } void DHL_PSI_ParseLogicalChannelDescriptor(DS_U8 *p_desc, memId_t memId, logical_channel_descriptor_t **pp_lcd) { DS_U8 *p; int i, len; int numServices; logical_channel_descriptor_t *p_lcd; logical_channel_t *p_lc; if (!p_desc || !pp_lcd || !memId) return; len = p_desc[1]; if (len<4) return; p_lcd = (logical_channel_descriptor_t *)memChainAlloc(memId, sizeof(logical_channel_descriptor_t)+1); numServices = (len / 4); p_lc = (logical_channel_t *)memChainAlloc(memId, sizeof(logical_channel_t)*numServices); p = &p_desc[2]; p_lcd->numServices = numServices; p_lcd->p_lc = p_lc; for (i=0; iservice_id = (p[0]<<8)+p[1]; p_lc->visible = (p[2] & 0x80); p_lc->logical_channel_number = ((p[2]<<8)+p[3]) & 0x3FF; p += 4; p_lc++; } *pp_lcd = p_lcd; return; } void DHL_PSI_ParseNetworkNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_network_name, DS_U8 *p_length) { int len; DS_U8 *p_network_name; if (!p_desc || !p_network_name || !p_length) return; len = p_desc[1]; p_network_name = (DS_U8 *)memChainAlloc( memId, len+1 ); memcpy(p_network_name, &p_desc[2], len ); p_network_name[len] = '\0'; *pp_network_name = p_network_name; *p_length = len; return; } void DHL_PSI_ParseServiceListDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_list_descriptor_t **pp_service_list) { int i, len; int numServices; DS_U8 *p; dvb_service_list_descriptor_t *p_sld = (dvb_service_list_descriptor_t *)NULL; dvb_service_t *p_service = (dvb_service_t *)NULL; len = p_desc[1]; p = &p_desc[2]; numServices = len / 3; if (len % 3) printf("%s: descriptor length is invalid (%d)\n", __func__, len); p_sld = (dvb_service_list_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_list_descriptor_t)); p_service = p_sld->p_service = (dvb_service_t *)memChainAlloc(memId, sizeof(dvb_service_t)*numServices); if ( !p_sld ) return; if ( !(p_sld->p_service) ) return; p_sld->numServices = numServices; for (i=0; iservice_id = (p[0]<<8)+p[1]; p_service->service_type = p[2]; p += 3; p_service++; } *pp_service_list = p_sld; return; } void DHL_PSI_ParseServiceDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_descriptor_t **pp_service_desc) { int provider_name_length; int service_name_length; dvb_service_descriptor_t *p_service = (dvb_service_descriptor_t *)NULL; if ( !p_desc || !pp_service_desc ) return; p_service = (dvb_service_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_descriptor_t)); if ( !p_service ) return; p_service->service_type = p_desc[2]; provider_name_length = p_service->i_provider_name_length = p_desc[3]; if (provider_name_length) { p_service->p_provider_name = (DS_U8 *)memChainAlloc(memId, provider_name_length+1); memcpy( p_service->p_provider_name, &p_desc[4], provider_name_length ); p_service->p_provider_name[provider_name_length] = '\0'; } else { p_service->p_provider_name = (DS_U8 *)NULL; } service_name_length = p_service->i_service_name_length = p_desc[4+provider_name_length]; if (service_name_length) { p_service->p_service_name = (DS_U8 *)memChainAlloc(memId, service_name_length+1); memcpy( p_service->p_service_name, &p_desc[5+provider_name_length], service_name_length ); p_service->p_service_name[service_name_length] = '\0'; } else { p_service->p_service_name = (DS_U8 *)NULL; } *pp_service_desc = p_service; return; } void DHL_PSI_ParseShortEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_short_event_descriptor_t **pp_short_event) { dvb_short_event_descriptor_t *p_short_event; int event_name_length, text_length; DS_U32 ISO_639_language_code; if (!p_desc || !pp_short_event) return; if (p_desc[0] != DVB_TAG_short_event_descriptor || p_desc[1] < 5) { printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]); return; } ISO_639_language_code = (p_desc[2]<<16) + (p_desc[3]<<8) + p_desc[4]; if ( prefLangCode && (prefLangCode != ISO_639_language_code) ) return; p_short_event = (dvb_short_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t)); if ( !p_short_event ) return; p_short_event->ISO_639_language_code = ISO_639_language_code; p_short_event->event_name_length = event_name_length = p_desc[5]; p_short_event->p_event_name = (DS_U8 *)NULL; if (event_name_length) { p_short_event->p_event_name = (DS_U8 *)memChainAlloc(memId, event_name_length+1); SysASSERT(p_short_event->p_event_name); memcpy( p_short_event->p_event_name, &p_desc[6], event_name_length ); p_short_event->p_event_name[event_name_length] = '\0'; } p_short_event->text_length = text_length = p_desc[6+event_name_length]; p_short_event->p_text = (DS_U8 *)NULL; if (text_length) { p_short_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length+1); SysASSERT(p_short_event->p_event_name); memcpy(p_short_event->p_text, &p_desc[7+event_name_length], text_length); p_short_event->p_text[text_length] = '\0'; } *pp_short_event = p_short_event; return; } void DHL_PSI_ParseExtendedEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_extended_event_descriptor_t **pp_extended_event) { dvb_extended_event_descriptor_t *p_extended_event; DS_U32 ISO_639_language_code; int length_of_items, text_length; int i, numItems; DS_U8 *p = (DS_U8 *)NULL; if (!p_desc || !pp_extended_event) return; if (p_desc[0] != DVB_TAG_extended_event_descriptor || p_desc[1] < 6) { printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]); return; } ISO_639_language_code = (p_desc[3]<<16) + (p_desc[4]<<8) + (p_desc[5]); if ( prefLangCode && (prefLangCode != p_extended_event->ISO_639_language_code) ) return; p_extended_event = (dvb_extended_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t)); if (!p_extended_event) return; p_extended_event->descriptor_number = (p_desc[2]>>4) & 0x0F; p_extended_event->last_descriptor_number = (p_desc[2]) & 0x0F; p_extended_event->ISO_639_language_code = ISO_639_language_code; length_of_items = p_desc[6]; p_extended_event->numItems = 0; p_extended_event->items = (dvb_ext_event_item_t *)NULL; if (length_of_items) { int item_description_length; int item_length; dvb_ext_event_item_t *p_item; /* * Calculate number of items. */ numItems = 0; p = &p_desc[7]; for(i=0; inumItems = numItems; p_item = p_extended_event->items = (dvb_ext_event_item_t *)memChainAlloc(memId, sizeof(dvb_ext_event_item_t)*numItems); for(i=0; iitem_description_length = item_description_length; if (item_description_length) { p_item->p_item_description = (DS_U8 *)memChainAlloc(memId, item_description_length+1); memcpy(p_item->p_item_description, &p[i+1], item_description_length); p_item->p_item_description[item_description_length] = '\0'; } p_item->item_length = item_length; if (item_length) { p_item->p_item_char = (DS_U8 *)memChainAlloc(memId, item_length+1); memcpy(p_item->p_item_char, &p[i+2+item_description_length], item_length); p_item->p_item_char[item_length] = '\0'; } i += item_description_length+item_length+2; p_item++; } } text_length = p_desc[7+length_of_items]; p_extended_event->text_length = text_length; p_extended_event->p_text = (DS_U8 *)NULL; if (text_length) { p_extended_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length); memcpy(p_extended_event->p_text, &p_desc[8+length_of_items], text_length); } *pp_extended_event = p_extended_event; return; } void DHL_PSI_ParseParentalRatingDescriptor (DS_U8* p, dvb_parental_rating_descriptor_t **pp_desc) { memId_t memId; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; DS_U8 length; DHL_RESULT err; dvb_parental_rating_descriptor_t *p_desc; dvb_parental_rating_entry_t *p_entry; int i, numEntries; DS_U8 *p_data; length = p[1]; /* create the memChain */ err = memChainCreate(&memId, &memSetup); if (err != DHL_OK) goto ParseDescriptorExit; /* create the descriptor memory */ p_desc = (dvb_parental_rating_descriptor_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_parental_rating_descriptor_t)+sizeof(memId_t))) + 1); if (p_desc == (dvb_parental_rating_descriptor_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } numEntries = length>>2; if (numEntries<=0) goto ParseDescriptorExit; p_entry = (dvb_parental_rating_entry_t *)memChainAlloc(memId, sizeof(dvb_parental_rating_entry_t)*numEntries); if (p_entry == (dvb_parental_rating_entry_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_desc->i_num_ratings = numEntries; p_desc->p_ratings = p_entry; p_data = &p[2]; for (i=0; icountry_code = (p_data[0]<<16) + (p_data[1]<<8) + (p_data[2]<<0); p_entry->rating_value = p_data[3]; p_data += 4; p_entry++; } *(((memId_t *)(p_desc))-1) = memId; memId = NULL; /* so memChain not deleted */ *pp_desc = p_desc; ParseDescriptorExit: if (memId) { /* delete the descriptor memory */ memChainDestroy(memId); } if (err) { printf("ERROR: %s returns %d!\n", __func__, err); } } static void DHL_PSI_ParseParentalRatingDescriptorEx (DS_U8* p, memId_t memId, dvb_parental_rating_descriptor_t **pp_desc) { //memId_t memId; //memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; DS_U8 length; DHL_RESULT err=DHL_OK; dvb_parental_rating_descriptor_t *p_desc; dvb_parental_rating_entry_t *p_entry; int i, numEntries; DS_U8 *p_data; length = p[1]; #if 0 /* create the memChain */ err = memChainCreate(&memId, &memSetup); if (err != DHL_OK) goto ParseDescriptorExit; #endif /* create the descriptor memory */ p_desc = (dvb_parental_rating_descriptor_t *)(memChainAlloc(memId,sizeof(dvb_parental_rating_descriptor_t))); if (p_desc == (dvb_parental_rating_descriptor_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } numEntries = length>>2; if (numEntries<=0) goto ParseDescriptorExit; p_entry = (dvb_parental_rating_entry_t *)memChainAlloc(memId, sizeof(dvb_parental_rating_entry_t)*numEntries); if (p_entry == (dvb_parental_rating_entry_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_desc->i_num_ratings = numEntries; p_desc->p_ratings = p_entry; p_data = &p[2]; for (i=0; icountry_code = (p_data[0]<<16) + (p_data[1]<<8) + (p_data[2]<<0); p_entry->rating_value = p_data[3]; p_data += 4; p_entry++; } *(((memId_t *)(p_desc))-1) = memId; memId = NULL; /* so memChain not deleted */ *pp_desc = p_desc; ParseDescriptorExit: if (memId) { /* delete the descriptor memory */ memChainDestroy(memId); } if (err) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseLocalTimeOffsetDescriptor( DS_U8 *p, int numItems, dvb_local_time_t *p_desc ) { int len, idx; int num_lto; dvb_local_time_t *p_lt; DS_U8 *puc; if ( !p || !p_desc ) return; len = p[1]; num_lto = len / 13; p_lt = p_desc; for (idx=0; idxcountry_code = (puc[2]<<16)+(puc[1]<<8)+puc[0]; p_lt->country_region_id = puc[3]>>2; p_lt->local_time_offset_polarity = puc[3] & 1; p_lt->local_time_offset = (puc[4]<<8)+puc[5]; p_lt->time_of_change_date = (puc[6]<<8)+puc[7]; p_lt->time_of_change_time = (puc[8]<<16)+(puc[9]<<8)+puc[10]; p_lt->next_time_offset = (puc[11]<<8)+puc[12]; p_lt++; } } static int DHL_PSI_ParseTSInformationDescriptor(DS_U8* p, memId_t memId, arib_ts_information_descriptor_t **pp_ts_info) { int len, i, j, off; int err = DHL_OK; arib_ts_information_descriptor_t *p_ts_info; len = p[1]; if (len < 2) return DHL_FAIL_INVALID_SIZE; p_ts_info = (arib_ts_information_descriptor_t *)memChainAlloc(memId,sizeof(arib_ts_information_descriptor_t)); if (p_ts_info == (arib_ts_information_descriptor_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_ts_info->remote_control_key_id = p[2]; p_ts_info->ts_name_length = (p[3]>>2) & 0x3F; p_ts_info->transmission_type_count = p[3]&0x03; p_ts_info->ts_name = (DS_U8 *)NULL; if (p_ts_info->ts_name_length) { p_ts_info->ts_name = (DS_U8 *)memChainAlloc(memId, p_ts_info->ts_name_length+1); for (i=0; its_name_length; i++) p_ts_info->ts_name[i] = p[4+i]; p_ts_info->ts_name[i] = '\0'; } off = 4+p_ts_info->ts_name_length; p_ts_info->transmission_type = (arib_transmission_type_t *)NULL; if (p_ts_info->transmission_type_count) { arib_transmission_type_t *p_tx_type; p_tx_type = p_ts_info->transmission_type = (arib_transmission_type_t *)memChainAlloc(memId, sizeof(arib_transmission_type_t)*p_ts_info->transmission_type_count); if (p_tx_type == (arib_transmission_type_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for (i=0; itransmission_type_count; i++) { p_tx_type->transmission_type_info = p[off]; p_tx_type->number_of_service = p[off+1]; p_tx_type->service_id = (DS_U16 *)NULL; off += 2; if (p_tx_type->number_of_service) { DS_U16 *p_service_id; p_service_id = p_tx_type->service_id = (DS_U16 *)memChainAlloc(memId, (p_tx_type->number_of_service) * sizeof(DS_U16)); if (p_service_id == (DS_U16 *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for (j=0; jnumber_of_service; j++) { *p_service_id = (p[off]<<8)+p[off+1]; p_service_id++; off += 2; } } p_tx_type++; } } *pp_ts_info = p_ts_info; ParseDescriptorExit: return err; } static int DHL_PSI_ParseSystemManagementDescriptor(DS_U8* p, DS_U16* p_system_management_id) { int len; DS_U16 system_mgmt_id; if (!p_system_management_id || !p) return -1; len = p[1]; if (len<2) return -1; system_mgmt_id = (p[2]<<8) + p[3]; *p_system_management_id = system_mgmt_id; return 0; } void DHL_PSI_ParseBouquetNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_bouquet_name, DS_U8 *p_length) { int len; DS_U8 *p_bouquet_name; if ( !p_desc || !p_bouquet_name || !p_length ) return; len = p_desc[1]; p_bouquet_name = (DS_U8 *)memChainAlloc( memId, len+1 ); memcpy(p_bouquet_name, &p_desc[2], len ); p_bouquet_name[len] = '\0'; *pp_bouquet_name = p_bouquet_name; return; } void DHL_PSI_ParseHierarchicalTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_hierarchical_transmission_descriptor_t **pp_hierarchical_transmission ) { int len; int err = DHL_OK; arib_hierarchical_transmission_descriptor_t *p_hierarchical_transmission; len = p[1]; p_hierarchical_transmission = (arib_hierarchical_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_hierarchical_transmission_descriptor_t)); if ( p_hierarchical_transmission == (arib_hierarchical_transmission_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } if ( len < 3 ) { return; // DHL_FAIL_OUT_OF_RESOURCE; } p_hierarchical_transmission->quality_level = ( p[2] & 0x01 ); p_hierarchical_transmission->reference_PID = (( p[3] << 8 ) + p[4] ) & 0x1FFF; *pp_hierarchical_transmission = p_hierarchical_transmission; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } // return err; } void DHL_PSI_ParseDigitalCopyControlDescriptor(DS_U8* p, memId_t memId, arib_digital_copy_control_descriptor_t **pp_digital_copy_control) { int i, len, component_control_length; // DS_U8 maximum_bitrate; DS_U8 maximum_bitrate_flag, component_control_flag; int err = DHL_OK; arib_digital_copy_control_descriptor_t *p_digital_copy_control; len = p[1]; if ( len < 1 ) return; // DHL_FAIL_INVALID_SIZE; p_digital_copy_control = (arib_digital_copy_control_descriptor_t *)memChainAlloc(memId,sizeof(arib_digital_copy_control_descriptor_t)); if (p_digital_copy_control == (arib_digital_copy_control_descriptor_t *)NULL) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_digital_copy_control->digital_recording_control_data = ( p[2] & 0xC0 ) >> 6; maximum_bitrate_flag = ( p[2] & 0x20 ) >> 5; component_control_flag = ( p[2] & 0x10 ) >> 4; p_digital_copy_control->copy_control_type = ( p[2] & 0xC ) >> 2; if ( p_digital_copy_control->copy_control_type != 0 ) { p_digital_copy_control->APS_control_data = p[2] & 0x2; } if ( maximum_bitrate_flag == 1 ) { p_digital_copy_control->maximum_bitrate = p[3]; } if ( component_control_flag == 1 ) { arib_component_control_t *p_component_control; p_digital_copy_control->component_control = (arib_component_control_t *)NULL; p_component_control = p_digital_copy_control->component_control = (arib_component_control_t *)memChainAlloc(memId, sizeof(arib_component_control_t)); if ( p_component_control == (arib_component_control_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } component_control_length = p[4]; for ( i = 0 ; i < component_control_length ; i++ ) { p_component_control->component_tag = p[5+i]; p_component_control->component_digital_recording_control_data = ( p[6+i] & 0xC0 ) >> 6; maximum_bitrate_flag = ( p[6+i] & 0x20 ) >> 5; p_component_control->component_copy_control_type = ( p[6+i] & 0xC ) >>2; if ( p_component_control->component_copy_control_type != 0 ) { p_component_control->component_APS_control_data = p[6+i] & 0x2; } if ( maximum_bitrate_flag == 1 ) { p_component_control->component_maximum_bitrate = p[7+i]; i = i+3; } else { i = i+2; } p_component_control++; } } *pp_digital_copy_control = p_digital_copy_control; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseNetworkIdentificationDescriptor( DS_U8 *p, memId_t memId, arib_network_identification_descriptor_t **pp_network_identification ) { int i, len; DS_U8 count; DHL_RESULT err; arib_network_identification_descriptor_t *p_network_identification; len = p[1]; if ( len < 7 ) return; p_network_identification = (arib_network_identification_descriptor_t *)memChainAlloc(memId, sizeof(arib_network_identification_descriptor_t)); if ( p_network_identification == (arib_network_identification_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_network_identification->Country_code = ( p[2] << 16 ) + ( p[3] << 8 ) + p[4]; p_network_identification->media_type = ( p[5] << 8 ) + p[6]; p_network_identification->Network_id = ( p[7] << 8 ) + p[8]; count = len - 9; if ( count > 9 ) { DS_U8 *p_private_data; p_private_data = p_network_identification->private_data = (DS_U8 *)memChainAlloc( memId, len-9 ); if ( p_private_data == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < count ; i++ ) { *p_private_data = (p[i+10]); p_private_data++; } } *pp_network_identification = p_network_identification; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParsePartialTSTimeDescriptor( DS_U8 *p, memId_t memId, arib_partialTS_time_descriptor_t **pp_partialTS_time ) { int len; DHL_RESULT err; arib_partialTS_time_descriptor_t *p_partialTS_time; len = p[1]; if ( len < 13 ) return; p_partialTS_time = (arib_partialTS_time_descriptor_t *)memChainAlloc(memId, sizeof(arib_partialTS_time_descriptor_t)); if ( p_partialTS_time == (arib_partialTS_time_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_partialTS_time->Event_version_number = p[2]; p_partialTS_time->Event_start_time = (( p[3] << 24 ) << 8 ) + ( p[4] << 24 ) + ( p[5] << 16 ) + ( p[6] << 8 ) + p[7]; p_partialTS_time->Duration = ( p[8] << 16 ) + ( p[9] << 8 ) + p[10]; p_partialTS_time->Offset = ( p[11] << 16 ) + ( p[12] << 8 ) + p[13]; p_partialTS_time->Offset_flag = ( p[14] & 0x4 ) >> 2; p_partialTS_time->Other_descriptor_status = ( p[14] & 0x2 ) >> 1; p_partialTS_time->JST_time_flag = p[14] & 0x1; if ( p_partialTS_time->JST_time_flag == 1 ) { p_partialTS_time->JST_time = (( p[15] << 24 ) << 8 ) + ( p[16] << 24 ) + ( p[17] << 16 ) + ( p[18] << 8 ) + p[19]; } *pp_partialTS_time = p_partialTS_time; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseAudioComponentDescriptor( DS_U8 *p, memId_t memId, arib_audio_component_descriptor_t **pp_audio_component ) { int i, len; DS_U8 count; DHL_RESULT err=0; arib_audio_component_descriptor_t *p_audio_component; len = p[1]; if ( len < 8 ) return; p_audio_component = (arib_audio_component_descriptor_t *)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t)); if ( p_audio_component == (arib_audio_component_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_audio_component->stream_content = ( p[2] & 0xF ); p_audio_component->component_type = p[3]; p_audio_component->component_tag = p[4]; p_audio_component->stream_type = p[5]; p_audio_component->simulcast_group_tag = p[6]; p_audio_component->ES_multi_lingual_flag = ( p[7] & 0x80 ) >> 7; p_audio_component->main_component_flag = ( p[7] & 0x40 ) >> 6; p_audio_component->quality_indicator = ( p[7] & 0x30 ) >> 4; p_audio_component->sampling_rate = ( p[7] & 0xE ) >> 1; p_audio_component->ISO_639_language_code = ( p[8] << 16 ) + ( p[9] << 8 ) + p[10]; if ( p_audio_component->ES_multi_lingual_flag == 1 ) { // DS_U8 *p_text_char; p_audio_component->ISO_639_language_code_2 = ( p[11] << 16 ) + ( p[12] << 8 ) + p[13]; count = len - 12; p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 ); if ( p_audio_component->text_char == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < count ; i++ ) { p_audio_component->text_char[i] = (p[i+14]); } p_audio_component->text_char[i] = '\0'; } else { count = len - 9; p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 ); if ( p_audio_component->text_char == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < count ; i++ ) { p_audio_component->text_char[i] = (p[i+11]); } p_audio_component->text_char[i] = '\0'; } *pp_audio_component = p_audio_component; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseHyperlinkDescriptor( DS_U8 *p, memId_t memId, arib_hyperlink_descriptor_t **pp_hyperlink ) { int i, j, k, len; DS_U8 count; DHL_RESULT err; arib_hyperlink_descriptor_t *p_hyperlink; len = p[1]; if ( len < 2 ) return; p_hyperlink = (arib_hyperlink_descriptor_t *)memChainAlloc(memId, sizeof(arib_hyperlink_descriptor_t)); if ( p_hyperlink == (arib_hyperlink_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_hyperlink->hyper_linkage_type = p[2]; p_hyperlink->link_destination_type = p[3]; p_hyperlink->selector_length = p[4]; if ( p_hyperlink->selector_length > 0 ) { DS_U8 *p_selector_byte; DS_U8 *p_private_data; p_selector_byte = p_hyperlink->selector_byte = (DS_U8 *)memChainAlloc( memId, p_hyperlink->selector_length); if ( p_selector_byte == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < p_hyperlink->selector_length ; i++ ) { *p_selector_byte = (p[i+5]); p_selector_byte++; } count = len - ( 4 + i ); p_private_data = p_hyperlink->private_data = (DS_U8 *)memChainAlloc( memId, count ); if ( p_private_data == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( j = 0 ; j < count ; j++ ) { *p_private_data = (p[i+j+6]); p_private_data++; } } else { DS_U8 *p_private_data; count = len - 3; p_private_data = p_hyperlink->private_data = (DS_U8 *)memChainAlloc( memId, count ); if ( p_private_data == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( k = 0 ; k < count ; k++ ) { *p_private_data = (p[k+5]); p_private_data++; } } *pp_hyperlink = p_hyperlink; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseTargetRegionDescriptor( DS_U8 *p, memId_t memId, arib_target_region_descriptor_t **pp_target_region ) { int i, len; DS_U8 count; DHL_RESULT err; arib_target_region_descriptor_t *p_target_region; len = p[1]; if ( len < 0 ) return; p_target_region = (arib_target_region_descriptor_t *)memChainAlloc(memId, sizeof(arib_target_region_descriptor_t)); if ( p_target_region == (arib_target_region_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_target_region->region_spec_type = p[2]; count = len - 1; if ( count > 0 ) { DS_U8 *p_target_region_spec; p_target_region_spec = p_target_region->target_region_spec = (DS_U8 *)memChainAlloc( memId, count ); if ( p_target_region_spec == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < count ; i++ ) { *p_target_region_spec = p[i+3]; p_target_region_spec++; } } *pp_target_region = p_target_region; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseDataContentDescriptor( DS_U8 *p, memId_t memId, arib_data_content_descriptor_t **pp_data_content ) { int i=0, j=0, k=0, len; DHL_RESULT err=0; arib_data_content_descriptor_t *p_data_content; len = p[1]; if ( len < 8 ) return; p_data_content = (arib_data_content_descriptor_t *)memChainAlloc(memId, sizeof(arib_data_content_descriptor_t)); if ( p_data_content == (arib_data_content_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_data_content->data_component_id = ( p[2] << 8 ) + p[3]; p_data_content->entry_component = p[4]; p_data_content->selector_length = p[5]; if ( p_data_content->selector_length > 0 ) { DS_U8 *p_selector_byte; p_selector_byte = p_data_content->selector_byte = (DS_U8 *)memChainAlloc( memId, p_data_content->selector_length ); if ( p_selector_byte == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < p_data_content->selector_length ; i++ ) { *p_selector_byte = p[i+6]; p_selector_byte++; } } p_data_content->num_of_component_ref = p[i+6]; if ( p_data_content->num_of_component_ref > 0 ) { DS_U8 *p_component_ref; p_component_ref = p_data_content->component_ref = (DS_U8 *)memChainAlloc( memId, p_data_content->num_of_component_ref ); if ( p_component_ref == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( j = 0 ; j < p_data_content->num_of_component_ref ; j++ ) { *p_component_ref = p[i+j+7]; p_component_ref++; } } p_data_content->ISO_639_language_code = ( p[i+j+7] << 16 ) + ( p[i+j+8] << 8 ) + p[i+j+9]; p_data_content->text_length = p[i+j+10]; if ( p_data_content->text_length > 0 ) { p_data_content->text_char = (DS_U8 *)memChainAlloc( memId, p_data_content->text_length+1 ); if ( p_data_content->text_char == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( k = 0 ; k < p_data_content->text_length ; k++ ) { p_data_content->text_char[k] = p[i+j+k+11]; } p_data_content->text_char[k] = '\0'; } *pp_data_content = p_data_content; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseVideoDecodeControlDescriptor( DS_U8 *p, memId_t memId, arib_video_decode_control_descriptor_t **pp_video_decode_control ) { int len; DHL_RESULT err; arib_video_decode_control_descriptor_t *p_video_decode_control; len = p[1]; if ( len < 0 ) return; p_video_decode_control = (arib_video_decode_control_descriptor_t *)memChainAlloc(memId, sizeof(arib_video_decode_control_descriptor_t)); if ( p_video_decode_control == (arib_video_decode_control_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_video_decode_control->still_picture_flag = ( p[2] & 0x80 ) >> 7; p_video_decode_control->sequence_end_code_flag = ( p[2] & 0x40 ) >> 6; p_video_decode_control->video_encode_format = ( p[2] & 0x3C ) >> 2; *pp_video_decode_control = p_video_decode_control; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseLogoTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_logo_transmission_descriptor_t **pp_logo_transmission ) { int i, len; DS_U8 logo_char_length; DHL_RESULT err=DHL_OK; arib_logo_transmission_descriptor_t *p_logo_transmission; len = p[1]; if ( len < 2 ) return; p_logo_transmission = (arib_logo_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_logo_transmission_descriptor_t)); if ( p_logo_transmission == (arib_logo_transmission_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_logo_transmission->logo_transmission_type = p[2]; if ( p_logo_transmission->logo_transmission_type == 0x01 ) { p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4]; p_logo_transmission->logo_version = (( p[5] & 0x7 ) << 8 ) + p[6]; p_logo_transmission->download_data_id = ( p[7] << 8 ) + p[8]; } else if ( p_logo_transmission->logo_transmission_type == 0x02 ) { p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4]; } else if ( p_logo_transmission->logo_transmission_type == 0x03 ) { logo_char_length = len - 1; p_logo_transmission->logo_char = (DS_U8 *)memChainAlloc( memId, logo_char_length+1 ); if ( p_logo_transmission->logo_char == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < logo_char_length ; i++ ) { p_logo_transmission->logo_char[i] = p[i+3]; } p_logo_transmission->logo_char[i] = '\0'; } *pp_logo_transmission = p_logo_transmission; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseBasicLocalEventDescriptor( DS_U8 *p, memId_t memId, arib_basic_local_event_descriptor_t **pp_basic_local_event ) { int i, len; int off = 0; DS_U8 component_tag_length; DHL_RESULT err; arib_basic_local_event_descriptor_t *p_basic_local_event; len = p[1]; if ( len < 1 ) return; p_basic_local_event = (arib_basic_local_event_descriptor_t *)memChainAlloc(memId, sizeof(arib_basic_local_event_descriptor_t)); if ( p_basic_local_event == (arib_basic_local_event_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_basic_local_event->segmentation_mode = p[2] & 0xF; p_basic_local_event->segmentation_info_length = p[3]; if ( p_basic_local_event->segmentation_mode == 0x0 ) { component_tag_length = len - 2; } else if ( p_basic_local_event->segmentation_mode == 0x1 ) { p_basic_local_event->start_time_NPT = ((( p[4] & 0x1 ) << 24 ) << 8 ) + ( p[5] << 24 ) + ( p[6] << 16 ) + ( p[7] << 8 ) + p[8]; p_basic_local_event->end_time_NPT = ((( p[9] & 0x1 ) << 24 ) << 8 ) + ( p[10] << 24 ) + ( p[11] << 16 ) + ( p[12] << 8 ) + p[13]; component_tag_length = len - 12; off = 14; } else if ( p_basic_local_event->segmentation_mode < 0x6 ) { p_basic_local_event->start_time = ( p[4] << 16 ) + ( p[5] << 8 ) + p[6]; p_basic_local_event->duration = ( p[7] << 16 ) + ( p[8] << 8 ) + p[9]; component_tag_length = len - 8; off = 10; if ( p_basic_local_event->segmentation_info_length == 10 ) { p_basic_local_event->start_time_extension = ( p[10] << 4 ) + (( p[11] & 0xF0 ) >> 4 ); p_basic_local_event->duration_extension = ( p[12] << 4 ) + (( p[13] & 0xF0 ) >> 4 ); component_tag_length = len - 12; off = 14; } } if ( component_tag_length > 0 ) { p_basic_local_event->component_tag = (DS_U8 *)memChainAlloc( memId, component_tag_length ); if ( p_basic_local_event->component_tag == (DS_U8 *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < component_tag_length ; i++ ) { p_basic_local_event->component_tag[i] = p[i+off]; } } *pp_basic_local_event = p_basic_local_event; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseReferenceDescriptor( DS_U8 *p, memId_t memId, arib_reference_descriptor_t **pp_reference ) { int i, len, off; DS_U8 count = 0; DHL_RESULT err; arib_reference_descriptor_t *p_reference; len = p[1]; if ( len < 3 ) return; p_reference = (arib_reference_descriptor_t *)memChainAlloc(memId, sizeof(arib_reference_descriptor_t)); if ( p_reference == (arib_reference_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_reference->information_provider_id = ( p[2] << 8 ) + p[3]; p_reference->event_relation_id = ( p[4] << 8 ) + p[5]; count = len - 4; off = 6; if ( count > 0 ) { arib_reference_node_t *p_reference_node; p_reference_node = p_reference->reference_node = (arib_reference_node_t *)memChainAlloc(memId, count); if ( p_reference_node == (arib_reference_node_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < count ; i++ ) { p_reference_node->reference_node_id = p[off]; p_reference_node->reference_number = p[off+1]; p_reference_node->last_reference_number = p[off+2]; off += 3; p_reference_node++; } } *pp_reference = p_reference; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseNodeRelationDescriptor( DS_U8 *p, memId_t memId, arib_node_relation_descriptor_t **pp_node_relation ) { int len, off; DHL_RESULT err; arib_node_relation_descriptor_t *p_node_relation; len = p[1]; if ( len < 3 ) return; p_node_relation = (arib_node_relation_descriptor_t *)memChainAlloc(memId, sizeof(arib_node_relation_descriptor_t)); if ( p_node_relation == (arib_node_relation_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_node_relation->reference_type = ( p[2] & 0xF0 ) >> 4; p_node_relation->external_reference_flag = ( p[3] & 0x8 ) >> 3; off = 4; if ( p_node_relation->external_reference_flag == 1 ) { p_node_relation->information_provider_id = p[off]; p_node_relation->event_relation_id = p[off+1]; off += 2; } p_node_relation->reference_node_id = p[off]; p_node_relation->reference_number = p[off+1]; *pp_node_relation = p_node_relation; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseShortNodeInformationDescriptor( DS_U8 *p, memId_t memId, arib_short_node_information_descriptor_t **pp_short_node_information ) { int len, node_name_length, text_length; DHL_RESULT err; arib_short_node_information_descriptor_t *p_short_node_information; len = p[1]; if ( len < 4 ) return; p_short_node_information = (arib_short_node_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_short_node_information_descriptor_t)); if ( p_short_node_information == (arib_short_node_information_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_short_node_information->ISO_639_language_code = ( p[2] << 16 ) + ( p[3] << 8 ) + p[4]; node_name_length = p[5]; p_short_node_information->node_name_length = node_name_length; p_short_node_information->node_name_char = (DS_U8 *)NULL; if ( node_name_length ) { p_short_node_information->node_name_char = (DS_U8 *)memChainAlloc(memId, node_name_length); memcpy(p_short_node_information->node_name_char, &p[6], node_name_length); } text_length = p[6 + node_name_length]; p_short_node_information->text_length = text_length; p_short_node_information->text_char = (DS_U8 *)NULL; if ( text_length ) { p_short_node_information->text_char = (DS_U8 *)memChainAlloc(memId, text_length+1); memcpy(p_short_node_information->text_char, &p[7 + node_name_length], text_length); } *pp_short_node_information = p_short_node_information; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseSTCReferenceDescriptor( DS_U8 *p, memId_t memId, arib_stc_reference_descriptor_t **pp_stc_reference ) { int len, off; DHL_RESULT err; arib_stc_reference_descriptor_t *p_stc_reference; len = p[1]; if ( len < 0 ) return; p_stc_reference = (arib_stc_reference_descriptor_t *)memChainAlloc(memId, sizeof(arib_stc_reference_descriptor_t)); if ( p_stc_reference == (arib_stc_reference_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_stc_reference->external_event_flag = ( p[2] & 0x10 ) >> 4; p_stc_reference->stc_reference_mode = ( p[2] & 0xF ); off = 3; if ( p_stc_reference->external_event_flag == 1 ) { arib_external_event_t *p_external_event; p_external_event = p_stc_reference->external_event = (arib_external_event_t *)memChainAlloc(memId, sizeof(arib_external_event_t)); if ( p_external_event == (arib_external_event_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_external_event->external_event_id = ( p[off] << 8 ) + p[off+1]; p_external_event->external_service_id = ( p[off+2] << 8 ) + p[off+3]; p_external_event->external_network_id = ( p[off+4] << 8 ) + p[off+5]; off += 6; } if ( p_stc_reference->stc_reference_mode == 0 ) { ; } else if ( p_stc_reference->stc_reference_mode == 1 ) { arib_stc_reference_mode1_t *p_stc_reference_mode1; p_stc_reference_mode1 = p_stc_reference->stc_reference_mode1 = (arib_stc_reference_mode1_t *)memChainAlloc(memId, sizeof(arib_stc_reference_mode1_t)); if ( p_stc_reference_mode1 == (arib_stc_reference_mode1_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_stc_reference_mode1->NPT_reference = ( p[off+1] << 24 ) + ( p[off+2] << 16 ) + ( p[off+3] << 8 ) + p[off+4]; p_stc_reference_mode1->STC_reference = ( p[off+6] << 24 ) + ( p[off+7] << 16 ) + ( p[off+8] << 8 ) + p[off+9]; } else if ( p_stc_reference->stc_reference_mode == 3 || p_stc_reference->stc_reference_mode == 5 ) { arib_stc_reference_mode3_t *p_stc_reference_mode3; p_stc_reference_mode3 = p_stc_reference->stc_reference_mode3 = (arib_stc_reference_mode3_t *)memChainAlloc(memId, sizeof(arib_stc_reference_mode3_t)); if ( p_stc_reference_mode3 == (arib_stc_reference_mode3_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_stc_reference_mode3->time_reference = ( p[off] << 16 ) + ( p[off+1] << 8 ) + p[off+2]; p_stc_reference_mode3->time_reference_extension = ( p[off+3] << 4 ) + (( p[off+4] & 0xF0 ) >> 4 ); p_stc_reference_mode3->STC_reference = ( p[off+6] << 24 ) + ( p[off+7] << 16 ) + ( p[off+8] << 8 ) + p[off+9]; } *pp_stc_reference = p_stc_reference; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseSeriesDescriptor( DS_U8 *p, memId_t memId, arib_series_descriptor_t **pp_series ) { int len, name_length; DHL_RESULT err; arib_series_descriptor_t *p_series; len = p[1]; if ( len < 7 ) return; p_series = (arib_series_descriptor_t *)memChainAlloc(memId, sizeof(arib_series_descriptor_t)); if ( p_series == (arib_series_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_series->series_id = ( p[2] << 8 ) + p[3]; p_series->repeat_label = ( p[4] & 0xF0 ) >> 4; p_series->program_pattern = ( p[4] &0x0E ) >> 1; p_series->expire_date_valid_flag = p[4] & 0x1; p_series->expire_date = ( p[5] << 8 ) + p[6]; p_series->episode_number = ( p[7] << 4 ) + (( p[8] & 0xF0 ) >> 4 ); p_series->last_episode_number = (( p[8] & 0x0F ) << 4 ) + p[9]; name_length = len - 8; p_series->series_name_char = (DS_U8 *)NULL; if ( name_length ) { p_series->series_name_char = (DS_U8 *)memChainAlloc(memId, name_length+1); memcpy(p_series->series_name_char, &p[10+name_length], name_length ); p_series->series_name_char[name_length] = '\0'; } *pp_series = p_series; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseSIParameterDescriptor( DS_U8 *p_desc, memId_t memId, arib_si_parameter_descriptor_t **pp_si_parameter ) { const DS_U8 *p; int numTable; int lenTable; int i, j, len, off; DHL_RESULT err; arib_si_parameter_descriptor_t *p_si_parameter; len = p_desc[1]; if ( len < 2 ) return; p_si_parameter = (arib_si_parameter_descriptor_t *)memChainAlloc(memId, sizeof(arib_si_parameter_descriptor_t)); if ( p_si_parameter == (arib_si_parameter_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_si_parameter->parameter_version = p_desc[2]; p_si_parameter->update_time = ( p_desc[3] << 8 ) + p_desc[4]; lenTable = len - 5; numTable = 0; p = &p_desc[5]; if ( lenTable > 0 ) { for ( i=0 ; inumTable = numTable; p_si_parameter->update_time = (p_desc[3]<<8) + p_desc[4]; off = 5; if ( numTable > 0 ) { arib_table_description_t *p_table_description; p_table_description = p_si_parameter->table_description = (arib_table_description_t *)memChainAlloc(memId, numTable*sizeof(arib_table_description_t)); if ( p_table_description == (arib_table_description_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i=0 ; i < numTable ; i++ ) { p_table_description->table_id = p_desc[off]; p_table_description->table_description_length = p_desc[off+1]; off += 2; if ( p_table_description->table_description_length > 0 ) { p_table_description->table_description_byte = (DS_U8 *)memChainAlloc(memId, p_table_description->table_description_length); for ( j=0 ; j < p_table_description->table_description_length ; j++ ) { p_table_description->table_description_byte[j] = p_desc[off+j]; } off += j; } else { p_table_description->table_description_byte = (DS_U8 *)NULL; } p_table_description++; } } else { p_si_parameter->table_description = (arib_table_description_t *)NULL; } err = DHL_OK; *pp_si_parameter = p_si_parameter; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseBroadcasterNameDescriptor(DS_U8 *p, memId_t memId, DS_U8 **pp_broadcaster_name, DS_U8 *p_length) { int len; DS_U8 *p_broadcaster_name; if (!p || !p_broadcaster_name || !p_length) return; len = p[1]; p_broadcaster_name = (DS_U8 *)memChainAlloc( memId, len+1 ); memcpy(p_broadcaster_name, &p[2], len ); p_broadcaster_name[len] = '\0'; *pp_broadcaster_name = p_broadcaster_name; return; } void DHL_PSI_ParseComponentGroupDescriptor( DS_U8 *p, memId_t memId, arib_component_group_descriptor_t **pp_component_group ) { int i, j, len, off; int num_of_group; DHL_RESULT err; arib_component_group_descriptor_t *p_component_group; len = p[1]; if ( len < 0 ) return; p_component_group = (arib_component_group_descriptor_t *)memChainAlloc(memId, sizeof(arib_component_group_descriptor_t)); if ( p_component_group == (arib_component_group_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_component_group->component_group_type = ( p[2] & 0xE0 ) >> 5; p_component_group->total_bit_rate_flag = ( p[2] >> 4 ) & 0x1 ; num_of_group = p[2] & 0xF; p_component_group->num_of_group = num_of_group; off = 3; if ( num_of_group ) { int num_of_CA_unit, text_length; arib_group_t *p_group; p_group = p_component_group->group = (arib_group_t *)memChainAlloc(memId, sizeof(arib_group_t)); if ( p_group == (arib_group_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( i = 0 ; i < num_of_group ; i++ ) { p_group->component_group_id = ( p[off] >> 4 ) & 0xF; num_of_CA_unit = p[off] & 0xF; p_group->num_of_CA_unit = num_of_CA_unit; off += 1; if ( num_of_CA_unit ) { int num_of_component; arib_unit_t *p_unit; p_unit = p_group->CA_unit = (arib_unit_t *)memChainAlloc(memId, sizeof(arib_unit_t)); if ( p_unit == (arib_unit_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } for ( j = 0 ; j < num_of_CA_unit ; j++ ) { p_unit->CA_unit_id = ( p[off] >> 4 ) & 0xF; p_unit->num_of_component = p[off] & 0xF; off += 1; if ( p_unit->num_of_component ) { p_unit->component_tag = (DS_U8 *)memChainAlloc(memId, p_unit->num_of_component); memcpy(p_unit->component_tag, &p[off], num_of_component); off += num_of_component; } p_unit++; } } if ( p_component_group->total_bit_rate_flag == 1 ) { p_group->total_bit_rate = p[off+1]; off += 1; } text_length = p[off]; p_group->text_length = text_length; off += 1; if ( text_length ) { p_group->text_char = (DS_U8 *)memChainAlloc(memId, text_length+1); memcpy(p_group->text_char, &p[off], text_length); p_group->text_char[text_length] = '\0'; off += text_length; } p_group++; } } *pp_component_group = p_component_group; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseSIPrimeTSDescriptor( DS_U8 *p, memId_t memId, arib_si_prime_ts_descriptor_t **pp_si_prime_ts ) { int len, table_len, off; DHL_RESULT err; arib_si_prime_ts_descriptor_t *p_si_prime_ts; len = p[1]; if ( len < 6 ) return; p_si_prime_ts = (arib_si_prime_ts_descriptor_t *)memChainAlloc(memId, sizeof(arib_si_prime_ts_descriptor_t)); if ( p_si_prime_ts == (arib_si_prime_ts_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_si_prime_ts->parameter_version= p[2]; p_si_prime_ts->update_time = ( p[3] << 8 ) + p[4]; p_si_prime_ts->SI_prime_ts_network_id = ( p[5] << 8 ) + p[6]; p_si_prime_ts->SI_prime_ts_id = ( p[7] << 8 ) + p[8]; table_len = len - 7; off = 9; if ( table_len ) { arib_table_description_t *p_table_description; p_table_description = p_si_prime_ts->table_description = (arib_table_description_t *)memChainAlloc(memId, table_len); if ( p_table_description == (arib_table_description_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } while ( table_len > 2 ) { p_table_description->table_id = p[off]; p_table_description->table_description_length = p[off+1]; off += 2; if ( p_table_description->table_description_length ) { p_table_description->table_description_byte = (DS_U8 *)memChainAlloc(memId, p_table_description->table_description_length); memcpy(p_table_description->table_description_byte, &p[off], p_table_description->table_description_length); off += p_table_description->table_description_length; } table_len = table_len - ( 2 + p_table_description->table_description_length ); p_table_description++; } } *pp_si_prime_ts = p_si_prime_ts; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseBoardInformationDescriptor( DS_U8 *p, memId_t memId, arib_board_information_descriptor_t **pp_board_information ) { int len, off; DHL_RESULT err; arib_board_information_descriptor_t *p_board_information; len = p[1]; if ( len < 1 ) return; p_board_information = (arib_board_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_board_information_descriptor_t)); if ( p_board_information == (arib_board_information_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_board_information->title_length = p[2]; off = 3; if ( p_board_information->title_length ) { p_board_information->title_char = (DS_U8 *)memChainAlloc(memId, p_board_information->title_length + 1); memcpy(p_board_information->title_char, &p[off], p_board_information->title_length + 1); p_board_information->title_char[p_board_information->title_length] = '\0'; off += p_board_information->title_length; } p_board_information->text_length = p[off]; if ( p_board_information->text_length ) { p_board_information->text_char = (DS_U8 *)memChainAlloc(memId, p_board_information->text_length + 1); memcpy(p_board_information->text_char, &p[off+1], p_board_information->text_length + 1); p_board_information->text_char[p_board_information->text_length] = '\0'; } *pp_board_information = p_board_information; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseLDTLinkageDescriptor( DS_U8 *p, memId_t memId, arib_ldt_linkage_descriptor_t **pp_ldt_linkage ) { int len, n, off; DHL_RESULT err; arib_ldt_linkage_descriptor_t *p_ldt_linkage; len = p[1]; if ( len < 5 ) return; p_ldt_linkage = (arib_ldt_linkage_descriptor_t *)memChainAlloc(memId, sizeof(arib_ldt_linkage_descriptor_t)); if ( p_ldt_linkage == (arib_ldt_linkage_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_ldt_linkage->original_service_id = ( p[2] << 8 ) | p[3]; p_ldt_linkage->ts_id = ( p[4] << 8 ) + p[5]; p_ldt_linkage->original_network_id = ( p[6] << 8 ) + p[7]; n = len - 6; off = 9; if ( n ) { arib_linked_description_t *p_linked_description; p_linked_description = p_ldt_linkage->linked_description = (arib_linked_description_t *)memChainAlloc(memId, n); if ( p_linked_description == (arib_linked_description_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } while ( n > 3 ) { p_linked_description->description_id = ( p[off] << 8 ) + p[off+1]; p_linked_description->description_id = ( p[off+2] & 0xF ); p_linked_description->user_defined = p[off+3]; off += 4; n -= 4; p_linked_description++; } } *pp_ldt_linkage = p_ldt_linkage; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseConnectedTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_connected_transmission_descriptor_t **pp_connected_tx ) { int len, n; DHL_RESULT err; arib_connected_transmission_descriptor_t *p_connected_tx; len = p[1]; if ( len < 2 ) return; p_connected_tx = (arib_connected_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_connected_transmission_descriptor_t)); if ( p_connected_tx == (arib_connected_transmission_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_connected_tx->connected_tx_group_id = ( p[2] << 8 ) + p[3]; p_connected_tx->segment_type = ( p[4] >> 6 ) & 0x3; p_connected_tx->modulation_type_A = ( p[4] >> 4 ) & 0x3; p_connected_tx->modulation_type_B = ( p[4] >> 2 ) & 0x3; n = len - 3; if ( n ) { p_connected_tx->additional_connected_tx_info = (DS_U8 *)memChainAlloc(memId, n); memcpy(p_connected_tx->additional_connected_tx_info, &p[5], n); } *pp_connected_tx = p_connected_tx; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseContentAvailabilityDescriptor( DS_U8 *p, memId_t memId, arib_content_availability_descriptor_t **pp_content_availability ) { int len; DHL_RESULT err; arib_content_availability_descriptor_t *p_content_availability; len = p[1]; if ( len < 0 ) return; p_content_availability = (arib_content_availability_descriptor_t *)memChainAlloc(memId, sizeof(arib_content_availability_descriptor_t)); if ( p_content_availability == (arib_content_availability_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_content_availability->image_constraint_token = ( p[2] >> 5 ) & 0x1; p_content_availability->retention_mode = ( p[2] >> 4 ) & 0x1; p_content_availability->retention_state = ( p[2] >> 1 ) & 0x7; p_content_availability->encryption_mode = ( p[2] & 0x1 ); *pp_content_availability = p_content_availability; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseConditionalPlaybackDescriptor( DS_U8 *p, memId_t memId, arib_conditional_playback_descriptor_t **pp_conditional_playback ) { int len, n; DHL_RESULT err; arib_conditional_playback_descriptor_t *p_conditional_playback; len = p[1]; if ( len < 3 ) return; p_conditional_playback = (arib_conditional_playback_descriptor_t *)memChainAlloc(memId, sizeof(arib_conditional_playback_descriptor_t)); if ( p_conditional_playback == (arib_conditional_playback_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_conditional_playback->CA_system_id = ( p[2] << 8 ) + p[3]; p_conditional_playback->private_data = ( p[4] >> 5 ) & 0x7; p_conditional_playback->CA_PID = (( p[4] << 4 ) & 0x1F ) + p[5]; n = len - 4; if ( n ) { p_conditional_playback->private_data_byte = (DS_U8 *)memChainAlloc(memId, n); memcpy(p_conditional_playback->private_data_byte, &p[6], n); } *pp_conditional_playback = p_conditional_playback; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParseTerrestrialDeliverySystemDescriptor( DS_U8 *p, memId_t memId, arib_terrestrial_delivery_system_descriptor_t **pp_terrestrial_delivery_system ) { int len, n; DHL_RESULT err; arib_terrestrial_delivery_system_descriptor_t *p_terrestrial_delivery_system; len = p[1]; if ( len < 1 ) return; p_terrestrial_delivery_system = (arib_terrestrial_delivery_system_descriptor_t *)memChainAlloc(memId, sizeof(arib_terrestrial_delivery_system_descriptor_t)); if ( p_terrestrial_delivery_system == (arib_terrestrial_delivery_system_descriptor_t *)NULL ) { err = DHL_FAIL_OUT_OF_RESOURCE; goto ParseDescriptorExit; } p_terrestrial_delivery_system->area_code = ( p[2] << 4 ) + (( p[3] & 0xF0 ) >> 4); p_terrestrial_delivery_system->guard_interval = ( p[3] >> 2 ) & 0x3; p_terrestrial_delivery_system->tx_mode = ( p[3] & 0x3 ); n = len - 2; if ( n ) { p_terrestrial_delivery_system->frequency = (DS_U8 *)memChainAlloc(memId, n); memcpy(p_terrestrial_delivery_system->frequency, &p[4], n); } *pp_terrestrial_delivery_system = p_terrestrial_delivery_system; ParseDescriptorExit: if ( err ) { printf("ERROR: %s returns %d!\n", __func__, err); } } void DHL_PSI_ParsePartialReceptionDescriptor(DS_U8 *p, memId_t memId, DS_U16 **pp_partial_reception, DS_U8 *p_length) { int len; DS_U16 *p_partial_reception; if (!p || !p_partial_reception || !p_length) return; len = p[1]; p_partial_reception = (DS_U16 *)memChainAlloc( memId, len ); memcpy(p_partial_reception, &p[2], len ); *pp_partial_reception = p_partial_reception; return; } void DHL_PSI_ParseEmergencyInformationDescriptor(DS_U8 *p_desc, memId_t memId, arib_emergency_information_descriptor_t **pp_emergency_info) { DS_U8 *p = p_desc; arib_emergency_information_descriptor_t *p_emergency_info; int i, j, k, len, off, area_len; // int numEvent; if (!p_desc || !pp_emergency_info || !memId) return; len = p_desc[1]; if (len<3) return; p_emergency_info = (arib_emergency_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_emergency_information_descriptor_t)); if ( len ) { off = 2; for ( i = 0 ; i < len ; i++ ) { p_emergency_info->service_id = ( p[off+0] << 8 ) + p[off+1]; p_emergency_info->start_end_flag = ( p[off+2] >> 7 ) & 0x1; p_emergency_info->signal_level = ( p[off+2] >> 6 ) & 0x1; area_len = p[off+3]; p_emergency_info->area_code_length = area_len; off += 4; if ( area_len ) { for ( j=0, k=0 ; j < area_len ; j+=2, k++ ) { p_emergency_info->area_code[k] = ( p[off+0] << 4 ) + (( p[off+1] >> 4) & 0xF ); p_emergency_info->area_code++; off += 2; } } p_emergency_info++; } } *pp_emergency_info = p_emergency_info; } void DHL_PSI_ParseDataComponentDescriptor(DS_U8 *p_desc, memId_t memId, arib_data_component_descriptor_t **pp_data_component) { DS_U8 *p = p_desc; arib_data_component_descriptor_t *p_data_component; int len, numInfo; if ( !p_desc || !pp_data_component || !memId ) return; len = p_desc[1]; if ( len < 2 ) return; p_data_component = (arib_data_component_descriptor_t *)memChainAlloc(memId, sizeof(arib_data_component_descriptor_t)); p_data_component->data_component_id = (p[2] << 8) + p[3]; numInfo = len - 2; if ( numInfo ) { p_data_component->additional_data_component_info = (DS_U8 *)memChainAlloc(memId, numInfo); memcpy(p_data_component->additional_data_component_info, &p[4], numInfo); } *pp_data_component = p_data_component; } void DHL_PSI_ParseExtendedBroadcasterDescriptor(DS_U8 *p_desc, memId_t memId, arib_extended_broadcaster_descriptor_t **pp_ex_broad) { DS_U8 *p = p_desc; arib_extended_broadcaster_descriptor_t *p_ex_broad; int i, j, len, off; int num, numId; if (!p_desc || !pp_ex_broad || !memId) return; len = p_desc[1]; if ( len<4 ) return; p_ex_broad = (arib_extended_broadcaster_descriptor_t *)memChainAlloc(memId, sizeof(arib_extended_broadcaster_descriptor_t)); p_ex_broad->broadcaster_type = (p[2] >> 4) & 0x0F; off = 3; if ( p_ex_broad->broadcaster_type == 0x1 ) { p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1]; p_ex_broad->num_affiliation_id = (p[off+2] & 0xF0) >> 4; p_ex_broad->num_broadcaster_id = p[off+2] & 0xF; off += 3; if ( p_ex_broad->num_affiliation_id ) { num = p_ex_broad->num_affiliation_id; p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num); memcpy(p_ex_broad->affiliation_id, &p[off], num); off += num; } if ( p_ex_broad->num_broadcaster_id ) { numId = p_ex_broad->num_broadcaster_id; p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2); p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId); for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 ) { p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1]; p_ex_broad->broadcaster_id[i] = p[off+2]; off += 3; p_ex_broad->origin_network_id++; p_ex_broad->broadcaster_id++; } } } else if ( p_ex_broad->broadcaster_type == 0x2 ) { p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1]; p_ex_broad->num_affiliation_id = (p[off+2] >> 4) & 0xF; p_ex_broad->num_broadcaster_id = p[off+2] & 0xF; off += 3; if ( p_ex_broad->num_affiliation_id ) { num = p_ex_broad->num_affiliation_id; p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num); memcpy(p_ex_broad->affiliation_id, &p[off], num); off += num; } if ( p_ex_broad->num_broadcaster_id ) { numId = p_ex_broad->num_broadcaster_id; p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2); p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId); for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 ) { p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1]; p_ex_broad->broadcaster_id[i] = p[off+2]; off += 3; p_ex_broad->origin_network_id++; p_ex_broad->broadcaster_id++; } } } else { p_ex_broad->affiliation_id = (DS_U8 *)NULL; p_ex_broad->origin_network_id = (DS_U16 *)NULL; p_ex_broad->broadcaster_id = (DS_U8 *)NULL; } *pp_ex_broad = p_ex_broad; } void DHL_PSI_ParseServiceGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_service_group_descriptor_t **pp_service_grp) { DS_U8 *p = p_desc; arib_service_group_descriptor_t *p_service_grp; int i, j, off, len, num; if ( !p_desc || !pp_service_grp || !memId ) return; len = p_desc[1]; if ( len < 2 ) return; p_service_grp->service_grp_type = p[2]; off = 3; if ( p_service_grp->service_grp_type == 0x1 ) { num = (len-1) / 4; if ( num ) { p_service_grp->pri_service_id = (DS_U16 *)memChainAlloc(memId, num); p_service_grp->sub_service_id = (DS_U16 *)memChainAlloc(memId, num); for ( i=0, j=0 ; j < num ; j+=4, i++ ) { p_service_grp->pri_service_id[i] = (p[off+0] << 8) + p[off+1]; p_service_grp->sub_service_id[i] = (p[off+2] << 8) + p[off+3]; off += 4; p_service_grp->pri_service_id++; p_service_grp->sub_service_id++; } } } *pp_service_grp = p_service_grp; } void DHL_PSI_ParseDownloadContentDescriptor(DS_U8 *p, memId_t memId, arib_download_content_descriptor_t **pp_download) { int i, j, k, len, off; int moduleInfolen, priDatalen; int textlen, numSubDesc; arib_download_content_descriptor_t *p_download; arib_compatibility_descriptor_t *p_comp; arib_comp_desc_type_t *p_desctype; arib_subdesc_t *p_subdesc; arib_text_lang_t *p_text; arib_module_t *p_module; if ( !p || !pp_download || !memId ) return; len = p[1]; p_download->reboot = (p[2] >> 7) & 0x1; p_download->add_on = (p[2] >> 6) & 0x1; p_download->comp_flag = (p[2] >> 5) &0x1; p_download->module_info_flag = (p[2] >> 4) & 0x1; p_download->text_info_flag = (p[2] >> 3) &0x1; p_download->component_size = (p[3] << 24) + (p[4] << 16) + (p[5] << 8) + p[6]; p_download->download_id = (p[7] << 24) + (p[8] << 16) + (p[9] << 8) + p[10]; p_download->time_out_value_DII = (p[11] << 24) + (p[12] << 16) + (p[13] << 8) + p[14]; p_download->leak_rate = (p[15] << 14) + (p[16] << 6) + ((p[17] >> 6) & 0x3F); p_download->comp_tag = p[18]; off = 19; if ( p_download->comp_flag == 1 ) { p_comp = p_download->comp_desc = (arib_compatibility_descriptor_t *)memChainAlloc(memId, sizeof(arib_compatibility_descriptor_t)); p_comp->comp_len = (p[off+0] << 8) + p[off+1]; p_comp->numDescriptor = (p[off+2] << 8) + p[off+3]; off += 4; p_desctype = p_comp->desc_type = (arib_comp_desc_type_t *)memChainAlloc(memId, sizeof(arib_comp_desc_type_t)); if ( p_comp->numDescriptor ) { for ( i=0 ; i < p_comp->numDescriptor ; i++ ) { p_desctype->desc_type = p[off+0]; p_desctype->len = p[off+1]; p_desctype->specifier_type = p[off+2]; p_desctype->specifier_data = (p[off+3] << 16) + (p[off+4] << 8) + p[off+5]; p_desctype->model = (p[off+6] << 8) + p[off+7]; p_desctype->version = (p[off+8] << 8) + p[off+9]; p_desctype->numSubDesc = p[off+10]; off += 11; if ( p_desctype->numSubDesc ) { p_subdesc = p_desctype->sub_desc = (arib_subdesc_t *)memChainAlloc(memId, sizeof(arib_subdesc_t)); for ( j=0 ; j < p_desctype->numSubDesc ; j++ ) { p_subdesc->subDescType = p[off+0]; numSubDesc = p[off+1]; p_subdesc->subDesclen = numSubDesc; off += 2; if ( p_subdesc->subDesclen ) { p_subdesc->addInfo = (DS_U8 *)memChainAlloc(memId, numSubDesc); memcpy(p_subdesc->addInfo, &p[off], numSubDesc); off += numSubDesc; } p_subdesc++; } } p_desctype++; } } } if ( p_download->module_info_flag == 1 ) { p_download->numModules = p[off+0]; off += 1; p_module = p_download->module = (arib_module_t *)memChainAlloc(memId, sizeof(arib_module_t)); if ( p_download->numModules ) { for ( k=0 ; k < p_download->numModules ; k++ ) { p_module->module_id = (p[off+0] << 8) + p[off+1]; p_module->module_size = (p[off+2] << 24) + (p[off+3] << 16) + (p[off+4] << 8) + p[off+5]; moduleInfolen = p[off+6]; p_module->module_info_len = moduleInfolen; off += 7; if ( moduleInfolen ) { p_module->module_info_byte = (DS_U8 *)memChainAlloc(memId, moduleInfolen); memcpy(p_module->module_info_byte, &p[off], moduleInfolen); off += moduleInfolen; } p_module++; } } } priDatalen = p[off]; p_download->private_data_len = priDatalen; off += 1; if ( priDatalen ) { p_download->private_data_byte = (DS_U8 *)memChainAlloc(memId, priDatalen); memcpy(p_download->private_data_byte, &p[off], priDatalen); off += priDatalen; } if ( p_download->text_info_flag == 1 ) { p_text = (arib_text_lang_t *)memChainAlloc(memId, sizeof(arib_text_lang_t)); p_text->ISO_639 = (p[off+0] << 16) + (p[off+1] << 8) + p[off+2]; textlen = p[off+3]; p_text->len = textlen; off += 4; if ( textlen ) { p_text->text_char = (DS_U8 *)memChainAlloc(memId, textlen); memcpy(p_text->text_char, &p[off], textlen); off += textlen; } } *pp_download = p_download; } void DHL_PSI_DecodeDate(DS_U16 date_in_mjd, DS_U16 *p_year, DS_U8 *p_month, DS_U8 *p_day) { DS_U32 _y, _m, _d; DS_U32 _y_int, _m_int; DS_U16 y; DS_U8 m, d, k; if (!p_year || !p_month || !p_day) return; _y = ((date_in_mjd * 100) - 1507820)/36525; _y_int = (_y * 3652500)/10000; _y_int *= 10000; _m = ((date_in_mjd * 10000) - 149561000 - _y_int)/306001; _m_int = (_m * 306001)/10000; _m_int *= 10000; _d = ((date_in_mjd*10000) - 149560000 - _y_int - _m_int)/10000; if (_m == 14 || _m == 15) k = 1; else k = 0; y = (_y+k)&0xFFFF; m = (_m-1-(k*12))&0xFF; d = (_d)&0xFF; if ( m>12 ) m = 1; if ( d>31 ) d = 31; *p_year = y+1900; *p_month = m; *p_day = d; } static DS_U32 _ConvertMJD2UTC(DS_U16 Mjd, DS_U32 TimeInBCD) { DS_U32 seconds_from_date=0; DS_U32 seconds_from_time=0; if ( Mjd && Mjd < (44238+6) ) { /* * If Mjd is less than "6 Jan. 1980", then error. */ return 0; } if (Mjd) { /* * Subtracts MJD from "44238+6" which is PSIP UTC 0. */ seconds_from_date = (Mjd - (44238+6)) * 3600 * 24; } seconds_from_time = (((TimeInBCD )&0x0F)>>0); /* second */ seconds_from_time += (((TimeInBCD )&0xF0)>>4)*10; /* second */ seconds_from_time += ((TimeInBCD>> 8)&0x0F) * 60; /* minutes */ seconds_from_time += ((TimeInBCD>>12)&0x0F) * 600; /* minutes */ seconds_from_time += ((TimeInBCD>>16)&0x0F) * 3600; /* hours */ seconds_from_time += ((TimeInBCD>>20)&0x0F) * 36000; /* hours */ return (seconds_from_date + seconds_from_time); } #if 0 ___Debugging_Routines___() #endif void get_date(int date) { DS_U16 y; DS_U8 m, d; printf("date: 0x%04X\n", date); DHL_PSI_DecodeDate(date, &y, &m, &d); printf("%d/%d/%d\n", y, m, d); }