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

📄 视频编解码器view.cpp

📁 H.263编码与解码程序,能将YUV文件压缩成H.263格式的视频文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 视频编解码器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 + -