当前位置: 代码迷 >> 多媒体/流媒体开发 >> 为什么在运行大概一分钟后,接收方的视频图像开始变慢甚至停滞?该如何解决
  详细解决方案

为什么在运行大概一分钟后,接收方的视频图像开始变慢甚至停滞?该如何解决

热度:910   发布时间:2013-02-26 00:00:00.0
为什么在运行大概一分钟后,接收方的视频图像开始变慢甚至停滞?
我想实现一个UDP协议的网络视频程序,

        发送端的GRAPH是:VideoCapture-> DivX;)Fast-Motion-> NetSender
        接收端的GRAPH是:NetRecv-> DivX   Devoder-> VideoRender

        我的思路是:NetSender接到一个   MediaSample后,通过GetPoint和GetActualDataLength得到视频帖数据和实际长度,然后对数据按1024长度进行分片发送。其算法是:


#define   LEN_PIECE1024

typedef   struct   _UDPMediaPacket//UDP数据包结构
{
DWORDdwFrameNo;//帧序号
WORDwMaxPiece;//本帧共多少片
WORDwPieceNo;//本片序号
CHARData[LEN_PIECE];//分片的压缩视频数据
}UDPMEDIAPACKET,   *LPUDPMEDIAPACKET;

{
...
UDPMEDIAPACKET   UDPMediaPacket;

UDPMediaPacket.dwFrameNo   =   m_nFrameVideo;//类成员变量,记录从发送开始到当前的帧序号
m_nFrameVideo   ++;//帧序号加1

BYTE   *pSourceBuf   =   NULL;
pSample-> GetPointer(&pSourceBuf);//取压缩视频数据起始指针

int   nSampleLength   =   pSample-> GetActualDataLength();//取帧数据长度

if   ((nSampleLength   %   LEN_PIECE)   >   0)//计算本帧共多少片
{
UDPMediaPacket.wMaxPiece   =   1   +   nSampleLength   /   LEN_PIECE;
}
else
{
UDPMediaPacket.wMaxPiece   =   nSampleLength   /   LEN_PIECE;
}

SOCKADDR_IN   remote;
remote.sin_addr.S_un.S_addr   =   ...
remote.sin_family   =   AF_INET;
remote.sin_port       =   ...;

int   nPieceNo   =   0,   nByteSent   =   0;

while   (nSampleLength   >   0)
{
UDPMediaPacket.wPieceNo   =   nPieceNo;

memset(UDPMediaPacket.Data,   0,   LEN_PIECE);

int   nLenPacket   =   0;
if   (nSampleLength   >   LEN_PIECE)
{
nLenPacket   =   LEN_PIECE;
}
else
{
nLenPacket   =   nSampleLength;
}

CopyMemory(UDPMediaPacket.Data,   pSourceBuf,   nLenPacket);

nByteSent   =   sendto(socket,   (char*)&UDPMediaPacket,   nLenPacket   +   8,   0,   (SOCKADDR*)&remote,   sizeof(remote));

nByteSent   -=   8;

nSampleLength   -=   nByteSent;
pSourceBuf   +=   nByteSent;

nPieceNo   ++;
}

pSample-> Release();//本帧发送完毕

...
}

        在接收端的思路是,根据接收到的UDP包中包含的帧、片序号进行拼帧,考虑UDP包的无序性,如果收到的数据帧序号错或者片丢失,则丢弃本帧,始终以完整的帧递增地交给DivX   Devoder解码。其算法是:

DWORD   dwFrame   =   0;
WORD     wPiece     =   0;
int       nLenVideoBuf   =   0;

BYTE   VideoBuf[304130],   *pVideoBuf   =   NULL;
pVideoBuf   =   VideoBuf;

while(...)
{
memset(Buf,   0,   1024);

nBytesRecved   =   recvfrom(socket,   (char*)Buf,   1024,   0,   (SOCKADDR*)&remote,   &dwSender);

if   (nBytesRecved   <=   0)
{
continue;
}
else
{
nBytesRecved   -=   8;

pUDPMediaPacket   =   (LPUDPMEDIAPACKET)Buf;

if   ((pUDPMediaPacket-> dwFrameNo   ==   dwFrame)   &&//收到的数据帧序号与片序号与应该接收的一致
        (pUDPMediaPacket-> wPieceNo   ==   wPiece))
{
CopyMemory(pVideoBuf,   pUDPMediaPacket-> Data,   nBytesRecved);

pVideoBuf   +=   nBytesRecved;
  相关解决方案