123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /****************************************************************************
- * Copyright 2019 Nreal Techonology Limited. All rights reserved.
- *
- * This file is part of NRSDK.
- *
- * https://www.nreal.ai/
- *
- *****************************************************************************/
- namespace NRKernal.Record
- {
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- /// <summary> A frame capture context. </summary>
- public class FrameCaptureContext
- {
- /// <summary> The blender. </summary>
- private BlenderBase m_Blender;
- /// <summary> The encoder. </summary>
- private IEncoder m_Encoder;
- /// <summary> Options for controlling the camera. </summary>
- private CameraParameters m_CameraParameters;
- /// <summary> The frame provider. </summary>
- private AbstractFrameProvider m_FrameProvider;
- /// <summary> The capture behaviour. </summary>
- private CaptureBehaviourBase m_CaptureBehaviour;
- /// <summary> True if is initialize, false if not. </summary>
- private bool m_IsInitialized = false;
- private List<IFrameConsumer> m_FrameConsumerList;
- /// <summary> Gets the preview texture. </summary>
- /// <value> The preview texture. </value>
- public Texture PreviewTexture
- {
- get
- {
- return m_Blender?.BlendTexture;
- }
- }
- /// <summary> Gets the behaviour. </summary>
- /// <returns> The behaviour. </returns>
- public CaptureBehaviourBase GetBehaviour()
- {
- return m_CaptureBehaviour;
- }
- /// <summary> Gets frame provider. </summary>
- /// <returns> The frame provider. </returns>
- public AbstractFrameProvider GetFrameProvider()
- {
- return m_FrameProvider;
- }
- /// <summary> Gets the blender. </summary>
- /// <returns> The blender. </returns>
- public BlenderBase GetBlender()
- {
- return m_Blender;
- }
- /// <summary> Request camera parameter. </summary>
- /// <returns> The CameraParameters. </returns>
- public CameraParameters RequestCameraParam()
- {
- return m_CameraParameters;
- }
- /// <summary> Gets the encoder. </summary>
- /// <returns> The encoder. </returns>
- public IEncoder GetEncoder()
- {
- return m_Encoder;
- }
- /// <summary> Constructor. </summary>
- public FrameCaptureContext() { }
- /// <summary> Starts capture mode. </summary>
- /// <param name="param"> The parameter.</param>
- public void StartCaptureMode(CameraParameters param)
- {
- if (m_IsInitialized)
- {
- this.Release();
- NRDebugger.Warning("[CaptureContext] Capture context has been started already, release it and restart a new one.");
- }
- NRDebugger.Info("[CaptureContext] Create...");
- if (m_CaptureBehaviour == null)
- {
- this.m_CaptureBehaviour = this.GetCaptureBehaviourByMode(param.camMode);
- }
- this.m_CameraParameters = param;
- this.m_Encoder = GetEncoderByMode(param.camMode);
- this.m_Encoder.Config(param);
- this.m_Blender = new ExtraFrameBlender();
- this.m_Blender.Init(m_CaptureBehaviour.CaptureCamera, m_Encoder, param);
- this.m_CaptureBehaviour.Init(this);
- this.m_FrameProvider = CreateFrameProviderByMode(param.blendMode, param.frameRate);
- this.m_FrameProvider.OnUpdate += UpdateFrame;
- this.m_FrameConsumerList = new List<IFrameConsumer>();
- this.Sequence(m_CaptureBehaviour)
- .Sequence(m_Blender);
- this.m_IsInitialized = true;
- }
- /// <summary> Auto adaption for BlendMode based on supported feature on current device. </summary>
- /// <param name="blendMode"> source blendMode.</param>
- /// <returns> Fallback blendMode. </returns>
- public BlendMode AutoAdaptBlendMode(BlendMode blendMode)
- {
- if (!NRDevice.Subsystem.IsFeatureSupported(NRSupportedFeature.NR_FEATURE_RGB_CAMERA))
- return BlendMode.VirtualOnly;
-
- return blendMode;
- }
- private FrameCaptureContext Sequence(IFrameConsumer consummer)
- {
- this.m_FrameConsumerList.Add(consummer);
- return this;
- }
- private void UpdateFrame(UniversalTextureFrame frame)
- {
- for (int i = 0; i < m_FrameConsumerList.Count; i++)
- {
- m_FrameConsumerList[i].OnFrame(frame);
- }
- }
- /// <summary> Gets capture behaviour by mode. </summary>
- /// <exception cref="Exception"> Thrown when an exception error condition occurs.</exception>
- /// <param name="mode"> The mode.</param>
- /// <returns> The capture behaviour by mode. </returns>
- private CaptureBehaviourBase GetCaptureBehaviourByMode(CamMode mode)
- {
- if (mode == CamMode.PhotoMode)
- {
- NRCaptureBehaviour capture = GameObject.FindObjectOfType<NRCaptureBehaviour>();
- var headParent = NRSessionManager.Instance.NRSessionBehaviour.transform.parent;
- if (capture == null)
- {
- capture = GameObject.Instantiate(Resources.Load<NRCaptureBehaviour>("Record/Prefabs/NRCaptureBehaviour"), headParent);
- }
- GameObject.DontDestroyOnLoad(capture.gameObject);
- return capture;
- }
- else if (mode == CamMode.VideoMode)
- {
- NRRecordBehaviour capture = GameObject.FindObjectOfType<NRRecordBehaviour>();
- var headParent = NRSessionManager.Instance.NRSessionBehaviour.transform.parent;
- if (capture == null)
- {
- capture = GameObject.Instantiate(Resources.Load<NRRecordBehaviour>("Record/Prefabs/NRRecorderBehaviour"), headParent);
- }
- GameObject.DontDestroyOnLoad(capture.gameObject);
- return capture;
- }
- else
- {
- throw new Exception("CamMode need to be set correctly for capture behaviour!");
- }
- }
- private AbstractFrameProvider CreateFrameProviderByMode(BlendMode mode, int fps)
- {
- AbstractFrameProvider provider;
- switch (mode)
- {
- case BlendMode.Blend:
- case BlendMode.RGBOnly:
- #if UNITY_EDITOR
- provider = new EditorFrameProvider();
- #else
- provider = new RGBCameraFrameProvider();
- #endif
- break;
- case BlendMode.VirtualOnly:
- default:
- provider = new NullDataFrameProvider(fps);
- break;
- }
- return provider;
- }
- /// <summary> Gets encoder by mode. </summary>
- /// <exception cref="Exception"> Thrown when an exception error condition occurs.</exception>
- /// <param name="mode"> The mode.</param>
- /// <returns> The encoder by mode. </returns>
- private IEncoder GetEncoderByMode(CamMode mode)
- {
- if (mode == CamMode.PhotoMode)
- {
- return new ImageEncoder();
- }
- else if (mode == CamMode.VideoMode)
- {
- return new VideoEncoder();
- }
- else
- {
- throw new Exception("CamMode need to be set correctly for encoder!");
- }
- }
- /// <summary> Stops capture mode. </summary>
- public void StopCaptureMode()
- {
- this.Release();
- }
- /// <summary> Starts a capture. </summary>
- public void StartCapture()
- {
- if (!m_IsInitialized)
- {
- return;
- }
- NRDebugger.Info("[CaptureContext] Start...");
- m_Encoder?.Start();
- m_FrameProvider?.Play();
- }
- /// <summary> Stops a capture. </summary>
- public void StopCapture()
- {
- if (!m_IsInitialized)
- {
- return;
- }
- NRDebugger.Info("[CaptureContext] Stop...");
- // Need stop encoder firstly.
- m_Encoder?.Stop();
- m_FrameProvider?.Stop();
- }
- /// <summary> Releases this object. </summary>
- public void Release()
- {
- if (!m_IsInitialized)
- {
- return;
- }
- NRDebugger.Info("[CaptureContext] Release begin...");
- System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
- stopwatch.Start();
- if (m_FrameProvider != null)
- {
- m_FrameProvider.OnUpdate -= UpdateFrame;
- m_FrameProvider?.Release();
- m_FrameProvider = null;
- }
- m_Blender?.Dispose();
- m_Encoder?.Release();
- if (m_CaptureBehaviour != null)
- {
- GameObject.DestroyImmediate(m_CaptureBehaviour.gameObject);
- m_CaptureBehaviour = null;
- }
- NRDebugger.Info("[CaptureContext] Release end, cost:{0} ms", stopwatch.ElapsedMilliseconds);
- m_IsInitialized = false;
- }
- }
- }
|