📄 psfdemux_parsing.c
字号:
len--; break; case PAT_PROGRAM_MAP_PID_LO: program_map_pid |= *p; /*fprintf(stderr, "\n %x %x", program_number, program_map_pid);*/ len--; if (len > 4) // another program follows PatState = PAT_PROGRAM_NUMBER_HI; else PatState++; out->program_map_pid[out->count] = program_map_pid; out->count++; if ( out->count > MAX_PROGRAM_NUMBER ) { fprintf(stderr, "ParsePAT has more programs than the max=0x%x !\n", MAX_PROGRAM_NUMBER); return RM_ERROR; } break; case PAT_CRC_3: case PAT_CRC_2: case PAT_CRC_1: PatState++; len--; break; case PAT_CRC_0: PatState++; len--; if (len) { fprintf(stderr, "ParsePAT reach CRC but there are 0x%x bytes left from 0x%x !\n", len, length); return RM_ERROR; } //uncomment next line to process all the sections in this buffer //PatState = PAT_TABLE_ID; break; } size--; size1--; if (size1 == 0) p = pBuffer2; else p++; } return RM_OK;}void ParseCADescriptor(RMuint8 *p, RMuint16 *ca_sys_id, RMuint16 *ecm_pid){ RMDBGLOG((CALLDBG, "parseCADescriptor\n")); if (p == 0) return; *ca_sys_id = (p[2] << 8) | p[3]; *ecm_pid = ((p[4] << 8) | p[5]) & 0x1FFF; /* * PID=0x1FFF: Place a limited reception method descriptor and point out * an ineffective ECM. There is no ECM stream. */}/************************************************************************ * Fetch the corresponding EMM pid from CA SYSTEM ID ************************************************************************/RMuint16 GetEMMPid(struct context_per_task *context, RMuint16 ca_id){ RMuint32 i; for (i = 0; i < context->cat_info.count; i++) { if (context->cat_info.ca_system_id[i] == ca_id) { return(context->cat_info.emm_pid[i]); } } return(0);}RMstatus ParsePMT(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, struct PMTInfo_type *out){ /* function assumes to be called on correct PMT boundaries */#define PMT_TABLE_ID 1#define PMT_LENGTH_HI 2#define PMT_LENGTH_LO 3#define PMT_PROGRAM_NUMBER_HI 4#define PMT_PROGRAM_NUMBER_LO 5#define PMT_VERSION_NUMBER 6#define PMT_SECTION_NUMBER 7#define PMT_LAST_SECTION_NUMBER 8#define PMT_PCR_PID_HI 9#define PMT_PCR_PID_LO 10#define PMT_PROGRAM_INFO_LENGHT_HI 11#define PMT_PROGRAM_INFO_LENGHT_LO 12#define PMT_DESCRIPTOR1 13#define PMT_STREAM_TYPE 14#define PMT_ELEMENTARY_PID_HI 15#define PMT_ELEMENTARY_PID_LO 16#define PMT_ES_INFO_LENGHT_HI 17#define PMT_ES_INFO_LENGHT_LO 18#define PMT_DESCRIPTOR2 19#define PMT_CRC_3 20#define PMT_CRC_2 21#define PMT_CRC_1 22#define PMT_CRC_0 23 RMuint32 PmtState = PMT_TABLE_ID; RMuint16 length = 0, program_number = 0, pcr_pid = 0, program_info_length = 0, elementary_pid = 0, es_info_length = 0; RMuint8 section_number, last_section_number, stream_type = 0; RMuint32 size = size1 + size2; RMuint16 len = 0, info_len = 0, es_info_len = 0; RMuint8 *p = NULL; RMuint16 next_descriptor = 0; RMDBGLOG((CALLDBG, "parsePMT\n")); if (out == NULL) return RM_ERROR; out->count = 0; out->ecm_count = 0; out->es_ecm_count = 0; out->mp4 = 0; out->bifsID = 0; out->bifsPid = 0x1fff; out->odID = 0; out->odPid = 0x1fff; out->mp4VideoID = 0; out->mp4AudioID = 0; out->mp4VideoPid = 0x1fff; out->mp4AudioPid = 0x1fff; if (pBuffer1 && size1) { p = pBuffer1; } while (size) { switch (PmtState) { case PMT_TABLE_ID: if (*p != 0x02) { fprintf(stderr, "ParsePMT table_id=%02x instead of 0x02 !\n", *p); return RM_ERROR; } PmtState++; break; case PMT_LENGTH_HI: // section_syntax_indicator and length_hi if ((*p & 0xc0) != 0x80) { fprintf(stderr, "ParsePMT section_syntax_indicator 0 !\n");// return RM_ERROR; } length = *p & 0x0f; length <<= 8; PmtState++; break; case PMT_LENGTH_LO: length |= *p; len = length; if (len > 0x3FD) { fprintf(stderr, "ParsePMT length greater than 0x3FD !\n"); return RM_ERROR; } PmtState++; break; case PMT_PROGRAM_NUMBER_HI: program_number = *p; program_number <<= 8; PmtState++; len--; break; case PMT_PROGRAM_NUMBER_LO: program_number |= *p; out->program_number = program_number; PmtState++; len--; break; case PMT_VERSION_NUMBER: /* version_number on bit 5..1, current_next_indicator on bit 0 */ out->version_number_current_next_indicator = *p & 0x3f; RMDBGLOG((DISABLE, "ParsePMT version number = %x current_next_indicator = %x\n", out->version_number_current_next_indicator>>1, out->version_number_current_next_indicator & 1)); PmtState++; len--; break; case PMT_SECTION_NUMBER: if (*p != 0x00) { fprintf(stderr, "ParsePMT section not NULL !\n"); return RM_ERROR; } section_number = *p; PmtState++; len--; break; case PMT_LAST_SECTION_NUMBER: if (*p != 0x00) { fprintf(stderr, "ParsePMT last_section not NULL !\n"); return RM_ERROR; } last_section_number = *p; PmtState++; len--; break; case PMT_PCR_PID_HI: pcr_pid = *p & 0x1f; pcr_pid <<= 8; PmtState++; len--; break; case PMT_PCR_PID_LO: pcr_pid |= *p; PmtState++; len--; out->pcr_pid = pcr_pid; break; case PMT_PROGRAM_INFO_LENGHT_HI: program_info_length = *p & 0x0f; program_info_length <<= 8; PmtState++; len--; break; case PMT_PROGRAM_INFO_LENGHT_LO: program_info_length |= *p; if (program_info_length > 0x3FF) { fprintf(stderr, "ParsePMT program_info_length greater than 0x3FF !\n"); return RM_ERROR; } info_len = program_info_length; next_descriptor = info_len; if (info_len == 0) PmtState = PMT_STREAM_TYPE; else PmtState++; len--; /*fprintf(stderr, "\n prog=%x len=%x pcr_pid=%x info_len=%x", program_number, length, pcr_pid, program_info_length);*/ break; case PMT_DESCRIPTOR1: /* * Conditional Accesss for entire program * descriptor tag = 0x09 * CA system ID = ? * PID = 0x???? (ECM) */ if (info_len == next_descriptor) {/* new descriptor*/ //fprintf(stderr,"PMT_DESCRIPTOR1 = 0x%X\n", *p); if ((next_descriptor > 5) && (*p == 0x09)) { RMuint16 ca_sys_id = 0, ecm_pid = 0x1FFF; ParseCADescriptor(p, &ca_sys_id, &ecm_pid); out->ca_system_id[out->ecm_count] = ca_sys_id; out->ecm_pid[out->ecm_count] = ecm_pid; //fprintf(stderr, "ParsePMT CA [%ld] descriptor CA_system_ID=0x%04x CA_PID=0x%03x\n", out->ecm_count, ca_sys_id, ecm_pid); out->ecm_count++; } else if ((next_descriptor > 5) && (*p == 0x1d) ) { out->mp4 = 1;#ifdef WITH_MONO fprintf( stderr, "Mono cannot parse MP$ IOD\n" ); out->odID = 0; out->bifsID = 0x1fff;#else ParseIODDescriptor(p, & out->bifsID, & out->odID ); //fprintf(stderr, "bifs id 0x%x and od id 0x%x\n",out->bifsID, out->odID );#endif } next_descriptor -= (p[1] + 2); } info_len--; len--; if (info_len == 0) PmtState++; break; case PMT_STREAM_TYPE: if (len == 4) { fprintf(stderr, "ParsePMT without stream info data, goto crc, len=%d !\n", len); PmtState = PMT_CRC_3; break; } if (len < 9) { fprintf(stderr, "ParsePMT not enough data for stream and crc, len=%d !\n", len); return RM_ERROR; } stream_type = *p; PmtState++; len--; out->stream_type[out->count] = stream_type; //printf("STREAM TYPE = 0x%X\n", out->stream_type[out->count]); break; case PMT_ELEMENTARY_PID_HI: elementary_pid = *p & 0x1f; elementary_pid <<= 8; PmtState++; len--; break; case PMT_ELEMENTARY_PID_LO: elementary_pid |= *p; PmtState++; len--; out->elementary_pid[out->count] = elementary_pid; break; case PMT_ES_INFO_LENGHT_HI: es_info_length = *p & 0x0f; es_info_length <<= 8; PmtState++; len--; break; case PMT_ES_INFO_LENGHT_LO: es_info_length |= *p; if (es_info_length > 0x3FF) { fprintf(stderr, "ParsePMT es_info_length greater than 0x3FF !\n"); return RM_ERROR; } es_info_len = es_info_length; next_descriptor = es_info_len; len--; /*fprintf(stderr, "\n %2x %3x %3x", stream_type, elementary_pid, es_info_length);*/ if ((es_info_len == 0) && (len > 4)) /* another stream follows */ PmtState = PMT_STREAM_TYPE; else if ((es_info_len == 0) && (len <= 4)) /* CRC_32 */ PmtState = PMT_CRC_3; else /* descriptor */ PmtState++; out->es_ca_system_id[out->count] = 0; out->es_ecm_pid[out->count] = 0x1FFF; out->descriptor_count[out->count] = 0; out->count++; if ( out->count > MAX_STREAM_NUMBER ) { fprintf(stderr, "ParsePMT has more streams than the max=0x%x !\n", MAX_STREAM_NUMBER); return RM_ERROR; } break; case PMT_DESCRIPTOR2: if (es_info_len == next_descriptor) { /* new descriptor */ //fprintf(stderr, "ParsePMT elementary descriptor (2) tag=0x%X\n", *p); if((out->count) && (out->descriptor_count[out->count-1] < MAX_DESCRIPTOR_NUMBER)) { out->stream_descriptor[out->count-1][out->descriptor_count[out->count-1]] = *p; out->descriptor_count[out->count-1]++; } out->descriptor_count[out->count] = 0; if ((next_descriptor > 5) && (*p == 0x09)) { RMuint16 ca_sys_id = 0, ecm_pid = 0x1FFF; ParseCADescriptor(p, &ca_sys_id, &ecm_pid); if ((ecm_pid != 0x1FFF) && (ca_sys_id != 0)) { out->es_ca_system_id[out->count - 1] = ca_sys_id; out->es_ecm_pid[out->count - 1] = ecm_pid; fprintf(stderr, "ParsePMT elementary [%ld] descriptor CA_system_ID=0x%04x CA_PID=0x%03x\n", out->count-1, ca_sys_id, ecm_pid); out->es_ecm_count++; } } else if ((next_descriptor >=4) && (*p == 0x1e)) { RMuint16 id = (((RMuint16)p[2]<<8) | (RMuint16)p[3] ); fprintf(stderr, "found id 0x%x \n", id ); if( out->stream_type[out->count-1] == 0x13 ) { // sl section stream if( id == out->bifsID ) { out->bifsPid = out->elementary_pid[out->count-1]; //fprintf(stderr, "found bifs id 0x%x pid 0x%x\n",out->bifsID, out->bifsPid ); } else if( id == out->odID ) { out->odPid = out->elementary_pid[out->count-1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -