请各位同门指导。Vfw视频压缩句柄为空

qq_22312047 2014-10-22 12:12:44
// VideoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "VideoTapedTest.h"
#include "VideoDlg.h"
#pragma comment(lib,"vfw32.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CVideoDlg
IMPLEMENT_DYNCREATE(CVideoDlg, CFormView)
CVideoDlg::CVideoDlg()
: CFormView(CVideoDlg::IDD)
{
//{{AFX_DATA_INIT(CVideoDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_hMyVideo = NULL;
m_pImageTmp = NULL;
#if(VIDEOLOGFILE_SWITCH)
m_CaptureLog.Open(TEXT("VideoCapture.log"),CFile::modeCreate|CFile::modeWrite); //打开日志文件
m_CaptureLog.WriteString(TEXT("构造采集类\n"));
#endif
}

CVideoDlg::~CVideoDlg()
{
#if(VIDEOLOGFILE_SWITCH)
m_CaptureLog.Close(); //关闭日志文件
#endif
}

void CVideoDlg::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVideoDlg)
DDX_Control(pDX, IDC_VIDEOPANEL, m_PictureBox);
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CVideoDlg, CFormView)
//{{AFX_MSG_MAP(CVideoDlg)
ON_WM_SIZE()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CVideoDlg diagnostics

#ifdef _DEBUG
void CVideoDlg::AssertValid() const
{
CFormView::AssertValid();
}

void CVideoDlg::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CVideoDlg message handlers


void CVideoDlg::OnInitialUpdate()
{
CFormView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class
// 将VideoDlg的滚动条设置的足够小实现滚动条假隐藏
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
SetScrollSizes(MM_TEXT,CSize(0,20));
// *******************************************
CWnd *pWnd = GetDlgItem(IDC_VIDEOPANEL); // 得到预示窗口的指针
CRect rect;
pWnd->GetWindowRect(&rect); // 得到窗口大小
// 设置预示窗口
m_hMyVideo = capCreateCaptureWindow((LPSTR)TEXT("视频捕捉测试程序"),WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME,0,0,
rect.Width(),rect.Width(),pWnd->GetSafeHwnd(),0);
if(NULL == m_hMyVideo)
{
MessageBox("视频采集窗口创建失败!");
return ;
}
// 将捕获窗口与当前类关联,在回调函数时作为参数传递
capSetUserData(m_hMyVideo,this);
// 给捕获窗口设置一个回调函数,每采集一帧图像返回给APP
capSetCallbackOnVideoStream(m_hMyVideo,OnCaptureVideo);
// 预览之前,首先断开之前摄像头的链接
if(m_hMyVideo)
{
capDriverDisconnect(m_hMyVideo);
}

// 与驱动设备链接
if(capDriverConnect(m_hMyVideo,0))
{
// 设置视频录制参数
capCaptureGetSetup(m_hMyVideo,&m_captureParms,sizeof(CAPTUREPARMS));
m_captureParms.dwRequestMicroSecPerFrame = (1*(10^6))/30;
m_captureParms.fYield = TRUE;
m_captureParms.fAbortLeftMouse = FALSE;
m_captureParms.fAbortRightMouse = FALSE;
m_captureParms.fCaptureAudio = FALSE;
m_captureParms.wPercentDropForError = 20; // 允许遗失的百分比
m_captureParms.fMakeUserHitOKToCapture = TRUE; // 保存了初始化捕获的状态值
capCaptureSetSetup(m_hMyVideo,&m_captureParms,sizeof(CAPTUREPARMS));
// 获得驱动器的性能
capDriverGetCaps(m_hMyVideo,sizeof(caps),&caps);
// 判断设备是否支持叠加模式
// if(caps.fHasOverlay)
// {
// capOverlay(m_hMyVideo,TRUE);
// }
if(caps.fCaptureInitialized)
{
/*CAPSTATUS capsStatus;*/
// 获得捕获窗口的状态
capGetStatus(m_hMyVideo,&m_CapsStatus,sizeof(m_CapsStatus));
::SetWindowPos(m_hMyVideo,NULL,0,0,m_CapsStatus.uiImageWidth,m_CapsStatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
//设置预览时的比例
capPreviewScale(m_hMyVideo,TRUE);
// 设置预览时的帧速率
capPreviewRate(m_hMyVideo,30);
// 是否支持比例变化
//capPreviewScale(m_hVideo,FALSE);
// 打开预览
capPreview(m_hMyVideo,TRUE);
}
else
{
AfxMessageBox("视频捕捉初始化失败!");
m_hMyVideo = NULL;
return ;
}
}
else
{
AfxMessageBox("与摄像头连接失败!");
m_hMyVideo = NULL;
return ;
}
}
LRESULT CALLBACK OnCaptureVideo(HWND hWnd,LPVIDEOHDR lpVHdr)
{
CVideoDlg* VideoDlg = (CVideoDlg*)capGetUserData(hWnd);
if (VideoDlg->m_pImageTmp)
{
delete[] VideoDlg->m_pImageTmp->lpData;
delete VideoDlg->m_pImageTmp;
}
char* buffer = new char[lpVHdr->dwBytesUsed+1];
memset(buffer,0,lpVHdr->dwBytesUsed+1);
DWORD dwCKID;
DWORD dwCompFlags;
DWORD dwQuality = 100;

// 视频压缩
if(ICCompress(VideoDlg->m_Com.hic,0,&VideoDlg->m_OutInfo.bmiHeader,buffer,&VideoDlg->m_InInfo.bmiHeader,
(unsigned char*)lpVHdr->lpData,&dwCKID,&dwCompFlags,VideoDlg->m_Frame++,0,dwQuality,NULL,NULL) == ICERR_OK)
{
AVIStreamSetFormat(VideoDlg->ps,VideoDlg->m_Frame,&VideoDlg->m_OutInfo,sizeof(VideoDlg->m_OutInfo));
AVIStreamWrite(VideoDlg->ps,VideoDlg->m_Frame,1,(LPBYTE)buffer,VideoDlg->m_OutInfo.bmiHeader.biSizeImage,AVIIF_KEYFRAME,
NULL,NULL);
}
delete[] buffer;
return TRUE;
}
void CVideoDlg::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);
//
// TODO: Add your message handler code here
CRect rcClient,rcPicture;
GetClientRect(&rcClient);
// 移动picture控件到对话框的左上角
rcPicture.left = rcClient.left;
rcPicture.top = rcClient.top;
// picture的长宽设置
rcPicture.right = rcClient.Width();
rcPicture.bottom = rcClient.Height();
// 移动picture控件使框架大小与VideoDlg对话框大小保持一致
GetDlgItem(IDC_VIDEOPANEL)->MoveWindow(rcClient);
}
void CVideoDlg::InitCaptureVideo()
{
// 注册状态回调函数
capSetCallbackOnStatus(m_hMyVideo,StatusCallBackProc);
// 注册错误回调函数
capSetCallbackOnError(m_hMyVideo,ErrorCallBackProc);
// 注册单帧回调函数
capSetCallbackOnFrame(m_hMyVideo,FrameCallBackProc);
}
//开启摄像头预览
void CVideoDlg::CapturePreview()
{
BOOL bFlags = FALSE;
bFlags = capPreview(m_hMyVideo,TRUE);
}
LRESULT CVideoDlg::StatusCallBackProc(HWND hWnd, int nID, LPSTR lpStatusText,CVideoDlg* VideoDlg)
{
if(!VideoDlg->m_hMyVideo)
{
return FALSE;
}
// 获得捕获窗的状态
capGetStatus(VideoDlg->m_hMyVideo,&VideoDlg->m_CapsStatus,sizeof(CAPSTATUS));
//更新捕获窗的大小
::SetWindowPos(VideoDlg->m_hMyVideo,NULL,0,0,VideoDlg->m_CapsStatus.uiImageWidth,
VideoDlg->m_CapsStatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
return (LRESULT)TRUE;
}

LRESULT CVideoDlg::ErrorCallBackProc(HWND hWnd, int nErrorID, LPSTR lpErrorText,CVideoDlg* VideoDlg)
{
LPSTR ErrorBuffer = NULL;
if(!VideoDlg->m_hMyVideo)
{
return FALSE;
}
if (nErrorID == 0)
{
return TRUE;
}
wsprintf(ErrorBuffer,"ERROR:%d",nErrorID);
::MessageBox(hWnd,lpErrorText,ErrorBuffer,MB_OK|MB_ICONEXCLAMATION);
return (LRESULT)TRUE;
}

LRESULT CVideoDlg::FrameCallBackProc(HWND hWnd, LPVIDEOHDR lpVHdr,CVideoDlg* VideoDlg)
{
if(!VideoDlg->m_hMyVideo)
{
return FALSE;
}
return TRUE;
}

void CVideoDlg::InitCompress()
{
capGetVideoFormat(m_hMyVideo,&m_InInfo,sizeof(BITMAPINFO));
capGetVideoFormat(m_hMyVideo,&m_OutInfo,sizeof(BITMAPINFO));
memset(&m_Com,0,sizeof(COMPVARS));
m_Com.cbSize = sizeof(m_Com);
// 利用代码选择压缩器
// //m_Com.dwFlags = ICMF_COMPVARS_VALID;
// m_Com.fccHandler = 0;
// m_Com.fccType =0;
// m_Com.lFrame = 0;
// m_Com.lKey = 0; // 关键帧的速率
// m_Com.lKeyCount = 0;
// m_Com.lDataRate = 0;
// m_Com.lpbiOut = 0;
// m_Com.hic = 0;
// m_Com.cbState = 0;
ICCompressorChoose(NULL,ICMF_CHOOSE_ALLCOMPRESSORS,(LPVOID)&m_InInfo,NULL,&m_Com,"选择压缩类型");
ICCompressGetFormat(m_Com.hic,&m_InInfo.bmiHeader,&m_OutInfo.bmiHeader);
// 开始压缩
int ret = ICCompressBegin(m_Com.hic,(BITMAPINFO*)&m_InInfo,(BITMAPINFO*)&m_OutInfo);
if (ret != ICERR_OK)
{
MessageBox("压缩失败");
}
}
void CVideoDlg::Initilaize()
{
char* CaremaVideo = NULL;
CString strDate;
SYSTEMTIME systemTime = {0};
GetLocalTime(&systemTime);
strDate.Format("%d%02d%02d_%02d%02d%02d",systemTime.wYear,systemTime.wMonth,systemTime.wDay,systemTime.wHour,
systemTime.wMinute,systemTime.wSecond);
strDate = "D:/Documents/CaremaVideo@"+strDate+".avi";
CaremaVideo = strDate.GetBuffer(strDate.GetLength());
strDate.ReleaseBuffer();
// AVI文件的初始化
AVIFileInit();
// // 设置压缩参数
// InitCompress();
//打开文件
AVIFileOpen(&m_pFile,CaremaVideo,OF_WRITE|OF_CREATE,NULL);
memset(&strhdr,0,sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;
strhdr.dwScale = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 30;
strhdr.dwSuggestedBufferSize = m_InInfo.bmiHeader.biSizeImage;
SetRect(&strhdr.rcFrame,0,0,m_InInfo.bmiHeader.biWidth,m_InInfo.bmiHeader.biHeight);
ps = NULL;
// 文件流
AVIFileCreateStream(m_pFile,&ps,&strhdr);
// 设置压缩参数
InitCompress();
// 开始捕捉
capCaptureSequenceNoFile(m_hMyVideo);
}

void CVideoDlg::CaremaVideoEnd()
{
capSetCallbackOnVideoStream(m_hMyVideo,NULL);
if(m_Com.hic != NULL)
{
// 结束数据压缩
ICCompressEnd(m_Com.hic);
// 关闭压缩句柄
ICClose(m_Com.hic);
}
AVIStreamClose(ps);
if(m_pFile != NULL)
{
AVIFileRelease(m_pFile);
}
AVIFileExit();
capCaptureAbort(m_hMyVideo);
}

void CVideoDlg::HideWindow()
{
ShowWindow(SW_HIDE);
}
多次测试都是m_Com.hic为空,,并且捕获到视频为空!!求指点,
...全文
451 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
精分患者 2014-10-23
  • 打赏
  • 举报
回复
直接ffmpeg或是libvlc,会简单一点,而且可移植性比较高
xengine-qyt 2014-10-22
  • 打赏
  • 举报
回复
xvid 里面有vfw 的代码 直接拿来用 。。。不用自己写
effortday 2014-10-22
  • 打赏
  • 举报
回复
没有。一般不用VFW.都用WDM了。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧