📄 视频编解码器view.cpp
字号:
// 视频编解码器View.cpp : implementation of the CMyView class
//
#include "stdafx.h"
#include <math.h>
#include "视频编解码器.h"
#include "视频编解码器Doc.h"
#include "视频编解码器View.h"
#include "OpenFiles.h"
#include "Global.h"
#include "ProgressBar.h"
#include "Display.h"
#include "PropertyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int pels,lines,mv_outside_frame,long_vectors,cpels;
CFile streamfile,psnrfile;
static void SeekPsnr(PictImage *curr,PictImage *recon,int width,int height,double psnr[3]);
#define OFFLINE_RATE_CONTROL//jwp
/////////////////////////////////////////////////////////////////////////////
// CMyView
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
//{{AFX_MSG_MAP(CMyView)
ON_COMMAND(ID_Encode, OnEncode)
ON_COMMAND(ID_Decode, OnDecode)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_COMMAND(ID_Encode, OnEncode)
ON_COMMAND(ID_Decode, OnDecode)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CMyView construction/destruction
CMyView::CMyView()
{
m_font.CreateFont(20,0,0,0,FW_THIN,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH|FF_MODERN,"宋体");
bFlag=0;
}
CMyView::~CMyView()
{
m_font.DeleteObject();
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMyView drawing
void CMyView::OnDraw(CDC* pDC)
{
CBitmap bitmap;
CDC dcMemory;
bitmap.LoadBitmap(IDB_car);
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SelectObject(&bitmap);
pDC->SetTextColor(0x64e896);
if(bFlag==1)//编码
{
CFont *pOldFont;
pOldFont=pDC->SelectObject(&m_font);
pDC->SetBkMode(TRANSPARENT);
pDC->StretchBlt(0,0,1024*3/4,768*3/4,&dcMemory,0,0,1024,768,SRCCOPY);
CString kk;
kk.Format("正在编码!共%d帧",MaxFrame);
pDC->TextOut(60,60,kk);
kk.Format("每%d帧进行一次帧内编码,进度情况请看状态栏!",Pbetween);
pDC->TextOut(60,100,kk);
}
else if(bFlag==2)//解码
{
CBrush Brush(RGB(100,200,150));//190,190,190
CBrush* oldBrush=pDC->SelectObject(&Brush);
CPen pen(0,2,RGB(100,200,150));
CPen *oldPen=pDC->SelectObject(&pen);
pDC->Rectangle(40,40,440,370);//画矩形
pDC->MoveTo(40,370); // (wide,height)
pDC->LineTo(620,370);
pDC->MoveTo(620,40);
pDC->LineTo(620,370);
pDC->MoveTo(40,40);
pDC->LineTo(620,40);
pDC->SelectObject(oldPen);
pDC->SelectObject(oldBrush);
//显示解码图象
CDisplay m_display;
m_display.play_movie(pDC,DecfileName);
conclusion=m_display.conclusion;
//输出解码结果
pDC->SetTextColor(RGB(200,100,150));
int dd=conclusion.Find(",",0);
CString kk=conclusion.Right(conclusion.GetLength()-dd-1);
int zz=kk.Find(",",0);
pDC->TextOut(470,180,conclusion.Left(dd));
pDC->TextOut(470,200,kk.Left(zz));
pDC->TextOut(500,220,kk.Right(kk.GetLength()-zz-1));
}
}
/////////////////////////////////////////////////////////////////////////////
// CMyView printing
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers
void CMyView::OnEncode()
{
CPropertyDlg properties("编码属性设置",this,0);
int ff;
CString dd;
if(properties.DoModal()==IDOK)
{
m_szFilePathName=properties.encodeDlg.m_InitDir;
m_szFileName=m_szFilePathName;
m_Type=properties.encodeDlg.typeindex;
MaxFrame=properties.encodeDlg.m_MaxFrame;
QP=properties.encodeDlg.m_QP;
QPI=properties.encodeDlg.m_QPI;
ifPsnr=properties.encodeDlg.m_ifPsnr;
Pbetween=properties.encodeDlg.m_Pbetween+1;
ratecontrol=properties.m_page1.m_ifratecontrol;
targetrate=properties.m_page1.m_bitrate;
switch(properties.m_page1.m_framerate)
{
case 1:
ref_frame_rate=30.0;break;
case 0:
ref_frame_rate=25.0;break;
case 2:
ref_frame_rate=10.0;break;
default:
ref_frame_rate=25.0;
}
int kk=targetrate;
ff=properties.m_page1.m_ifratecontrol;
dd.Format("采用率控制,码率是%d,帧率是%f。",kk,ref_frame_rate);
if(ff)
MessageBox(dd);
if(m_Type==2)
CodeYUV();
else
CodeBmps();
}
else
return;
}
void CMyView::CodeYUV()
{
//率控制
#ifndef OFFLINE_RATE_CONTROL
float DelayBetweenFramesInSeconds;
int CommBacklog;
#else
PictImage *stored_image = NULL;
int start_rate_control;
#endif
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//初始化
CProgressBar bar(_T("Encode Progress"), 50, MaxFrame);
m_pImageData=new unsigned char[352*288*3/2];
CFile file;
if((file.Open(m_szFilePathName,CFile::modeRead|CFile::shareDenyNone))==NULL)
{
AfxMessageBox("Can not open the yuv file!");
return;
}
PictImage *prev_image = NULL;
PictImage *curr_image = NULL;
PictImage *curr_recon = NULL;
PictImage *prev_recon = NULL;
int frame_no,first_frameskip=0;
int start=1;//从第1帧到第MaxFrame帧
int orig_frameskip=1;//输入图像原始偏移
int frameskip=1;//非发送帧
long_vectors =0;//帧间编码的参数
mv_outside_frame=0;
Pict *pic = (Pict *)malloc(sizeof(Pict));
Bits *bits = (Bits *)malloc(sizeof(Bits));
//率控制
Bits *total_bits = (Bits *)malloc(sizeof(Bits));
Bits *intra_bits = (Bits *)malloc(sizeof(Bits));
pic->BQUANT = DEF_BQUANT;
pic->seek_dist = DEF_SEEK_DIST;
pic->use_gobsync = DEF_INSERT_SYNC;//=0
pic->PB = 0;
pic->TR = 0;
pic->QP_mean = (float)0.0;
pic->unrestricted_mv_mode = 0;
pic->picture_coding_type =0; // PCT_INTRA;
m_orgHeight=288;
m_orgWidth=352;
pic->source_format = SF_CIF;
switch (pic->source_format) {
case (SF_SQCIF):
fprintf(stdout, "Encoding format: SQCIF (128x96)\n");
pels = 128;
lines = 96;
break;
case (SF_QCIF):
fprintf(stdout, "Encoding format: QCIF (176x144)\n");
pels = 176;
lines = 144;
break;
case (SF_CIF):
fprintf(stdout, "Encoding format: CIF (352x288)\n");
pels = 352;
lines = 288;
break;
case (SF_4CIF):
fprintf(stdout, "Encoding format: 4CIF (704x576)\n");
pels = 704;
lines = 576;
break;
case (SF_16CIF):
fprintf(stdout, "Encoding format: 16CIF (1408x1152)\n");
pels = 1408;
lines = 1152;
break;
default:
fprintf(stderr,"Illegal coding format\n");
exit(-1);
}
cpels = pels/2;
curr_recon = InitImage(pels*lines);
//率控制
#ifndef OFFLINE_RATE_CONTROL
// rate control variables
pic->bit_rate = targetrate;
pic->src_frame_rate = (int)(ref_frame_rate / orig_frameskip);
DelayBetweenFramesInSeconds = (float) 1.0/(float)pic->src_frame_rate;
InitializeRateControl();
#endif
#ifdef OFFLINE_RATE_CONTROL
start_rate_control = 0;//DEF_START_RATE_CONTROL;
#else
pic->target_frame_rate = (float)DEF_TARGET_FRAME_RATE;
#endif
//建立输出文件
CString outfilename=m_szFileName.Left(m_szFileName.GetLength()-4);
CFileDialog dlg(FALSE,".263",outfilename,OFN_OVERWRITEPROMPT,"263 Files(*.263)|*.263|",NULL);
if (dlg.DoModal()==IDOK)
{
bFlag=1;
pDoc->UpdateAllViews(NULL);
CString tempname;
tempname=dlg.GetPathName();
outfilename=tempname.Left(tempname.GetLength()-4);
if((streamfile.Open(tempname,CFile::modeWrite|CFile::modeCreate))==FALSE)
AfxMessageBox("Can't create file!");
streamfile.SeekToBegin();
initbits ();
CTime StartTime=CTime::GetCurrentTime();
CTimeSpan ElapsedTime;
file.Read(m_pImageData,sizeof(BYTE)*352*288*3/2);
pic->QUANT=QPI;
curr_image = FillImage(m_pImageData);
curr_recon = CodeOneIntra(curr_image, QPI, bits, pic);
bits->header += alignbits (); // pictures shall be byte aligned
//率控制
AddBitsPicture(bits);
memcpy(intra_bits,bits,sizeof(Bits));
ZeroBits(total_bits);
//* number of seconds to encode *
int chosen_frameskip=1;//jwp
//* compute first frameskip *
#ifdef OFFLINE_RATE_CONTROL
float seconds = (MaxFrame - start + chosen_frameskip) * orig_frameskip/ ref_frame_rate;
first_frameskip = chosen_frameskip;
frameskip = chosen_frameskip;
#else
CommBacklog = intra_bits->total -(int)(DelayBetweenFramesInSeconds * pic->bit_rate);
if (pic->bit_rate == 0) {
frameskip = chosen_frameskip;
}
else { //* rate control is used *
frameskip = 1;
while ( (int)(DelayBetweenFramesInSeconds*pic->bit_rate) <= CommBacklog) {
CommBacklog -= (int) ( DelayBetweenFramesInSeconds * pic->bit_rate );
frameskip += 1;
}
}
first_frameskip = frameskip;
#endif
CString kk,m_Spsnr;
if(ifPsnr)
{
if(psnrfile.Open(outfilename+".doc",CFile::modeWrite|CFile::modeCreate)==FALSE)
MessageBox("Cannot create the output psnr file!", "Error",MB_ICONERROR | MB_OK);
SeekPsnr(curr_image,curr_recon,352,288,psnrs);
frame_no=1;
kk.Format("第%d帧的lum峰值信噪比为%6.4fdB\n",frame_no,psnrs[0]);
m_Spsnr=kk;
kk.Format("第%d帧的Cb峰值信噪比为%6.4fdB\n",frame_no,psnrs[1]);
m_Spsnr+=kk;
kk.Format("第%d帧的Cr峰值信噪比为%6.4fdB\n",frame_no,psnrs[2]);
m_Spsnr+=kk;
MessageBox(m_Spsnr);
psnrfile.SeekToBegin();
psnrfile.Write(m_Spsnr,m_Spsnr.GetLength());
}
//第二帧
pic->QUANT=QP;
for(frame_no=start+first_frameskip;frame_no<=MaxFrame;frame_no+=frameskip)
{
file.Seek((frame_no-1)*352*288*3/2,SEEK_SET);
file.Read(m_pImageData,sizeof(BYTE)*352*288*3/2);
if(m_pImageData==NULL)
return;
pic->picture_coding_type =1; // PCT_INTER;
if(!ratecontrol)
pic->QUANT=QP;
prev_image=curr_image;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -