问题描述:
我用TIdTCPServer和TIdTCPClient进行视频通信,服务端有两路视频,以不同的发送命令同时发送给客户端,客户端根据不同的发送命令,获取两路视频,然后显示在客户端界面上的Image1和Image2中。现在碰到的问题是,能接受到图像信号,但是在界面上显示时,无法达到第一路信号稳定地在Image1中显示,第二路信号稳定地在Image2中显示。而是出现Image1和Image2交替同时显示两路信号的情况,也就是说Image1中一会显示第一路信号,一会显示第二路信号。Image2的情况也一样,求帮忙解决!!!我的自己感觉可能是跟多线程中VCL控件不安全相关,但是不知道怎么解决
  
我的代码如下:
procedure ReceiveBitmapToImage(Sender: TObject);
var
  BIInfo: TBitmapInfo;
  BitmapHandle: HBitmap;
  DIBPtr: Pointer;
  DIBSize: LongInt;
  tmpBuffer : TIdBytes;
  ibuffer: TIdBytes;
begin
  try
    //接收服务端发送过来的图像信息
    VideoForm.idtcpclnt1.IOHandler.ReadBytes(ibuffer, 4);
    imgSendBuf.ImgSize := PInteger(ibuffer)^;
    VideoForm.idtcpclnt1.IOHandler.ReadBytes(tmpBuffer, imgSendBuf.ImgSize);
    BytesToRaw(tmpBuffer, imgSendBuf.Buffer, imgSendBuf.ImgSize);
  with VideoForm do
  begin
    //将接收的数据imgSendBuf进行解码
    
    //设置BIInfo信息
    BIInfo.bmiHeader.biSize := 40;
    BIInfo.bmiHeader.biWidth := 320;
    BIInfo.bmiHeader.biHeight := 240;
    BIInfo.bmiHeader.biPlanes := 1;
    BIInfo.bmiHeader.biBitCount := 24;
    BIInfo.bmiHeader.biCompression := 0;
    BIInfo.bmiHeader.biSizeImage := 320 * 240 * 3;
    BIInfo.bmiHeader.biXPelsPerMeter := 0;
    BIInfo.bmiHeader.biYPelsPerMeter := 0;
    BIInfo.bmiHeader.biClrUsed := 0;
    BIInfo.bmiHeader.biClrImportant := 0;
    //创建BitmapHandle
    BitmapHandle := CreateDIBSection(0, BIInfo, DIB_RGB_COLORS, DIBPtr, 0, 0);
    Move(FrameImg, DIBPtr^, BIInfo.bmiHeader.biSizeImage );    EnterCriticalSection(CS);
    //将BitmapHandle赋给全局变量Bitmap
    Bitmap.Handle := BitmapHandle;
    //将Bitmap显示在Image1中
    image1.Canvas.Lock;
    Bitmap.Canvas.Lock;
    image1.Canvas.Draw(0,0,Bitmap);
    Bitmap.Canvas.Unlock;
    image1.Canvas.Unlock;    LeaveCriticalSection(CS);
   end;
  finally
   DeleteObject(BitmapHandle);
  end;
end;

解决方案 »

  1.   

    网络传输有个延时问题 数据上传下载的速率是时刻变化的 
    所以你想实现实时播放视频 
    要 先下载一定数据量的数据到本地 
    然后再给Bitmap赋数据 以实现视频的连续性 
      

  2.   

    idtcpclnt1.IOHandler.ReadBytes请注意第三个参数为false,否则是一直append。
    然后两路视频最好使用两个socket,不要在一个里面传输。命令和视频的传输也不要在一路socket里操作。
    两路视频显示交叉应该在查下你代码,应该是没有处理好。