📄 h263displayer.cpp
字号:
#include "stdafx.h"
#include "afxmt.h"
#include "afxtempl.h"
#include "ExpandYUV411.h"
#include "color.h"
#include "sactable.h"
#include "dbitstream.h"
#include "CChannel.h"
#include "safelist.h"
#include "sad.h"
#include "Dh263class.h"
#include "commonfunc.h"
#include "h263displayer.h"
extern BOOL bExpand;
UINT H263DisplayerThread(LPVOID lpData)
{
((CH263Displayer*)lpData)->ThreadFunc();
return 0;
}
CH263Displayer::CH263Displayer(CSafeList<CPacket> * pInputList,int nMaxSourceFormat)
{
m_pList=pInputList;
m_nMaxSourceFormat=nMaxSourceFormat;
m_pFrame=new BYTE[FormatInfo[nMaxSourceFormat].TotalBytes*3*4+8];
m_pAlignFrame=(BYTE*)(((UINT)m_pFrame+7)/8*8);
m_nFrameCount=0;
m_bPreview=0;
m_pWnd=0;
m_pThread=0;
m_nIntervalTime=50;
m_nMaxIntervalTime=200;
m_nMinIntervalTime=20;
m_nLastTime=0;
ZeroMemory(&m_BitmapInfoHeader,sizeof(m_BitmapInfoHeader));
m_BitmapInfoHeader.biSize=sizeof(m_BitmapInfoHeader);
m_BitmapInfoHeader.biPlanes=1;
m_BitmapInfoHeader.biBitCount=24;
m_BitmapInfoHeader.biCompression=BI_RGB;
int nFrameSize=FormatInfo[nMaxSourceFormat].TotalBytes;
m_pExpand=new CExpandYUV411(nFrameSize*6);
m_expandYUV.Image=m_pExpand->m_pbyExpandedPicture;
m_expandYUV.Y=m_pExpand->m_pbyExpandedPicture;
m_expandYUV.U=m_pExpand->m_pbyExpandedPicture+nFrameSize*4;
m_expandYUV.V=m_pExpand->m_pbyExpandedPicture+nFrameSize*4+nFrameSize;
}
CH263Displayer::~CH263Displayer()
{
if(m_pThread)
End();
if(m_pFrame)
delete m_pFrame;
if(m_pExpand)
delete m_pExpand;
}
bool CH263Displayer::Begin(CWnd * pWnd)
{
m_pWnd=pWnd;
m_pThread=AfxBeginThread(H263DisplayerThread,this);
if(!m_pThread)return false;
m_nLastTime=GetTickCount();
return true;
}
void CH263Displayer::End()
{
if(!m_pThread)return;
m_RequestQuitEvent.SetEvent();
m_pThread=NULL;
CSingleLock sLock(&m_QuitEvent);
if(sLock.Lock(1000))
{
m_pThread=NULL;
return;
}
TerminateThread(m_pThread->m_hThread,0);
m_pThread=NULL;
}
bool CH263Displayer::DisplayFrame(CWnd* pWnd)
{
if(!m_nFrameCount)
{
if(!m_bPreview)
{
m_DisplayEvent.SetEvent();
return false;
}
Display(pWnd);
m_DisplayEvent.SetEvent();
return true;
}
if((PictureInfo.SourceFormat < 0) || (PictureInfo.SourceFormat >4))//Some error happen
{
//Skip one frame
return FALSE;
}
int nFrameSize=FormatInfo[PictureInfo.SourceFormat].TotalBytes;//PictureInfo.SourceFormat<5
int nWidth=FormatInfo[PictureInfo.SourceFormat].Pixels;
int nHeight=FormatInfo[PictureInfo.SourceFormat].Lines;
m_expandYUV.U=m_pExpand->m_pbyExpandedPicture+nFrameSize*4;
m_expandYUV.V=m_pExpand->m_pbyExpandedPicture+nFrameSize*4+nFrameSize;
if(m_nFrameCount==1)
{
if(!bExpand)
YUV_RGB(CurRecon,(RGBPixel*)m_pAlignFrame,nWidth,nHeight);//for expand
else
{
m_pExpand->ExpandYUV411(CurRecon.Image,nWidth,nHeight);
YUV_RGB(m_expandYUV,(RGBPixel*)m_pAlignFrame,nWidth*2,nHeight*2);
}
SwapPtr(CurRecon,PrevRecon);
}
else
{
if(!bExpand)
YUV_RGB(BRecon,(RGBPixel*)m_pAlignFrame,nWidth,nHeight);
else
{
m_pExpand->ExpandYUV411(BRecon.Image,nWidth,nHeight);
YUV_RGB(m_expandYUV,(RGBPixel*)m_pAlignFrame,nWidth*2,nHeight*2);
}
}
Display(pWnd);
m_bPreview=true;
m_nFrameCount--;
m_DisplayEvent.SetEvent();
return true;
}
void CH263Displayer::Display(CWnd* pWnd)
{
CDC* pDC;
CRect rc;
int nSourceFormat=PictureInfo.SourceFormat;//for expand
m_BitmapInfoHeader.biWidth=FormatInfo[nSourceFormat].Pixels;
m_BitmapInfoHeader.biHeight=FormatInfo[nSourceFormat].Lines;
m_BitmapInfoHeader.biSizeImage=FormatInfo[nSourceFormat].TotalBytes*3;
if(bExpand)
{
m_BitmapInfoHeader.biWidth=m_BitmapInfoHeader.biWidth*2;
m_BitmapInfoHeader.biHeight=m_BitmapInfoHeader.biHeight*2;
m_BitmapInfoHeader.biSizeImage=m_BitmapInfoHeader.biSizeImage*2;
}
pWnd->GetClientRect(rc);
pDC=pWnd->GetDC();
StretchDIBits(pDC->m_hDC,0,0,m_BitmapInfoHeader.biWidth,m_BitmapInfoHeader.biHeight, //for expand
0,0,m_BitmapInfoHeader.biWidth,
m_BitmapInfoHeader.biHeight,m_pAlignFrame,
(BITMAPINFO*)&m_BitmapInfoHeader,
DIB_RGB_COLORS,SRCCOPY);
pWnd->ReleaseDC(pDC);
}
void CH263Displayer::ThreadFunc()
{
//Wait Video Data put into buffer
CSyncObject* Objects[]={&m_RequestQuitEvent,&m_DisplayEvent};
CMultiLock mLock(Objects,2);
DWORD dwWaitResult;
int nDecodingFrameCount;
int nInterval;
int nSleepTime=0;
while(1)
{
dwWaitResult=mLock.Lock(m_nMinIntervalTime,FALSE);
//have request quit
if(dwWaitResult==WAIT_OBJECT_0)
break;//quit
//compute the PB frame Interval time
nDecodingFrameCount=m_pList->GetCount();
nInterval=m_nIntervalTime;
switch(nDecodingFrameCount)//缓冲中的帧数
{
case 0://缓冲中无帧,增加间隔时间
nInterval+=10;
m_nIntervalTime=min(nInterval,m_nMaxIntervalTime);
break;
case 1://缓冲中1、2、3、4帧,减少间隔时间
case 2:
nInterval-=5;
case 3:
nInterval-=10;
m_nIntervalTime=max(nInterval,m_nMinIntervalTime);
break;
case 4:
m_nIntervalTime=m_nMinIntervalTime;
break;
default:
m_nIntervalTime=m_nMinIntervalTime;
}
if(!m_nFrameCount&&nDecodingFrameCount)
{
for(int i=0;i<nDecodingFrameCount-5;i++)
{
DataLength=m_pList->GetHead().m_nLength;
CopyMemory(CompressData,m_pList->GetHead().m_pPacket,DataLength);
m_pList->RemoveHead();
DecodePicture();
SwapPtr(CurRecon,PrevRecon);
}
DataLength=m_pList->GetHead().m_nLength;
CopyMemory(CompressData,m_pList->GetHead().m_pPacket,DataLength);
m_pList->RemoveHead();
DecodePicture();
if(PictureInfo.PBMode)
m_nFrameCount=2;
else
m_nFrameCount=1;
}
nSleepTime=m_nIntervalTime-(GetTickCount()-m_nLastTime);
nSleepTime=max(m_nMinIntervalTime,nSleepTime);
Sleep(nSleepTime);
m_nLastTime=GetTickCount();
m_pWnd->PostMessage(WM_PAINT);
}
m_QuitEvent.SetEvent();
}
BOOL CH263Displayer::IsIntraFrame(BYTE * pFrame)
{
BYTE byTemp=pFrame[4];
byTemp&=2;
if(!byTemp)
return TRUE;
return FALSE;
}
void CH263Displayer::RemoveAFrame()
{
if(!m_nFrameCount)
{
if(!m_bPreview)
{
m_DisplayEvent.SetEvent();
return ;
}
// Display(pWnd);
m_DisplayEvent.SetEvent();
return ;
}
if(m_nFrameCount==1)
{
// YUV_RGB(CurRecon,(RGBPixel*)m_pAlignFrame,PictureInfo.SourceFormat);
SwapPtr(CurRecon,PrevRecon);
}
//else
//YUV_RGB(BRecon,(RGBPixel*)m_pAlignFrame,PictureInfo.SourceFormat);
//Display(pWnd);
m_bPreview=true;
m_nFrameCount--;
m_DisplayEvent.SetEvent();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -