CConvertAVI.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "StdAfx.h"
  2. #include "CConvertAVI.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. CConvertAVI::CConvertAVI()
  9. {
  10. m_pOutAVI = NULL;
  11. m_pIndexes = NULL;
  12. m_nMaxFrames = 0;
  13. ZeroMemory(&m_strAVIPara, sizeof(AVI_CONVERT_PARA));
  14. }
  15. CConvertAVI::~CConvertAVI()
  16. {
  17. }
  18. BOOL CConvertAVI::InitResource(AVI_CONVERT_PARA* pParam, CString strAVIPath)
  19. {
  20. m_nCurFrameNum = 0;
  21. m_nFirstFrameOffset = 0;
  22. m_bWriteHdr = TRUE;
  23. CopyMemory(&m_strAVIPara, pParam, sizeof(AVI_CONVERT_PARA));
  24. m_nMaxFrames = MAX_FILE_LEN/m_strAVIPara.dwTotalFrames;
  25. #ifdef WRITE_INDEX
  26. m_pIndexes = new AVIINDEXENTRY[m_nMaxFrames];
  27. if(NULL == m_pIndexes)
  28. {
  29. return FALSE;
  30. }
  31. ZeroMemory(m_pIndexes, m_nMaxFrames * sizeof(AVIINDEXENTRY));
  32. m_nMoviOffset = 0;
  33. #endif
  34. if ( (m_pOutAVI = riffCreate( LPCTSTR(strAVIPath) )) == NULL )
  35. {
  36. ReleaseResource();
  37. return FALSE;
  38. }
  39. return TRUE;
  40. }
  41. void CConvertAVI::ReleaseResource()
  42. {
  43. if(m_pOutAVI != NULL)
  44. {
  45. TRACE("Close wriff files.\n");
  46. CloseWriffFiles();
  47. m_pOutAVI = NULL;
  48. }
  49. #ifdef WRITE_INDEX
  50. if(m_pIndexes != NULL)
  51. {
  52. TRACE("Delete m_pIndexes.\n");
  53. delete [] m_pIndexes;
  54. m_pIndexes = NULL;
  55. }
  56. #endif
  57. ZeroMemory(&m_strAVIPara, sizeof(AVI_CONVERT_PARA));
  58. }
  59. BOOL CConvertAVI::IsWriteAVIHdr()
  60. {
  61. return m_bWriteHdr;
  62. }
  63. BOOL CConvertAVI::WriteHeaders()
  64. {
  65. MainAVIHeader mainAviHeader;
  66. AVIStreamHeader aviStreamHeader;
  67. BITMAPINFOHEADER bitmapHeader;
  68. DWORD fcc;
  69. riffAddList( m_pOutAVI, "RIFF", "AVI " );
  70. //
  71. // Write hdr1 list
  72. //
  73. riffAddList( m_pOutAVI, "LIST", "hdrl" );
  74. mainAviHeader.dwMicroSecPerFrame = 1000000 / (m_strAVIPara.dwFPS);
  75. mainAviHeader.dwMaxBytesPerSec = m_strAVIPara.dwFrameSize + PADDING_GRANULARITY; // Spare
  76. mainAviHeader.dwPaddingGranularity = 0;
  77. mainAviHeader.dwFlags = AVIF_HASINDEX;
  78. mainAviHeader.dwTotalFrames = m_strAVIPara.dwTotalFrames;
  79. mainAviHeader.dwInitialFrames = 0;
  80. mainAviHeader.dwStreams = 1;
  81. mainAviHeader.dwSuggestedBufferSize = m_strAVIPara.dwFrameSize + PADDING_GRANULARITY; // Spare
  82. mainAviHeader.dwWidth = m_strAVIPara.dwFrameWidth;
  83. mainAviHeader.dwHeight = m_strAVIPara.dwFrameHeight;
  84. mainAviHeader.dwReserved[0] = 0;
  85. mainAviHeader.dwReserved[1] = 0;
  86. mainAviHeader.dwReserved[2] = 0;
  87. mainAviHeader.dwReserved[3] = 0;
  88. riffAddChunk ( m_pOutAVI, "avih" );
  89. riffWriteData ( m_pOutAVI, &mainAviHeader, sizeof( mainAviHeader ) );
  90. riffCloseChunk( m_pOutAVI );
  91. //
  92. // Write the "strl" video list
  93. //
  94. riffAddList( m_pOutAVI, "LIST", "strl" );
  95. //
  96. // Write the "strh" chunk
  97. //
  98. fcc = mmioFOURCC( 'Y', 'V', '1', '2' );
  99. aviStreamHeader.fccType = mmioFOURCC( 'v', 'i', 'd', 's' );
  100. aviStreamHeader.fccHandler = 0;
  101. aviStreamHeader.dwFlags = fcc;
  102. aviStreamHeader.wPriority = 0;
  103. aviStreamHeader.wLanguage = 0;
  104. aviStreamHeader.dwInitialFrames = 0;
  105. aviStreamHeader.dwScale = 1;
  106. aviStreamHeader.dwRate = m_strAVIPara.dwFPS;
  107. aviStreamHeader.dwStart = 0;
  108. aviStreamHeader.dwLength = m_strAVIPara.dwTotalFrames;
  109. aviStreamHeader.dwSuggestedBufferSize = m_strAVIPara.dwFrameSize + PADDING_GRANULARITY;
  110. aviStreamHeader.dwQuality = 0xFFFFFFFF; // -1
  111. aviStreamHeader.dwSampleSize = 0;
  112. aviStreamHeader.dwTop = 0;
  113. aviStreamHeader.dwLeft = 0;
  114. aviStreamHeader.dwRight = 0;
  115. aviStreamHeader.dwBottom = 0;
  116. riffAddChunk ( m_pOutAVI, "strh" );
  117. riffWriteData ( m_pOutAVI, &aviStreamHeader, sizeof( aviStreamHeader ) );
  118. riffCloseChunk( m_pOutAVI );
  119. //
  120. //
  121. // Write the "strf" chunk
  122. //
  123. bitmapHeader.biSize = sizeof( bitmapHeader );
  124. bitmapHeader.biWidth = m_strAVIPara.dwFrameWidth;
  125. bitmapHeader.biHeight = m_strAVIPara.dwFrameHeight;
  126. bitmapHeader.biPlanes = 1;
  127. bitmapHeader.biBitCount = 12;
  128. bitmapHeader.biCompression = fcc;
  129. bitmapHeader.biSizeImage = m_strAVIPara.dwFrameSize;
  130. bitmapHeader.biXPelsPerMeter = 0;
  131. bitmapHeader.biYPelsPerMeter = 0;
  132. bitmapHeader.biClrUsed = 0;
  133. bitmapHeader.biClrImportant = 0;
  134. riffAddChunk ( m_pOutAVI, "strf" );
  135. riffWriteData ( m_pOutAVI, &bitmapHeader, sizeof( bitmapHeader ) );
  136. riffCloseChunk( m_pOutAVI );
  137. //
  138. // Close the strl list
  139. //
  140. riffCloseList( m_pOutAVI );
  141. //
  142. // Close the hdrl list
  143. //
  144. riffCloseList( m_pOutAVI );
  145. //
  146. // Write JUNK chunk
  147. //
  148. riffPadJunk( m_pOutAVI, PADDING_GRANULARITY, 0 );
  149. //
  150. // Write the "movi" list
  151. //
  152. riffAddList( m_pOutAVI, "LIST", "movi" );
  153. m_nFirstFrameOffset = riffSize( m_pOutAVI );
  154. #ifdef WRITE_INDEX
  155. m_nMoviOffset = m_nFirstFrameOffset - 4;
  156. #endif
  157. //
  158. // Return
  159. //
  160. m_bWriteHdr = FALSE;
  161. return TRUE;
  162. }
  163. DWORD CConvertAVI::GetCurFrameNum()
  164. {
  165. return m_nCurFrameNum;
  166. }
  167. BOOL CConvertAVI::AddFileToAVI(char* pBuf, DWORD nSize)
  168. {
  169. #ifdef WRITE_REC_LIST
  170. //
  171. // Write "rec " list
  172. //
  173. #ifdef WRITE_INDEX
  174. riffPadWord( m_pOutAVI );
  175. #endif // WRITE_INDEX
  176. riffAddList( m_pOutAVI, "LIST", "rec" );
  177. #endif // WRITE_REC_LIST
  178. //
  179. // Write the "00dc" chunk
  180. //
  181. #ifdef WRITE_INDEX
  182. riffPadWord( m_pOutAVI );
  183. m_pIndexes[m_nCurFrameNum].ckid = mmioFOURCC( '0', '0', 'd', 'c' );
  184. m_pIndexes[m_nCurFrameNum].dwFlags = AVIIF_KEYFRAME;
  185. m_pIndexes[m_nCurFrameNum].dwChunkOffset = riffSize( m_pOutAVI ) - m_nMoviOffset;
  186. m_pIndexes[m_nCurFrameNum].dwChunkLength = m_strAVIPara.dwFrameSize;
  187. #endif // WRITE_INDEX
  188. //
  189. // Write the chunk
  190. //
  191. riffAddChunk ( m_pOutAVI, "00dc" );
  192. riffWriteData ( m_pOutAVI, pBuf, m_strAVIPara.dwFrameSize );
  193. riffCloseChunk( m_pOutAVI );
  194. #ifdef WRITE_REC_LIST
  195. //
  196. // Close the "rec " list
  197. //
  198. riffCloseList( m_pOutAVI );
  199. #endif // WRITE_REC_LIST
  200. //
  201. // Write JUNK chunk to align video frames
  202. //
  203. #ifdef ALIGN_VIDEO_FRAMES
  204. riffPadJunk( m_pOutAVI, PADDING_GRANULARITY, m_nFirstFrameOffset );
  205. #endif // ALIGN_VIDEO_FRAMES
  206. m_nCurFrameNum ++;
  207. return TRUE;
  208. }
  209. BOOL CConvertAVI::CloseWriffFiles()
  210. {
  211. //
  212. // Close the "movi" list
  213. //
  214. riffCloseList( m_pOutAVI );
  215. //
  216. // Write the "idx1" chunk
  217. //
  218. #ifdef WRITE_INDEX
  219. riffPadWord ( m_pOutAVI );
  220. riffAddChunk ( m_pOutAVI, "idx1" );
  221. riffWriteData ( m_pOutAVI, m_pIndexes, m_nCurFrameNum*sizeof( AVIINDEXENTRY) );
  222. riffCloseChunk( m_pOutAVI );
  223. #endif // WRITE_INDEX
  224. //
  225. // Close the "RIFF" LIST
  226. //
  227. riffCloseList( m_pOutAVI );
  228. //
  229. // Close the riff file
  230. //
  231. riffClose( m_pOutAVI );
  232. return TRUE;
  233. }
  234. void CConvertAVI::SetFPS(DWORD nFps)
  235. {
  236. m_strAVIPara.dwFPS = nFps;
  237. }
  238. BOOL CConvertAVI::IsExceedMaxFileLen()
  239. {
  240. return ( (m_nCurFrameNum >= m_nMaxFrames) ? TRUE : FALSE);
  241. }