📄 play_psfdemux_multicast.c
字号:
if (! context->audio_opt->auto_detect_codec) { ACodec = context->MulticastACodec[context->MulticastCurrent]; goto audio_codec; } for (index = 0; index < context->AudioPidList.count; index++) { if (context->AudioPidList.elementary_pid[index] == context->audio_pid) break; } if (index >= context->AudioPidList.count) return RM_OK; switch (context->AudioPidList.stream_type[index]) { case 3: // mpeg 1 audio case 4: // mpeg 2 audio RMDBGLOG((ENABLE, "%lx_SwitchCodec: mpeg audio detected\n", context->id)); ACodec = AudioDecoder_Codec_MPEG1; break; case 6: // private, can be DTS audio RMDBGLOG((ENABLE, "%lx_SwitchCodec: unknown codec id = 6, by default DTS\n", context->id)); ACodec = stream_type_6; break; case 0x0f: // ISO/IEC 13818-7 Audio with ADTS transport syntax RMDBGLOG((ENABLE, "%lx_SwitchCodec: ADTS audio detected\n", context->id)); ACodec = AudioDecoder_Codec_AAC; context->audio_opt->AACParams.InputFormat = 1; // adif, no sync word context->audio_opt->AACParams.OutputChannels = Aac_LR; break; case 0x80: // 0x80 = bdlpcm RMDBGLOG((ENABLE, "%lx_SwitchCodec: bdlpcm audio detected\n", context->id)); ACodec = AudioDecoder_Codec_PCM; context->audio_opt->SubCodec = 3; context->audio_opt->PcmCdaParams.ChannelAssign = PcmCda2_LR; context->audio_opt->PcmCdaParams.BitsPerSample = 16; if (!context->audio_opt->OutputChannelsExplicitAssign) context->audio_opt->OutputChannels = Audio_Out_Ch_LR; break; case 0x81: // 0x81 = ac3 case 0x83: // 0x83 = dolby lossless - to check case 0x84: // 0x84 = dolby digital plus - to check RMDBGLOG((ENABLE, "%lx_SwitchCodec: ac3 audio detected\n", context->id)); ACodec = AudioDecoder_Codec_AC3; break; case 0x82: // 0x82 = dts case 0x85: // 0x85 = dts hd - to check RMDBGLOG((ENABLE, "%lx_SwitchCodec: dts audio detected\n", context->id)); ACodec = AudioDecoder_Codec_DTS; break; case 0xe6: // 0xe6 = wmaTS - Vincent case 0x11: // 0x11, audio with LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1 default: RMDBGLOG((ENABLE, "%lx_SwitchCodec: audio codec unknown, don't SwitchAudioDecoder !\n", context->id)); return RM_OK; } audio_codec: err = SwitchAudioDecoder(context, ACodec); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%lx_SwitchCodec: SwitchAudioDecoder Error=%d\n", context->id, err)); return RM_ERROR; } return RM_OK;}static RMstatus SetPidFilterForAVPlayback(struct context_per_task *context){ RMstatus err; fprintf(stderr, " m> %ld_SetPidFilterForAVPlayback ", context->id); if (!(context->av_flags & VIDEO_PID_FROM_CMDLINE)) { if(context->VideoPidList.count) { fprintf(stderr, "vpid[%lu]= 0x%04x(0x%02x) ", context->VideoPidList.index, context->VideoPidList.elementary_pid[context->VideoPidList.index], context->VideoPidList.stream_type[context->VideoPidList.index]); context->video_pid = context->VideoPidList.elementary_pid[context->VideoPidList.index]; context->ecm_pid[0] = context->VideoPidList.es_ecm_pid[context->VideoPidList.index]; } else fprintf(stderr, " vpid= NO pid in the list "); } if (!(context->av_flags & AUDIO_PID_FROM_CMDLINE)) { if(context->AudioPidList.count) { fprintf(stderr, "apid[%lu]= 0x%04x(0x%02x) ", context->AudioPidList.index, context->AudioPidList.elementary_pid[context->AudioPidList.index], context->AudioPidList.stream_type[context->AudioPidList.index]); context->audio_pid = context->AudioPidList.elementary_pid[context->AudioPidList.index]; context->ecm_pid[1] = context->AudioPidList.es_ecm_pid[context->AudioPidList.index]; } else fprintf(stderr, " apid= NO pid in the list "); } if (!(context->av_flags & PCR_PID_FROM_CMDLINE)) { context->pcr_pid = context->VideoPidList.pcr_pid; fprintf(stderr, "pcrpid= 0x%04x", context->VideoPidList.pcr_pid); } fprintf(stderr, "\n"); context->av_flags &= ~VIDEO_PID_FROM_CMDLINE; context->av_flags &= ~AUDIO_PID_FROM_CMDLINE; context->av_flags &= ~PCR_PID_FROM_CMDLINE; err = HwStop(context); //TODO play with disable if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_SetPidFilterForAVPlayback HwStop Error\n", context->id)); return err; } err = SwitchCodec(context); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_SetPidFilterForAVPlayback SwitchCodec Error\n", context->id)); return err; } /* set the new pids in the hardware pid filter */ err = SetHwAVPlayback(context); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_SetPidFilterForAVPlayback SetHwAVPlayback Error\n", context->id)); //return err; } err = HwPlay(context); //TODO with enable if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_SetPidFilterForAVPlayback HwPlay Error", context->id)); return err; } context->av_flags &= ~AV_PIDS_ENABLE_FIRST_TIME; return RM_OK;}static RMstatus SetNextPMT(struct context_per_task *context){ RMstatus err; struct DemuxTask_PidEntry_type entry; struct PMTInfo_type *pmt_info; RMDBGLOG((CALLDBG, "setNextPMT (context @0x%08lx)\n", (RMuint32)context)); if ( context->pat_info.count == 0 ) { fprintf(stderr, " m> %ld_NextPMT error: pat_info.count=0\n", context->id); return RM_ERROR; } /* next pmt in list */ context->pmt_index = (context->pmt_index+1)%context->pat_info.count; if (context->pat_info.program_number[context->pmt_index] == 0) { /* skip network PID*/ context->pmt_index = (context->pmt_index+1)%context->pat_info.count; } pmt_info = &context->pmt_info[context->pmt_index]; if (pmt_info->count) { context->pmt = TRUE; } /* for time being use same Pid entry */ RMDBGLOG((ENABLE, " %ld_SetNextPMT sets pmt_pidentry_%lx pid=%lx\n", context->id, context->pmt_pidentry, context->pat_info.program_map_pid[context->pmt_index])); entry.index = context->pmt_pidentry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryDisable, &entry.index, sizeof(entry.index), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_PMT Error RMDemuxTaskPropertyID_PidEntryEnable", context->id)); return err; } entry.PidEntry.pid = context->pat_info.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)); return err; } 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)); return err; } { struct DemuxTask_MatchSectionEntry_type section_entry; /* * reset pmt version in hardware section filter */ context->match_section_table[1].section_entry.mask[5] = 0x00; context->match_section_table[1].section_entry.mode[5] = 0x00; context->match_section_table[1].section_entry.comp[5] = 0x00; 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")); } /* * reset ECM for next parity */ context->match_section_table[4].section_entry.mask[0] = 0xFC; context->match_section_table[4].section_entry.comp[0] = 0x80; section_entry.Index = context->match_section_table[4].index; section_entry.SectionEntry = context->match_section_table[4].section_entry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, §ion_entry, sizeof(section_entry), 0); if (RMFAILED(err)) { fprintf(stderr, "decoder: Error RMDemuxTaskPropertyID_MatchSectionEntry"); } context->match_section_table[5].section_entry.mask[0] = 0xFC; context->match_section_table[5].section_entry.comp[0] = 0x80; section_entry.Index = context->match_section_table[5].index; section_entry.SectionEntry = context->match_section_table[5].section_entry; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, §ion_entry, sizeof(section_entry), 0); if (RMFAILED(err)) { fprintf(stderr, "decoder: Error RMDemuxTaskPropertyID_MatchSectionEntry"); } } return RM_OK;}static RMstatus CheckAVPlaybackAgainstAVList(struct context_per_task *context){ RMDBGLOG((CALLDBG, "checkAVPlaybackAgainstAVList (context @0x%08lx)\n", (RMuint32)context)); if ( (context->video_pid == context->VideoPidList.elementary_pid[context->VideoPidList.index]) && (context->pcr_pid == context->VideoPidList.pcr_pid) && (context->audio_pid == context->AudioPidList.elementary_pid[context->AudioPidList.index]) ) return RM_OK; return RM_ERROR;}static RMstatus PmtSetAVList(struct context_per_task *context){ RMuint32 i, ai=0, vi=0; struct PMTInfo_type *pmt_info; RMDBGLOG((CALLDBG, "pmtSetAVList (context @0x%08lx)\n", (RMuint32)context)); if ( context->pat_info.count == 0 ) { fprintf(stderr, " m> %ld_PmtSetAVList error: empty PmtPidList\n", context->id); return RM_ERROR; } if (context->pat_info.program_number[context->pmt_index] == 0) { /* skip network PID*/ context->pmt_index = (context->pmt_index+1)%context->pat_info.count; } pmt_info = &context->pmt_info[context->pmt_index]; if (pmt_info->count == 0) { /* prepare for next pmt in list */ context->pmt_index = (context->pmt_index+1)%context->pat_info.count; fprintf(stderr, " m> %ld_PmtSetAVList index=%lx not found => try next pmt from pat list!\n", context->id, context->pmt_index); return RM_ERROR; } pmt_info->update = FALSE; /* handshake with ParsePMT */ fprintf(stderr, " m> %ld_PmtSetAVList index=%lx prog=0x%03x pid=0x%03x\n", context->id, context->pmt_index, context->pat_info.program_number[context->pmt_index], context->pat_info.program_map_pid[context->pmt_index]); fprintf(stderr, " m> %lu PES streams:\n", pmt_info->count); context->VideoPidList.pcr_pid = pmt_info->pcr_pid; for(i=0;i<pmt_info->count;i++) { // see page 45, 13818-1 (MPEG-2 Systems spec) switch (pmt_info->stream_type[i]) { case 1: // mpeg 1 video case 2: // mpeg 2 video case 0x10: // mpeg 4 video case 0x1b: // H264 video case 0xea: // VC-1 video //case 0x80: // video, it is used by wsnet to indicate a video stream context->VideoPidList.stream_type[vi] = pmt_info->stream_type[i]; context->VideoPidList.elementary_pid[vi] = pmt_info->elementary_pid[i]; if (pmt_info->es_ecm_count == 0) { // ECM for entire program if (pmt_info->ecm_count == 0) // No ECM context->VideoPidList.es_ecm_pid[vi] = 0x1FFF; else if (pmt_info->ecm_count == 1) // Standard context->VideoPidList.es_ecm_pid[vi] = pmt_info->ecm_pid[0]; else { // Wired TS if ((vi + ai) < pmt_info->ecm_count) context->VideoPidList.es_ecm_pid[vi] = pmt_info->ecm_pid[vi + ai]; else context->VideoPidList.es_ecm_pid[vi] = 0x1FFF; } } else { // ECM for elementary context->VideoPidList.es_ecm_pid[vi] = pmt_info->es_ecm_pid[i]; } fprintf(stderr, " m> vpid[%lu]= 0x%04x(0x%02x)= %s\n", vi, pmt_info->elementary_pid[i], pmt_info->stream_type[i], VideoTypeToString(pmt_info->stream_type[i])); fprintf(stderr, " m> ecm_pid=0x%04X\n", context->VideoPidList.es_ecm_pid[vi]); vi++; break; case 3: // mpeg 1 audio case 4: // mpeg 2 audio case 6: // private, can be DTS audio case 0x0f: // ISO/IEC 13818-7 Audio with ADTS transport syntax case 0x80: // audio for BR disc !! case 0x81: // 0x81 = ac3 case 0x82: // 0x82 = dts case 0x83: // 0x83 = dolby lossless case 0x84: // 0x84 = dolby digital plus case 0x85: // 0x85 = dts hd case 0xe6: // 0xe6 = wmaTS - Vincent case 0x11: // 0x11, audio with LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1 context->AudioPidList.stream_type[ai] = pmt_info->stream_type[i]; context->AudioPidList.elementary_pid[ai] = pmt_info->elementary_pid[i]; if (pmt_info->es_ecm_count == 0) { // ECM for entire program if (pmt_info->ecm_count == 0) // No ECM context->AudioPidList.es_ecm_pid[ai] = 0x1FFF; else if (pmt_info->ecm_count == 1) // Standard context->AudioPidList.es_ecm_pid[ai] = pmt_info->ecm_pid[0]; else { // Wired TS if ((ai + vi) < pmt_info->ecm_count) context->AudioPidList.es_ecm_pid[ai] = pmt_info->ecm_pid[ai + vi]; else context->AudioPidList
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -