c# - Streaming WebCamTexture with new Unity 5.1 Transport Layer API -


as question states, have been trying stream webcamtexture client webcam server. both sides (client , server) in unity. later, client deployed android , server desktop application.

currently getting pixels of texture using:

tex.getpixels32(); 

and serializing them custom serializer (to optimize size). have uncompressed byte array around 3,5mb per frame ready sent. know huge, wanted have transmitted before start compression part , real time part.

the last part of process should send using new unity networktransport static class. has been long time since last time used sockets , rotten. unable have working.

here code server side (omitting serialization code clarity):

void start() {     webcamtexture = new webcamtexture();     background.texture = webcamtexture;     background.material.maintexture = webcamtexture;     webcamtexture.play();      if (!_isstarted)     {         _isstarted = true;          networktransport.init();         m_config = new connectionconfig();         m_communicationchannel  = m_config.addchannel(qostype.reliablefragmented);         hosttopology topology = new hosttopology(m_config, 12);         m_generichostid = networktransport.addhost(topology, 0);         byte error;         m_connectionid = networktransport.connect(m_generichostid, ip, port, 0, out error);     } }  void update() {     if (!_isstarted)         return;      networkeventtype recdata = networktransport.receive(out rechostid, out connectionid, out channelid, recbuffer, buffersize, out datasize, out error);      switch (recdata)     {         case networkeventtype.nothing:         //1             break;         case networkeventtype.connectevent:    //2             debug.log("received connection confirmation");             _readytosend = true;             break;         case networkeventtype.dataevent:       //3              break;         case networkeventtype.disconnectevent: //4             //one of established connection has been disconnected             debug.log(string.format("disconnect host {0} connection {1}", rechostid, connectionid));              break;     }      if (_readytosend)     {         _readytosend = false; // send first frame          byte[] colourarray = serializeobject(makeserializable(getrendertexturepixels(webcamtexture))); // serialize webcam texture          // sending total size         byte[] sizetosend = bitconverter.getbytes(colourarray.length);         networktransport.send(m_generichostid, m_connectionid, m_communicationchannel, sizetosend, sizetosend.length, out error);          byte[] bytes = new byte[bufferlenght];         int remainingbytes = colourarray.length;         int index = 0;         int = 1;          while (remainingbytes >= bufferlenght)         {             system.buffer.blockcopy(colourarray, index, bytes, 0, bufferlenght);             networktransport.send(m_generichostid, m_connectionid, m_communicationchannel, bytes, bytes.length, out error);             remainingbytes -= bufferlenght;             debug.log(i++ + "remaining bytes: " + remainingbytes + " - error: "+error);             index += bufferlenght;         }          if (remainingbytes > 0) // send last fragment below bufferlenght bytes         {             system.buffer.blockcopy(colourarray, index, bytes, 0, remainingbytes);             networktransport.send(m_generichostid, m_connectionid, m_communicationchannel, bytes, remainingbytes, out error);             debug.log("error: "+error);         }     } } 

and client side:

void start() {     if (!_isstarted)     {         _isstarted = true;          networktransport.init();          m_config = new connectionconfig();          m_communicationchannel  = m_config.addchannel(qostype.reliablefragmented);          hosttopology topology = new hosttopology(m_config, 12);          m_generichostid = networktransport.addhost(topology, port, null);     } }  void update() {     if (!_isstarted)         return;      int rechostid;      int connectionid;      int channelid;      byte[] recbuffer = new byte[bufferlenght];      int buffersize = bufferlenght;     int datasize;     byte error;      networkeventtype recdata = networktransport.receive(out rechostid, out connectionid, out channelid, recbuffer, buffersize, out datasize, out error);      switch (recdata)     {         case networkeventtype.nothing:         //1             break;          case networkeventtype.connectevent:    //2                  //somebody else connect me             log.text += string.format("connect host {0} connection {1}\n", rechostid, connectionid);             break;          case networkeventtype.dataevent:       //3              if (!sizereceived)             {                 sizereceived = true;                  if (datasize == 2)                 {                     bytestoreceive = bitconverter.toint16(recbuffer, 0);                 }                 else if (datasize == 4)                 {                     bytestoreceive = bitconverter.toint32(recbuffer, 0);                 }                  debug.log("we receive: "+bytestoreceive);             }             else             {                 log.text = string.format("received event host {0} connection {1} channel {2} message length {3}\n", rechostid, connectionid, channelid, datasize);                  log.text += "received " + buffersize + " bytes\n";                 bytestoreceive -= buffersize;                 log.text += "remaining " + bytestoreceive + " bytes\n";             }             break;          case networkeventtype.disconnectevent: //4              break;      } } 

i know block update function until sent, not important right me, since trying frame transmitted understand how new system works, , proceed there. getting error after first package sent, buffer of 32768 bytes:

no free events long message unityengine.networking.networktransport:send(int32, int32, int32, byte[], int32, byte&) camerastreamer:update() (at assets/scripts/client/camerastreamer.cs:112) 

i have tried use 1024 buffer, , takes longer show message (after more 100 sent packages).

according this thread, related messages being sent fast , filling queue, none of proposed solutions worked me. appreciate or orientation, since unity documentation poor.

this particular test code / example still have issues unity 5.2 patch.

running code in unity 5.3.4f1, able see error 4 (networkerror.noresource) occurs after 200 packets , stops sending shortly afterwards. presume reason because blocking send , message queue never flushes properly.

i've rewritten code grab webcam image off texture after 2 second delay (because webcam needs time intialise, otherwise send blank image).

afterwards sending through webcam image, single packet per execution of update seems fine. because update had time run , not blocked. send packet , exit update function, moving index , other variables out of update.

hope helps else looking @ this, took me 3 days figure out.

edit: testing, more simple method move out blocking send (while bit) , add co-routine. seems work way well.


Comments

Popular posts from this blog

How to provide Authorization & Authentication using Asp.net, C#? -

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

How to use Authorization & Authentication in Asp.net, C#? -