VisionLab VCL
Sending Video through a socket
Thread Starter: SebCestBien Started: 1/23/2007 6:22 PM UTC
Replies: 1
Sending Video through a socket
Hello,

First... a big thank you for yours components...

I'm trying to send video through a tcp socket. I have linked a VDLSCapture to a VLVideoCompressor and finally to a SLGenericFilter where the ProcessData event send to a tcp socket....

here the code to send video:
void __fastcall TForm1::SLGenericFilter1ProcessData(TObject *Sender,
     TSLCBlockBuffer InBuffer, TSLCBlockBuffer &OutBuffer,
     bool &SendOutputData)
{
 if (SendVideo)
 {
   ClientSocket->Socket->SendBuf((void *)InBuffer.Read(),InBuffer.GetSize());
 }
}

On the client side I get the buffer in a socket:

void __fastcall TForm1::ServerSocketClientRead(TObject *Sender,
     TCustomWinSocket *Socket)
{
 int ASize = Socket->ReceiveLength();
 TSLCBlockBuffer *InBuffer = new TSLCBlockBuffer( ASize );
 Socket->ReceiveBuf(*InBuffer, ASize);
 SLGenericFilter2->SendData( *InBuffer );
 delete InBuffer;
}


and it's is processed in a SLGenericFilter and to a VLVideoDecompressor and finally in a VLImageDisplay.


I have used different codec: MPG4, DIVX, MPG...
And all these compressor made the same problem : The video on the client side is not full (I have send an attach to clarify the problem...)

Do you have any idea to resolve this problem ?


Thanks a lot
Seb

P.S: Sorry for my extrem english....

This message includes the following attachments:

Re: Sending Video through a socket
SebCestBien wrote:
I have used different codec: MPG4, DIVX, MPG...
And all these compressor made the same problem : The video on the client side
is not full (I have send an attach to clarify the problem...)

Do you have any idea to resolve this problem ?

Yes, you're not sending and receiving the data properly. When the OnRead event is called, it does not necessarily contain all the data that you sent previously.

A good way to handle this is to send the size of the data before sending any data, and then buffer the receive operation, so that you read the correct number of bytes.

Something like this:

// Untested

// Server side:
void __fastcall TForm1::SLGenericFilter1ProcessData(TObject *Sender,
     TSLCBlockBuffer InBuffer, TSLCBlockBuffer &OutBuffer,
     bool &SendOutputData)
{
 if (SendVideo)
 {
   int Size = InBuffer.GetByteSize();

   ClientSocket->Socket->SendBuf(&Size, sizeof( int ) );
   ClientSocket->Socket->SendBuf( (void *)InBuffer.Read(), Size );
 }
}

// Client side:
void __fastcall TForm1::ServerSocketClientRead(TObject *Sender,
     TCustomWinSocket *Socket)
{
 int ASize = Socket->ReceiveLength();
 char *Buffer = new char[ ASize ];

 Socket->ReceiveBuf( Buffer, ASize );

 BufferStream->Write( Buffer, ASize );
 while( BufferStream->Size > sizeof( int ) )
 {
   int SendSize = *( (int*)(BufferStream->Memory) );

   if( BufferStream->Size >= ( SendSize + sizeof( int ) ) )
   {
       TSLCBlockBuffer InBuffer( SendSize );

       BufferStream->Position = sizeof( int );
       BufferStream->Read( InBuffer.Read(), SendSize );
       SLGenericFilter2->SendData( InBuffer );

       MoveMemory( BufferStream->Memory, BufferStream->Memory + sizeof(int) + SendSize, BufferStream->Size - sizeof( int ) - SendSize );

       BufferStream->Size = BufferStream->Size - sizeof( int ) - SendSize;
       BufferStream->Seek( 0, soFromEnd );
    }
    else
    {
       break;
    }
 }
}

You'll need to add a TMemoryStream *BufferStream to your form's declaration, and initialize it in the constructor.

HTH

Jonathan