Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Receiver #2

Open
bigzaiko opened this issue Sep 5, 2022 · 0 comments
Open

Image Receiver #2

bigzaiko opened this issue Sep 5, 2022 · 0 comments

Comments

@bigzaiko
Copy link

bigzaiko commented Sep 5, 2022

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using UnityEngine;

public class TCPImage : MonoBehaviour
{
public NetworkStream stream { get; private set; }
public int ImageSizeWidth = 640;
public int ImageSizeHeight = 360;
public int receiveBufferSize = 2000000;
public Material TargetMaterial;

private Thread tcpThread;

private TcpClient tcpClient;
private TcpListener tcpListener;

private byte[] dumpPixels;
private byte[] bytes;
private byte[] pixels;

private Texture2D texture;

private int bufferIndex = 0;
private int bufferFrameStart = 0;
private Queue<int> frameIndex = new Queue<int>();
private int frameBufferCount = 0;
private int bufferSize;

// Start is called before the first frame update
void OnEnable()
{
	try
	{
		this.receiveBufferSize = this.ImageSizeWidth * this.ImageSizeHeight * 3;
		this.texture = new Texture2D(this.ImageSizeWidth, this.ImageSizeHeight, TextureFormat.RGB24, false);
		this.texture.filterMode = FilterMode.Bilinear;
		this.texture.wrapMode = TextureWrapMode.Clamp;

        this.bufferSize = this.receiveBufferSize * 3;
        this.dumpPixels = new byte[this.bufferSize];
        this.pixels = new byte[this.receiveBufferSize];

		for (int i = 0; i < this.receiveBufferSize; i += 3)
		{
			this.pixels[i + 0] = 255;
			this.pixels[i + 1] = 0;
			this.pixels[i + 2] = 255;
		}

		this.texture.LoadRawTextureData(this.pixels);
		this.texture.Apply(false);

		this.TargetMaterial.mainTexture = this.texture;
	}
	catch (Exception ex)
	{
		DebugLog.Log("Exception " + ex.ToString());
	}
}

public void TcpConnection()
{
    this.tcpListener = new TcpListener(IPAddress.Any, 3005);
    this.tcpListener.ExclusiveAddressUse = false;
	this.tcpListener.Server.DontFragment = true;
    this.tcpListener.Start();


    this.tcpThread = new Thread(ListenForTCPPackages);
    this.tcpThread.IsBackground = true;
    this.tcpThread.SetApartmentState(ApartmentState.STA);
    this.tcpThread.Start();
}

private void ListenForTCPPackages()
{
	try
	{
		// Get a stream object for reading and writing
		this.tcpClient = this.tcpListener.AcceptTcpClient();
		this.tcpClient.Client.DontFragment = true;
        this.stream = this.tcpClient.GetStream();

		this.bytes = new byte[this.receiveBufferSize];
		
		int i;
        // Loop to receive all the data sent by the client.
        while ((i = this.stream.Read(this.bytes, 0, this.bytes.Length)) != 0)
        {
            //if (this.bufferFrameStart == this.bufferSize)
                //this.bufferFrameStart = 0;

            if (this.bufferIndex + i > this.bufferSize)
            {
                var diff = this.bufferSize - this.bufferIndex;

                if (diff != 0)
                {
                    Array.Copy(this.bytes, 0, this.dumpPixels, this.bufferIndex, diff);
                    this.bufferIndex = i - diff;
                }
                else
                {
                    Array.Copy(this.bytes, 0, this.dumpPixels, 0, i);
                    this.bufferIndex = i;
                    this.bufferFrameStart = 0;
                }
            }
            else
            {
                Array.Copy(this.bytes, 0, this.dumpPixels, this.bufferIndex, i);
                this.bufferIndex += i;
            }

            if (this.bufferIndex - this.bufferFrameStart >= this.receiveBufferSize)
            {
                this.frameIndex.Enqueue(this.bufferFrameStart);
                this.frameBufferCount++;
                this.bufferFrameStart += this.receiveBufferSize;
            }
        }
	}
	catch (Exception ex)
	{
		//DisposeListener();
        Debug.Log("lost video stream");
        Debug.Log("listener thread: " + ex.ToString());
    }
}

private void Update()
{
    if (this.frameBufferCount > 0 && this.frameIndex.Count != 0)
    {
        var deq = this.frameIndex.Dequeue();
        Array.Copy(this.dumpPixels, deq, this.pixels, 0, this.receiveBufferSize);
        this.texture.LoadRawTextureData(this.pixels);
        this.texture.Apply(false);
        this.frameBufferCount--;
    }
}

private void DisposeListener()
{
    this.bufferFrameStart = 0;
    this.bufferIndex = 0;
    this.frameIndex.Clear();

    if (this.tcpListener != null)
    {
        this.tcpListener.Stop();
        this.tcpListener = null;
    }

    if (this.tcpClient != null)
    {
        this.tcpClient.Close();
        this.tcpClient.Dispose();
        this.tcpClient = null;
    }

    if(this.stream != null)
    {
        this.stream.Flush();
        this.stream.Close();
        this.stream.Dispose();
        this.stream = null;
    }

    if (this.tcpThread != null)
    {
        this.tcpThread.Abort();
        this.tcpThread = null;
    }
}
private void OnDestroy()
{
	DisposeListener();
}

private void OnDisable()
{
    DisposeListener();
}

private void OnApplicationQuit()
{
    DisposeListener();
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant