www.pudn.com > Videodisplay.rar > VideoView.cpp
// VideoView.cpp : implementation of the CVideoView class
//
#include "stdafx.h"
#include "Video.h"
#include "VideoDoc.h"
#include "VideoView.h"
#include "math.h"
#include "convert.h"
#include "wtdlg.h"
#include "yuvdlg.h"
#include "time.h"
#include "fstream.h"
#include "dwt.h"
#include "stdio.h"
#include "stdlib.h"
#include "intwt.h"
#include "mcvqdlg.h"
#include "RelationDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CVideoView
IMPLEMENT_DYNCREATE(CVideoView, CScrollView)
BEGIN_MESSAGE_MAP(CVideoView, CScrollView)
//{{AFX_MSG_MAP(CVideoView)
ON_COMMAND(ID_PLAY_YUV, OnPlayYuv)
ON_COMMAND(ID_WT_SPIHT_ENCODE, OnWtSpihtEncode)
ON_COMMAND(ID_WT_SPIHT_DECODE, OnWtSpihtDecode)
ON_COMMAND(ID_PLAY_WT, OnPlayWt)
ON_COMMAND(ID_MC_INT_ENCODE, OnMcIntEncode)
ON_COMMAND(ID_INT_MC_DECODE, OnIntMcDecode)
ON_COMMAND(ID_MCVQ_ENCODE, OnMcvqEncode)
ON_COMMAND(ID_MCVQ_DECODE, OnMcvqDecode)
ON_COMMAND(ID_INTRO_FRAME, OnIntroFrame)
// ON_COMMAND(ID_INTER_FRAME, OnInterFrame)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVideoView construction/destruction
CVideoView::CVideoView()
{
pels=352;
lines=288; //默认CIF
bFlag=0;
str_FileName="0";
nFrameNum=0;
frequency=30;
hloc = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256));
BmpInfo = (LPBITMAPINFO) GlobalLock(hloc);
// TODO: add construction code here
}
CVideoView::~CVideoView()
{
}
BOOL CVideoView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CVideoView drawing
void CVideoView::OnDraw(CDC* pDC)
{
CVideoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(bFlag==1) //表示播放原始视频序列
{
BmpInfo->bmiHeader.biBitCount = 24;
create();
showVideo(pDC);
bFlag=0;
//str_FileName="0";
}
if(bFlag==2) //表示小波变换+RLC+Huffman编码
{
CString str;
str.Format("Encoding,please wait for a moment!");
pDC->SetBkColor(255);
pDC->TextOut(5000,-5000,str);
bFlag=0;
}
if(bFlag==3) //表示小波+RLC+Huffman解码
{
BmpInfo->bmiHeader.biBitCount=24;
create();
RlcHuffDe(pDC);
bFlag=0;
}
if(bFlag==4) //IDWT+反量化
{
BmpInfo->bmiHeader.biBitCount=24;
create();
iwt(pDC);
bFlag=0;
}
if(bFlag==2) //表示提升小波变换+运动补偿
{
CString str;
str.Format("Encoding,please wait for a moment!");
pDC->SetBkColor(255);
pDC->TextOut(5000,-5000,str);
bFlag=0;
}
}
void CVideoView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal(30000, 40000); // 30-by-40 cm
CSize sizeLine = CSize(sizeTotal.cx / 100, sizeTotal.cy / 100);
SetScrollSizes(MM_HIMETRIC, sizeTotal, sizeTotal, sizeLine);
CClientDC dc(this);
}
/////////////////////////////////////////////////////////////////////////////
// CVideoView diagnostics
#ifdef _DEBUG
void CVideoView::AssertValid() const
{
CScrollView::AssertValid();
}
void CVideoView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CVideoDoc* CVideoView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVideoDoc)));
return (CVideoDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CVideoView message handlers
void CVideoView::OnPlayYuv() //播放原始YUV序列
{
CYUVdlg dlgyuv;
dlgyuv.DoModal();
pels=dlgyuv.pels;
lines=dlgyuv.lines;
frequency=dlgyuv.m_nFrequency;
CFileDialog dlg(TRUE,"yuv","*.yuv"); //打开文件的对话狂
if(dlg.DoModal()==IDOK)
{
str_FileName=dlg.GetPathName();
bFlag=1; //改变程序运行的状态
}
Invalidate();
}
void CVideoView::create() //生成图象的头文件
{
int i;
HANDLE hloc1;
RGBQUAD *argbq;
hloc1 = LocalAlloc(LMEM_ZEROINIT | LMEM_MOVEABLE,(sizeof(RGBQUAD) * 256));
argbq = (RGBQUAD *) LocalLock(hloc1);
for(i=0;i<256;i++) {
argbq[i].rgbBlue=i;
argbq[i].rgbGreen=i;
argbq[i].rgbRed=i;
argbq[i].rgbReserved=0;
} //生成调色板
BmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfo->bmiHeader.biPlanes = 1;
BmpInfo->bmiHeader.biBitCount = 24;
BmpInfo->bmiHeader.biCompression = BI_RGB;
BmpInfo->bmiHeader.biWidth = pels;
BmpInfo->bmiHeader.biHeight =lines;
memcpy(BmpInfo->bmiColors, argbq, sizeof(RGBQUAD) * 256);
LocalUnlock(hloc1);
LocalFree(hloc1);
}
void CVideoView::showVideo(CDC* pDC) //播放原始视频序列
{
ColorSpaceConversions conv;
CFile fileVideo; //视频文件
fileVideo.Open(str_FileName,CFile::modeRead);
unsigned char* lum=new unsigned char[pels*lines];
unsigned char* Cb=new unsigned char[pels*lines/4];
unsigned char* Cr=new unsigned char[pels*lines/4];
UINT PicSize=pels*lines*3/2;
unsigned char* m_pImageData=new unsigned char[pels*lines*3/2];
m_pDataRGB=new unsigned char[pels*lines*3];
CString str;
for(nFrameNum=0;nFrameNum<1500;nFrameNum++)
{
fileVideo.Seek(nFrameNum*pels*lines*3/2,SEEK_SET);
if(PicSize!=fileVideo.Read(m_pImageData,sizeof(BYTE)*pels*lines*3/2))//在文件中读取一幅图象
{
AfxMessageBox("播放结束!");
break;
}
memcpy(lum, m_pImageData, pels*lines); //Y
memcpy(Cb, m_pImageData + pels*lines, pels*lines/4); //u
memcpy(Cr, m_pImageData + pels*lines + pels*lines/4, pels*lines/4); //V
conv.YV12_to_RGB24(lum,Cb,Cr,m_pDataRGB,pels,lines);
SetDIBitsToDevice(pDC->GetSafeHdc(),600,-660,pels,
lines,
0,0,0,lines,
m_pDataRGB,BmpInfo,DIB_PAL_COLORS);
str.Format("The number of frame is %d",nFrameNum+1);
pDC->TextOut(13000,-600,str);
delay(frequency); //延时
}
fileVideo.Close();
}
void CVideoView::delay(int n) //延时函数,其中n为每秒的祯数
{
long int i;
clock_t t1,t2;
t1=clock();
float tmp=(float)0.95; //tmp为比例因子,消除其他运算对时间的影响
for(i=0;i<3500000;i++)
{
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
sin(i);
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
sin(2*i);
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
sin(3*i);
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
sin(4*i);
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
sin(5*i);
t2=clock();
if(((float)(t2-t1)/((float)CLOCKS_PER_SEC))>=(tmp/(float)n))
return;
}
}
void CVideoView::OnWtSpihtEncode() //小波变换+行程+huffman编码
{
BeginWaitCursor();
CFileDialog dlgsource(TRUE,"yuv","*.yuv"); //打开文件的对话狂
if(dlgsource.DoModal()==IDOK)
{
str_FileName=dlgsource.GetPathName();
}
else
{
bFlag=0;
return;
}
CWTDlg dlgwt;
dlgwt.DoModal();
int SpaceLevel,TimeLevel; //空间分解层数和时间分解层数
int nNum; //时间多少祯做一次小拨分解
int stepY,stepU,stepV; //Y, U, V的量化步长
SpaceLevel=dlgwt.m_nSpaceLevel;
TimeLevel=dlgwt.m_nTimeLevel;
nNum=dlgwt.m_nFrame;
stepY=dlgwt.m_nStepY;
stepU=dlgwt.m_nStepU;
stepV=dlgwt.m_nStepV;
pels=dlgwt.pels;
lines=dlgwt.lines;
AfxMessageBox("请选择编码以后的文件保存:");
CString str_Save; //编码后的文件保存路径
CFileDialog dlgsave(FALSE,"ws","*.ws");
if(dlgsave.DoModal()==IDOK)
{
str_Save=dlgsave.GetPathName();
bFlag=2; //改变程序运行状态
Invalidate();
}
else
{
bFlag=0; //恢复程序运行状态
return;
}
AfxMessageBox("编码时间可能较长,请耐心等待");
double* tmpBlockY=new double[pels*lines*nNum];
double* tmpBlockU=new double[pels*lines*nNum/4];
double* tmpBlockV=new double[pels*lines*nNum/4];
unsigned char* blockY=new unsigned char[pels*lines*nNum];
unsigned char* blockU=new unsigned char[pels*lines*nNum/4];
unsigned char* blockV=new unsigned char[pels*lines*nNum/4];
unsigned char* m_pData=new unsigned char[pels*lines*3/2];
CFile fileSource;
if(!fileSource.Open(str_FileName,CFile::modeRead))
{
bFlag=0;
AfxMessageBox("读入文件发生错误!");
return;
}
ofstream tmpout;
tmpout.open("D:\\tmp.yuv",ios::trunc|ios::binary);
tmpout<<(unsigned char)SpaceLevel<<(unsigned char)TimeLevel<<(unsigned char)nNum<<(unsigned char)stepY<<(unsigned char)stepU<<(unsigned char)stepV;
int i,j,k,m;
int flag=0; //临时标记
CDwt dwt;
unsigned char* spaceDataY=new unsigned char[pels*lines];
unsigned char* spaceDataU=new unsigned char[pels*lines/4];
unsigned char* spaceDataV=new unsigned char[pels*lines/4];
double* timeData=new double[nNum];
double *tmpSpaceDataY=new double[pels*lines];
double *tmpSpaceDataU=new double[pels*lines/4];
double *tmpSpaceDataV=new double[pels*lines/4];
double *tmpTimeData=new double[nNum];
double minC,maxC; //小波变换以后的最小系数和最大系数
minC=10000;
maxC=0;
for(nFrameNum=0;nFrameNum<15000;)
{
for(k=0;k=pels*lines)
goto loo;
}
else if(dataNew!=dataOld)
{
i++;
goto loo;
}
}
loo: out<=pels*lines/4)
goto loou;
}
else if(dataNew!=dataOld)
{
i++;
goto loou;
}
}
loou: out<=pels*lines/4)
goto loov;
}
else
{
i++;
goto loov;
}
}
loov: out<>tmp[i];
for(nFrameNum=0;nFrameNum<305;)
{
//下面开始解码
for(k=0;k>num>>data;
for(j=0;j=pels*lines)
break;
}
}
//U
for(i=0;i>num>>data;
for(j=0;j=pels*lines/4)
break;
}
}
//V
for(i=0;i>num>>data;
for(j=0;j=pels*lines/4)
break;
}
}
//上面已经读入
for(i=0;iGetSafeHdc(),600,-660,pels,
lines,
0,0,0,lines,
m_pDataRGB,BmpInfo,DIB_PAL_COLORS);
str.Format("The number of frame is %d",nFrameNum+1);
pDC->TextOut(13000,-600,str);
nFrameNum++;
}
//上面已经读入块中
//下面、是播放
/* for(k=0;kGetSafeHdc(),600,-660,pels,
lines,
0,0,0,lines,
m_pDataRGB,BmpInfo,DIB_PAL_COLORS);
}*/
}
delete []blockY;
delete []blockU;
delete []blockV;
delete []tmp;
}
void CVideoView::OnPlayWt() //播放小波变换量化后的
{
bFlag=4;
Invalidate();
}
void CVideoView::iwt(CDC* pDC)//反量化+IDWT
{
m_pDataRGB=new unsigned char[pels*lines*3];
ColorSpaceConversions conv;
CString str;
CFile tmpfile;
tmpfile.Open("d:\\tmp.yuv",CFile::modeRead);
/////////
unsigned char *tmp=new unsigned char[6];
tmpfile.Read(tmp,6);
int nNum,SpaceLevel,TimeLevel,stepY,stepU,stepV;
SpaceLevel=tmp[0];
TimeLevel=tmp[1];
nNum=tmp[2];
stepY=tmp[3];
stepU=tmp[4];
stepV=tmp[5];
char*m_pData=new char[pels*lines*3/2];
unsigned char *Lum=new unsigned char[pels*lines];
unsigned char *Cb=new unsigned char[pels*lines/4];
unsigned char *Cr=new unsigned char[pels*lines/4];
double *spaceY=new double[pels*lines];
double *spaceU=new double[pels*lines/4];
double *spaceV=new double[pels*lines/4];
double *blockY=new double[nNum*pels*lines];
double *blockU=new double[nNum*pels*lines/4];
double *blockV=new double[nNum*pels*lines/4];
double *timeData=new double[nNum];
double *tmpTimeData=new double[nNum];
int i,j,k;
CDwt dwt;
int pixelnum=pels*lines;
for(nFrameNum=0;nFrameNum<1500;)
{
for(k=0;kGetSafeHdc(),600,-660,pels,
lines,
0,0,0,lines,
m_pDataRGB,BmpInfo,DIB_PAL_COLORS);
str.Format("The number of frame is %d",nFrameNum+1);
pDC->TextOut(13000,-600,str);
nFrameNum++;
}
}
endp:tmpfile.Close();
}
void CVideoView::OnMcIntEncode() //提升格式小波变换与运动补偿编码
{
// TODO: Add your command handler code here
BeginWaitCursor();
CFileDialog dlgsource(TRUE,"yuv","*.yuv"); //打开文件的对话狂
if(dlgsource.DoModal()==IDOK)
{
str_FileName=dlgsource.GetPathName();
}
else
{
bFlag=0;
return;
}
CWTDlg dlgwt;
dlgwt.DoModal();
int SpaceLevel,TimeLevel; //空间分解层数和时间分解层数
int nNum; //时间多少祯做一次小拨分解
int stepY,stepU,stepV; //Y, U, V的量化步长
SpaceLevel=dlgwt.m_nSpaceLevel;
TimeLevel=dlgwt.m_nTimeLevel;
nNum=dlgwt.m_nFrame;
stepY=dlgwt.m_nStepY;
stepU=dlgwt.m_nStepU;
stepV=dlgwt.m_nStepV;
pels=dlgwt.pels;
lines=dlgwt.lines;
AfxMessageBox("请选择编码以后的文件保存:");
CString str_Save; //编码后的文件保存路径
CFileDialog dlgsave(FALSE,"lwr","*.lwr");
if(dlgsave.DoModal()==IDOK)
{
str_Save=dlgsave.GetPathName();
bFlag=5; //改变程序运行状态
Invalidate();
}
else
{
bFlag=0; //恢复程序运行状态
return;
}
AfxMessageBox("编码时间可能较长,请耐心等待");
//下面是定义
int pixelnum=pels*lines;
double* baseBlockY=new double[pixelnum*nNum/2]; //原始块
double* baseBlockU=new double[pixelnum/4*nNum/2];
double* baseBlockV=new double[pixelnum/4*nNum/2];
//下面是预测块
double* preBlockY=new double[pixelnum*nNum/2];
double* preBlockU=new double[pixelnum/4*nNum/2];
double* preBlockV=new double[pixelnum/4*nNum/2];
unsigned char* spaceData=new unsigned char[pels*lines*3/2]; //总的每祯图象
unsigned char* spaceY=new unsigned char[pels*lines];
unsigned char* spaceU=new unsigned char[pels*lines/4];
unsigned char* spaceV=new unsigned char[pels*lines/4];
double* tmpSpaceY=new double[pels*lines]; //经过小波变换以后的
double* tmpSpaceU=new double[pels*lines/4];
double* tmpSpaceV=new double[pels*lines/4];
double* timeData=new double[nNum/2];
double* tmpTimeData=new double[nNum/2];
//上面已经定义完全了所需要的变量
int i,j,k; //循环变量
CFile fileSource;
if(!fileSource.Open(str_FileName,CFile::modeRead))
{
bFlag=0;
AfxMessageBox("读入文件发生错误!");
return;
}
//从下面开始小波变换
CIntWT intwt;
CDwt dwt;
int flag=0; //flag表示读了多少祯,是一个判断程序该何时结束的参数
for(nFrameNum=0;nFrameNum<1500;)
{
//下面先让原始祯成块,并对每祯进行整数小波变换
for(i=0;i