VideoUSB.cpp
资源名称:视频会议系统.rar [点击查看]
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:8k
源码类别:
IP电话/视频会议
开发平台:
Visual C++
- // VideoUSB.cpp : implementation file
- //
- #include "stdafx.h"
- #include "VideoUSB.h"
- #include "SelectDriverDialog.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #pragma comment( lib , "vfw32.lib" )
- /////////////////////////////////////////////////////////////////////////////
- // CVideoUSB
- CVideoUSB::CVideoUSB( )
- {
- this->OnCapture = NULL;
- this->pContext = NULL;
- memset( &this->header , 0 , sizeof( BITMAPINFOHEADER ) );
- this->m_bPreview = false;
- this->m_bCapture = false;
- }
- CVideoUSB::~CVideoUSB( )
- {
- this->StopPreview( );
- this->StopCapture( );
- this->ReleaseDraw( );
- // if( this->hDraw )
- // ::DrawDibClose( this->hDraw );
- }
- BEGIN_MESSAGE_MAP(CVideoUSB, CWnd )
- //{{AFX_MSG_MAP(CVideoUSB)
- ON_WM_CLOSE()
- //}}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 ) )
- {
- CRect rc;
- CWnd::FromHandle( hWnd )->GetClientRect( &rc );
- this->SubclassWindow( ::capCreateCaptureWindow( "本地视频窗口" , WS_CHILD | WS_VISIBLE , 0 , 0 , rc.Width( ) , rc.Height( ) , 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 , "3iv2");
- //压缩失败,再次选择压缩器
- 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( ) );
- return true;
- }
- //获得视频头信息
- 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 )
- {
- this->m_bCapture = true;
- ::AfxBeginThread( CVideoUSB::OnSend , this );
- return true;
- }
- void CVideoUSB::StopCapture( void )
- {
- this->m_bCapture = false;
- while( ! this->buffer_list.empty( ) ) ::Sleep( 100 );
- }
- LRESULT CALLBACK CVideoUSB::OnVideo( HWND hWnd , VIDEOHDR * lpVHdr )
- {
- CVideoUSB * pThis = ( CVideoUSB * )capGetUserData( hWnd );
- int size = lpVHdr->dwBufferLength;
- char * buffer = ( char * )lpVHdr->lpData;
- //添加日期和时间
- CTime tm = CTime::GetCurrentTime( );
- //使用第一个32位数保存
- *( int * )( buffer + size - sizeof( int ) ) = tm.GetTime( );
- if( pThis->m_bPreview )
- {
- pThis->Draw( buffer , size );
- }
- if( pThis->OnCapture && pThis->m_bCapture && pThis->buffer_list.size( ) < 10 )
- {
- char * buf = new char[ sizeof( int ) + size ];
- if( buf )
- {
- *( int * )buf = size;
- memcpy( buf + sizeof( int ) , buffer , size );
- pThis->buffer_list.push_back( buf );
- }
- }
- 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 )
- {
- if( ! pThis->buffer_list.empty( ) )
- {
- buffer = ( char * ) * pThis->buffer_list.begin( );
- pThis->buffer_list.pop_front( );
- buf = buffer + sizeof( int );
- s = * ( int * )buffer;
- buf = ( char * )pThis->codec.Encode( buf , &s );
- if( buf && s )
- { //添加日期和时间
- CTime tm = CTime::GetCurrentTime( );
- //使用第一个32位数保存
- *( int * )( buf + s - sizeof( int ) )= tm.GetTime( );
- pThis->OnCapture( pThis->pContext , buf , s , false );
- }
- delete []buffer;
- }
- }
- while( ! pThis->buffer_list.empty( ) )
- {
- buffer = ( char * ) * pThis->buffer_list.begin( );
- pThis->buffer_list.pop_front( );
- delete []buffer;
- }
- return 0;
- }
- bool CVideoUSB::InitDraw( HWND hWnd , char * buffer , int size )
- {
- 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 );
- }
- this->ddraw.InitDirectDraw( this->GetSafeHwnd( ) , this->header.biWidth , this->header.biHeight , this->header.biBitCount );
- return true;
- }
- bool CVideoUSB::Draw( char * buffer , int size )
- {
- return this->ddraw.DrawDirectDraw( this->m_bPreview ? buffer : this->codec.Decode( buffer , size ) , true , this->codec.GetEncodeTime( ) );
- }
- void CVideoUSB::ReleaseDraw( void )
- {
- this->ddraw.ReleaseDirectDraw( );
- this->codec.ReleaseDecode( );
- if( ::IsWindow( this->GetSafeHwnd( ) ) && ::GetProp( this->GetSafeHwnd( ) , "isCreateWindow" ) )
- this->DestroyWindow( );
- this->m_hWnd = NULL;
- }