📄 play_psfdemux_multicast.c
字号:
video_profile.BitstreamFIFOSize = context->video_opt->fifo_size; video_profile.XferFIFOCount = 0; video_profile.PtsFIFOCount = 180; video_profile.InbandFIFOCount = 16; video_profile.XtaskInbandFIFOCount = 0; video_profile.MpegEngineID = context->video_opt->MpegEngineID; video_profile.VideoDecoderID = context->video_opt->VideoDecoderID; /* DCC spu_hack */ video_profile.SPUProtectedFlags = 0; video_profile.SPUBitstreamFIFOSize = (context->enable_spu) ? SPU_FIFO_SIZE : 0; video_profile.SPUXferFIFOCount = 0; video_profile.SPUPtsFIFOCount = (context->enable_spu) ? 180 : 0; video_profile.SPUInbandFIFOCount = (context->enable_spu) ? 16 : 0; video_profile.SPUCodec = EMhwlibDVDSpuCodec; video_profile.SPUProfile = 0; video_profile.SPULevel = 0; video_profile.SPUExtraPictureBufferCount = 0; video_profile.SPUMaxWidth = 720; video_profile.SPUMaxHeight = 576; video_profile.STCID = context->id; /* set codec based on command line options either "-pv" or "-vcodec" */ if (context->video_opt->vcodec_max_width) { video_profile.Codec = context->video_opt->vcodec; video_profile.Profile = context->video_opt->vcodec_profile; video_profile.Level = context->video_opt->vcodec_level; video_profile.MaxWidth = context->video_opt->vcodec_max_width; video_profile.MaxHeight = context->video_opt->vcodec_max_height; } else { err = video_profile_to_codec(context->video_opt->MPEGProfile, &video_profile.Codec, &video_profile.Profile, &video_profile.Level, &video_profile.ExtraPictureBufferCount, &video_profile.MaxWidth, &video_profile.MaxHeight); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Unknown video decoder codec \n")); return RM_ERROR; } } /* set the extra pictures after the profile to codec conversion */ video_profile.ExtraPictureBufferCount = context->video_opt->vcodec_extra_pictures; err = DCCXOpenVideoDecoderSource(context->dcc_info->pDCC, &video_profile, &context->dcc_info->pVideoSource); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot open video decoder err=%d\n", context->id, err); return RM_ERROR; } /* save the video codec to set it after demux output connection */ context->vcodec = video_profile.Codec; err = DCCGetScalerModuleID(context->dcc_info->pDCC, context->dcc_info->route, DCCSurface_Video, context->disp_opt->video_scaler, &context->dcc_info->SurfaceID); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot get surface to display video source %d\n", context->id, err); return RM_ERROR; } err = DCCSetSurfaceSource(context->dcc_info->pDCC, context->dcc_info->SurfaceID, context->dcc_info->pVideoSource); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot set the surface source err=%d\n", context->id, err); return RM_ERROR; } err = DCCGetVideoDecoderSourceInfo(context->dcc_info->pVideoSource, &(context->dcc_info->video_decoder), &(context->dcc_info->spu_decoder), &(context->dcc_info->video_timer)); if (RMFAILED(err)) { fprintf(stderr, "%lx_Error getting video decoder source information err=%d\n", context->id, err); return RM_ERROR; }#ifndef WITH_MONO context->dcc_info->disp_info->video_enable = TRUE; set_default_out_window(&(context->dcc_info->disp_info->out_window)); set_default_out_window(&(context->dcc_info->disp_info->osd_window[0])); set_default_out_window(&(context->dcc_info->disp_info->osd_window[1])); context->dcc_info->disp_info->active_window = &(context->dcc_info->disp_info->out_window); err = apply_display_options(context->dcc_info, context->disp_opt); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot set display options %d\n", context->id, err); return RM_ERROR; } /* set first decoder in top left quarter, second in right top quarter, third in center bottom quarter */ if (task_count == 2) { context->dcc_info->disp_info->active_window->X = (context->id ? 3072:1024); context->dcc_info->disp_info->active_window->Y = (context->id ? 3072:1024); context->dcc_info->disp_info->active_window->Width = 2048; context->dcc_info->disp_info->active_window->Height = 2048; } else if (task_count == 3) { context->dcc_info->disp_info->active_window->X = (context->id == 2) ? 2048:(context->id ? 3072:1024); context->dcc_info->disp_info->active_window->Y = (context->id == 2) ? 3072:1024; context->dcc_info->disp_info->active_window->Width = 2048; context->dcc_info->disp_info->active_window->Height = 2048; } set_display_out_window(context->dcc_info);#endif if (context->enable_spu) { RMuint32 spu_decoder = context->dcc_info->spu_decoder; enum SpuDecoder_StreamType_type spu_st = SpuDecoder_StreamType_4by3; // type according to selected stream from PGC_SPST_CTL RMbool spu_disp = TRUE; // shall sub picture be displayed? may be overridden by forced display from stream. use GetProp_Display to check actual state. struct SpuDecoder_Palette_type spu_lut = {{ // DVD format: Y,Cr,Cb 0x00, 0x28, 0x6d, 0xf0, 0x00, 0x51, 0xf0, 0x5a, 0x00, 0x10, 0x80, 0x80, 0x00, 0xea, 0x80, 0x80, 0x00, 0x66, 0xdb, 0x4e, 0x00, 0x6a, 0xdd, 0xca, 0x00, 0xd2, 0x92, 0x10, 0x00, 0x5b, 0x49, 0x92, 0x00, 0x7b, 0x80, 0x80, 0x00, 0xc9, 0x98, 0x77, 0x00, 0x30, 0xb6, 0x6d, 0x00, 0x4f, 0x51, 0x5b, 0x00, 0x1c, 0x77, 0xb6, 0x00, 0x61, 0xcf, 0xcf, 0x00, 0x10, 0x80, 0x80, 0x00, 0xbf, 0x80, 0x80, }}; // dummy ScalerModuleID err = RUASetProperty(context->pRUA, spu_decoder, RMSpuDecoderPropertyID_Palette, &spu_lut, sizeof(spu_lut), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set spu palette\n")); return RM_ERROR; } err = RUASetProperty(context->pRUA, spu_decoder, RMSpuDecoderPropertyID_StreamType,&spu_st, sizeof(spu_st), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set spu type\n")); return RM_ERROR; } err = RUASetProperty(context->pRUA, spu_decoder, RMSpuDecoderPropertyID_SubpictureOn, &spu_disp, sizeof(spu_disp), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set spu ON\n")); return RM_ERROR; } } return RM_OK;}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);#ifndef WITH_MONO clear_display_options(context->dcc_info, context->disp_opt);#endif 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; }fprintf( stderr, "\n\n\n\n *****************************video codec %d ************************************\n", context->vcodec ); /* 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 else returns error and we have to ignore the error */ 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 err = RM_OK; /* ignore the error */ } 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 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 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) { MPEGProfile = context->MulticastMPEGProfile[context->MulticastCurrent]; VCodec = context->MulticastVCodec[context->MulticastCurrent]; goto video_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 switch_audio; 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 switch_audio; } video_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; } switch_audio:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -