AVI.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:5k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // AVI.cpp: implementation of the CAVI class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "....stdafx.h"
  5. #include "AVI.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CAVI::CAVI( )
  15. {
  16. this->m_avi_file = NULL;
  17. this->m_avi_stream = NULL;
  18. this->read_frame = 0;
  19. this->avi_buffer = NULL;
  20. this->m_bMode = 0;
  21. this->write_frame = 0;
  22. this->time_interval = 0;
  23. this->time_now = 0;
  24. memset( &m_avi_stream_info , 0 , sizeof( AVISTREAMINFO ) );
  25. memset( &m_avi_bmp_info , 0 , sizeof( BITMAPINFOHEADER ) );
  26. }
  27. CAVI::~CAVI( )
  28. {
  29. this->CloseAVI( );
  30. }
  31. BOOL CAVI::OpenAVI( LPCSTR filename ,DWORD openmode )
  32. {
  33. HRESULT hr;
  34. if( openmode == AVI_WRITE )
  35. {   //线程内打开出错
  36. hr = ::AVIFileOpen( &this->m_avi_file , filename , OF_CREATE | OF_WRITE , NULL );
  37. //打开文件失败
  38. if( hr != AVIERR_OK || this->m_avi_file == NULL ) 
  39. return !this->CloseAVI( );
  40. }
  41. else if( openmode == AVI_READ )
  42. {
  43. hr = ::AVIFileOpen( &this->m_avi_file , filename , OF_SHARE_DENY_NONE | OF_READ , NULL );
  44. //打开文件失败
  45. if( hr != AVIERR_OK || this->m_avi_file == NULL ) 
  46. return !this->CloseAVI( );
  47. //创建流
  48. hr = ::AVIFileGetStream( this->m_avi_file , &this->m_avi_stream , streamtypeVIDEO , 0 );
  49. if( hr != AVIERR_OK )
  50.     return ! this->CloseAVI( );
  51. //读取avi图像信息
  52. memset( &this->m_avi_stream_info , 0 ,sizeof( this->m_avi_stream_info ) );  
  53. hr = ::AVIStreamInfo( this->m_avi_stream , &this->m_avi_stream_info , sizeof( AVISTREAMINFO ) );
  54. if( hr != AVIERR_OK )
  55. return !this->CloseAVI( );
  56. //读取位图信息
  57. long size=sizeof( BITMAPINFOHEADER );
  58. hr = ::AVIStreamReadFormat( this->m_avi_stream , 0 , &this->m_avi_bmp_info , &size );  
  59. if( hr != AVIERR_OK )
  60. return !this->CloseAVI( );
  61.     //申请内存
  62. this->avi_buffer = new char[ this->m_avi_bmp_info.biSizeImage ];
  63. ASSERT( this->avi_buffer != NULL );
  64. this->read_frame = 0;
  65. }
  66.     this->m_bMode = openmode;
  67. return TRUE;
  68. }
  69. BOOL CAVI::CloseAVI(void)
  70. {
  71. this->m_bMode = 0;
  72. if( this->m_avi_stream )
  73. {
  74. ::AVIStreamRelease( this->m_avi_stream );
  75. this->m_avi_stream = NULL; 
  76. }
  77. if( this->m_avi_file )
  78. {
  79. ::AVIFileRelease( this->m_avi_file );
  80. this->m_avi_file=NULL; 
  81. }
  82. if( this->avi_buffer )
  83. {
  84. delete [ ]this->avi_buffer;
  85. this->avi_buffer = NULL;
  86. }
  87. this->codec.ReleaseEncode( );
  88. this->read_frame = 0;
  89.     this->write_frame = 0;
  90. this->time_interval = 0;
  91. this->time_now = 0;
  92. return TRUE;
  93. }
  94. BOOL CAVI::SetAVIInfo( BITMAPINFOHEADER header , DWORD rate )
  95. {
  96. HRESULT hr;
  97. if( this->m_bMode != CAVI::AVI_WRITE || this->m_avi_file == NULL) 
  98. return FALSE;
  99. memcpy( &this->m_avi_bmp_info , &header , sizeof( BITMAPINFOHEADER ) );
  100. //设置流信息
  101. memset( &this->m_avi_stream_info , 0 ,sizeof( AVISTREAMINFO ) );
  102. this->m_avi_stream_info.fccType                = streamtypeVIDEO;//视频流类型
  103. this->m_avi_stream_info.fccHandler             = header.biCompression; //压缩方式
  104. this->m_avi_stream_info.dwScale                = 1; // 对于视频,取值为 1
  105. this->m_avi_stream_info.dwRate                 = rate;     // 帧速率
  106. this->m_avi_stream_info.dwSuggestedBufferSize  = header.biSizeImage; // 推荐的图像大小
  107. SetRect( &this->m_avi_stream_info.rcFrame , 0 , 0 , header.biWidth , header.biHeight );// 图形矩形大小
  108. // 创建视频流
  109. hr = AVIFileCreateStream( this->m_avi_file , &this->m_avi_stream , &this->m_avi_stream_info );
  110. if( hr != AVIERR_OK )
  111. return !this->CloseAVI( );
  112. //写流格式
  113.     hr = ::AVIStreamSetFormat( this->m_avi_stream , 0 , &this->m_avi_bmp_info ,sizeof( BITMAPINFOHEADER ) );  
  114. if( hr != AVIERR_OK )
  115. return ! this->CloseAVI( );
  116.     //当前写入帧数
  117.     this->write_frame = 0;
  118. this->time_interval = int ( 1000.0 / rate + 0.5 );
  119. this->time_now = ::timeGetTime( );
  120. //初始化压缩器
  121.     this->codec.InitEncode( header );
  122. return TRUE;
  123. }
  124. BOOL CAVI::GetAVIInfo( BITMAPINFOHEADER * header , DWORD * rate )
  125. {
  126. if( this->m_bMode != CAVI::AVI_READ || this->m_avi_file == NULL) 
  127. return FALSE;
  128. memcpy( header  ,&this->m_avi_bmp_info , sizeof( BITMAPINFOHEADER ) );
  129. *rate = this->m_avi_stream_info.dwRate / this->m_avi_stream_info.dwScale;
  130. return TRUE;
  131. }
  132. BOOL CAVI::AddFrame( void * data , UINT size )
  133. {
  134. DWORD now = ::timeGetTime( );
  135. if( this->m_bMode != CAVI::AVI_WRITE || this->m_avi_file == NULL || now - this->time_now < this->time_interval )
  136. return FALSE;
  137. this->time_now = now;
  138. if( size == 0 )
  139. size = this->m_avi_bmp_info.biSizeImage;  
  140. data = this->codec.Encode( data , ( int * )&size );
  141. if( data && size )
  142. return AVIERR_OK == ::AVIStreamWrite( this->m_avi_stream , this->write_frame ++ , 1 , data , size , AVIIF_KEYFRAME , NULL , NULL ); 
  143. return false;
  144. }
  145. BOOL CAVI::GetFrame( void ** data , UINT * size , int index )
  146. {
  147. if( this->m_bMode != CAVI::AVI_READ )
  148. return false;
  149. if(index != -1 ) this->read_frame = index;
  150.     
  151. *data = NULL;
  152. HRESULT hr = ::AVIStreamRead( this->m_avi_stream , this->read_frame ++ , 1 , this->avi_buffer , this->m_avi_bmp_info.biSizeImage , ( long * )size , 0 ); 
  153. if( hr == AVIERR_OK )
  154. *data = this->avi_buffer; 
  155. return *data != NULL;
  156. }