BlueRoseNote/02-Note/ASoul/流程笔记/MultiView逻辑.md

5.3 KiB
Raw Blame History

TsScreenPlayerTextureRenderer => AMultiViewActor

渲染逻辑

  • UMultiViewRendererComponent::DrawMultiViewCameras()

渲染函数:GetRendererModule().BeginRenderingViewFamily(&SceneCanvas, &ViewFamily); 摄像机相关函数:FSceneView* UMultiViewRendererComponent::CalcSceneView(FSceneViewFamily* InViewFamily, UCineCameraComponent* InCamera,
const uint32 InViewIndex)

多屏与采集卡

以Preview为例 TsDirectorCamManagerActor.ts

this.PreviewWindow = UE.MultiViewActor.Open(this.GetWorld(), UE.EMultiViewCameraLayout.Display_1920x1080_Layout_4x4, UE.EMultiViewMultiGPUMode.HalfSplit)
this.PreviewWindow.SetRenderFeaturePlanarReflection(false);
this.PreviewWindow.SetRenderFeatureNiagara(false);

// video output
let videoOutputParam = new UE.VideOutputParam()
videoOutputParam.bBlackMagicCard = false
videoOutputParam.bLazyStart = false
this.PreviewWindow.StartVideoOutput(videoOutputParam)

PVW&PGM使用 BLACKMAGIC_OUTPUT_CONFIG_HORIZONTAL  也就是/Game/ResArt/BlackmagicMedia/MO_BlackmagicVideoOutput。

 export function StartVideoOutput(camManager : TsDirectorCamManagerActor, targetWindow : UE.MultiViewActor):void{
	 let videoOutpuParam = new UE.VideOutputParam()
	videoOutpuParam.FilmbackMode = camManager.FilmbackMode
	videoOutpuParam.OutputConfigPath = BLACKMAGIC_OUTPUT_CONFIG_HORIZONTAL
	videoOutpuParam.bBlackMagicCard = true
	videoOutpuParam.bLazyStart = false
	if(camManager.FilmbackMode == UE.EFilmbackMode.EFM_1080x1920){
		videoOutpuParam.MatV2H = GetV2HMaterialInstace(camManager)
	}
	targetWindow.StartVideoOutput(videoOutpuParam)
 }
  • DirectorMode.PreviewbBlackMagicCard = false
  • PVW&PGMbBlackMagicCard = true

c++

核心函数在于AMultiViewActor::StartVideoOutput

TS传入设置位置

  • TsDirectorCamManagerActor.ts SwitchToDirectMode(newTag: UE.GameplayTag)
  • FilmbackHelper.ts StartVideoOutput()

SwitchToDirectMode()

case DirectorMode.Preview:
	console.log('启动Splite4x4预览窗口')
	if (shouldCreateWindow) {
		this.PreviewWindow = UE.MultiViewActor.Open(this.GetWorld(), UE.EMultiViewCameraLayout.Display_1920x1080_Layout_4x4, UE.EMultiViewMultiGPUMode.HalfSplit)
		this.PreviewWindow.SetRenderFeaturePlanarReflection(false);
		this.PreviewWindow.SetRenderFeatureNiagara(false);
	
		// video output
		let videoOutputParam = new UE.VideOutputParam()
		videoOutputParam.bBlackMagicCard = false
		videoOutputParam.bLazyStart = false
		this.PreviewWindow.StartVideoOutput(videoOutputParam)
	}
function StartVideoOutput(camManager : TsDirectorCamManagerActor, targetWindow : UE.MultiViewActor):void{
	if(!BE_USE_DECKLINK){
		let videoOutpuParam = new UE.VideOutputParam()
		videoOutpuParam.FilmbackMode = camManager.FilmbackMode
		videoOutpuParam.OutputConfigPath = BLACKMAGIC_OUTPUT_CONFIG_HORIZONTAL
		videoOutpuParam.bBlackMagicCard = true
		videoOutpuParam.bLazyStart = false
		if(camManager.FilmbackMode == UE.EFilmbackMode.EFM_1080x1920){
			videoOutpuParam.MatV2H = GetV2HMaterialInstace(camManager)
		}
		targetWindow.StartVideoOutput(videoOutpuParam)
	}
}

UDeckLinkMediaCapture

m_DeckLinkOutputDevice = DeckLinkDiscovery->GetDeviceByName(m_DeviceName);

FDeckLinkDeviceDiscovery::DeckLinkDeviceArrived(IDeckLink *device)
{
	/*TComPtr<IDeckLink> device_;
	device_ = device;*/
	
	TComPtr<FDeckLinkOutputDevice> newDeviceComPtr = new FDeckLinkOutputDevice(device);
	if (!newDeviceComPtr->Init())
		return S_OK;
	
	std::lock_guard<std::recursive_mutex> lock(m_DeviceMutex);
	FString deviceName = newDeviceComPtr->GetDeviceName();//看这个Com对象的设备名称是否对应
	if (!m_Devices.Contains(deviceName) )
	{
		m_Devices.Add(deviceName,newDeviceComPtr);
	}
	return S_OK;
}

DeckLinkDeviceArrived调用逻辑位于DeckLinkAPI_h.h

ADeckLinkOutputActor

ADeckLinkOutputActor的DeviceName 默认值为"DeckLink Mini Monitor 4K";

判断错误函数 UMediaCapture::CaptureTextureRenderTarget2D()=>UMediaCapture::StartSourceCapture() => ValidateMediaOutput()

bool UMediaCapture::ValidateMediaOutput() const  
{  
    if (MediaOutput == nullptr)  
    {       UE_LOG(LogMediaIOCore, Error, TEXT("Can not start the capture. The Media Output is invalid."));  
       return false;  
    }  
    FString FailureReason;  
    if (!MediaOutput->Validate(FailureReason))  
    {       UE_LOG(LogMediaIOCore, Error, TEXT("Can not start the capture. %s."), *FailureReason);  
       return false;  
    }  
    if(DesiredCaptureOptions.bAutostopOnCapture && DesiredCaptureOptions.NumberOfFramesToCapture < 1)  
    {       UE_LOG(LogMediaIOCore, Error, TEXT("Can not start the capture. Please set the Number Of Frames To Capture when using Autostop On Capture in the Media Capture Options"));  
       return false;  
    }  
    return true;  
}
bool UDeckLinkMediaCapture::InitBlackmagic(int _Width, int _Height)
{
	if (DeckLinkDiscovery == nullptr)
	{
		return false;
	}
	Width = _Width;
	Height = _Height;
	check(Height > 0 && Width > 0)
	BMDDisplayMode displayMode = GetDisplayMode(Width, Height);
	m_DeckLinkOutputDevice = DeckLinkDiscovery->GetDeviceByName(m_DeviceName);
	if (m_DeckLinkOutputDevice.Get() == nullptr)
	{
		return false;
	}
	if (!m_DeckLinkOutputDevice->EnableOutput(displayMode, bmdFormat8BitYUV))
	{
		m_DeckLinkOutputDevice.Reset();
		return false;
	}


	return true;
}

DeckLinkDiscovery->GetDeviceByName(m_DeviceName);