如何解决用c#unity
我打算使用GStreamer进行编码,并通过TCP发送该流,然后在Unity中对其进行解码。
这是我的GStreamer管道:
gst-launch-1.0 v4l2src ! queue ! videoconvert ! video/x-raw,width=640,height=480,framerate=30/1 ! jpegenc ! multipartmux ! tcpserversink host=127.0.0.1 port=5000
我在获取每个jpeg帧的字节数组大小时遇到问题。
为了正确读取每个帧,我需要首先获取每个帧的大小,然后创建该大小的字节数组。
var read = serverStream.Read(imageBytes,**size**);
如果我从流水线中取出multipartmux
,似乎是一长串数据,并且在接收到第一帧后停止(serverStream.DataAvailable
= FALSE)
如果将multipartmux
保留在管道中,我将首先收到一个字节数组,其长度大约为70〜80,然后得到数据序列。
看起来像这样:
{ 45,45,84,104,105,115,82,97,110,100,111,109,83,116,114,103,13,10,67,101,121,112,58,32,47,106,76,51,54,55,49,52,}
但是我不明白那个字节数组的含义...字节数组的大小在其中以某种方式描述了吗?
如果有人可以帮助我解释这些数据,或者让我对GStreamer jpeg编码及其解码方式有一些了解,那就太好了。谢谢!
private void readFrameByteArray(int size) {
bool disconnected = false;
UnityEngine.Debug.Log("- image size: " + size);
NetworkStream serverStream = client.GetStream();
serverStream.ReadTimeout = 10;
UnityEngine.Debug.Log("ckp 1");
byte[] imageBytes = new byte[size];
var total = 0;
var sb = new StringBuilder("imageBytes[] { ");
do
{
//serverStream.ReadTimeout = 100;
UnityEngine.Debug.Log("ckp2: "+ serverStream.DataAvailable);
if (!serverStream.DataAvailable)return;
var read = serverStream.Read(imageBytes,total,size);
UnityEngine.Debug.Log("ckp3");
if (read == 0)
{
disconnected = true;
break;
}
total += read;
//UnityEngine.Debug.Log("- read: " + read);
UnityEngine.Debug.Log("- FrameByteArray total: " + total);
foreach (var b in imageBytes)
{
sb.Append(b + ",");
//if (b == 0) break;
}
sb.Append("}");
UnityEngine.Debug.Log(sb.ToString());
} while (serverStream.DataAvailable);
UnityEngine.Debug.Log("!serverStream.DataAvailable");
bool readyToReadAgain = false;
//display Image
if (!disconnected) {
//display Image on the main Thread
Loom.QueueOnMainThread(() => {
loadReceivedImage(imageBytes);
readyToReadAgain = true;
});
}
//Wait until old Image is displayed
while (!readyToReadAgain) {
UnityEngine.Debug.Log("!readyToReadAgain");
System.Threading.Thread.Sleep(1);
}
}
解决方法
对于任何正在寻找解决方案的人,这就是我最终的解决方法:
public class _TextureReceiver : MonoBehaviour
{
public int port = 5000;
public string IP = "127.0.0.1";
TcpClient client;
private NetworkStream serverStream;
[HideInInspector]
public Texture2D texture;
private bool stop = false;
[Header("Must be the same in sender and receiver")]
public int messageByteLength = 24;
public int maxFrameSize = 40000;
int try_count = 1;
// Use this for initialization
void Start()
{
//UnityEngine.Debug.Log("Start!");
Application.runInBackground = true;
client = new TcpClient();
//Connect to server from another Thread
Loom.RunAsync(() =>
{
TCP_Connect();
});
}
public void enStop()
{
stop = true;
if (client != null)
{
client.Close();
}
if (serverStream != null)
{
serverStream.Close();
}
return;
}
public void TCP_Connect()
{
client = new TcpClient();
IAsyncResult result = client.BeginConnect(IPAddress.Parse(IP),port,null,null);
result.AsyncWaitHandle.WaitOne(1000,true);
if (!client.Connected)
{
if (try_count > 0)
{
// UnityEngine.Debug.LogError("Ethernet Connection Error,Retry");
try_count++;
client.Close();
TCP_Connect();
}
else
{
client.Close();
//UnityEngine.Debug.Log("Missing Connection");
}
}
else
{
//UnityEngine.Debug.Log("V");
imageReceiver();
}
}
public void imageReceiver()
{
//While loop in another Thread is fine so we don't block main Unity Thread
Loom.RunAsync(() =>
{
while (!stop)
{
readFrameByteArray(maxFrameSize);
}
});
}
private void readFrameByteArray(int size)
{
bool disconnected = false;
serverStream = client.GetStream();
byte[] imageBytes = new byte[size];
var total = 0;
//UnityEngine.Debug.Log("serverStream.DataAvailable: "+ serverStream.DataAvailable);
if (!serverStream.DataAvailable) return;
var read = serverStream.Read(imageBytes,total,size);
if (read == 0)
{
disconnected = true;
//break;
}
total += read;
if (read == maxFrameSize) maxFrameSize += 5000;
//UnityEngine.Debug.Log("[V]read: " + read);
bool readyToReadAgain = false;
//Display Image
if (!disconnected)
{
//Display Image on the main Thread
Loom.QueueOnMainThread(() =>
{
loadReceivedImage(imageBytes);
readyToReadAgain = true;
});
}
//Wait until old Image is displayed
while (!readyToReadAgain)
{
System.Threading.Thread.Sleep(1);
}
return;
}
void loadReceivedImage(byte[] receivedImageBytes)
{
//UnityEngine.Debug.Log("* load Received Image *");
if (texture)
{
if (receivedImageBytes[0] == 255 && receivedImageBytes[1] == 216 && receivedImageBytes[2] == 255 && receivedImageBytes[3] == 224 && receivedImageBytes[4] == 0 && receivedImageBytes[5] == 16 && receivedImageBytes[6] == 74 && receivedImageBytes[7] == 70 && receivedImageBytes[8] == 73 && receivedImageBytes[9] == 70)
{
//UnityEngine.Debug.Log("* texture *");
texture.LoadImage(receivedImageBytes);
}
}
}
public void SetTargetTexture(Texture2D t)
{
texture = t;
}
public void OnApplicationQuit()
{
enStop();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。