PhotoCaputure 导致 Unity 内存泄漏
PhotoCaputure causes memory leak in Unity
我正在使用 unity 的 Photocapture Object 用全息镜头拍摄视频。
我根据官方示例代码编写了代码,但我将更新功能中的过程更改为拍摄多张图片而不是一张。
https://docs.unity3d.com/2018.4/Documentation/Manual/windowsholographic-photocapture.html
但是,当我 运行 这段代码时,它最终 运行 超出 pagefile.sys、内存不足并中止。
我已经搜索并发现大部分内存泄漏是由纹理 2d 引起的,但是在这段代码中,即使我省略了它们,它们也会发生。此外,unity profiler 没有显示代码执行后内存使用量逐渐增加。
可能是什么原因?如果你能告诉我,我将不胜感激。
using UnityEngine;
using System;
using System.Linq;
using UnityEngine.XR;
using UnityEngine.Windows.WebCam;
using System.Threading.Tasks;
using UnityEngine.Networking;
using System.Text;
using System.IO;
using System.Net;
using System.Collections;
using System.Collections.Generic;
public class photocap : MonoBehaviour
{
PhotoCapture PhotoCapture = null;
Texture2D targetTexture = null;
Resolution cameraResolution;
Renderer quadRenderer;
float dt = 0;
void Start()
{
cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
quadRenderer = quad.GetComponent<Renderer>() as Renderer;
quadRenderer.material = new Material(Shader.Find("Unlit/Texture"));
quad.transform.parent = this.transform;
quad.transform.localPosition = new Vector3(0.0f, 0.0f, 0.3f);
}
async void StartCapture()
{
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
PhotoCapture = captureObject;
CameraParameters cameraParameters = new CameraParameters();
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
PhotoCapture.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result)
{
PhotoCapture.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
PhotoCapture.StopPhotoModeAsync(OnStoppedPhotoMode);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
PhotoCapture.Dispose();
PhotoCapture = null;
}
void Update()
{
dt += Time.deltaTime;
if (dt > 3)
{
dt = 0.0f;
StartCapture();
}
}
}
我很确定你也 want/have 处理 photoCaptureFrame
!
否则存储的纹理将永远保留在您的应用程序内存中。
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// TODO: Obviously you first would want to do something with the just captured image ...
photoCaptureFrame.Dispose();
PhotoCapture.StopPhotoModeAsync(OnStoppedPhotoMode);
}
哦还有一件事:
您目前正在根据经过的时间开始新的捕获。
如果拍照、处理数据和处理的时间超过该间隔会怎样?
您可能宁愿仅在第一次捕获实际完全完成后才触发新的捕获延迟!
实际上为什么还要一直创建、启动、停止和处理捕获?您可以坚持使用一个并始终重复使用它
private PhotoCapture _photoCapture = null;
private Texture2D targetTexture = null;
private Resolution cameraResolution;
private Renderer quadRenderer;
private float dt = 0;
private void Start()
{
cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
var quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
quadRenderer = quad.GetComponent<Renderer>();
quadRenderer.material = new Material(Shader.Find("Unlit/Texture"));
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
quadRenderer.material.mainTexture = targetTexture;
quad.transform.parent = transform;
quad.transform.localPosition = new Vector3(0.0f, 0.0f, 0.3f);
StartCapture();
}
private void StartCapture()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
private void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
_photoCapture = captureObject;
var cameraParameters = new CameraParameters
{
hologramOpacity = 0.0f,
cameraResolutionWidth = cameraResolution.width,
cameraResolutionHeight = cameraResolution.height,
pixelFormat = CapturePixelFormat.BGRA32
};
_photoCapture.StartPhotoModeAsync(cameraParameters, OnPhotoCaptureStarted);
}
private void OnPhotoCaptureStarted(PhotoCapture.PhotoCaptureResult result)
{
// Take the first picture
TakePhoto();
// or if you really want more delay
//Invoke(nameof(TakePhoto, 3f));
}
private void TakePhoto()
{
_photoCapture.TakePhotoAsync(OnCapturedPhotoToMemory);
}
private void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// Don't all the time destroy and create textures
// simply upload the new data to the already existing image
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
Debug.Log("Captured");
photoCaptureFrame.Dispose();
// without the overhead of stopping and disposing etc simply take the next image
TakePhoto();
// or if you really want more delay
//Invoke(nameof(TakePhoto, 3f));
}
我正在使用 unity 的 Photocapture Object 用全息镜头拍摄视频。 我根据官方示例代码编写了代码,但我将更新功能中的过程更改为拍摄多张图片而不是一张。
https://docs.unity3d.com/2018.4/Documentation/Manual/windowsholographic-photocapture.html
但是,当我 运行 这段代码时,它最终 运行 超出 pagefile.sys、内存不足并中止。 我已经搜索并发现大部分内存泄漏是由纹理 2d 引起的,但是在这段代码中,即使我省略了它们,它们也会发生。此外,unity profiler 没有显示代码执行后内存使用量逐渐增加。 可能是什么原因?如果你能告诉我,我将不胜感激。
using UnityEngine;
using System;
using System.Linq;
using UnityEngine.XR;
using UnityEngine.Windows.WebCam;
using System.Threading.Tasks;
using UnityEngine.Networking;
using System.Text;
using System.IO;
using System.Net;
using System.Collections;
using System.Collections.Generic;
public class photocap : MonoBehaviour
{
PhotoCapture PhotoCapture = null;
Texture2D targetTexture = null;
Resolution cameraResolution;
Renderer quadRenderer;
float dt = 0;
void Start()
{
cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
quadRenderer = quad.GetComponent<Renderer>() as Renderer;
quadRenderer.material = new Material(Shader.Find("Unlit/Texture"));
quad.transform.parent = this.transform;
quad.transform.localPosition = new Vector3(0.0f, 0.0f, 0.3f);
}
async void StartCapture()
{
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
PhotoCapture = captureObject;
CameraParameters cameraParameters = new CameraParameters();
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
PhotoCapture.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result)
{
PhotoCapture.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
PhotoCapture.StopPhotoModeAsync(OnStoppedPhotoMode);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
PhotoCapture.Dispose();
PhotoCapture = null;
}
void Update()
{
dt += Time.deltaTime;
if (dt > 3)
{
dt = 0.0f;
StartCapture();
}
}
}
我很确定你也 want/have 处理 photoCaptureFrame
!
否则存储的纹理将永远保留在您的应用程序内存中。
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// TODO: Obviously you first would want to do something with the just captured image ...
photoCaptureFrame.Dispose();
PhotoCapture.StopPhotoModeAsync(OnStoppedPhotoMode);
}
哦还有一件事:
您目前正在根据经过的时间开始新的捕获。
如果拍照、处理数据和处理的时间超过该间隔会怎样?
您可能宁愿仅在第一次捕获实际完全完成后才触发新的捕获延迟!
实际上为什么还要一直创建、启动、停止和处理捕获?您可以坚持使用一个并始终重复使用它
private PhotoCapture _photoCapture = null;
private Texture2D targetTexture = null;
private Resolution cameraResolution;
private Renderer quadRenderer;
private float dt = 0;
private void Start()
{
cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
var quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
quadRenderer = quad.GetComponent<Renderer>();
quadRenderer.material = new Material(Shader.Find("Unlit/Texture"));
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
quadRenderer.material.mainTexture = targetTexture;
quad.transform.parent = transform;
quad.transform.localPosition = new Vector3(0.0f, 0.0f, 0.3f);
StartCapture();
}
private void StartCapture()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
private void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
_photoCapture = captureObject;
var cameraParameters = new CameraParameters
{
hologramOpacity = 0.0f,
cameraResolutionWidth = cameraResolution.width,
cameraResolutionHeight = cameraResolution.height,
pixelFormat = CapturePixelFormat.BGRA32
};
_photoCapture.StartPhotoModeAsync(cameraParameters, OnPhotoCaptureStarted);
}
private void OnPhotoCaptureStarted(PhotoCapture.PhotoCaptureResult result)
{
// Take the first picture
TakePhoto();
// or if you really want more delay
//Invoke(nameof(TakePhoto, 3f));
}
private void TakePhoto()
{
_photoCapture.TakePhotoAsync(OnCapturedPhotoToMemory);
}
private void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// Don't all the time destroy and create textures
// simply upload the new data to the already existing image
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
Debug.Log("Captured");
photoCaptureFrame.Dispose();
// without the overhead of stopping and disposing etc simply take the next image
TakePhoto();
// or if you really want more delay
//Invoke(nameof(TakePhoto, 3f));
}