本文只涉及到获取YUV420P数据后实现播放,至于这数据怎么来的以及相关C++的DLL不进行详细讨论,俺也不清楚
代码大致流程:初始化DLL,并开始从DLL获取数据,存进Queue,在FixedUpdate()取出Queue图像并贴图
Shader下载地址http://download.csdn.net/download/le_sam/9980147
相关Inspector如下:(把下载的Shander绑定到player)
public class Player : MonoBehaviour
{
public static string SHARE_MEMORY_NAME = "user-defined";
public static int SHARE_MEM_SIZE = "user-defined";
private bool isRead = true;
public Material mShareMaterial;
private Texture2D texY, texU, texV;
private Queue ListQueue = new Queue();
private void Awake()
{
gameObject.GetComponent().sharedMaterial = mShareMaterial;
shareMemRead();
}
private void shareMemRead()
{
//Application.targetFrameRate = AppFps;
Sharemem.hLib = Sharemem.pisoft_share_mem_create();
int ret = Sharemem.pisoft_share_mem_init(1, 0, SHARE_MEM_SIZE, SHARE_MEMORY_NAME, Sharemem.hLib);
if (ret < 0)
{
}
Debug.LogFormat("SHARE_MEM_SIZE:{0}", SHARE_MEM_SIZE);
Debug.LogFormat("SHARE_MEMORY_NAME:{0}", SHARE_MEMORY_NAME);
StartCoroutine(readFrames());
}
private IEnumerator readFrames()
{
int len = 0;
int isVideo = 0;
byte[] data = new byte[Width * Height * 3 / 2];
//dataY = new byte[Width * Height];
//dataU = new byte[Width * Height / 4];
//dataV = new byte[Width * Height / 4];
texY = new Texture2D(Width, Height, TextureFormat.Alpha8, false);
texU = new Texture2D(Width / 2, Height / 2, TextureFormat.Alpha8, false);
texV = new Texture2D(Width / 2, Height / 2, TextureFormat.Alpha8, false);
//float lastTiem = Time.deltaTime;
while (isRead)
{
yield return new WaitForEndOfFrame();
if (Sharemem.pisoft_share_mem_is_exit(Sharemem.hLib) == 1)//quit
{
Debug.LogFormat("SharedMemory quit...");
break;
}
//从dll里获取YUV420__byte[]
Sharemem.pisoft_share_mem_read(ref isVideo, ref len, data, Sharemem.hLib);
if (len > 0)
{
len = 0;
ListQueue.Enqueue(data);
//Buffer.BlockCopy(data, 0, dataY, 0, Width * Height);
//Buffer.BlockCopy(data, Width * Height, dataU, 0, Width * Height / 4);
//Buffer.BlockCopy(data, Width * Height * 5 / 4, dataV, 0, Width * Height / 4);
}
}
Sharemem.pisoft_share_mem_deinit(Sharemem.hLib);
}
void FixedUpdate() {
if (ListQueue.Count > 0)
{
byte[] data = ListQueue.Dequeue();
MemoryStream ms = new MemoryStream(data);
BinaryReader reader = new BinaryReader(ms);
byte[] dataY = reader.ReadBytes(Width * Height);
byte[] dataU = reader.ReadBytes(Width * Height / 4);
byte[] dataV = reader.ReadBytes(Width * Height / 4);
StickTexture(Width, Height, dataY, dataU, dataV);
}
}
private void StickTexture(int width, int height, byte[] dataY, byte[] dataU, byte[] dataV)
{
//if (width == mLastWidth && height == mLastHeight)
//{
// return;
//}
//if (width == 0 || height == 0)
//{
// return;
//}
//mLastWidth = width;
//mLastHeight = height;
//Color32[] grayColors = new Color32[width * height];
//for (int i = 0; i < grayColors.Length; ++i)
//{
// grayColors[i].a = 0;
//}
//Y
//if (texY)
//{
// Destroy(texY);
//}
//texY.filterMode = FilterMode.Bilinear;
//texY.wrapMode = TextureWrapMode.Clamp;
//texY.SetPixels32(grayColors);
texY.LoadRawTextureData(dataY);
texY.Apply();
//grayColors = new Color32[(width / 2) * (height / 2)];
//for (int i = 0; i < grayColors.Length; ++i)
//{
// grayColors[i].a = 128;
//}
//U
//if (texU)
//{
// Destroy(texU);
//}
//texU.filterMode = FilterMode.Point;
//texU.wrapMode = TextureWrapMode.Clamp;
//texU.SetPixels32(grayColors);
texU.LoadRawTextureData(dataU);
texU.Apply();
//V
//if (texV)
//{
// Destroy(texV);
//}
//texV.filterMode = FilterMode.Point;
//texV.wrapMode = TextureWrapMode.Clamp;
//texV.SetPixels32(grayColors);
texV.LoadRawTextureData(dataV);
texV.Apply();
mShareMaterial.mainTexture = texY;
mShareMaterial.SetTexture("_MainTexU", texU);
mShareMaterial.SetTexture("_MainTexV", texV);
}
void OnApplicationQuit()
{
isRead = false;
StartCoroutine(DelayedStart());
Debug.Log("app quit");
}
private IEnumerator DelayedStart()
{
yield return new WaitForSeconds(1f);
Sharemem.pisoft_share_mem_set_exit(1, Sharemem.hLib);
}
}
public class Sharemem : MonoBehaviour{ //Dll
public static IntPtr hLib = new IntPtr(0);
[DllImport("pisoft_share_mem")]
public static extern IntPtr pisoft_share_mem_create();
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_init(int is_read, int wait_ms, int mem_size, string name, IntPtr handle);
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_deinit(IntPtr handle);
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_read(ref int stream_type, ref int len, [MarshalAs(UnmanagedType.LPArray)] byte[] data, IntPtr handle);
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_write(int is_video, int len, [MarshalAs(UnmanagedType.LPArray)] byte[] data, IntPtr handle);
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_set_exit(int is_exit, IntPtr handle);
[DllImport("pisoft_share_mem")]
public static extern int pisoft_share_mem_is_exit(IntPtr handle);
}