这是刚到单位的第一个月,他们项目组让我看一个类,我也看不大懂,求大神讲解,最好能派生出一个 显示图像的类出来:
class CVideoProcessBase
{
public:
CVideoProcessBase(void);
virtual ~CVideoProcessBase(void); // 新增一帧纯数据用于处理
virtual BOOL AddNewFrame(long length,PBYTE pData); // 新增一个帧数据用于处理
virtual BOOL AddNewFrame(IMediaSample* pSample);

// 启动视频处理线程
virtual BOOL StartThread(void); // 停止视频处理线程
virtual BOOL StopThread(BOOL bWaitForExit = TRUE); // 设定处理帧的像素宽高
virtual BOOL SetFrameSize(int width, int height); // 得到处理帧的像素宽高
virtual BOOL GetFrameSize(int *pWidth, int *pHeight); // 设定处理使用的帧率
virtual BOOL SetFPS(double fps); // 设定是否执行处理,如果bEnable为FALSE,则忽略所有输入视频帧
virtual BOOL SetEnable(bool bEnable);protected:
// 新Sample到达的时候,由后台线程自动调用
virtual BOOL OnNewFrame(IMediaSample* pSample); // 视频处理线程
static DWORD WINAPI threadProcess(LPVOID lpParam);protected:
HANDLE m_hThread; // 线程句柄
DWORD m_dwThreadID; // 线程ID
HANDLE m_hEventNewFrame; // 来新视频数据的信号
HANDLE m_hEventExitThread; // 通知线程退出的信号 // 当前需要处理的帧数据Sample指针
IMediaSample* m_pCurSample; int m_nFrameWidth; // 视频宽
int m_nFrameHeight; // 视频高
double m_fps; // 桢率
LONGLONG m_lastFrameTime; // 最后一帧到达的时间(用于帧率控制计算) // 临界区,防止多线程同时访问数据
CCritSec m_CritSec; // 是否执行处理
BOOL m_bEnable; //内存分配器
IMemAllocator *m_pMemAlloc;
};下面是cpp:#include "StdAfx.h"
#include "VideoProcessBase.h"
#include <Mmsystem.h>
#include <stdio.h>CVideoProcessBase::CVideoProcessBase(void)
{
m_hThread = NULL;
m_dwThreadID = 0;
m_hEventNewFrame = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventExitThread = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_pCurSample = NULL; m_nFrameWidth = 0;
m_nFrameHeight = 0; m_fps = 15.00;
m_lastFrameTime = 0; m_bEnable = TRUE; m_pMemAlloc = NULL;
CreateMemoryAllocator(&m_pMemAlloc);
ALLOCATOR_PROPERTIES arRequest;
ALLOCATOR_PROPERTIES arActual;
arRequest.cBuffers = 10;
arRequest.cbAlign = 1;
arRequest.cbBuffer = 0x2000*200;
arRequest.cbPrefix = 0;
m_pMemAlloc->SetProperties(&arRequest, &arActual);
m_pMemAlloc->Commit();
}CVideoProcessBase::~CVideoProcessBase(void)
{
StopThread();
CloseHandle(m_hEventNewFrame);
CloseHandle(m_hEventExitThread); // 释放Sample
if ( m_pCurSample )
{
LONG nRet = m_pCurSample->Release();
m_pCurSample = NULL;
}}// 设定处理帧的像素宽高
BOOL CVideoProcessBase::SetFrameSize(int width, int height)
{
CAutoLock   lockit(&m_CritSec);
m_nFrameWidth = width;
m_nFrameHeight = height; return TRUE;
}// 得到处理帧的像素宽高
BOOL CVideoProcessBase::GetFrameSize(int *pWidth, int *pHeight)
{
CAutoLock   lockit(&m_CritSec);
*pWidth = m_nFrameWidth;
*pHeight = m_nFrameHeight; return TRUE;
}// 设定处理使用的帧率
BOOL CVideoProcessBase::SetFPS(double fps)
{
CAutoLock   lockit(&m_CritSec);
m_fps = fps;
return TRUE;
}// 新增一个帧纯数据 并且把它构造成一个Sample
BOOL CVideoProcessBase::AddNewFrame(long length,PBYTE pData)
{
CAutoLock   lockit(&m_CritSec); // 帧率控制
if ( 0 == m_fps )
return TRUE; LONGLONG startTime, endTime;
endTime = startTime = timeGetTime();// GetTickCount(); if ( 0 == m_lastFrameTime )
{
m_lastFrameTime = startTime;
}
else
{
const LONGLONG minInterval = (1/m_fps)*1000;
if ( (startTime - m_lastFrameTime) < minInterval )
{
return TRUE;
}
}// ASSERT(pSample); // 如果正在处理(还没处理完),则丢弃这个数据,不处理
if ( ::WaitForSingleObject(m_hEventNewFrame, 0 ) == WAIT_OBJECT_0 )
return FALSE; m_lastFrameTime = startTime; if ( m_pCurSample )
{
m_pCurSample->Release();
m_pCurSample = NULL;
} IMediaSample *pSample = NULL;
PBYTE pByte = NULL;
m_pMemAlloc->GetBuffer(&pSample, NULL, NULL, 0); pSample->GetPointer(&pByte); //设置数据长度
pSample->SetActualDataLength(length); memcpy(pByte,pData,length); m_pCurSample = pSample;
m_pCurSample->AddRef();
::SetEvent(m_hEventNewFrame);
pSample->Release();
}// 新增一个帧数据用于处理
BOOL CVideoProcessBase::AddNewFrame(IMediaSample* pSample)
{
// 如果已经等待退出了,则不处理数据
if ( ::WaitForSingleObject(m_hEventExitThread, 0 ) == WAIT_OBJECT_0 )
return FALSE; CAutoLock   lockit(&m_CritSec); if ( FALSE == m_bEnable )
return FALSE; // 线程没启动的情况下,AddNewFrame无效
if ( NULL == m_hThread )
return FALSE;
// ----------------- 帧率控制 -----------------
// 0 帧率 就是不处理的意思
if ( 0 == m_fps )
return TRUE; LONGLONG startTime, endTime;
endTime = startTime = timeGetTime();// GetTickCount(); if ( 0 == m_lastFrameTime )
{
m_lastFrameTime = startTime;
}
else
{
const LONGLONG minInterval = (1/m_fps)*1000;
// 如果时间间隔不够,则不处理
if ( (startTime - m_lastFrameTime) < minInterval )
{
return TRUE;
}
} ASSERT(pSample); // 如果正在处理(还没处理完),则丢弃这个数据,不处理
if ( ::WaitForSingleObject(m_hEventNewFrame, 0 ) == WAIT_OBJECT_0 )
return FALSE; m_lastFrameTime = startTime; // 释放上次的Sample
if ( m_pCurSample )
{
LONG nRet = m_pCurSample->Release();
m_pCurSample = NULL;
}

// 使用新的Sample
m_pCurSample = pSample;
m_pCurSample->AddRef();
::SetEvent(m_hEventNewFrame); return TRUE;
}// 启动视频处理线程
BOOL CVideoProcessBase::StartThread(void)
{
CAutoLock   lockit(&m_CritSec);

if ( NULL != m_hThread )
return FALSE; ::ResetEvent(m_hEventExitThread); //DWORD dwThreadID;
m_hThread = ::CreateThread ( NULL, 0, threadProcess, this, 0, &m_dwThreadID); //DWORD dwError = GetLastError();
if ( NULL == m_hThread )
{
return FALSE;
} return TRUE;
}// 停止视频处理线程
BOOL CVideoProcessBase::StopThread(BOOL bWaitForExit /*= TRUE*/)
{
// CAutoLock   lockit(&m_CritSec); if ( NULL == m_hThread )
return FALSE; ::SetEvent(m_hEventExitThread);
if ( bWaitForExit )
{
if ( WAIT_OBJECT_0 != ::WaitForSingleObject(m_hThread, INFINITE) )
{
ASSERT(FALSE);
::TerminateThread ( m_hThread , 0 );
}
} ::CloseHandle ( m_hThread ); m_hThread = NULL;
m_dwThreadID = 0; // 复位帧数据到达信号
::ResetEvent(m_hEventNewFrame); // 释放Sample
if ( m_pCurSample )
{
LONG nRet = m_pCurSample->Release();
m_pCurSample = NULL;
} return TRUE;
}// 新Sample到达的时候,由后台线程自动调用
BOOL CVideoProcessBase::OnNewFrame(IMediaSample* pSample)
{
return FALSE;
}// 视频处理线程
DWORD WINAPI CVideoProcessBase::threadProcess(LPVOID lpParam)
{ CVideoProcessBase *pThis = reinterpret_cast<CVideoProcessBase*>(lpParam); HANDLE waitEvents[2] = { pThis->m_hEventExitThread, pThis->m_hEventNewFrame };
while ( true )
{
int   nEventIndex = 0;
DWORD dwEvent = ::WaitForMultipleObjects(2, waitEvents, FALSE, INFINITE);
switch(dwEvent)
        {
        case WAIT_TIMEOUT:
            break;
        case WAIT_FAILED:
            return 1;
        default:
nEventIndex = dwEvent - WAIT_OBJECT_0;
// 退出信号
if ( 0 == nEventIndex )
{
#ifdef _DEBUG
char szMsg[200];
sprintf(szMsg, "CVideoProcessBase::threadProcess Exit,id=%d,this=%08x\n", pThis->m_dwThreadID, pThis);
OutputDebugStr(szMsg);
#endif
return 0;
}
// 新视频数据
else if ( 1 == nEventIndex )
{
ASSERT(pThis->m_pCurSample);
pThis->OnNewFrame(pThis->m_pCurSample);
ASSERT(pThis->m_pCurSample);
LONG nRet = pThis->m_pCurSample->Release();
pThis->m_pCurSample = NULL;
::ResetEvent(pThis->m_hEventNewFrame);
}
}
} // 这里永远执行不到
ASSERT(0);
return 0;
}// 设定是否执行处理,如果bEnable为FALSE,则忽略所有输入视频帧
BOOL CVideoProcessBase::SetEnable(bool bEnable)
{
CAutoLock   lockit(&m_CritSec); m_bEnable = bEnable;
return TRUE;
}

解决方案 »

  1.   

    代码是做什么用的?有完整的代码么?
    发我一份,研究下,毕业设计打算做视频交互式分割的,谢谢啊!
    可以的话发我邮箱:[email protected]
      

  2.   

    看样子用的是DSHOW. 注释很详细了.AddNewFrame(long length,PBYTE pData)
    输入数据封装出一个DSHOW SAMPLE,然后通知threadProcess
    线程处理.AddNewFrame(IMediaSample* pSample)
    直接一个DSHOW SAMPLE,然后然后通知threadProcess
    线程处理.