I use the following script to display video overlay on Unity quad mesh. Works on tango tablet. But fps is low, I guess because of the resolution of color camera (1280 x 720).
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Tango;
public class CameraBackgorund : VideoOverlayListener
{
Texture2D backgroundTexture = null;
// texture data
bool isDirty = false;
byte[] yuv12 = null;
int width;
int height;
private void Update()
{
if (isDirty)
{
if (backgroundTexture == null)
backgroundTexture = new Texture2D (width, height);
// convert from YV12 to RGB
int size = (int)(width * height);
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
byte y = yuv12[i * width + j];
byte v = yuv12[(i / 2) * (width / 2) + (j / 2) + size];
byte u = yuv12[(i / 2) * (width / 2) + (j / 2) + size + (size / 4)];
backgroundTexture.SetPixel(j, height - i - 1, YUV2Color(y, u, v));
}
}
// update texture
backgroundTexture.Apply(true);
GetComponent<MeshRenderer> ().material.mainTexture = backgroundTexture;
isDirty = false;
}
}
protected override void _OnImageAvailable(IntPtr callbackContext,
Tango.TangoEnums.TangoCameraId cameraId,
Tango.TangoImageBuffer imageBuffer)
{
if (cameraId != Tango.TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR)
return;
// allocate for the first time
width = (int)imageBuffer.width;
height = (int)imageBuffer.height;
if (yuv12 == null)
yuv12 = new byte[width * height * 2];
// copy data in yv12 format
IntPtr dataPtr = imageBuffer.data;
int offset = 0;
Int64 stride = (Int64)imageBuffer.stride;
for (int i = 0; i < height; ++i, dataPtr = new IntPtr(dataPtr.ToInt64() + stride), offset += width)
Marshal.Copy(dataPtr, yuv12, offset, width);
for (int i = 0; i < height / 2; ++i, dataPtr = new IntPtr(dataPtr.ToInt64() + stride / 2), offset += width / 2)
Marshal.Copy(dataPtr, yuv12, offset, width / 2);
for (int i = 0; i < height / 2; ++i, dataPtr = new IntPtr(dataPtr.ToInt64() + stride / 2), offset += width / 2)
Marshal.Copy(dataPtr, yuv12, offset, width / 2);
isDirty = true;
}
public static Color YUV2Color(byte y, byte u, byte v)
{
// http://en.wikipedia.org/wiki/YUV
const float Umax = 0.436f;
const float Vmax = 0.615f;
float y_scaled = y / 255.0f;
float u_scaled = 2 * (u / 255.0f - 0.5f) * Umax;
float v_scaled = 2 * (v / 255.0f - 0.5f) * Vmax;
return new Color(y_scaled + 1.13983f * v_scaled,
y_scaled - 0.39465f * u_scaled - 0.58060f * v_scaled,
y_scaled + 2.03211f * u_scaled);
}
}
Using Unity WebCamTexture successfully retrieves color, but breaks the depth provider.