static BOOL append_audio_pid(struct pmt_es_info *es, PROG_INFO *info, UINT16 attr) { BOOL ret; UINT32 audio_cnt; UINT8 i,j = 0; UINT8 *lang = es->lang; audio_cnt = info->audio_count; if(audio_cnt < P_MAX_AUDIO_NUM) { #if (defined(DTG_AUDIO_SELECT) || defined(AUDIO_DESCRIPTION_SUPPORT)) if(es->track_count != 0) { for(i=0; i<es->track_count; i++) { MEMCPY(info->audio_lang[audio_cnt], lang, 3); info->audio_type[audio_cnt] = es->audio_type[i]; info->audio_pid[audio_cnt] = es->pid|attr; //left and right track have same PID info->audio_com_tag[audio_cnt] = es->audio_com_tag; lang += 3; audio_cnt++; } info->audio_count = audio_cnt; } else { MEMSET(info->audio_lang[audio_cnt], 0, 3); info->audio_pid[audio_cnt] = es->pid|attr; info->audio_com_tag[audio_cnt] = es->audio_com_tag; info->audio_count = audio_cnt+1; } #else info->audio_pid[audio_cnt] = es->pid|attr; info->audio_com_tag[audio_cnt] = es->audio_com_tag; if (lang[0]&&lang[1]&&lang[2]) { MEMCPY(info->audio_lang[audio_cnt], lang, 3); } else { MEMSET(info->audio_lang[audio_cnt], 0, 3); } info->audio_count = audio_cnt+1; #endif PP_PRINTF("+aud_pid=%d\n", es->pid); ret = TRUE; } else { PP_PRINTF("-aud_pid=%d\n", es->pid); ret = FALSE; } PP_PRINTF("lang code: %c%c%c\n", lang[0], lang[1], lang[2]); return ret; }
static INT32 loop2_ca_desc_handle(UINT8 tag, UINT8 len, UINT8 *desc, void *priv) { struct pmt_es_info *info = (struct pmt_es_info *)priv; if (info->cas_count < P_MAX_CA_NUM) { info->cas_sysid[info->cas_count]= (desc[0]<<8) |desc[1]; info->cas_pid[info->cas_count] = ((desc[2]&0x1F)<<8) |desc[3]; PP_PRINTF("PMT loop2 ca_desc_handler, ca_sysid=0x%x,pid=%d,CA_count=%d\n", info->cas_sysid[info->cas_count],info->cas_pid[info->cas_count],info->cas_count+1); info->cas_count++; } else { PP_PRINTF("%s: ca count %d full!\n",__FUNCTION__,info->cas_count); } return SI_SUCCESS; }
static INT32 loop1_ca_desc_handle(UINT8 tag, UINT8 len, UINT8 *desc, void *priv) { PROG_INFO *info = (PROG_INFO *)priv; if (info->CA_count < P_MAX_CA_NUM) { info->CA_info[info->CA_count].CA_system_id = (desc[0]<<8) |desc[1]; info->CA_info[info->CA_count].CA_pid = ((desc[2]&0x1F)<<8) |desc[3]; PP_PRINTF("PMT loop1 ca_desc_handler, ca_sysid=0x%x,pid=%d,CA_count=%d\n", info->CA_info[info->CA_count].CA_system_id,info->CA_info[info->CA_count].CA_pid,info->CA_count+1); info->CA_count++; } else { PP_PRINTF("%s: ca count %d full!\n",__FUNCTION__,info->CA_count); } return SI_SUCCESS; }
static INT32 loop1_pr_desc_handle(UINT8 tag, UINT8 len, UINT8 *desc, void *priv) { PROG_INFO *info = (PROG_INFO *)priv; UINT8 country_code[3]; UINT8 rating=0; //do //{ country_code[0] = desc[0]; country_code[1] = desc[1]; country_code[2] = desc[2]; g_pmt_rating=desc[3]; PP_PRINTF("country_code: %c%c%c\n",country_code[0],country_code[1],country_code[2]); PP_PRINTF("rating: %d\n",rating); //desc+= 4; //} while (p < desc+len); 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;; }
static BOOL append_audio_pid(struct pmt_es_info *es, PROG_INFO *info, UINT16 attr) { BOOL ret; UINT32 audio_cnt; UINT8 j = 0; UINT8 *lang = es->lang; audio_cnt = info->audio_count; if(audio_cnt < P_MAX_AUDIO_NUM) { #ifdef CONAX_AUDIO_LAN_USE if (lang[0]&&lang[1]&&lang[2]) { MEMCPY(info->audio_lang[audio_cnt], lang, 3); info->audio_pid[audio_cnt] = es->pid|attr; audio_cnt ++; info->audio_count = audio_cnt; } else { MEMSET(info->audio_lang[audio_cnt], 0, 3); } if (lang[3]&&lang[4]&&lang[5]) { MEMCPY(info->audio_lang[audio_cnt], (lang + 3), 3); info->audio_pid[audio_cnt] = es->pid|attr; audio_cnt ++; info->audio_count = audio_cnt; } else { MEMSET(info->audio_lang[audio_cnt], 0, 3); } if ((lang[0]&&lang[1]&&lang[2]) == 0) { info->audio_pid[audio_cnt] = es->pid|attr; info->audio_count = audio_cnt+1; } #else info->audio_pid[audio_cnt] = es->pid|attr; if (lang[0]&&lang[1]&&lang[2]) { MEMCPY(info->audio_lang[audio_cnt], lang, 3); } else { MEMSET(info->audio_lang[audio_cnt], 0, 3); } #ifdef NL_BZ if (lang[3]&&lang[4]&&lang[5]) { MEMCPY(info->audio_lang[audio_cnt + 3], (lang + 3), 3); } else { MEMSET(info->audio_lang[audio_cnt + 3], 0, 3); } #endif info->audio_count = audio_cnt+1; #ifdef AUDIO_CHANNEL_LANG_SUPPORT if ((info->audio_count < P_MAX_AUDIO_NUM) && (lang[3] && lang[4] && lang[5])) { // add one more audio pid for the channel language MEMCPY(info->audio_lang[info->audio_count], (lang + 3), 3); info->audio_pid[info->audio_count] = es->pid | attr; info->audio_count++; } #endif #endif PP_PRINTF("+aud_pid=%d\n", es->pid); ret = TRUE; } else { PP_PRINTF("-aud_pid=%d\n", es->pid); ret = FALSE; } PP_PRINTF("lang code: %c%c%c\n", lang[0], lang[1], lang[2]); return ret; }