INT32 subt_callback(UINT8 *buff, INT32 len, UINT32 param) { INT32 prog_info_length; INT32 es_info_length; INT32 i; UINT16 es_pid; struct pmt_section *pms = (struct pmt_section *)buff; struct pmt_stream_info *stream; prog_info_length = SI_MERGE_HL8(pms->program_info_length); g_is_subt_available = FALSE; for(i=sizeof(struct pmt_section)+prog_info_length-4; i<len-4; i+=es_info_length+sizeof(struct pmt_stream_info)) { stream = (struct pmt_stream_info *)(buff+i); es_info_length = SI_MERGE_HL8(stream->es_info_length); es_pid = SI_MERGE_HL8(stream->elementary_pid); desc_loop_parser(stream->descriptor, es_info_length, subt_desc_info, 1, NULL, (void *)&es_pid); } return SUCCESS; }
INT32 si_bat_parser(UINT8 *data, INT32 len, struct section_parameter *param) { INT16 sec_len = 0; INT16 bouquet_loop_len = 0; INT16 ts_loop_len =0; INT16 desc_loop_len = 0; INT16 i, j; INT16 pos = 0; struct bat_section_info *pinfo = (struct bat_section_info *)param->priv; BAT_PRINTF("%s: len %d\n",__FUNCTION__,len); sec_len = ((data[1]&0xf)<<8) |data[2]; pinfo->b_id = (data[3]<<8)|data[4]; BAT_PRINTF("bouquet id = 0x%X\n",pinfo->b_id); //empty section if(sec_len <= 13 ) { return SUCCESS; } bouquet_loop_len = ((data[8]&0xf)<<8) |data[9]; pos = 10+bouquet_loop_len; //bouquet descriptor loop BAT_PRINTF("bouquet descriptor loop len[%d]\n",bouquet_loop_len); for(i = 10; (i<pos)&&(i<sec_len-1); i += 2+data[i+1]) { desc_loop_parser(data+i, data[i+1], bat_loop1, 1, NULL, pinfo); } //ts loop ts_loop_len = ((data[pos]&0xf)<<8) |data[pos+1]; BAT_PRINTF("ts_stream loop len[%d]\n",ts_loop_len); pos += 2+ts_loop_len; for(i += 2; (i<pos)&&(i<sec_len-1); i += 6+desc_loop_len) { pinfo->ts_id = (data[i]<<8)|data[i+1]; pinfo->orig_netid = (data[i+2]<<8)|data[i+3]; BAT_PRINTF("ts_id=0x%X,org_netid=0x%X\n",pinfo->ts_id,pinfo->orig_netid); desc_loop_len = ((data[i+4]&0xf)<<8)|data[i+5]; for(j = i+6; (j<(i+6+desc_loop_len))&&(j<(sec_len-1)); j += 2+data[j+1]) { desc_loop_parser(data+j, data[j+1], bat_loop2, 2, NULL, pinfo); } } return SUCCESS; }
INT32 psi_pmt_parser(UINT8 *pmt, PROG_INFO *p_info, INT32 max_es_nr) { INT32 ret; UINT32 stat = 0; UINT16 len = ((pmt[1]<<8)|pmt[2])&0x0FFF; p_info->pcr_pid = ((pmt[8]<<8)|pmt[9])&PSI_STUFF_PID; p_info->video_pid = PSI_STUFF_PID; p_info->service_type = 0; p_info->pmt_version = (pmt[5]&0x3e)>>1; p_info->audio_count = 0; desc_loop_parser(pmt+12, ((pmt[10]<<8)|pmt[11])&0xFFF, pmt_loop1, 1, &stat, p_info); ret = pmt_parse_loop2(pmt, len, p_info, max_es_nr); if(p_info->video_pid == PSI_STUFF_PID) p_info->video_pid = 0; PP_PRINTF("PMT parse ret=%d, prog num=%d, pmt pid=%d,ca count=%d,av flag=%d\n", ret,p_info->prog_number, p_info->pmt_pid, p_info->CA_count,p_info->av_flag); return ret; }
/* * Name : psi_parse_loop2 * Description : parse pmt second loop. * Parameter : * INT8 *buff :seciton buffer * INT16 buff_len :buffer length * Return : */ static INT32 pmt_parse_loop2(UINT8 *pmt, UINT16 pmt_len, PROG_INFO *p_info, INT32 max_es_nr) { INT32 ret, es_cnt; UINT32 i, loop_len; struct pmt_stream_info *info; struct pmt_es_info es; UINT32 loop1_len = ((pmt[10]<<8)|pmt[11])&0x0FFF; UINT16 invalid_flag = 1; UINT32 j=0; UINT8 k=0; PP_PRINTF("\n %s(): es stream :\n",__FUNCTION__); for(es_cnt=0, i = sizeof(struct pmt_section)-4+loop1_len;i < (UINT32)pmt_len-4; i += sizeof(struct pmt_stream_info)+loop_len) { info = (struct pmt_stream_info *)(pmt+i); MEMSET(&es, 0, sizeof(struct pmt_es_info)); es.stream_type = info->stream_type; es.pid = SI_MERGE_HL8(info->elementary_pid); loop_len = SI_MERGE_HL8(info->es_info_length); ret = desc_loop_parser(info->descriptor, loop_len, pmt_loop2, ARRAY_SIZE(pmt_loop2), &es.stat, (void *)&es); if (ret != SI_SUCCESS) PP_PRINTF("%s: desc_loop_parser error, error= %d\n", ret); if (es.stat&ES_CA_EXIST) { //check if current es ca system is same with those recorded ones for(j=0;j<es.cas_count;j++) { //fix BUG17636, to get all ecm pids /* for(k=0; k<p_info->CA_count; k++) { if(p_info->CA_info[k].CA_system_id==es.cas_sysid[j]) { PP_PRINTF("es pid=%d, ca count=%d, cas_sysid[%d]=0x%x has same ca sysid with p_info->CA_info[%d]!\n" , es.pid, es.cas_count, j,es.cas_sysid[j], k); break; } } if( k==p_info->CA_count)*/ { if (p_info->CA_count < P_MAX_CA_NUM) { p_info->CA_info[p_info->CA_count].CA_system_id = es.cas_sysid[j]; p_info->CA_info[p_info->CA_count].CA_pid = es.cas_pid[j]; p_info->CA_count++; } else { PP_PRINTF("pmt_parse_loop2: ca system id count %d full!\n",p_info->CA_count); break; } } } } PP_PRINTF("es stream type=%d\n",es.stream_type); switch(es.stream_type) { case MPEG1_AUDIO_STREAM: case MPEG2_AUDIO_STREAM: if (TRUE == append_audio_pid(&es, p_info, 0)) invalid_flag = 0; break; case PRIVATE_DATA_STREAM: //case MPEG_AAC_STREAM: //case AC3_AUDIO_STREAM: if(es.stat&ES_TTX_EXIST) p_info->teletext_pid = es.pid; else if(es.stat&ES_SUB_EXIST) p_info->subtitle_pid = es.pid; #ifdef AC3DEC else if((es.stat&ES_AC3_EXIST)&&(TRUE == append_audio_pid(&es, p_info,AC3_DES_EXIST))) { //if(es.stream_type == AC3_AUDIO_STREAM) //p_info->prog_number +=1; invalid_flag = 0; } #if 1 else if((es.stat&ES_EAC3_EXIST)&&(TRUE == append_audio_pid(&es, p_info,EAC3_DES_EXIST))) { //if(es.stream_type == AC3_AUDIO_STREAM) //p_info->prog_number +=1; invalid_flag = 0; } #endif #endif break; #ifdef AC3DEC case AC3_AUDIO_STREAM: if(TRUE == append_audio_pid(&es, p_info,AC3_DES_EXIST)) { invalid_flag = 0; } break; case MPEG_AAC_STREAM: if(TRUE == append_audio_pid(&es, p_info,AAC_DES_EXIST)) { invalid_flag = 0; } break; case MPEG_ADTS_AAC_STREAM: if(TRUE==append_audio_pid(&es, p_info,ADTS_AAC_DES_EXIST)) { invalid_flag = 0; } break; #endif case MPEG1_VIDEO_STREAM: case MPEG2_VIDEO_STREAM: case MPEG4_VIDEO_STREAM: if (p_info->video_pid == PSI_STUFF_PID) { p_info->av_flag = 1; p_info->video_pid = es.pid; invalid_flag = 0; } break; case H264_VIDEO_STREAM: if (p_info->video_pid == PSI_STUFF_PID) { p_info->av_flag = 1; p_info->video_pid = es.pid|H264_VIDEO_PID_FLAG; invalid_flag = 0; } break; #if (SYS_PROJECT_FE == PROJECT_FE_DVBC) //case ISO13818_6_TYPE_A: case 0x05: case ISO13818_6_TYPE_B: //case ISO13818_6_TYPE_C: //case ISO13818_6_TYPE_D: invalid_flag = 0; break; #endif default: PP_PRINTF("es_type = 0x%x unknown!\n",__FUNCTION__, es.stream_type); break; } if (++es_cnt>=max_es_nr) { PP_PRINTF("es_cnt = %d exceed max_es_nr!\n",__FUNCTION__, es_cnt); break; } } PP_PRINTF("%s: es_cnt = %d!\n\n",__FUNCTION__, es_cnt); return invalid_flag? ERR_NO_PROG_INFO : SI_SUCCESS;; }
INT32 si_nit_parser(UINT8 *data, INT32 len, struct section_parameter *param) { INT32 i, ret, dloop_len; struct network_descriptor *nw_desc; struct nit_section_info *n_info = (struct nit_section_info *)param->priv; struct transport_stream_info *ts_info; if (data == NULL) { n_info->xp_nr = 0; return SI_SUCCESS; } #if(defined( _MHEG5_ENABLE_) || defined( _MHEG5_V20_ENABLE_)||defined(SUPPORT_FRANCE_HD)) //network_id n_info->net_id = (data[3]<<8) | data[4]; #endif #ifdef SUPPORT_FRANCE_HD n_info->version_num = (data[5]&0x3e)>>1; #endif nw_desc = &((struct nit_section *)data)->network; dloop_len = SI_MERGE_HL8(nw_desc->network_descriptor_length); if (n_info->lp1_nr&&(dloop_len>0)) { #ifdef AUTO_OTA ret = desc_loop_parser(nw_desc->descriptor, dloop_len, n_info->loop1, n_info->lp1_nr, &n_info->p_firstloopinfo.descriptors_parse_stat, n_info); #else ret = desc_loop_parser(nw_desc->descriptor, dloop_len, n_info->loop1, n_info->lp1_nr, NULL, n_info); #endif if (ret != SI_SUCCESS) { SN_PRINTF("%s: loop1 parse failure!\n", __FUNCTION__); return ret; } #ifdef AUTO_OTA if(0 == (&n_info->p_firstloopinfo.descriptors_parse_stat)&(1<<NIT_LINKAGE_EXIST_BIT)) set_linkagetype09_exist(0); #endif } if (n_info->lp2_nr==0) { return SI_SUCCESS; } for(i=sizeof(struct nit_section)+dloop_len-4; i<len-4; i += sizeof(struct transport_stream_info)+dloop_len) { ts_info = (struct transport_stream_info *)(data+i); n_info->tsid = SI_MERGE_UINT16(ts_info->transport_stream_id); n_info->onid = SI_MERGE_UINT16(ts_info->original_network_id); dloop_len = SI_MERGE_HL8(ts_info->transport_stream_length); if (dloop_len>0) { ret = desc_loop_parser(ts_info->descriptor, dloop_len, n_info->loop2, n_info->lp2_nr, NULL, n_info); if (ret != SI_SUCCESS) { SN_PRINTF("%s: loop2 parse failure!\n", __FUNCTION__); return ret; } } } return SI_SUCCESS; }