- Home /
How to render YUV file properly in Unity?
I'm trying to render a YUV file inside of Unity. I found some code online and I managed to load the file (a 15 -20 second video) and play it, but the framerate is absolutely horrendous. I'm getting about 5 FPS on average. Is there any way for me to increase the framerate to at least about 30, but preferably 60 or above?
The Code:
{
public RawImage img;
int frameCount;
int frameNow = 0;
byte[] file;
// Plana continuous storage, Packed interleaved storage
// This example uses Plana YUV420 format
void Start()
{
file = File.ReadAllBytes("C:/Users/Gigatron/Desktop/video.yuv");
frameCount = GetFrameCount(file, 1280, 720); // Image width and height
print("Frame Count : " + frameCount);
//File.WriteAllBytes("C:/Users/Gigatron/Desktop/video.yuv", t.EncodeToPNG());
}
void Update()
{
if (frameNow >= frameCount - 1) return;
img.texture = GetTexture(file, 1280, 720); // Image width and height
frameNow++;
print("Frame : " + (frameNow) + " (" + (int)(frameNow / (float)(frameCount - 1) * 100) + "%)");
}
int GetFrameCount(byte[] file, int width, int height)
{
return file.Length / ((width * height) * 3 / 2);
}
Texture2D t = null;
Texture2D GetTexture(byte[] file, int width, int height)
{
if (t != null) Destroy(t);
t = new Texture2D(width, height, TextureFormat.RGB24, false);
int Ysize = t.width * t.height;
int UorVsize = t.width * t.height / 4;
Color[] cArr = new Color[t.width * t.height];
byte U = 0;
byte V = 0;
int k = 0;
int offset = frameNow * ((width * height) * 3 / 2);
for (int y = 0; y < t.height; y += 2)
{
for (int x = 0; x < t.width; x += 2)
{
U = file[offset + Ysize + k++];
V = file[offset + Ysize + k + UorVsize];
int i = y * t.width + x;
int mY = t.height - 1 - y;
byte Y00 = file[offset + i];
byte Y01 = file[offset + i + t.width];
byte Y10 = file[offset + i + 1];
byte Y11 = file[offset + i + t.width + 1];
float R00 = (Y00 + 1.4075f * (V - 128)) / 255f;
float G00 = (Y00 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
float B00 = (Y00 + 1.779f * (U - 128)) / 255f;
float R01 = (Y01 + 1.4075f * (V - 128)) / 255f;
float G01 = (Y01 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
float B01 = (Y01 + 1.779f * (U - 128)) / 255f;
float R10 = (Y10 + 1.4075f * (V - 128)) / 255f;
float G10 = (Y10 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
float B10 = (Y10 + 1.779f * (U - 128)) / 255f;
float R11 = (Y11 + 1.4075f * (V - 128)) / 255f;
float G11 = (Y11 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
float B11 = (Y11 + 1.779f * (U - 128)) / 255f;
t.SetPixel(x, mY, new Color(R00, G00, B00, 1));
t.SetPixel(x, mY - 1, new Color(R01, G01, B01, 1));
t.SetPixel(x + 1, mY, new Color(R10, G10, B10, 1));
t.SetPixel(x + 1, mY - 1, new Color(R11, G11, B11, 1));
}
}
t.Apply();
return t;
}
Comment