Browse Source

Jiggling bits until avi writer unbreaks.

bkaradzic 13 years ago
parent
commit
21e78cf7b0
1 changed files with 48 additions and 10 deletions
  1. 48 10
      examples/common/aviwriter.h

+ 48 - 10
examples/common/aviwriter.h

@@ -16,6 +16,7 @@ struct AviWriter
 	AviWriter()
 		: m_frame(NULL)
 		, m_frameSize(0)
+		, m_numFrames(0)
 		, m_width(0)
 		, m_height(0)
 		, m_yflip(false)
@@ -31,6 +32,7 @@ struct AviWriter
 
 		m_frameSize = _width * _height * 3;
 		m_frame = new uint8_t[m_frameSize + 8];
+		m_numFrames = 0;
 		m_width = _width;
 		m_height = _height;
 		
@@ -44,13 +46,14 @@ struct AviWriter
 		bx::write(&mem, m_frameSize);
 
 		bx::write(&m_writer, BX_MAKEFOURCC('R', 'I', 'F', 'F') );
+		m_riffSizeOffset = m_writer.seek();
 		bx::write(&m_writer, UINT32_C(0) );
 
 		bx::write(&m_writer, BX_MAKEFOURCC('A', 'V', 'I', ' ') );
 
 		// AVI RIFF Form http://msdn.microsoft.com/en-us/library/ms899422.aspx
 		bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
-		bx::write(&m_writer, UINT32_C(196) );
+		bx::write(&m_writer, UINT32_C(192) );
 		bx::write(&m_writer, BX_MAKEFOURCC('h', 'd', 'r', 'l') );
 
 		// AVI Main Header http://msdn.microsoft.com/en-us/library/ms779632.aspx
@@ -59,8 +62,11 @@ struct AviWriter
 		bx::write(&m_writer, UINT32_C(0) );      // dwMicroSecPerFrame
 		bx::write(&m_writer, UINT32_C(0) );      // dwMaxBytesPerSec
 		bx::write(&m_writer, UINT32_C(0) );      // dwPaddingGranularity
-		bx::write(&m_writer, UINT32_C(0) );      // dwFlags
+		bx::write(&m_writer, UINT32_C(0x101) );  // dwFlags
+
+		m_totalFramesOffset = m_writer.seek();
 		bx::write(&m_writer, UINT32_C(0) );      // dwTotalFrames
+
 		bx::write(&m_writer, UINT32_C(0) );      // dwInitialFrames
 		bx::write(&m_writer, UINT32_C(1) );      // dwStreams
 		bx::write(&m_writer, UINT32_C(0) );      // dwSuggestedBufferSize
@@ -72,7 +78,7 @@ struct AviWriter
 		bx::write(&m_writer, UINT32_C(0) );      // dwReserved3
 
 		bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
-		bx::write(&m_writer, UINT32_C(120) );
+		bx::write(&m_writer, UINT32_C(116) );
 		bx::write(&m_writer, BX_MAKEFOURCC('s', 't', 'r', 'l') );
 
 		// AVISTREAMHEADER Structure http://msdn.microsoft.com/en-us/library/ms779638.aspx
@@ -88,17 +94,20 @@ struct AviWriter
 		bx::write(&m_writer, UINT32_C(1000) );   // dwScale
 		bx::write(&m_writer, 1000*_fps);         // dwRate
 		bx::write(&m_writer, UINT32_C(0) );      // dwStart
+
+		m_lengthOffset = m_writer.seek();
 		bx::write(&m_writer, UINT32_C(0) );      // dwLength
-		bx::write(&m_writer, UINT32_C(0) );      // dwSuggestedBufferSize
-		bx::write(&m_writer, UINT32_C(0) );      // dwQuality
+
+		bx::write(&m_writer, m_frameSize);       // dwSuggestedBufferSize
+		bx::write(&m_writer, UINT32_MAX);        // dwQuality
 		bx::write(&m_writer, UINT32_C(0) );      // dwSampleSize
 		bx::write(&m_writer, INT16_C(0) );       // rcFrame.left
 		bx::write(&m_writer, INT16_C(0) );       // rcFrame.top
-		bx::write(&m_writer, INT16_C(0) );       // rcFrame.right
-		bx::write(&m_writer, INT16_C(0) );       // rcFrame.bottom
+		bx::write(&m_writer, uint16_t(_width) ); // rcFrame.right
+		bx::write(&m_writer, uint16_t(_height) );// rcFrame.bottom
 
 		bx::write(&m_writer, BX_MAKEFOURCC('s', 't', 'r', 'f') );
-		bx::write(&m_writer, UINT32_C(44) );
+		bx::write(&m_writer, UINT32_C(40) );
 
 		// BITMAPINFOHEADER structure http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229%28v=vs.85%29.aspx
 		bx::write(&m_writer, UINT32_C(40) );     // biSize
@@ -107,14 +116,15 @@ struct AviWriter
 		bx::write(&m_writer, UINT16_C(1) );      // biPlanes
 		bx::write(&m_writer, UINT16_C(24) );     // biBitCount
 		bx::write(&m_writer, UINT32_C(0) );      // biCompression
-		bx::write(&m_writer, UINT32_C(0) );      // biSizeImage
+		bx::write(&m_writer, m_frameSize);       // biSizeImage
 		bx::write(&m_writer, UINT32_C(0) );      // biXPelsPerMeter
 		bx::write(&m_writer, UINT32_C(0) );      // biYPelsPerMeter
 		bx::write(&m_writer, UINT32_C(0) );      // biClrUsed
 		bx::write(&m_writer, UINT32_C(0) );      // biClrImportant
-		bx::write(&m_writer, UINT32_C(0) );
 
 		bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
+
+		m_moviListOffset = m_writer.seek();
 		bx::write(&m_writer, UINT32_C(0) );
 		bx::write(&m_writer, BX_MAKEFOURCC('m', 'o', 'v', 'i') );
 
@@ -125,6 +135,28 @@ struct AviWriter
 	{
 		if (NULL != m_frame)
 		{
+			int64_t pos = m_writer.seek();
+			m_writer.seek(m_moviListOffset, bx::Whence::Begin);
+			bx::write(&m_writer, uint32_t(pos-m_moviListOffset+4) );
+			m_writer.seek(pos, bx::Whence::Begin);
+
+			bx::write(&m_writer, BX_MAKEFOURCC('i', 'd', 'x', '1') );
+			bx::write(&m_writer, UINT32_C(16) );
+			bx::write(&m_writer, BX_MAKEFOURCC('0', '0', 'd', 'b') );
+			bx::write(&m_writer, UINT32_C(16) );
+			bx::write(&m_writer, UINT32_C(4) );
+			bx::write(&m_writer, m_frameSize);
+
+			pos = m_writer.seek();
+			m_writer.seek(m_riffSizeOffset, bx::Whence::Begin);
+			bx::write(&m_writer, uint32_t(pos-m_riffSizeOffset+4) );
+
+			m_writer.seek(m_totalFramesOffset, bx::Whence::Begin);
+			bx::write(&m_writer, m_numFrames);
+
+			m_writer.seek(m_lengthOffset, bx::Whence::Begin);
+			bx::write(&m_writer, m_numFrames);
+
 			m_writer.close();
 
 			delete [] m_frame;
@@ -137,6 +169,7 @@ struct AviWriter
 	{
 		if (NULL != m_frame)
 		{
+			++m_numFrames;
 			uint32_t width = m_width;
 			uint32_t height = m_height;
 
@@ -176,8 +209,13 @@ struct AviWriter
 	}
 
 	bx::CrtFileWriter m_writer;
+	int64_t m_riffSizeOffset;
+	int64_t m_totalFramesOffset;
+	int64_t m_lengthOffset;
+	int64_t m_moviListOffset;
 	uint8_t* m_frame;
 	uint32_t m_frameSize;
+	uint32_t m_numFrames;
 	uint32_t m_width;
 	uint32_t m_height;
 	bool m_yflip;