#include <avi.h>
Inheritance diagram for AVI2File:


Public Member Functions | |
| AVI2File () | |
| virtual | ~AVI2File () |
| virtual void | Init (int format, int sampleFrequency, int indexType) |
| Initialize the AVI structure to its initial state, either for PAL or NTSC format. | |
| virtual bool | WriteFrame (const Frame &frame) |
| Write a DV video frame. | |
| virtual void | WriteRIFF (void) |
| Writes out the directory structure. | |
| virtual void | setDVINFO (DVINFO &) |
Private Member Functions | |
| AVI2File (const AVI2File &) | |
| AVI2File & | operator= (const AVI2File &) |
Private Attributes | |
| BITMAPINFOHEADER | bitmapinfo |
| WAVEFORMATEX | waveformatex |
This file type contains both audio and video tracks. It is therefore more compatible to certain Windows programs, which expect any AVI having both audio and video tracks. The video tracks contain the raw DV data (as in type 1) and the extracted audio tracks.
Note that because the DV data contains audio information anyway, this means duplication of data and a slight increase of file size.
Definition at line 316 of file avi.h.
|
|
Definition at line 1335 of file avi.cc. 01335 : AVIFile() 01336 {}
|
|
|
Definition at line 1339 of file avi.cc. 01340 {}
|
|
|
|
|
||||||||||||||||
|
Initialize the AVI structure to its initial state, either for PAL or NTSC format. Initialize the AVIFile attributes: mainHdr, indx, ix00, idx1
Reimplemented from AVIFile. Definition at line 1346 of file avi.cc. References RIFFFile::AddDirectoryEntry(), AVI_LARGE_INDEX, AVI_NTSC, AVI_PAL, AVIFile::avih_chunk, bitmapinfo, AVIFile::dmlh_chunk, AVIFile::file_list, FOURCC, RIFFFile::GetDirectoryEntry(), AVIFile::hdrl_list, AVIFile::idx1, AVIFile::index_type, AVIFile::indx, AVIFile::indx_chunk, AVIFile::Init(), AVIFile::ix_chunk, AVIFile::junk_chunk, AVIFile::mainHdr, make_fourcc(), AVIFile::movi_list, AVIFile::odml_list, PADDING_SIZE, RIFF_HEADERSIZE, AVIFile::riff_list, RIFF_LISTSIZE, RIFF_NO_PARENT, AVIFile::streamHdr, AVIFile::strf_chunk, AVIFile::strh_chunk, AVIFile::strl_list, and waveformatex. 01347 {
01348 int num_blocks;
01349 FOURCC type;
01350 FOURCC name;
01351 off_t length;
01352 off_t offset;
01353 int parent;
01354
01355 assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) );
01356
01357 AVIFile::Init( format, sampleFrequency, indexType );
01358
01359 switch ( format )
01360 {
01361
01362 case AVI_PAL:
01363 mainHdr.dwStreams = 2;
01364 mainHdr.dwWidth = 720;
01365 mainHdr.dwHeight = 576;
01366
01367 /* Initialize the 'strh' chunk */
01368
01369 streamHdr[ 0 ].fccType = make_fourcc( "vids" );
01370 streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" );
01371 streamHdr[ 0 ].dwFlags = 0;
01372 streamHdr[ 0 ].wPriority = 0;
01373 streamHdr[ 0 ].wLanguage = 0;
01374 streamHdr[ 0 ].dwInitialFrames = 0;
01375 streamHdr[ 0 ].dwScale = 1;
01376 streamHdr[ 0 ].dwRate = 25;
01377 streamHdr[ 0 ].dwStart = 0;
01378 streamHdr[ 0 ].dwLength = 0;
01379 streamHdr[ 0 ].dwSuggestedBufferSize = 144008;
01380 streamHdr[ 0 ].dwQuality = -1;
01381 streamHdr[ 0 ].dwSampleSize = 0;
01382 streamHdr[ 0 ].rcFrame.top = 0;
01383 streamHdr[ 0 ].rcFrame.bottom = 0;
01384 streamHdr[ 0 ].rcFrame.left = 0;
01385 streamHdr[ 0 ].rcFrame.right = 0;
01386
01387 bitmapinfo.biSize = sizeof( bitmapinfo );
01388 bitmapinfo.biWidth = 720;
01389 bitmapinfo.biHeight = 576;
01390 bitmapinfo.biPlanes = 1;
01391 bitmapinfo.biBitCount = 24;
01392 bitmapinfo.biCompression = make_fourcc( "dvsd" );
01393 bitmapinfo.biSizeImage = 144000;
01394 bitmapinfo.biXPelsPerMeter = 0;
01395 bitmapinfo.biYPelsPerMeter = 0;
01396 bitmapinfo.biClrUsed = 0;
01397 bitmapinfo.biClrImportant = 0;
01398
01399 streamHdr[ 1 ].fccType = make_fourcc( "auds" );
01400 streamHdr[ 1 ].fccHandler = 0;
01401 streamHdr[ 1 ].dwFlags = 0;
01402 streamHdr[ 1 ].wPriority = 0;
01403 streamHdr[ 1 ].wLanguage = 0;
01404 streamHdr[ 1 ].dwInitialFrames = 0;
01405 streamHdr[ 1 ].dwScale = 2 * 2;
01406 streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2;
01407 streamHdr[ 1 ].dwStart = 0;
01408 streamHdr[ 1 ].dwLength = 0;
01409 streamHdr[ 1 ].dwSuggestedBufferSize = 8192;
01410 streamHdr[ 1 ].dwQuality = -1;
01411 streamHdr[ 1 ].dwSampleSize = 2 * 2;
01412 streamHdr[ 1 ].rcFrame.top = 0;
01413 streamHdr[ 1 ].rcFrame.bottom = 0;
01414 streamHdr[ 1 ].rcFrame.left = 0;
01415 streamHdr[ 1 ].rcFrame.right = 0;
01416
01417 break;
01418
01419 case AVI_NTSC:
01420 mainHdr.dwTotalFrames = 0;
01421 mainHdr.dwStreams = 2;
01422 mainHdr.dwWidth = 720;
01423 mainHdr.dwHeight = 480;
01424
01425 /* Initialize the 'strh' chunk */
01426
01427 streamHdr[ 0 ].fccType = make_fourcc( "vids" );
01428 streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" );
01429 streamHdr[ 0 ].dwFlags = 0;
01430 streamHdr[ 0 ].wPriority = 0;
01431 streamHdr[ 0 ].wLanguage = 0;
01432 streamHdr[ 0 ].dwInitialFrames = 0;
01433 streamHdr[ 0 ].dwScale = 1001;
01434 streamHdr[ 0 ].dwRate = 30000;
01435 streamHdr[ 0 ].dwStart = 0;
01436 streamHdr[ 0 ].dwLength = 0;
01437 streamHdr[ 0 ].dwSuggestedBufferSize = 120008;
01438 streamHdr[ 0 ].dwQuality = -1;
01439 streamHdr[ 0 ].dwSampleSize = 0;
01440 streamHdr[ 0 ].rcFrame.top = 0;
01441 streamHdr[ 0 ].rcFrame.bottom = 0;
01442 streamHdr[ 0 ].rcFrame.left = 0;
01443 streamHdr[ 0 ].rcFrame.right = 0;
01444
01445 bitmapinfo.biSize = sizeof( bitmapinfo );
01446 bitmapinfo.biWidth = 720;
01447 bitmapinfo.biHeight = 480;
01448 bitmapinfo.biPlanes = 1;
01449 bitmapinfo.biBitCount = 24;
01450 bitmapinfo.biCompression = make_fourcc( "dvsd" );
01451 bitmapinfo.biSizeImage = 120000;
01452 bitmapinfo.biXPelsPerMeter = 0;
01453 bitmapinfo.biYPelsPerMeter = 0;
01454 bitmapinfo.biClrUsed = 0;
01455 bitmapinfo.biClrImportant = 0;
01456
01457 streamHdr[ 1 ].fccType = make_fourcc( "auds" );
01458 streamHdr[ 1 ].fccHandler = 0;
01459 streamHdr[ 1 ].dwFlags = 0;
01460 streamHdr[ 1 ].wPriority = 0;
01461 streamHdr[ 1 ].wLanguage = 0;
01462 streamHdr[ 1 ].dwInitialFrames = 1;
01463 streamHdr[ 1 ].dwScale = 2 * 2;
01464 streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2;
01465 streamHdr[ 1 ].dwStart = 0;
01466 streamHdr[ 1 ].dwLength = 0;
01467 streamHdr[ 1 ].dwSuggestedBufferSize = 8192;
01468 streamHdr[ 1 ].dwQuality = 0;
01469 streamHdr[ 1 ].dwSampleSize = 2 * 2;
01470 streamHdr[ 1 ].rcFrame.top = 0;
01471 streamHdr[ 1 ].rcFrame.bottom = 0;
01472 streamHdr[ 1 ].rcFrame.left = 0;
01473 streamHdr[ 1 ].rcFrame.right = 0;
01474
01475 break;
01476 }
01477 waveformatex.wFormatTag = 1;
01478 waveformatex.nChannels = 2;
01479 waveformatex.nSamplesPerSec = sampleFrequency;
01480 waveformatex.nAvgBytesPerSec = sampleFrequency * 2 * 2;
01481 waveformatex.nBlockAlign = 4;
01482 waveformatex.wBitsPerSample = 16;
01483 waveformatex.cbSize = 0;
01484
01485 file_list = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT );
01486
01487 /* Create a basic directory structure. Only chunks defined from here on will be written to the AVI file. */
01488
01489 riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVI " ), RIFF_LISTSIZE, file_list );
01490 hdrl_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "hdrl" ), RIFF_LISTSIZE, riff_list );
01491 avih_chunk = AddDirectoryEntry( make_fourcc( "avih" ), 0, sizeof( MainAVIHeader ), hdrl_list );
01492
01493 strl_list[ 0 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list );
01494 strh_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 0 ] );
01495 strf_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( BITMAPINFOHEADER ), strl_list[ 0 ] );
01496 if ( index_type & AVI_LARGE_INDEX )
01497 {
01498 indx_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 0 ] );
01499 ix_chunk[ 0 ] = -1;
01500 indx[ 0 ] ->dwChunkId = make_fourcc( "00dc" );
01501 }
01502
01503 strl_list[ 1 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list );
01504 strh_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 1 ] );
01505 strf_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( WAVEFORMATEX ) - 2, strl_list[ 1 ] );
01506 junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, 2, strl_list[ 1 ] );
01507 if ( index_type & AVI_LARGE_INDEX )
01508 {
01509 indx_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 1 ] );
01510 ix_chunk[ 1 ] = -1;
01511 indx[ 1 ] ->dwChunkId = make_fourcc( "01wb" );
01512
01513 odml_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "odml" ), RIFF_LISTSIZE, hdrl_list );
01514 dmlh_chunk = AddDirectoryEntry( make_fourcc( "dmlh" ), 0, 0x00f8, odml_list );
01515 }
01516
01517 /* align movi list to block */
01518 GetDirectoryEntry( hdrl_list, type, name, length, offset, parent );
01519 num_blocks = length / PADDING_SIZE + 1;
01520 length = num_blocks * PADDING_SIZE - length - 5 * RIFF_HEADERSIZE; // why 5 headers?
01521 junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list );
01522
01523 movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list );
01524
01525 idx1->aIndex[ idx1->nEntriesInUse ].dwChunkId = make_fourcc( "7Fxx" );
01526 idx1->aIndex[ idx1->nEntriesInUse ].dwFlags = 0;
01527 idx1->aIndex[ idx1->nEntriesInUse ].dwOffset = 0;
01528 idx1->aIndex[ idx1->nEntriesInUse ].dwSize = 0;
01529 idx1->nEntriesInUse++;
01530 }
|
|
|
|
|
|
Reimplemented from AVIFile. Definition at line 1700 of file avi.cc. 01701 {}
|
|
|
Write a DV video frame.
Reimplemented from AVIFile. Definition at line 1566 of file avi.cc. References RIFFFile::AddDirectoryEntry(), AVI_LARGE_INDEX, AVI_SMALL_INDEX, Frame::data, AVIFile::dmlh, Frame::ExtractAudio(), AVIFile::file_list, AVIFile::FlushIndx(), FOURCC, g_zeroes, RIFFFile::GetDirectoryEntry(), Frame::GetFrameSize(), AVIFile::idx1, AVIFile::idx1_chunk, AVIFile::index_type, AVIFile::isUpdateIdx1, AVIFile::ix, IX00_INDEX_SIZE, AVIFile::junk_chunk, AVIFile::mainHdr, make_fourcc(), AVIFile::movi_list, PADDING_SIZE, RIFF_HEADERSIZE, AVIFile::riff_list, RIFF_LISTSIZE, AVIFile::streamHdr, AVIFile::UpdateIdx1(), AVIFile::UpdateIndx(), waveformatex, and RIFFFile::WriteChunk(). 01567 {
01568 int audio_chunk;
01569 int frame_chunk;
01570 int junk_chunk;
01571 char soundbuf[ 20000 ];
01572 int audio_size;
01573 int num_blocks;
01574 FOURCC type;
01575 FOURCC name;
01576 off_t length;
01577 off_t offset;
01578 int parent;
01579
01580 /* exit if no large index and 1GB reached */
01581 if ( !( index_type & AVI_LARGE_INDEX ) && isUpdateIdx1 == false )
01582 return false;
01583
01584 /* Check if we need a new ix00 Standard Index. It has a
01585 capacity of IX00_INDEX_SIZE frames. Whenever we exceed that
01586 number, we need a new index. The new ix00 chunk is also
01587 part of the movi list. */
01588
01589 if ( ( index_type & AVI_LARGE_INDEX ) && ( ( ( streamHdr[ 0 ].dwLength - 0 ) % IX00_INDEX_SIZE ) == 0 ) )
01590 {
01591 FlushIndx( 0 );
01592 FlushIndx( 1 );
01593 }
01594
01595 /* Write audio data if we have it */
01596
01597 audio_size = frame.ExtractAudio( soundbuf );
01598 if ( audio_size > 0 )
01599 {
01600 #if BYTE_ORDER == BIG_ENDIAN
01601 int16_t* p = reinterpret_cast< int16_t* >( soundbuf );
01602 for ( int i = 0; i < audio_size / sizeof( int16_t ); ++i, ++p )
01603 *p = bswap_16( *p );
01604 #endif
01605 audio_chunk = AddDirectoryEntry( make_fourcc( "01wb" ), 0, audio_size, movi_list );
01606 if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 )
01607 {
01608 GetDirectoryEntry( audio_chunk, type, name, length, offset, parent );
01609 ix[ 1 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE;
01610 }
01611 WriteChunk( audio_chunk, soundbuf );
01612 // num_blocks = (audio_size + RIFF_HEADERSIZE) / PADDING_SIZE + 1;
01613 // length = num_blocks * PADDING_SIZE - audio_size - 2 * RIFF_HEADERSIZE;
01614 // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list);
01615 // WriteChunk(junk_chunk, g_zeroes);
01616 if ( index_type & AVI_LARGE_INDEX )
01617 UpdateIndx( 1, audio_chunk, audio_size / waveformatex.nChannels / 2 );
01618 if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 )
01619 UpdateIdx1( audio_chunk, 0x00 );
01620 streamHdr[ 1 ].dwLength += audio_size / waveformatex.nChannels / 2;
01621
01622 }
01623
01624 /* Write video data */
01625
01626 frame_chunk = AddDirectoryEntry( make_fourcc( "00dc" ), 0, frame.GetFrameSize(), movi_list );
01627 if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 )
01628 {
01629 GetDirectoryEntry( frame_chunk, type, name, length, offset, parent );
01630 ix[ 0 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE;
01631 }
01632 WriteChunk( frame_chunk, frame.data );
01633 // num_blocks = (frame.GetFrameSize() + RIFF_HEADERSIZE) / PADDING_SIZE + 1;
01634 // length = num_blocks * PADDING_SIZE - frame.GetFrameSize() - 2 * RIFF_HEADERSIZE;
01635 // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list);
01636 // WriteChunk(junk_chunk, g_zeroes);
01637 if ( index_type & AVI_LARGE_INDEX )
01638 UpdateIndx( 0, frame_chunk, 1 );
01639 if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 )
01640 UpdateIdx1( frame_chunk, 0x10 );
01641
01642 /* update some variables with the new frame count. */
01643
01644 if ( isUpdateIdx1 )
01645 ++mainHdr.dwTotalFrames;
01646 ++streamHdr[ 0 ].dwLength;
01647 ++dmlh[ 0 ];
01648
01649 /* Find out if the current riff list is close to 1 GByte in
01650 size. If so, start a new (extended) RIFF. The only allowed
01651 item in the new RIFF chunk is a movi list (with video
01652 frames and indexes as usual). */
01653
01654 GetDirectoryEntry( riff_list, type, name, length, offset, parent );
01655 if ( length > 0x3f000000 )
01656 {
01657
01658 /* write idx1 only once and before end of first GB */
01659 if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 )
01660 {
01661 int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list );
01662 WriteChunk( idx1_chunk, ( void* ) idx1 );
01663 }
01664 isUpdateIdx1 = false;
01665
01666 if ( index_type & AVI_LARGE_INDEX )
01667 {
01668 /* padding for alignment */
01669 GetDirectoryEntry( riff_list, type, name, length, offset, parent );
01670 num_blocks = ( length + 4 * RIFF_HEADERSIZE ) / PADDING_SIZE + 1;
01671 length = ( num_blocks * PADDING_SIZE ) - length - 4 * RIFF_HEADERSIZE - 2 * RIFF_LISTSIZE;
01672 if ( length > 0 )
01673 {
01674 junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list );
01675 WriteChunk( junk_chunk, g_zeroes );
01676 }
01677
01678 riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVIX" ), RIFF_LISTSIZE, file_list );
01679 movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list );
01680 }
01681 }
01682 return true;
01683 }
|
|
|
Writes out the directory structure. For all items in the directory list that have not been written yet, it seeks to the file position where that item should be stored and writes the type and length field. If the item has a name, it will also write the name field.
Reimplemented from AVIFile. Definition at line 1533 of file avi.cc. References RIFFFile::AddDirectoryEntry(), AVI_LARGE_INDEX, AVI_SMALL_INDEX, AVIFile::avih_chunk, bitmapinfo, AVIFile::dmlh, AVIFile::dmlh_chunk, AVIFile::idx1, AVIFile::idx1_chunk, AVIFile::index_type, AVIFile::indx, AVIFile::indx_chunk, AVIFile::isUpdateIdx1, AVIFile::ix, AVIFile::ix_chunk, AVIFile::mainHdr, make_fourcc(), AVIFile::riff_list, AVIFile::streamHdr, AVIFile::strf_chunk, AVIFile::strh_chunk, waveformatex, RIFFFile::WriteChunk(), and RIFFFile::WriteRIFF(). 01534 {
01535 WriteChunk( avih_chunk, ( void* ) & mainHdr );
01536 WriteChunk( strh_chunk[ 0 ], ( void* ) & streamHdr[ 0 ] );
01537 WriteChunk( strf_chunk[ 0 ], ( void* ) & bitmapinfo );
01538 if ( index_type & AVI_LARGE_INDEX )
01539 {
01540 WriteChunk( dmlh_chunk, ( void* ) & dmlh );
01541 WriteChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ] );
01542 WriteChunk( ix_chunk[ 0 ], ( void* ) ix[ 0 ] );
01543 }
01544 WriteChunk( strh_chunk[ 1 ], ( void* ) & streamHdr[ 1 ] );
01545 WriteChunk( strf_chunk[ 1 ], ( void* ) & waveformatex );
01546 if ( index_type & AVI_LARGE_INDEX )
01547 {
01548 WriteChunk( indx_chunk[ 1 ], ( void* ) indx[ 1 ] );
01549 WriteChunk( ix_chunk[ 1 ], ( void* ) ix[ 1 ] );
01550 }
01551
01552 if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 )
01553 {
01554 int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list );
01555 WriteChunk( idx1_chunk, ( void* ) idx1 );
01556 }
01557 RIFFFile::WriteRIFF();
01558 }
|
|
|
Definition at line 328 of file avi.h. Referenced by Init(), and WriteRIFF(). |
|
|
Definition at line 329 of file avi.h. Referenced by Init(), WriteFrame(), and WriteRIFF(). |
1.4.2