下面的算法用来接收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;
}
然后把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;
}
我能够获得jpg数据流,也可以获得视频流,但是如何保持成视频格式呢?