?? psfdemux_parsing.c
字號:
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]; //fprintf(stderr, "found od id 0x%x pid 0x%x\n",out->odID, out->odPid ); } } else if( out->stream_type[out->count-1] == 0x12 ) { // sl pes stream if( p[0] == 0x1e ) { // sl descriptor if( out->mp4AudioID != 0 ) { out->mp4VideoID = id; // assume first pes is audio out->mp4VideoPid = out->elementary_pid[out->count-1]; } else { out->mp4AudioID = id; out->mp4AudioPid = out->elementary_pid[out->count-1]; } } } } next_descriptor -= (p[1] + 2); } len--; es_info_len--; if (es_info_len == 0) { if (len > 4) { // another stream follows PmtState = PMT_STREAM_TYPE; } else { PmtState++; } } break; case PMT_CRC_3: case PMT_CRC_2: case PMT_CRC_1: PmtState++; len--; break; case PMT_CRC_0: PmtState++; len--; if (len) { fprintf(stderr, "ParsePMT 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 = PMT_TABLE_ID; break; } size--; size1--; if (size1 == 0) p = pBuffer2; else p++; } //fprintf(stderr, "BIFS id 0x%x pid 0x%x, OD id 0x%x pid 0x%x, ",out->bifsID, out->bifsPid, out->odID, out->odPid ); //fprintf(stderr, "VIDEO id 0x%x pid 0x%x, AUDIO id 0x%x pid 0x%x \n",out->mp4VideoID, out->mp4VideoPid, out->mp4AudioID, out->mp4AudioPid ); return RM_OK;}void PATCallback(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, RMstatus err, RMuint32 mask, void *context_in){ /* the API is more general with two pointers - in current implementation we use only first buffer */ struct context_per_task *context = (struct context_per_task *)context_in; struct PATInfo_type pat_info_temp; RMuint32 i; RMuint32 pat_compare_size; RMDBGLOG((CALLDBG, "PATCallback (context @0x%08lx)\n", (RMuint32)context_in)); if(RMFAILED(err)) { fprintf(stderr, "%ld_PATCallback ERROR\n", context->id); return; } // if (size1 > 188) // fprintf(stderr, "multiple PAT sections %ld\n", size1); RMMemset(&pat_info_temp, 0, sizeof(struct PATInfo_type)); err = ParsePAT(pBuffer1, size1, pBuffer2, size2, &pat_info_temp); if(RMFAILED(err)) { fprintf(stderr, "%ld_PATCallback ERROR\n", context->id); return; } /* compare the PAT content except for version */ pat_compare_size = (RMuint32)&pat_info_temp.version_number_current_next_indicator - (RMuint32)&pat_info_temp.count; if ( RMMemcmp((void*)&context->pat_info, (void*)&pat_info_temp, pat_compare_size) != 0 ) { struct DemuxTask_PidEntry_type entry; context->pat_info = pat_info_temp; fprintf(stderr, " %ld_PAT: ", context->id); for (i=0; i<pat_info_temp.count; i++) { fprintf(stderr, "[%4x %3x] ", pat_info_temp.program_number[i], pat_info_temp.program_map_pid[i]); /* allocate pid entries for every PMT and keep track of these PMT pid entries in one list */ } fprintf(stderr, "\n"); if (context->pmt_index >= pat_info_temp.count) { RMDBGLOG((ENABLE, " %ld_PATCallback user selected pmt index is invalid(%ld), set pmt_index=0\n", context->id, context->pmt_index)); context->pmt_index = 0; } if (pat_info_temp.program_number[context->pmt_index] == 0) { /* skip network PID*/ context->pmt_index = (context->pmt_index + 1) % pat_info_temp.count; } RMDBGLOG((ENABLE, " %ld_PATCallback sets pmt_pidentry_%lx pid=%lx\n", context->id, context->pmt_pidentry, pat_info_temp.program_map_pid[context->pmt_index])); /* check if the new pmt pid is already used in the PidBank by this task. The pid filter doesn't support more than one pid entry with same pid value. */ { struct EMhwlibPidUsage_type pid_usage; RMuint32 pid_value = pat_info_temp.program_map_pid[context->pmt_index]; err = RUAExchangeProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidUsage, &pid_value, sizeof(pid_value), &pid_usage, sizeof(pid_usage)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error xchg property RMDemuxTaskPropertyID_PidUsage! %s\n", RMstatusToString(err))); } else if (pid_usage.flags) { if (pid_usage.flags && PID_USED_IN_PID_BANK) { for (i=0; i<RMmin(pid_usage.count, 4); i++) { // disable the same pid in the table entry.index = pid_usage.pid_entries[i]; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryDisable, &entry.index, sizeof(entry.index), 0); } } if (pid_usage.flags && PID_USED_AS_HWPCR) { // disable the hw pcr pid RMuint32 dummy; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PCRPidEntryDisable, &dummy, sizeof(dummy), 0); } if ((pid_usage.flags & PID_USED_AS_PAT) || (pid_usage.flags & PID_USED_AS_CAT) || (pid_usage.flags & PID_USED_AS_MGT)) { RMDBGLOG((ENABLE, "New PMT pid is 0x%lx - is it correct PAT, CAT, MGT ?!\n", pid_value)); } } } /* set the first pmt pid */ entry.index = context->pmt_pidentry; entry.PidEntry.pid = pat_info_temp.program_map_pid[context->pmt_index]; entry.PidEntry.input_type = EMhwlibPid_Ts; entry.PidEntry.flags = TS_FLAGS; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntry, &entry, sizeof(entry), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_PMT Error RMDemuxTaskPropertyID_PidEntry", context->id)); } err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryEnable, &entry.index, sizeof(entry.index), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_PMT Error RMDemuxTaskPropertyID_PidEntryEnable", context->id)); } { struct DemuxTask_MatchSectionEntry_type section_entry; /* filter any version of pmt section in hardware section filter */ context->match_section_table[1].section_entry.mask[5] = 0; context->match_section_table[1].section_entry.mode[5] = 0; context->match_section_table[1].section_entry.comp[5] = 0; section_entry.Index = context->match_section_table[1].index; section_entry.SectionEntry = context->match_section_table[1].section_entry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, §ion_entry, sizeof(section_entry), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error RMDemuxTaskPropertyID_MatchSectionEntry")); } } context->pat = TRUE; RMDBGLOG((ENABLE, "PAT SET!\n")); }#ifndef WITH_TIME_SHIFT if(context->section_filter_based_on_new_version & 1) { /* filter only a new pat version in hardware section filter - in order to optimize CPU usage on standalone */ struct DemuxTask_MatchSectionEntry_type section_entry; /* version_number on bit 5..1, current_next_indicator on bit 0 */ context->match_section_table[0].section_entry.mask[5] = 0x3f; context->match_section_table[0].section_entry.mode[5] = ~0x3f; context->match_section_table[0].section_entry.comp[5] = pat_info_temp.version_number_current_next_indicator; section_entry.Index = context->match_section_table[0].index; section_entry.SectionEntry = context->match_section_table[0].section_entry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, §ion_entry, sizeof(section_entry), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error RMDemuxTaskPropertyID_MatchSectionEntry")); } }#endif}void PMTCallback(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, RMstatus err, RMuint32 mask, void *context_in){ /* the API is more general with two pointers - in current implementation we use only first buffer */ struct context_per_task *context = (struct context_per_task *)context_in; static struct PMTInfo_type pmt_info_temp; RMuint32 i, j; RMuint32 pmt_compare_size; RMDBGLOG((CALLDBG, "PMTCallback (context @0x%08lx)\n", (RMuint32)context_in)); if(RMFAILED(err)) { fprintf(stderr, "%ld_PMTCallback ERROR\n", context->id); return; } // if (size1 > 188) // fprintf(stderr, "%ld_PMT multiple sections in callback %ld\n", context->id, size1); RMMemset(&pmt_info_temp, 0, sizeof(struct PMTInfo_type)); err = ParsePMT(pBuffer1, size1, pBuffer2, size2, &pmt_info_temp); if(RMFAILED(err)) { fprintf(stderr, "%ld_PMTCallback ERROR\n", context->id); return; } for (i=0; i<context->pat_info.count; i++) { if ( pmt_info_temp.program_number == context->pat_info.program_number[i] ) break; } if (i >= context->pat_info.count) { fprintf(stderr, " %ld_PMT - pat not found yet\n", context->id); return; } if (0) { /* debug messages */ fprintf(stderr, " %ld_PMT: index=%ld prog=0x%04x pid=0x%x ", context->id, i, pmt_info_temp.program_number, context->pat_info.program_map_pid[i]); for (j=0; j<pmt_info_temp.count; j++) { fprintf(stderr, "[0x%04x 0x%03x] ", pmt_info_temp.stream_type[j], pmt_info_temp.elementary_pid[j]); } fprintf(stderr, "\n"); } /* compare the PMT content except for version and update */ pmt_compare_size = (RMuint32)&pmt_info_temp.version_number_current_next_indicator - (RMuint32)&pmt_info_temp.count; if ( (RMMemcmp((void*)&context->pmt_info[i], (void*)&pmt_info_temp, pmt_compare_size) != 0) ) { pmt_info_temp.update = TRUE; context->pmt_info[i] = pmt_info_temp; fprintf(stderr, " %ld_PMT: index=%ld prog=0x%04x pid=0x%x pcr_pid=0x%x ", context->id, i, pmt_info_temp.program_number, context->pat_info.program_map_pid[i], pmt_info_temp.pcr_pid); for (i=0; i<pmt_info_temp.count; i++) { fprintf(stderr, "[0x%04x 0x%03x] ", pmt_info_temp.stream_type[i], pmt_info_temp.elementary_pid[i]); } fprintf(stderr, "\n"); for (i=0; i<pmt_info_temp.ecm_count; i++) { fprintf(stderr, " %ld_PMT: ", context->id); fprintf(stderr, "ecm=0x%04x ca=0x%04x emm=0x%04x\n", pmt_info_temp.ecm_pid[i], pmt_info_temp.ca_system_id[i], GetEMMPid(context, pmt_info_temp.ca_system_id[i])); } if (pmt_info_temp.es_ecm_count != 0) { for (i=0; i<pmt_info_temp.count; i++) { fprintf(stderr, " %ld_PMT: ", context->id); fprintf(stderr, "es_ecm=0x%04x es_ca=0x%04x es_emm=0x%04x\n", pmt_info_temp.es_ecm_pid[i], pmt_info_temp.es_ca_system_id[i], GetEMMPid(context, pmt_info_temp.es_ca_system_id[i])); } } context->pmt = TRUE; }#ifndef WITH_TIME_SHIFT if(context->section_filter_based_on_new_version & 2) { /* filter only a new pmt version in hardware section filter - in order to optimize CPU usage on standalone */ struct DemuxTask_MatchSectionEntry_type section_entry; /* version_number on bit 5..1, current_next_indicator on bit 0 */ context->match_section_table[1].section_entry.mask[5] = 0x3f; context->match_section_table[1].section_entry.mode[5] = ~0x3f; /* negative mode */ context->match_section_table[1].section_entry.comp[5] = pmt_info_temp.version_number_current_next_indicator; section_entry.Index = context->match_section_table[1].index; section_entry.SectionEntry = context->match_section_table[1].section_entry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, §ion_entry, sizeof(section_entry), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error RMDemuxTaskPropertyID_MatchSectionEntry")); } }#endif}/************************************************************************ * MPEG-2-system.pdf (ISO/IEC 13818-1: 1994(E) * 2.4.4.6 Conditional access table ************************************************************************/RMstatus ParseCAT(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, struct CATInfo_type *out){ /* * function assumes to be called on correct CAT boundaries */#define CAT_TABLE_ID 1#define CAT_LENGTH_HI 2#define CAT_LENGTH_LO 3#define CAT_RESERVED_0 4#define CAT_RESERVED_1 5#define CAT_VERSION_NUMBER 6#define CAT_SECTION_NUMBER 7#define CAT_LAST_SECTION_NUMBER 8#define CAT_DESCRIPTOR_TAG 9#define CAT_DESCRIPTOR_LENGTH 10#define CAT_CA_SYSTEM_ID_HI 11#define CAT_CA_SYSTEM_ID_LO 12#define CAT_CA_PID_HI 13#define CAT_CA_PID_LO 14#define CAT_CA_PRIVATE_DATA 15#define CAT_CRC_3 16#define CAT_CRC_2 17#define CAT_CRC_1 18#define CAT_CRC_0 19 RMuint32 CatState = CAT_TABLE_ID; RMuint16 length = 0, descriptor_tag = 0, descriptor_length = 0, ca_system_id = 0, ca_pid = 0; RMuint8 section_number, last_section_number; RMuint32 size = size1 + size2; RMuint16 len = 0; RMuint8 *p = NULL; RMDBGLOG((CALLDBG, "parseCAT\n")); if (out == 0) return RM_ERROR; out->count = 0; if (pBuffer1 && size1) p = pBuffer1; while (size) { switch (CatState) { case CAT_TABLE_ID: if (*p != 0x01) { fprintf(stderr, "ParseCAT table_id=%02x instead of 0x01 !\n", *p); return RM_ERROR; } CatState++; break; case CAT_LENGTH_HI: /* section_syntax_indicator and length_hi*/ if ((*p & 0xC0) != 0x80) { fprintf(stderr, "ParseCAT section_syntax_indicator 0 !\n"); return RM_ERROR; } length = *p & 0x0F; length <<= 8;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -