using System;
using Convai.Runtime.Vision.Sources;
using UnityEngine;
public class MyCustomFrameSource : MonoBehaviour, IVisionFrameSource
{
[SerializeField] private int _width = 1280;
[SerializeField] private int _height = 720;
[SerializeField] private float _targetFps = 15f;
[SerializeField] private string _sourceId = "custom";
private RenderTexture _outputRt;
private long _frameCount;
private float _captureInterval;
private float _nextCaptureTime;
// IVisionFrameSource
public bool IsCapturing { get; private set; }
public long FrameCount => _frameCount;
public (int Width, int Height) FrameDimensions => IsCapturing ? (_width, _height) : (0, 0);
public float TargetFrameRate => _targetFps;
public string SourceId => _sourceId;
public RenderTexture CurrentRenderTexture => _outputRt;
public bool IsFrameReady => _frameCount > 0;
public event Action FrameReady;
public void StartCapture()
{
如果 IsCapturing,则直接返回;
_outputRt = new RenderTexture(_width, _height, 24, RenderTextureFormat.ARGB32)
{
name = $"CustomFrameSource_{_sourceId}"
};
_outputRt.Create();
_frameCount = 0;
_captureInterval = _targetFps > 0f ? 1f / _targetFps : 1f / 15f;
_nextCaptureTime = Time.realtimeSinceStartup;
IsCapturing = true;
}
public void StopCapture()
{
如果未在捕获,则直接返回;
IsCapturing = false;
如果 _outputRt 不为空
{
_outputRt.Release();
Destroy(_outputRt);
_outputRt = null;
}
}
private void Update()
{
如果未在捕获,则直接返回;
float now = Time.realtimeSinceStartup;
如果 now 小于 _nextCaptureTime,则直接返回;
_nextCaptureTime = now + _captureInterval;
CaptureFrame();
}
private void OnDestroy() => StopCapture();
private void CaptureFrame()
{
// 用你的实际源纹理替换
RenderTexture sourceTexture = GetYourSourceTexture();
如果 sourceTexture 为空,则返回;
// 将 Y 轴翻转写入输出 RenderTexture
Graphics.Blit(sourceTexture, _outputRt, new Vector2(1f, -1f), new Vector2(0f, 1f));
_frameCount++;
FrameReady?.Invoke();
}
private RenderTexture GetYourSourceTexture()
{
// 返回你自定义管线中的 RenderTexture
return null;
}
}