[急切求助]从MJPEG视频流数据包中,解析出FFD8和FFD9之间部分!

c_fans_2010 2010-11-29 11:05:16
下面的算法用来接收MJPEG视频流,
然后把FFD8和FFD9之间的部分存储到一个JPEG图片中,
但是结果是图片上半部分清楚,下半部分模糊,不知道哪里出问题了,
请大家帮忙看下,谢谢。。。

//线程功能函数
bool CImageView::Start(CImageView* pObj)
{
int nRet;
if(WSAStartup(MAKEWORD(2,2),&wsadata))
AfxMessageBox("初始化SOCKET出错");

hsocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //TCP协议
saServer.sin_family = AF_INET;
saServer.sin_port = htons(80); //端口
saServer.sin_addr.s_addr=inet_addr("211.1.1.x"); //IP地址

//SOCKET+TCP连接网络摄相机
nRet = connect(hsocket,(LPSOCKADDR)&saServer,sizeof(SOCKADDR_IN));
if(nRet == SOCKET_ERROR)
{
AfxMessageBox("建立连接时出错");
closesocket(hsocket);
return FALSE;
}

char* req21=
"GET /videostream.asf?resolution=8&rate=15 HTTP/1.1\r\n"
"Host: 211.1.1.x:80\r\n";

char* req22=
"User-Agent: vlc/1.1.5\r\n"
"Range: bytes=0-\r\n"
"Authorization: Basic YWRtaW46\r\n" //认证信息
"Icy-MetaData: 1\r\n\r\n";

//根据Sniffer抓的数据包,进行模拟发包
nRet = send(hsocket,req21,strlen(req21),0);
Sleep(500);

nRet = send(hsocket,req22,strlen(req22),0);
Sleep(500);

if(nRet==SOCKET_ERROR)
{
AfxMessageBox("指令发送出错");
closesocket(hsocket);
return FALSE;
}

char Dest[3000] = {0}; //存储接收到的数据包
nRet=0; //接收到的数据包长度

//FFD8和FFD9之间的数据包写入dest.jpg文件
FILE* fpWRJPEGFILE = fopen("dest.jpg", "wb+");

unsigned char chBuf[MAX_SIZE] = {0}; //存储接收到的Socket数据包
unsigned char tmpBuf[MAX_SIZE] = {0}; //临时变量
unsigned char chBegin[2] = {0xFF,0xD8}; //JPEG开始标记
unsigned char chEnd[2] = {0xFF,0xD9}; //JPEG结束标记

int tmpBufLen = 0;
int BufLen = 0; //缓冲区内数据包长度
int iBegin = 0; //FFD8索引
int iEnd = 0; //FFD9索引

while(1 == bFlag) //bFlag静态变量,判断线程是否需要退出
{
memset(Dest,'\0',3000); //char数组初始化
nRet = recv(hsocket,(LPSTR)Dest,sizeof(Dest),0);

//收到Socket数据包,存储到chBuf
memcpy(chBuf+BufLen,Dest,nRet);
BufLen = BufLen+nRet; //缓冲区内数据包长度
tmpBufLen = BufLen;

//在缓冲区内 查找FFD8和FFD9
for (int i =0; i< tmpBufLen; i++)
{
if (!memcmp(chBuf+i, chBegin, 2))
{ //找到FFD8
iBegin = i;
}

if (!memcmp(chBuf+i, chEnd, 2))
{ //找到FFD9
iEnd = i;

fpWRJPEGFILE = fopen("dest.jpg", "wb"); //打开JPEG文件
if (NULL != fpWRJPEGFILE)
{
//找到FFD8和FFD9
fwrite(chBuf+iBegin, 1,iEnd-iBegin+2, fpWRJPEGFILE);

//FF09之后的数据包长度
int leaveMsgLen = BufLen-iEnd-2;

//缓冲区FF09之前的内容清空
memset(tmpBuf,0,MAX_SIZE); //初始化
memcpy(tmpBuf,chBuf+iEnd+2,leaveMsgLen);
memset(chBuf,0,MAX_SIZE); //初始化
memcpy(chBuf,tmpBuf,leaveMsgLen);

//修改缓冲区数据包长度,方便向缓冲区追加数据
BufLen = leaveMsgLen;

} // if (NULL != fpWRJPEGFILE)
fclose(fpWRJPEGFILE); //关闭JPEG文件

break; //找到一张图片就退出For循环
}
} //for (int i =0; i< BufLen; i++)

Sleep(10);
} //while(1 == bFlag)

return TRUE;
}
...全文
211 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
c_fans_2010 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fengbingchun 的回复:]
上下部分同时存放FFD8或FFD9试试看
[/Quote]
---------------------
FFD8和FFD9之前的部分,
才是一个JPEG图片吧?
fengbingchun 2010-11-30
  • 打赏
  • 举报
回复
上下部分同时存放FFD8或FFD9试试看

19,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧