⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videoiomgr.cpp

📁 基于SAA7113的MPEG-4程序
💻 CPP
字号:
// VideoIOMgr.cpp: implementation of the CVideoIOMgr class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MonClient.h"
#include "VideoIOMgr.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

class CMonClientDlg;

CVideoIOMgr* CVideoIOMgr::m_pInstance = NULL;

CVideoIOMgr* CVideoIOMgr::getInstance()
{
	if(m_pInstance==NULL)
		m_pInstance = new CVideoIOMgr();

	return m_pInstance;
}

void CVideoIOMgr::releaseInstance()
{
	if(m_pInstance)
	{
		delete m_pInstance;
		m_pInstance = NULL;
	}
}



CVideoIOMgr::CVideoIOMgr()
{
	for(int i=0;i<SIZE_BUFFER_NUM;i++)
	{
		m_VBuff[i].id = 0;
		m_VBuff[i].data_size=0;
		m_VBuff[i].data_size_total=0;
	}

	m_pDlg = NULL;

	for(i=0;i<4;i++)
		m_IPArr[i]=0;
	m_iport = 0;

	m_pSocket= NULL;
}

CVideoIOMgr::~CVideoIOMgr()
{

}

void CVideoIOMgr::SetShowDlg(CMonClientDlg* pDlg)
{
	m_pDlg = pDlg;	
}

void CVideoIOMgr::InputVideoPack(AVIO_VIDEO *pVPack)
{
	if(pVPack->flag != FLAG_VIDEO)
		return;

	//得到可用缓冲区
	int itarbuf = GetReadyBuf(pVPack->id);
	AVIO_VIDEO_BUFFER* pbuf = (AVIO_VIDEO_BUFFER*)&m_VBuff[itarbuf];

	//把数据导入缓冲区
	pbuf->id = pVPack->id;
	pbuf->data_size_total = pVPack->data_size_total;
	pbuf->data_size += pVPack->data_size;

	BYTE* pdst = (BYTE*)&(pbuf->data[pVPack->subid*SIZE_VIDEO_PACKED]);
	BYTE* psrc = (BYTE*)&(pVPack->data[0]);
	memcpy(pdst,psrc,pVPack->data_size);

	//输出调试信息
	TRACE("目前缓冲区ID:%d  图像帧ID:%d  SUBID:%d \n 当前帧中数据:%d  已接收数据大小:%d  总数据大小%d \n\n",itarbuf,pbuf->id,pVPack->subid,pVPack->data_size,pbuf->data_size,pbuf->data_size_total);


	//判断已经接受到完整的图像帧,就显示,然后清空该缓冲区
	if(pbuf->data_size == pbuf->data_size_total)
	{

	TRACE("\n**************************\n");

		//发送并显示图像帧
		if(m_pDlg)
		{
			BYTE* pdate = (BYTE*)&(pbuf->data[0]);
			int ilen = pbuf->data_size_total;
			m_pDlg->RcvPicData(pdate,ilen);
/*
			int ifile = 0;
			if(ifile<20)
				ifile=0;
			else
				ifile++;

			CString strFile;

			strFile.Format("c:\\%d.jpg",ifile);

			CFile file(strFile,CFile::modeCreate|CFile::modeWrite);
			file.Write(pdate,ilen);
*/
			pbuf->id = 0;
			pbuf->data_size = 0;
			pbuf->data_size_total = 0;

		}
		
		//清空缓冲区
		pbuf->id = 0;
		pbuf->data_size = 0;
		pbuf->data_size_total = 0;
	}	
}

int CVideoIOMgr::GetReadyBuf(BYTE rcvid)
{
	//**************判断该报应该放在那个缓冲区中*************
	int itarbuf=-1;

	//1.首先判断是否已经有该ID的帧缓冲区存在
	for(int i=0;i<SIZE_BUFFER_NUM;i++)
	{
		if(m_VBuff[i].id==rcvid)
		{
			itarbuf=i;
			break;
		}
	}

	if(itarbuf>=0)
		return itarbuf;
	
	//2.如果判断该帧报为新报,则寻找新的空缓冲区.
	//如果有空的缓冲区,则放置在该空缓冲区中
	for(i=0;i<SIZE_BUFFER_NUM;i++)
	{
		if(m_VBuff[i].id==0)
		{
			itarbuf=i;
			break;
		}
	}

	if(itarbuf>=0)
	{
		m_VBuff[itarbuf].data_size = 0;
		m_VBuff[itarbuf].data_size_total = 0;		
		return itarbuf;
	}

	//3.如果没有空缓冲区,则认为最老的缓冲区中保存了无效的数据,
	//清空该缓冲区,并把数据放置在该缓冲区中
	if(itarbuf==-1)
	{
		//得到最小的ID帧和最大的ID帧编号
		BYTE imaxid = 0;
		BYTE imaxbufid = 0;
		BYTE iminid = 255;
		BYTE iminbufid = 0;

		for(i=0;i<SIZE_BUFFER_NUM;i++)
		{
			if(m_VBuff[i].id > imaxid)
			{
				imaxid = m_VBuff[i].id;
				imaxbufid = i;
			}

			if(m_VBuff[i].id < iminid)
			{
				iminid = m_VBuff[i].id;
				iminbufid = i;
			}
		}

		//由最大最小帧ID判断当前最老的帧
		if(imaxid - iminid > 128) //有环绕,则最大的ID代表最老的帧
		{
			itarbuf = imaxbufid;
		}
		else
		{
			itarbuf = iminbufid;
		}

		m_VBuff[itarbuf].data_size = 0;
		m_VBuff[itarbuf].data_size_total = 0;


	}

	if(itarbuf<0)
		itarbuf = 0;

	return itarbuf;
}

void CVideoIOMgr::InitSocket(BYTE* IPArr,USHORT iport)
{
	if(m_pSocket==NULL)
	{
		m_pSocket = new CSocket();
		m_pSocket->Create(PORT_SOCKET_CLIENT,SOCK_DGRAM,"192.168.1.126");
		m_pSocket->Bind(PORT_SOCKET_CLIENT,"192.168.1.126");
	}

	for(int i=0;i<4;i++)
	{
		m_IPArr[i] = *(IPArr+i);
	}
	m_iport = iport;
}

void CVideoIOMgr::RcvSocketData()
{
	if(m_pSocket==NULL)
		return;

	CString strIP;
	strIP.Format("%d.%d.%d.%d",m_IPArr[0],m_IPArr[1],m_IPArr[2],m_IPArr[3]);
	UINT iport = m_iport;

	AVIO_VIDEO videopack;
	memset(&videopack,0,sizeof(AVIO_VIDEO));
	int ilen = sizeof(videopack);
	int iRecv = m_pSocket->ReceiveFrom((BYTE*)&videopack,ilen,strIP,iport,0);

	if(iRecv>0)
	{
		//TRACE("接收到数据ID: %d  数据subID:%d  大小:%d \n",videopack.id,videopack.subid,videopack.data_size);
		InputVideoPack(&videopack);  //192.168.1.121
		
	}
}

void CVideoIOMgr::Test()
{
	typedef struct tagBITMAPFILEHEADER
	{
		WORD bfType; // 位图文件的类型,必须为BM
		DWORD bfSize; // 位图文件的大小,以字节为单位
		WORD bfReserved1; // 位图文件保留字,必须为0
		WORD bfReserved2; // 位图文件保留字,必须为0
		DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
		// 文件头的偏移量表示,以字节为单位
	} BITMAPFILEHEADER;
	
		
//		BMP位图信息头数据用于说明位图的尺寸等信息。
		typedef struct tagBITMAPINFOHEADER{
		DWORD biSize; // 本结构所占用字节数
		LONG biWidth; // 位图的宽度,以像素为单位
		LONG biHeight; // 位图的高度,以像素为单位
		WORD biPlanes; // 目标设备的级别,必须为1
		WORD biBitCount;// 每个像素所需的位数,必须是1(双色),
			// 4(16色),8(256色)或24(真彩色)之一
			DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
		// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
		DWORD biSizeImage; // 位图的大小,以字节为单位
		LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数
		LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数
		DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
		DWORD biClrImportant;// 位图显示过程中重要的颜色数
	} BITMAPINFOHEADER;

		int iwidth = 640;
		int iheight = 480;
		BITMAPFILEHEADER filehead;
		filehead.bfType=19778;
		filehead.bfReserved1=0;
		filehead.bfReserved2=0;
		filehead.bfOffBits=54;
		filehead.bfSize=iwidth*iheight*3+54;
		
		BITMAPINFOHEADER bmiHeader;
		bmiHeader.biSize = 40;
		bmiHeader.biWidth=iwidth;
		bmiHeader.biHeight=iheight;
		bmiHeader.biPlanes=1;
		bmiHeader.biBitCount=8*3;
		bmiHeader.biCompression=0;
		bmiHeader.biSizeImage=iwidth*iheight*3;			
		bmiHeader.biXPelsPerMeter=3780;
		bmiHeader.biYPelsPerMeter=3780;
		bmiHeader.biClrImportant=0;
		bmiHeader.biClrUsed=0;

		WORD header[27] ;
		memcpy(header,&filehead,sizeof(filehead));
		memcpy(header+sizeof(filehead),&bmiHeader,sizeof(bmiHeader));

		int ss = sizeof(bmiHeader) + sizeof(filehead);

		int i=0;
		i++;

		


		
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -