📄 play_psfswpvr.c
字号:
/* disable the ecm audio pid */ entry.index = context->ecm_pidentry[1]; err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryDisable, &entry.index, sizeof(entry.index), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%ld_SetHwAVPlayback Error ECM1 RMDemuxTaskPropertyID_PidEntryDisable", context->id)); return err; } }#if (FORCE_DECRYPTION) if (((context->app_type == aes_cbc_decryption) || (context->app_type == aes_ecb_decryption) || (context->app_type == multi2_decryption) || (context->app_type == dvbcsa_decryption)) && ((context->ecm_pid[0] == 0x1FFF) && (context->ecm_pid[1] = 0x1FFF))) { // Apply cipher to pid of video cipher.index = context->video_pidentry; /* pid index */ cipher.pid_cipher_index = 0; /* first and only cipher per pid in current implementation */ cipher.cipher_index = context->cipher_index[0]; /* 1st cipher index of this task */ err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryAddCipher, &cipher, sizeof(cipher), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "InitPidTablePerTask Error RMDemuxTaskPropertyID_PidEntryAddCipher")); return err; } // Apply cipher to pid of audio cipher.index = context->audio_pidentry; /* pid index */ cipher.pid_cipher_index = 0; /* first and only cipher per pid in current implementation */ cipher.cipher_index = context->cipher_index[0]; /* 1st cipher index of this task */ err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_PidEntryAddCipher, &cipher, sizeof(cipher), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "InitPidTablePerTask Error RMDemuxTaskPropertyID_PidEntryAddCipher")); return err; } }#endif return RM_OK;}static RMstatus SwitchAudioDecoder(struct context_per_task *context, enum AudioDecoder_Codec_type ACodec){ RMstatus err = RM_OK; if (context->audio_opt->Codec == ACodec) return err; RMDBGLOG((ENABLE, "%lx_SwitchAudioDecoder: from %u to %u SPDIF[%u]\n", context->id, context->audio_opt->Codec, ACodec, context->audio_opt->Spdif)); context->audio_opt->Codec = ACodec; if (ACodec == AudioDecoder_Codec_AC3) { context->audio_opt->Ac3Params.OutputChannels = Ac3_LR; if (!context->audio_opt->OutputChannelsExplicitAssign) context->audio_opt->OutputChannels = Audio_Out_Ch_LR; } /* apply the audio format - uninit, set codec, set specific parameters, init */ err = apply_audio_decoder_options(context->dcc_info, context->audio_opt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%lx_Error applying audio_decoder_options err=%d\n", context->id, err)); return RM_ERROR; } apply_dvi_hdmi_audio_options(context->dcc_info, context->audio_opt, 0, FALSE, FALSE, FALSE); return err;}static RMstatus SwitchVideoDecoder(struct context_per_task *context, enum VideoDecoder_Codec_type VCodec, enum MPEG_Profile MPEGProfile){ RMstatus err = RM_OK; RMuint32 dummy; struct ReceiveThreshold_type rec_thr; struct DemuxOutput_Connect_type connect; RMuint32 demux_output; if ((context->video_opt->MPEGProfile == MPEGProfile) && (context->video_opt->Codec == VCodec)) return err; fprintf(stderr, "\nSwitch Video Codec from %u to %u Profile from %u to %u\n", context->video_opt->Codec, VCodec, context->video_opt->MPEGProfile, MPEGProfile); demux_output = EMHWLIB_MODULE(DemuxOutput, context->videoDemuxOutputIndex + output_count_per_task * context->id); err = RUASetProperty(context->pRUA, demux_output, RMDemuxOutputPropertyID_Close, &dummy, sizeof(dummy), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "SwitchVideoDecoder cannot close DemuxOutput %lu err=%d\n", demux_output, err)); return err; } RMDBGLOG((LOCALDBG, "SwitchVideoDecoder: CloseVideoSource %p\n", context->dcc_info->pVideoSource)); err = DCCCloseVideoSource(context->dcc_info->pVideoSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%lx_Error cannot close video decoder err=%d\n", context->id, err)); return err; } clear_video_options(context->dcc_info, context->video_opt); clear_display_options(context->dcc_info, context->disp_opt); context->video_opt->Codec = VCodec; context->video_opt->MPEGProfile = MPEGProfile; err = OpenVideoDecoder(context); /* spu_hack: this will open the SpuDecoder too */ if (RMFAILED(err)) { RMDBGLOG((ENABLE, "SwitchVideoDecoder: can NOT open video decoder\n")); return err; } /* the decoder will provide the bitstream, pts and inband fifo - no need to open a DemuxOutput, just connect */ context->output_table[context->videoDemuxOutputIndex].consumer_module_id = context->dcc_info->video_decoder; connect.demux_task_module_id = context->demux_task; connect.consumer_module_id = context->output_table[context->videoDemuxOutputIndex].consumer_module_id; err = RUASetProperty(context->pRUA, demux_output, RMDemuxOutputPropertyID_Connect, &connect, sizeof(connect), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "SwitchVideoDecoder: DemuxOutput %ld failed to connect consumer=0x%lx\n", demux_output, connect.consumer_module_id)); return err; } err = DCCXSetVideoDecoderSourceCodec(context->dcc_info->pVideoSource, context->vcodec); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set video decoder codec %d\n", err)); return err; } /* apply the fixed vop rate if required */ err = apply_video_decoder_options(context->dcc_info, context->video_opt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%lx_Error applying video_decoder_options err=%d\n", context->id, err)); return RM_ERROR; } if ((! context->video_opt->VopInfo.FixedVopRate) && (! context->video_opt->vtimescale.enable)) { /* time stamps are in 45k, ask the decoder to interpolate the time info from stream. For m4v the property will succeed. */ context->video_opt->vtimescale.enable = TRUE; context->video_opt->vtimescale.time_resolution = 90000; err = RUASetProperty(context->dcc_info->pRUA, context->dcc_info->video_decoder, RMVideoDecoderPropertyID_VideoTimeScale, &context->video_opt->vtimescale, sizeof(context->video_opt->vtimescale), 0 ); if (RMSUCCEEDED(err)) { RMDBGLOG((ENABLE, "set video time scale: %ld ticks per second\n", context->video_opt->vtimescale.time_resolution)); } else if (0){ /* time scaling is not supported - it happens for NO M4V decoders. We have to use fixed vop rate. */ context->video_opt->VopInfo.FixedVopRate = TRUE; context->video_opt->VopInfo.VopTimeIncrementResolution = 90000; context->video_opt->VopInfo.FixedVopTimeIncrement = 3000; err = RUASetProperty(context->dcc_info->pRUA, context->dcc_info->video_decoder, RMVideoDecoderPropertyID_VopInfo, &context->video_opt->VopInfo, sizeof(context->video_opt->VopInfo), 0 ); if (RMSUCCEEDED(err)) { RMDBGLOG((ENABLE, "video time scale not supported. Set fixed vop rate: %ld / %ld frames per second\n", context->video_opt->VopInfo.VopTimeIncrementResolution, context->video_opt->VopInfo.FixedVopTimeIncrement)); } else { RMDBGLOG((ENABLE,"video time scale not supported. Error setting fixed VOP rate : %d !\n", err)); } } } RUASetProperty(context->pRUA, demux_output, RMDemuxOutputPropertyID_Enable, &dummy, sizeof(dummy), 0); RUASetProperty(context->pRUA, demux_output, RMDemuxOutputPropertyID_DataType, &context->output_table[context->videoDemuxOutputIndex].type, sizeof(context->output_table[context->videoDemuxOutputIndex].type), 0); /* set to 0 the threshold because in case of playback I don't need the interrupts for receive */ rec_thr.partial_read = FALSE; rec_thr.size = 0; RUASetProperty(context->pRUA, demux_output, RMGenericPropertyID_Threshold, &rec_thr, sizeof(rec_thr), 0); /* by default the output has the pts enabled */ if (!context->play_opt->send_video_pts) { err = RUASetProperty(context->dcc_info->pRUA, demux_output, RMDemuxOutputPropertyID_EnablePts, &context->play_opt->send_video_pts, sizeof(context->play_opt->send_video_pts), 0 ); } return err;}static RMstatus SwitchCodec(struct context_per_task *context){ enum AudioDecoder_Codec_type ACodec; enum VideoDecoder_Codec_type VCodec; enum MPEG_Profile MPEGProfile; RMuint32 index; RMstatus err; if (! context->video_opt->auto_detect_codec) goto audio_codec; for (index = 0; index < context->VideoPidList.count; index++) { if (context->VideoPidList.elementary_pid[index] == context->video_pid) break; } if (index >= context->VideoPidList.count) goto audio_codec; switch (context->VideoPidList.stream_type[index]) { case 1: // mpeg 1 video RMDBGLOG((ENABLE, "mpeg1 video detected, error\n")); return RM_ERROR; break; case 2: // mpeg 2 video RMDBGLOG((LOCALDBG, "mpeg2 video detected\n")); MPEGProfile = Profile_MPEG2_HD; VCodec = VideoDecoder_Codec_MPEG2_HD; break; case 0x10: // mpeg 4 video RMDBGLOG((LOCALDBG, "mpeg4 video detected\n")); MPEGProfile = Profile_MPEG4_HD; VCodec = VideoDecoder_Codec_MPEG4_HD; break; case 0x1b: // H264 video RMDBGLOG((LOCALDBG, "h264 video detected\n")); MPEGProfile = Profile_H264_HD; VCodec = VideoDecoder_Codec_H264_HD; break; case 0xea: // VC-1 video RMDBGLOG((LOCALDBG, "VC-1 video detected\n")); MPEGProfile = Profile_VC1_HD; VCodec = VideoDecoder_Codec_VC1_HD; default: RMDBGLOG((ENABLE, "%lx_SwitchCodec: video codec unknown, don't SwitchVideoDecoder !\n", context->id)); goto audio_codec; } err = SwitchVideoDecoder(context, VCodec, MPEGProfile); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "%lx_Error Switch video decoder err=%d\n", context->id, err)); return RM_ERROR; } audio_codec: if (! context->audio_opt->auto_detect_codec) return RM_OK; 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 0x81: // 0x81 = ac3 RMDBGLOG((ENABLE, "%lx_SwitchCodec: ac3 audio detected\n", context->id)); ACodec = AudioDecoder_Codec_AC3; break; case 0x82: // 0x82 = dts RMDBGLOG((ENABLE, "%lx_SwitchCodec: dts audio detected\n", context->id)); ACodec = AudioDecoder_Codec_DTS; break; default: RMDBGLOG((ENABLE, "%lx_SwitchCodec: audio codec unknown, don't SwitchAudioDecoder !\n", context->id)); return RM_OK; } 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]; } else fprintf(stderr, " vpid= NO pid in the list "); } if (!(context->av_flags & ECM0_PID_FROM_CMDLINE)) { if (context->VideoPidList.count) { context->ecm_pid[0] = context->VideoPidList.es_ecm_pid[context->VideoPidList.index]; } } 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],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -