AccessViolationException using CopyRawImageDataIntoBuffer

I am using the following Unity Scripting example for my HoloLens Application:

Example Code

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.VR.WSA.WebCam;

public class PhotoCaptureRawImageExample : MonoBehaviour
{
    PhotoCapture photoCaptureObject = null;
    Texture2D targetTexture = null;
    Renderer quadRenderer = null;

    // Use this for initialization
    void Start()
    {
        Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();

        targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height, TextureFormat.RGBA32, false);

        PhotoCapture.CreateAsync(false, delegate(PhotoCapture captureObject) {
                photoCaptureObject = captureObject;

                CameraParameters c = new CameraParameters();
                c.cameraResolutionWidth = targetTexture.width;
                c.cameraResolutionHeight = targetTexture.height;
                c.pixelFormat = CapturePixelFormat.BGRA32;

                captureObject.StartPhotoModeAsync(c, delegate(PhotoCapture.PhotoCaptureResult result) {
                    photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
                });
            });
    }

    void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
    {
        List<byte> imageBufferList = new List<byte>();
        // Copy the raw IMFMediaBuffer data into our empty byte list.
        photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList);

        // In this example, we captured the image using the BGRA32 format.
        // So our stride will be 4 since we have a byte for each rgba channel.
        // The raw image data will also be flipped so we access our pixel data
        // in the reverse order.
        int stride = 4;
        float denominator = 1.0f / 255.0f;
        List<Color> colorArray = new List<Color>();
        for (int i = imageBufferList.Count - 1; i >= 0; i -= stride)
        {
            float a = (int)(imageBufferList[i - 0]) * denominator;
            float r = (int)(imageBufferList[i - 1]) * denominator;
            float g = (int)(imageBufferList[i - 2]) * denominator;
            float b = (int)(imageBufferList[i - 3]) * denominator;

            colorArray.Add(new Color(r, g, b, a));
        }

        targetTexture.SetPixels(colorArray.ToArray());
        targetTexture.Apply();

        if (quadRenderer == null)
        {
            GameObject p = GameObject.CreatePrimitive(PrimitiveType.Quad);
            quadRenderer = p.GetComponent<Renderer>() as Renderer;
            quadRenderer.material = new Material(Shader.Find("Custom/Unlit/UnlitTexture"));

            p.transform.parent = this.transform;
            p.transform.localPosition = new Vector3(0.0f, 0.0f, 1.0f);
        }

        quadRenderer.material.SetTexture("_MainTex", targetTexture);

        // Take another photo
        photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
    }
}

I keep getting a System.AccessViolationException inside of

photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList);

I am using Unity 2017.1.1f1, Visual Studio 2015 (Update 3) and a Release build.

Any help would be appreciated.

Can you provide more data on the exception?
Just from what I can see in your script it appears your didn’t create the photocapture object before starting the capture

Well, the script sample (provided in the spoiler section) is copied directly from the Unity Scripting API documentation:

The photocapture object is created inside the Start() function by calling PhotoCapture.CreateAsync (lines 20 and 21). Btw, the photoCaptureFrame itself seems to work fine. I am able to call other functions like UploadImageDataToTexture, TryGetCameraToWorldMatrix or TryGetProjectionMatrix. The error seems to be located somewhere inside the CopyRawImageDataIntoBuffer function.

I will try to provide more data on the exception tomorrow when I get my hands back on the device.

This looks like a bug in Unity to me… Access violation exceptions should never be thrown. Can we get a bug report?

I submitted a bug report a few minutes ago (sorry for the delay). It’s case 955107.

Disposing of the photoCaptureFrame before taking a new photo seems to be a workaround for this issue:

// Dispose of the current photoCaptureFrame
photoCaptureFrame.Dispose();

// Take another photo
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);