www.pudn.com > XvidQP.rar > AC3FileSrc.cpp
#include#include #include #include #include "AC3FileSrc.h" ///////////////////////////// // byte swapping routine #define SWAP_ENDIAN32(x) ((((uint_8*)&x)[0] << 24) | \ (((uint_8*)&x)[1] << 16) | \ (((uint_8*)&x)[2] << 8) | \ ((uint_8*)&x)[3]) AC3_Bitstream::AC3_Bitstream(FILE *f) { file = f; current_word = 0; bits_left = 0; total_bits_read = 0; done = FALSE; // preload data this->Load(); } AC3_Bitstream::~AC3_Bitstream() { } // Load data from file - does byte swapping int AC3_Bitstream::Load() { int bytes_read = 0; if (file!=NULL){ bytes_read = fread(¤t_word,4,1,file); } bytes_read = ( bytes_read << 2 ); /* multiply by 4 */ current_word = SWAP_ENDIAN32(current_word); bits_left = bytes_read * 8; //FIXME finishing up the stream isn't done too gracefully if (bytes_read < 4){ // check to see if end of file done = TRUE; file = NULL; } return bytes_read; } // Fetches 1-32 bits from the file opened in bitstream_open int AC3_Bitstream::GetBitSequence(uint_32 num_bits) { uint_32 result; uint_32 bits_read; uint_32 bits_to_go; if(num_bits == 0) return 0; bits_read = num_bits > bits_left ? bits_left : num_bits; result = current_word >> (32 - bits_read); current_word <<= bits_read; bits_left -= bits_read; if(bits_left == 0){ long loaded = Load(); } if (bits_read < num_bits) { bits_to_go = num_bits - bits_read; result <<= bits_to_go; result |= current_word >> (32 - bits_to_go); current_word <<= bits_to_go; bits_left -= bits_to_go; } total_bits_read += num_bits; // crc_process(result,num_bits); return result; } // Positions the stream pointer to a sync word int AC3_Bitstream::Resync() { int i = 0; uint_16 sync_word; if (!file) return -1; sync_word = GetBitSequence(16); /* Make sure we sync'ed */ while(1) { if(sync_word == 0x0b77) break; sync_word = ( sync_word << 1 ); sync_word |= GetBitSequence(1); i++; if (i > 32) { // fix added to handle EOF or closed files // printf( "EOF %d\n", ftell( bs->file ) ); if ( ftell(file)==-1 || feof(file) ) { i = -1; break; } } } total_bits_read = 16; // crc_init(); return i; /* return # bits skipped */ } /////////////////////////// const uint_16 nfchans[] = {2,1,2,3,3,4,4,5}; struct frmsize_s { uint_16 bit_rate; uint_16 frm_size[3]; }; const struct frmsize_s frmsizecod_tbl[] = { { 32 ,{64 ,69 ,96 } }, { 32 ,{64 ,70 ,96 } }, { 40 ,{80 ,87 ,120 } }, { 40 ,{80 ,88 ,120 } }, { 48 ,{96 ,104 ,144 } }, { 48 ,{96 ,105 ,144 } }, { 56 ,{112 ,121 ,168 } }, { 56 ,{112 ,122 ,168 } }, { 64 ,{128 ,139 ,192 } }, { 64 ,{128 ,140 ,192 } }, { 80 ,{160 ,174 ,240 } }, { 80 ,{160 ,175 ,240 } }, { 96 ,{192 ,208 ,288 } }, { 96 ,{192 ,209 ,288 } }, { 112 ,{224 ,243 ,336 } }, { 112 ,{224 ,244 ,336 } }, { 128 ,{256 ,278 ,384 } }, { 128 ,{256 ,279 ,384 } }, { 160 ,{320 ,348 ,480 } }, { 160 ,{320 ,349 ,480 } }, { 192 ,{384 ,417 ,576 } }, { 192 ,{384 ,418 ,576 } }, { 224 ,{448 ,487 ,672 } }, { 224 ,{448 ,488 ,672 } }, { 256 ,{512 ,557 ,768 } }, { 256 ,{512 ,558 ,768 } }, { 320 ,{640 ,696 ,960 } }, { 320 ,{640 ,697 ,960 } }, { 384 ,{768 ,835 ,1152 } }, { 384 ,{768 ,836 ,1152 } }, { 448 ,{896 ,975 ,1344 } }, { 448 ,{896 ,976 ,1344 } }, { 512 ,{1024 ,1114 ,1536 } }, { 512 ,{1024 ,1115 ,1536 } }, { 576 ,{1152 ,1253 ,1728 } }, { 576 ,{1152 ,1254 ,1728 } }, { 640 ,{1280 ,1393 ,1920 } }, { 640 ,{1280 ,1394 ,1920 } } }; AC3FileSrc::AC3FileSrc(FILE *ac3File) { // set the file ptr m_ac3File = ac3File; } AC3FileSrc::~AC3FileSrc() { // nothing } BOOL AC3FileSrc::Parse(LPWAVEFORMATEX fmt) { if (m_ac3File==NULL) { return FALSE; } // create a bitstream m_ac3Bitstream = new AC3_Bitstream(m_ac3File); // sync to the start of an AC3 frame if (m_ac3Bitstream->Resync() < 0) { // unable to resync - clean up and return delete m_ac3Bitstream; return FALSE; } // create sync info structure m_sync_info = new AC3_SYNCINFO(); // and parse the sync_info ParseSyncInfo(); // create the BSI m_bsi = new AC3_BSI(); ParseBSI(); fmt->wFormatTag = WAVE_FORMAT_DOLBY_AC3; fmt->nChannels = m_bsi->nfchans; switch (m_sync_info->fscod) { case 2: fmt->nSamplesPerSec = 32000; break; case 1: fmt->nSamplesPerSec = 44100; break; case 0: fmt->nSamplesPerSec = 48000; break; default: fmt->nSamplesPerSec = 0; break; } fmt->nAvgBytesPerSec = (1000 * m_sync_info->bit_rate) / 8; fmt->nBlockAlign = 1; fmt->wBitsPerSample = 0; fmt->cbSize = sizeof(WAVEFORMATEX); delete m_bsi; delete m_sync_info; delete m_ac3Bitstream; return TRUE; } // Parse a syncinfo structure, minus the sync word void AC3FileSrc::ParseSyncInfo() { /* Get crc1 - we don't actually use this data though */ m_ac3Bitstream->GetBitSequence(16); /* Get the sampling rate */ m_sync_info->fscod = m_ac3Bitstream->GetBitSequence(2); /* Get the frame size code */ m_sync_info->frmsizecod = m_ac3Bitstream->GetBitSequence(6); m_sync_info->bit_rate = frmsizecod_tbl[m_sync_info->frmsizecod].bit_rate; m_sync_info->frame_size = frmsizecod_tbl[m_sync_info->frmsizecod].frm_size[m_sync_info->fscod]; // stats_printf_syncinfo(syncinfo); } void AC3FileSrc::ParseBSI() { uint_32 i; /* Check the AC-3 version number */ m_bsi->bsid = m_ac3Bitstream->GetBitSequence(5); /* Get the audio service provided by the steram */ m_bsi->bsmod = m_ac3Bitstream->GetBitSequence(3); /* Get the audio coding mode (ie how many channels)*/ m_bsi->acmod = m_ac3Bitstream->GetBitSequence(3); /* Predecode the number of full bandwidth channels as we use this * number a lot */ m_bsi->nfchans = nfchans[m_bsi->acmod]; /* If it is in use, get the centre channel mix level */ if ((m_bsi->acmod & 0x1) && (m_bsi->acmod != 0x1)) m_bsi->cmixlev = m_ac3Bitstream->GetBitSequence(2); /* If it is in use, get the surround channel mix level */ if (m_bsi->acmod & 0x4) m_bsi->surmixlev = m_ac3Bitstream->GetBitSequence(2); /* Get the dolby surround mode if in 2/0 mode */ if(m_bsi->acmod == 0x2) m_bsi->dsurmod= m_ac3Bitstream->GetBitSequence(2); /* Is the low frequency effects channel on? */ m_bsi->lfeon = m_ac3Bitstream->GetBitSequence(1); /* Get the dialogue normalization level */ m_bsi->dialnorm = m_ac3Bitstream->GetBitSequence(5); /* Does compression gain exist? */ m_bsi->compre = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->compre) { /* Get compression gain */ m_bsi->compr = m_ac3Bitstream->GetBitSequence(8); } /* Does language code exist? */ m_bsi->langcode = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->langcode) { /* Get langauge code */ m_bsi->langcod = m_ac3Bitstream->GetBitSequence(8); } /* Does audio production info exist? */ m_bsi->audprodie = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->audprodie) { /* Get mix level */ m_bsi->mixlevel = m_ac3Bitstream->GetBitSequence(5); /* Get room type */ m_bsi->roomtyp = m_ac3Bitstream->GetBitSequence(2); } /* If we're in dual mono mode then get some extra info */ if (m_bsi->acmod ==0) { /* Get the dialogue normalization level two */ m_bsi->dialnorm2 = m_ac3Bitstream->GetBitSequence(5); /* Does compression gain two exist? */ m_bsi->compr2e = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->compr2e) { /* Get compression gain two */ m_bsi->compr2 = m_ac3Bitstream->GetBitSequence(8); } /* Does language code two exist? */ m_bsi->langcod2e = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->langcod2e) { /* Get langauge code two */ m_bsi->langcod2 = m_ac3Bitstream->GetBitSequence(8); } /* Does audio production info two exist? */ m_bsi->audprodi2e = m_ac3Bitstream->GetBitSequence(1); if (m_bsi->audprodi2e) { /* Get mix level two */ m_bsi->mixlevel2 = m_ac3Bitstream->GetBitSequence(5); /* Get room type two */ m_bsi->roomtyp2 = m_ac3Bitstream->GetBitSequence(2); } } /* Get the copyright bit */ m_bsi->copyrightb = m_ac3Bitstream->GetBitSequence(1); /* Get the original bit */ m_bsi->origbs = m_ac3Bitstream->GetBitSequence(1); /* Does timecode one exist? */ m_bsi->timecod1e = m_ac3Bitstream->GetBitSequence(1); if(m_bsi->timecod1e) { m_bsi->timecod1 = m_ac3Bitstream->GetBitSequence(14); } /* Does timecode two exist? */ m_bsi->timecod2e = m_ac3Bitstream->GetBitSequence(1); if(m_bsi->timecod2e) { m_bsi->timecod2 = m_ac3Bitstream->GetBitSequence(14); } /* Does addition info exist? */ m_bsi->addbsie = m_ac3Bitstream->GetBitSequence(1); if(m_bsi->addbsie) { /* Get how much info is there */ m_bsi->addbsil = m_ac3Bitstream->GetBitSequence(6); /* Get the additional info */ for(i=0;i<(m_bsi->addbsil + 1);i++) m_bsi->addbsi[i] = m_ac3Bitstream->GetBitSequence(8); } // stats_printf_bsi(bsi); }