VideoUSB.cpp
资源名称:视频会议系统.rar [点击查看]
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:9k
源码类别:
IP电话/视频会议
开发平台:
Visual C++
- // VideoUSB.cpp : implementation file
- //
- #include "../../stdafx.h"
- #include "VideoUSB.h"
- #include "SelectDriverDialog.h"
- #include "../../Conference.h""
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #pragma comment( lib , "vfw32.lib" )
- extern CConferenceApp theApp;
- /////////////////////////////////////////////////////////////////////////////
- // CVideoUSB
- CVideoUSB::CVideoUSB( )
- {
- this->OnCapture = NULL;
- this->pContext = NULL;
- memset( &this->header , 0 , sizeof( BITMAPINFOHEADER ) );
- this->m_bPreview = false;
- this->m_bCapture = false;
- this->send_buffer = NULL;
- this->m_bRecord = false;
- this->recordDir = "";
- }
- CVideoUSB::~CVideoUSB( )
- {
- this->StopPreview( );
- this->StopCapture( );
- this->ReleaseDraw( );
- }
- BEGIN_MESSAGE_MAP(CVideoUSB, CWnd )
- //{{AFX_MSG_MAP(CVideoUSB)
- ON_WM_CLOSE()
- ON_WM_TIMER()
- ON_WM_NCHITTEST()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CVideoUSB message handlers
- //关闭窗口
- void CVideoUSB::OnClose( )
- {
- this->StopCapture( );
- this->StopPreview( );
- capDriverDisconnect( this->GetSafeHwnd( ) );
- this->ReleaseDraw( );
- CWnd::OnClose( );
- }
- /////////////////////////////////////////////////////////////////////////////////
- bool CVideoUSB::Init( HWND hWnd , void ( * OnCapture )( void * pContext , char * buffer , int size , bool m_bHeader ) , void * pContext )
- { //选择驱动器
- int driver = CSelectDriverDialog::SelectDriver( );
- if( driver == -1 ) return false;
- //如果没有设置驱动,那么先设置驱动
- if( ::IsWindow( hWnd ) )
- this->SubclassWindow( ::capCreateCaptureWindow( "本地视频窗口" , WS_CHILD | WS_VISIBLE , 0 , 0 , 1 , 1 , hWnd , 0 ) );
- else
- this->SubclassWindow( ::capCreateCaptureWindow( "本地视频窗口" , WS_OVERLAPPEDWINDOW | WS_VISIBLE , 0 , 0 , 320 , 240 , NULL , 0 ) );
- //连接驱动
- capDriverConnect( this->GetSafeHwnd( ) , driver );
- //设置图像格式
- capGetVideoFormat( this->GetSafeHwnd( ) , &this->header , sizeof( BITMAPINFOHEADER ) );
- //图像的宽度
- this->header.biWidth = 320;
- //图像高度
- this->header.biHeight = 240;
- //图像深度
- this->header.biBitCount = 24;
- //如果设置失败,那么弹出对话框
- if( ! capSetVideoFormat( this->GetSafeHwnd( ) , &this->header , sizeof( BITMAPINFOHEADER ) ) )
- capDlgVideoFormat( this->GetSafeHwnd( ) );
- //取出视频格式
- capGetVideoFormat( this->GetSafeHwnd( ) , &this->header , sizeof( BITMAPINFOHEADER ) );
- this->ddraw.InitDirectDraw( this->GetSafeHwnd( ) , this->header.biWidth , this->header.biHeight , this->header.biBitCount );
- //压缩视频
- BITMAPINFOHEADER * h = this->codec.InitEncode( this->header.biWidth , this->header.biHeight , this->header.biBitCount ,"MP42" );
- //压缩失败,再次选择压缩器
- if( ! h && ! ( h = this->codec.InitEncode( this->header.biWidth , this->header.biHeight , this->header.biBitCount ) ) )
- return false;
- //保存压缩后的图像
- memcpy( &this->header , h , sizeof( BITMAPINFOHEADER ) );
- //用户自定义信息
- capSetUserData( this->GetSafeHwnd( ) , ( long )this );
- this->OnCapture = OnCapture;
- this->pContext = pContext;
- //开始捕捉图像
- CAPTUREPARMS setup;
- capCaptureGetSetup( this->GetSafeHwnd( ) , &setup , sizeof( setup ) );
- setup.dwRequestMicroSecPerFrame = 1000000 / 20 ; //帧速率
- setup.fYield = true;
- setup.fCaptureAudio = false;
- setup.vKeyAbort = 0;
- setup.fAbortLeftMouse = false;
- setup.fAbortRightMouse = false;
- setup.fLimitEnabled = false;
- setup.fMCIControl = false;
- //设定回调函数
- capSetCallbackOnVideoStream( this->GetSafeHwnd( ) , CVideoUSB::OnVideo );
- //安装捕捉驱动
- capCaptureSetSetup( this->GetSafeHwnd( ) , &setup , sizeof( setup ) );
- //开始捕捉
- capCaptureSequenceNoFile( this->GetSafeHwnd( ) );
- //录像文件夹
- this->recordDir = theApp.appIni.Left( theApp.appIni.ReverseFind( '\' ) + 1 ) + "录像文件夹";
- this->m_bRecord = ( bool )::GetPrivateProfileInt( "用户信息" , "运行时录像" , 0 , theApp.appIni );
- if( this->m_bRecord )
- { //创建录像文件夹
- ::CreateDirectory( this->recordDir , NULL );
- CTime tm = CTime::GetCurrentTime( );
- CString aviName;
- aviName.Format( "%s\%s.avi" , this->recordDir, tm.Format( "%Y-%m-%d %H:%M:%S" ) );
- //录像
- this->avi.OpenAVI( aviName , CAVI::AVI_WRITE );
- this->avi.SetAVIInfo( this->header , 15 );
- //启动定时器,要求每隔一个小时保存一个文件
- this->SetTimer( 1 , 3600000 , NULL );
- }
- return true;
- }
- //定时录像
- void CVideoUSB::OnTimer(UINT nIDEvent)
- {
- CWnd ::OnTimer( nIDEvent );
- if( nIDEvent == 1 )
- {
- this->avi.CloseAVI( );
- //创建录像文件夹
- ::CreateDirectory( this->recordDir , NULL );
- CTime tm = CTime::GetCurrentTime( );
- CString aviName;
- aviName.Format( "%s\%s.avi" , this->recordDir, tm.Format( "%Y-%m-%d %H:%M:%S" ) );
- this->avi.OpenAVI( aviName , CAVI::AVI_WRITE );
- this->avi.SetAVIInfo( this->header , 15 );
- }
- }
- //获得视频头信息
- bool CVideoUSB::GetHeader( char ** header , int * size )
- {
- * header = NULL;
- * size = 0;
- if( this->GetSafeHwnd( ) )
- {
- * header = ( char * )&this->header;
- * size = sizeof( this->header );
- return true;
- }
- return false;
- }
- //开始预览
- bool CVideoUSB::StartPreview( int fps )
- {
- this->m_bPreview = true;
- return true;
- }
- //停止预览
- void CVideoUSB::StopPreview( void )
- {
- if( this->m_bPreview )
- this->m_bPreview = false;
- }
- //开始捕捉
- bool CVideoUSB::StartCapture( void )
- {
- if( ! this->m_bCapture && this->GetSafeHwnd( ) )
- {
- this->m_bCapture = true;
- ::AfxBeginThread( CVideoUSB::OnSend , this );
- }
- return true;
- }
- //停止捕捉
- void CVideoUSB::StopCapture( void )
- {
- if( this->m_bCapture )
- {
- this->m_bCapture = false;
- while( this->send_buffer ) ::Sleep( 100 );
- }
- }
- //视频信号回调函数
- LRESULT CALLBACK CVideoUSB::OnVideo( HWND hWnd , VIDEOHDR * lpVHdr )
- {
- CVideoUSB * pThis = ( CVideoUSB * )capGetUserData( hWnd );
- int size = lpVHdr->dwBufferLength;
- char * buffer = ( char * )lpVHdr->lpData;
- //本地显示
- if( pThis->m_bPreview )
- pThis->Draw( buffer , size );
- //网络发送
- if( pThis->OnCapture && pThis->m_bCapture && ! pThis->send_buffer )
- {
- char * buf = new char[ sizeof( int ) + size ];
- if( buf )
- {
- *( int * )buf = size;
- memcpy( buf + sizeof( int ) , buffer , size );
- pThis->send_buffer = buf;
- }
- }//本地录像
- pThis->avi.AddFrame( buffer , size );
- return ( LRESULT ) true;
- }
- //发送视频数据
- UINT CVideoUSB::OnSend( void * wParam )
- {
- CVideoUSB * pThis = ( CVideoUSB * )wParam;
- char * buffer = NULL;
- char * buf;
- int s;
- while( pThis->m_bCapture && pThis->OnCapture )
- {
- try
- {
- if( pThis->send_buffer )
- {
- buffer = pThis->send_buffer;
- s = *( int * )buffer;
- buf = ( char * )pThis->codec.Encode( buffer + sizeof( int ) , &s );
- if( buf && s )
- pThis->OnCapture( pThis->pContext , buf , s , false );
- pThis->send_buffer = NULL;
- delete [ ]buffer;
- }
- else
- ::Sleep( 40 );
- }
- catch( ... )
- {
- }
- }
- try
- {
- delete pThis->send_buffer;
- }
- catch( ... )
- {
- }
- pThis->send_buffer = NULL;
- return 0;
- }
- bool CVideoUSB::InitDraw( HWND hWnd , char * buffer , int size )
- {
- if( ! ::IsWindow( hWnd ) )
- return false;
- memcpy( &this->header , buffer , sizeof( BITMAPINFOHEADER ) );
- //初始化解压器
- if( ! this->codec.InitDecode( &this->header ) )
- return false;
- //如果不是窗口
- if( ! ::IsWindow( hWnd ) )
- { //界面处理
- const char * className = ::AfxRegisterWndClass( 0 , ::AfxGetApp( )->LoadStandardCursor( IDC_ARROW ) , ::CreateSolidBrush( RGB( 10 , 10 , 10 ) ) , NULL );
- this->CreateEx( NULL , className , "显示视频窗口" , WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0 , 0 , 300 , 200 , NULL , NULL );
- ::SetProp( this->GetSafeHwnd( ) , "isCreateWindow" , (HANDLE)true );
- }
- else
- {
- this->m_hWnd = hWnd;
- ::SetProp( this->GetSafeHwnd( ) , "isCreateWindow" , (HANDLE)false );
- }
- return this->ddraw.InitDirectDraw( this->GetSafeHwnd( ) , this->header.biWidth , this->header.biHeight , this->header.biBitCount );
- }
- bool CVideoUSB::Draw( char * buffer , int size )
- {
- return this->ddraw.DrawDirectDraw( this->m_bPreview ? buffer : this->codec.Decode( buffer , size ) , true , 0 );
- }
- void CVideoUSB::ReleaseDraw( void )
- {
- this->ddraw.ReleaseDirectDraw( );
- this->codec.ReleaseDecode( );
- if( ::IsWindow( this->GetSafeHwnd( ) ) && ::GetProp( this->GetSafeHwnd( ) , "isCreateWindow" ) )
- this->DestroyWindow( );
- else
- {
- if( ::IsWindow( this->GetSafeHwnd( ) ) )
- this->Invalidate( );
- this->m_hWnd = NULL;
- }
- }
- UINT CVideoUSB::OnNcHitTest(CPoint point)
- {
- UINT hitTest = CWnd ::OnNcHitTest( point );
- return ( hitTest == HTCLIENT || hitTest == HTCAPTION ) ? HTTRANSPARENT : hitTest;
- }