现在我通过一个端口接受来自服务器视频数据包,当收到数据为一个人时解码显示OK
当收到多个人的数据包时候就会显示混乱,代码逻辑个人感觉没有什么问题:
帮忙解决的可另外加分,不胜感激,参与讨论的也会酌情给分,谢谢。关键代码如下:struct UserListItem
{
ID recvID;

//用户所在组指针
CGroupMgr *pGroup;

//用户是否需要显示
BOOL show; //接收到的用户视频数据
char videoData[MAX_VIDEO_SIZE]; //用户视频数据的窗口指针
CWnd* vWnd;
};
收到一个包ppv后,
void CGAVEngine::OnDecodeVideoData(PACK_VIDEO *ppv, int len)
{ vector<UserListItem>::iterator it;
for(it=m_UserList.begin();it!= m_UserList.end();it++)
{
//如果用户列表里面存在该数据包的发送用户,则通知该用户所在组
if (it->recvID == ppv->local_ID && it->show == TRUE)
{
                        //(char*)ppv)+sizeof(PACK_VIDEO)是将指针转到视频数据区,就是跳过包前面的包信息段;
if(m_CodecMgr.DecodeVideoData(((char*)ppv)+sizeof(PACK_VIDEO),ppv->data_size,it->videoData,0,0))
m_nCurVid=ppv -> id;                        //该函数将显示用户的视频,数据内容从it->videoData中获取
it->pGroup->OnRecvVideo(FALSE, ppv->local_ID, this);
}
}
}

解决方案 »

  1.   


    谢谢wenxy1,获取数据的方式每个用户独立的videoData,上面结构体里面有定义,刚才检查了一遍,这块代码逻辑上没有什么问题
      

  2.   

    //通过ID来获取视频数据
    char* CGAVEngine::GetRemoteVideo(UINT &len, ID id)
    {
    vector<ReceivedListItem>::iterator it;
    for(it=m_ReceiveList.begin();it!=m_ReceiveList.end();it++)
    {
    //如果接受列表里面存在该数据包的发送用户,则通知该用户所在组
    if (it->recvID == id && it->videoData)
    return it->videoData;
    }
    AfxMessageBox(_T("远程视频错误"));
    return 0;
    }
    消息响应函数:
    LRESULT CVideoWnd::OnMsgVideo(WPARAM wParam, LPARAM lParam)
    {
    if((CGAVEngine*)lParam && (ID)wParam)
    m_vs.OnVideoData(ID(wParam), (CGAVEngine*)lParam); return 0;
    }视频显示代码,通过消息触发:
    /*------------------------------------------------------------------------------*/
    //得到视频数据,并画出来。TODO:大小位置还需要斟酌
    void CVideoShow::OnVideoData(DWORD id, CGAVEngine *pEngine)
    {

    RECT rc;
    CDC* cdc=GetDC();
    HDC hdc = cdc->GetSafeHdc();
    HDC hMemDC=CreateCompatibleDC(hdc);
    GetClientRect(&rc);
    m_hBmp=CreateCompatibleBitmap(hdc,176,144);
    HBITMAP hob=(HBITMAP)SelectObject(hMemDC,m_hBmp);

    if(hob)
    {
    UINT len;
    char* p;
    if(id == pEngine->GetLocalID())
    p=pEngine->GetLocalVideo(len);
    else
    p=pEngine->GetRemoteVideo(len, id); BITMAPINFOHEADER* pbih=&pEngine->GetBitampInfo()->bmiHeader;

    HDRAWDIB h=DrawDibOpen();
    DrawDibDraw(h,hMemDC,0,0,rc.right,rc.bottom,pbih,p,0,0,pbih->biWidth,pbih->biHeight,DDF_NOTKEYFRAME);
    DrawDibClose(h);

    BitBlt(hdc,0,0,rc.right,rc.bottom,hMemDC,0,0,SRCCOPY);
    SelectObject(hMemDC,hob);
    }
    DeleteDC(hMemDC);
    ReleaseDC(cdc);

    if(!IsWindowVisible())
    ShowWindow(SW_SHOW);
    }
      

  3.   

    是有套接字回调线程的
    m_hSockThread=CreateThread(0,0,SockThreadProc,(LPVOID)this,0,&m_dwSockThreadId);然后收到数据包,之后就按照上面代码顺序执行了
      

  4.   

    你这个SockThreadProc回调函数,是否在这个函数中接收数据,然后调用上面你写的哪些函数进行处理的?
      

  5.   

    那你这个就是多线程调用了
    像是你的这些m_UserList成员变量,都没有做互斥处理,多线程会有问题的
    建议做同步后试一下
      

  6.   

    多线程访问同一个变量的,就需要对这个变量做同步的。
    你这种情况用mutex就可以了
    例如:m_UserList
      

  7.   

    多线程访问同一个变量的,就需要对这个变量做同步的。
    你这种情况用mutex就可以了
    例如:m_UserList
      

  8.   

    多线程访问同一个变量的,就需要对这个变量做同步的。
    你这种情况用mutex就可以了
    例如:m_UserList
      

  9.   

    猫兄,不胜感激
    我的理解是:监听端口线程,现在只是执行这段代码:
    case FLAG_VIDEO:
    {
    PACK_VIDEO* packVideo= (PACK_VIDEO*) buf; //将视频数据包包解压;
    if(pEngine->m_videoCodec)
    pEngine->OnDecodeVideoData(packVideo, iLen);
    }//视频解码
    void CEngine::OnDecodeVideoData(PACK_VIDEO *ppv, int len)
    { vector<UserListItem>::iterator it;
    for(it=m_UserList.begin();it!=m_UserList.end();it++)
    {
    //如果接受列表里面存在该数据包的发送用户,则通知该用户所在组
    if (it->recvID == ppv->local_ID && it->show == TRUE)
    {
    if(m_CodecMgr.DecodeVideoData(((char*)ppv)+sizeof(PACK_VIDEO),ppv->data_size,it->videoData,0,0))
    {
    m_nCurVid=ppv -> id;
    } //统计收到的数据
    m_uDataRcv+=sizeof(PACK_VIDEO)+ppv->data_size; it->pGroup->OnRecvVideo(FALSE, ppv->local_ID, this);
    }
    }里面的ppv需不需要同步,因为m_UserList是保存了所有的用户列表,是通过ppv中的id来识别一个用户的,是不是说明该同步ppv,以前没有做过多线程的东西,希望高手指教
      

  10.   

    ppv是不需要的,ppv是你传过来的一个,每个线程执行的时候都会传过来一个ppv;但是你的m_UserList这些东西,每个线程都访问同一个东西,所以要同步
      

  11.   

    这个监听会建立多线程么?黑猫兄,我总觉得是就是SockThreadProc回调函数这样一个处理函数呢
      

  12.   

    你不是启动了线程来跑这段代码么?SockThreadProc这个是一个线程,你的主函数又是另外的线程