OggPaginator.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 #include "stdafx.h"
00033 #include <libOOOgg/OggPaginator.h>
00034 //LEAK CHECK::: Potential for leak based on mPendingPage. if setSettings is called. and also the last page won't get deleted. 20041018
00035 
00036 //Checksum tables from libogg
00037 static unsigned long crc_lookup[256]={
00038   0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
00039   0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
00040   0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
00041   0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
00042   0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
00043   0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
00044   0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
00045   0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
00046   0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
00047   0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
00048   0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
00049   0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
00050   0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
00051   0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
00052   0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
00053   0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
00054   0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
00055   0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
00056   0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
00057   0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
00058   0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
00059   0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
00060   0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
00061   0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
00062   0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
00063   0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
00064   0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
00065   0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
00066   0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
00067   0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
00068   0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
00069   0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
00070   0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
00071   0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
00072   0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
00073   0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
00074   0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
00075   0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
00076   0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
00077   0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
00078   0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
00079   0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
00080   0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
00081   0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
00082   0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
00083   0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
00084   0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
00085   0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
00086   0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
00087   0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
00088   0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
00089   0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
00090   0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
00091   0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
00092   0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
00093   0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
00094   0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
00095   0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
00096   0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
00097   0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
00098   0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
00099   0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
00100   0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
00101   0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4
00102 };
00103 
00104   //End libogg tables
00105 
00106 OggPaginator::OggPaginator(void)
00107         :       mPageCallback(NULL)
00108         ,       mSettings(NULL)
00109         ,       mPendingPage(NULL)
00110         ,       mCurrentPageSize(0)
00111         ,       mSegmentTableSize(0)
00112         ,       mPendingPageHasData(false)
00113         ,       mSequenceNo(0)
00114         ,       mPacketCount(0)
00115         ,       mLastGranulePos(0)
00116 {
00117         //debugLog.open("G:\\logs\\paginator.log", ios_base::out);
00118 
00119         mHeaderBuff = new unsigned char[300];           //Deleted in destructor.
00120         
00121 }
00122 
00123 OggPaginator::~OggPaginator(void)
00124 {
00125         delete mHeaderBuff;
00126         mHeaderBuff = NULL;
00127         //debugLog.close();
00128 }
00129 
00130 //Calling this after you have fed in packets will cause lost data and memory leak (mPending page)
00131 bool OggPaginator::setParameters(OggPaginatorSettings* inSettings) {
00132         delete mSettings;
00133     mSettings = inSettings;
00134         //string x= "G:\\logs\\paginator" + StringHelper::numToString(inSettings->mSerialNo) + ".log";
00135         //debugLog.open(x.c_str(), ios_base::out);
00136         createFreshPage();
00137         return true;
00138 }
00139 
00140 OggPaginatorSettings* OggPaginator::parameters() {
00141         return mSettings;
00142 }
00143 
00144 //Keeps packet.
00145 bool OggPaginator::acceptStampedOggPacket(StampedOggPacket* inOggPacket) 
00146 {               
00147 
00148         //debugLog<<"Accepting packet"<<endl;
00149         addPacketToPage(inOggPacket);
00150 
00151         delete inOggPacket;
00152 
00153         return true;
00154 }
00155 bool OggPaginator::finishStream() 
00156 {
00157         //When we get a signal to finish a stream, we set the EOS Flag on the current page pending
00158         // which may be empty, and then deliver it.
00159 
00160         //debugLog<<endl;
00161         //debugLog<<"finishStream : ";
00162         //This makes sure if our last page is empty and we want to send the EOS page, we stamp it with the previous granule pos
00163         //      since if this page has no packets it must be the same. Makes it easier to find the stream duration.
00164         if (mPendingPage->numPackets() == 0) {
00165                 //debugLog<<"finishStream : Setting gran pos on 0 pack last page to "<<mLastGranulePos<<endl;
00166                 mPendingPage->header()->setGranulePos(mLastGranulePos);
00167 
00168         }
00169 
00170         mPendingPage->header()->setHeaderFlags(mPendingPage->header()->HeaderFlags() | 4);
00171         deliverCurrentPage();
00172         return true;
00173 }
00174 
00175 bool OggPaginator::setChecksum() 
00176 {
00177         unsigned long locChecksum = 0;
00178         unsigned long locTemp = 0;
00179 
00180         /* Note: now that there's a OggPage::computeAndSetCRCChecksum() function,
00181            we can just use that instead of setting the checksum ourselves.  i.e.
00182 
00183                 if (mPendingPage != NULL) {
00184                         mPendingPage->computeAndSetCRCChecksum();
00185                         return true;
00186                 } else {
00187                         return false;
00188                 }
00189 
00190            Zen, if you'd like to make the changes here, feel free.
00191          */
00192 
00193         if (mPendingPage != NULL) {
00194                 //Set the checksum to NULL for the checksumming process.
00195                 mPendingPage->header()->setCRCChecksum((unsigned long)0);
00196                 mPendingPage->header()->rawData(mHeaderBuff, 300);
00197 
00198                 for(unsigned long i = 0; i < mPendingPage->headerSize(); i++) {
00199                         //Create the index we use for the lookup
00200                         locTemp = ((locChecksum >> 24) & 0xff) ^ mHeaderBuff[i];
00201                         //XOR the lookup value with the the current checksum shifted left 8 bits.
00202                         locChecksum=(locChecksum << 8) ^ crc_lookup[locTemp];
00203                 }
00204 
00205 
00206 
00207                 unsigned char* locBuff = NULL;
00208                 for(unsigned long i = 0; i < mPendingPage->numPackets(); i++) {
00209                         locBuff = mPendingPage->getPacket(i)->packetData();                     //View only don't delete.
00210 
00211                         for (unsigned long j = 0; j < mPendingPage->getPacket(i)->packetSize(); j++) {
00212                                 locTemp = ((locChecksum >> 24) & 0xff) ^ locBuff[j];
00213                 locChecksum = (locChecksum << 8) ^ crc_lookup[locTemp];
00214                         }
00215                 }
00216 
00217                 mPendingPage->header()->setCRCChecksum(locChecksum);
00218         }
00219         return true;
00220 
00221 }
00222 bool OggPaginator::deliverCurrentPage() {
00223         //debugLog<<endl;
00224         //debugLog<<"deliverCurrentPage : "<<endl;
00225         mPendingPage->header()->setSegmentTable((const unsigned char*)mSegmentTable, mSegmentTableSize);
00226 
00227         mPendingPage->header()->setDataSize(mCurrentPageSize - mPendingPage->headerSize());  //This is odd
00228 
00229         setChecksum();
00230 
00231         //We save this in case we need to send an empty EOS page, and we can stamp it with this value.
00232         mLastGranulePos = mPendingPage->header()->GranulePos();
00233         
00234         //TODO::: Should catch and propagate return value.
00235         mPageCallback->acceptOggPage(mPendingPage);             //Gives away page.
00236         mPendingPage = NULL;
00237         createFreshPage();
00238         return true;
00239 
00240 }
00241 bool OggPaginator::createFreshPage() {
00242         //debugLog<<endl;
00243         //debugLog<<"createFreshPage : "<<endl;
00244         mPendingPage = new OggPage;                     //Potential for leak here if setsettings called. Otherwise deleted in destructor or dispatched
00245         mCurrentPageSize = OggPageHeader::OGG_BASE_HEADER_SIZE;
00246         mPendingPageHasData = false;
00247         mSegmentTableSize = 0;
00248         
00249         mPendingPage->header()->setStreamSerialNo(mSettings->mSerialNo);
00250         mPendingPage->header()->setPageSequenceNo(mSequenceNo);
00251         
00252         //If it's the first page it gets the BOS Flag
00253         if (mSequenceNo == 0) {
00254                 //debugLog<<"createFreshPage : Setting as BOS"<<endl;
00255                 mPendingPage->header()->setHeaderFlags(OggPageHeader::BOS);
00256         } else {
00257                 //debugLog<<"createFreshPage : Setting NO FLAGS"<<endl;
00258                 mPendingPage->header()->setHeaderFlags(OggPageHeader::NO_FLAGS);
00259         }
00260 
00261         mPendingPage->header()->setGranulePos(OggPageHeader::UNKNOWN_GRANULE_POS);
00262         mSequenceNo++;
00263         return true;
00264 
00265 }
00266 bool OggPaginator::addPacketToPage(StampedOggPacket* inOggPacket) {
00267 
00268         //debugLog<<endl;
00269         //debugLog<<"addPacketToPage : "<<endl;
00270         mPendingPageHasData = true;
00271         //while some packet left
00272         //      add as much as possible
00273         //      update how much packet is left
00274         //wend
00275 
00276 
00277         //ADD AS MUCH AS POSSIBLE
00278         //howmuchToAdd = MIN(numSegsLeft * 255, maxsize - current size)
00279         //add part of packet
00280         //if page has enough deliver it
00281         //return how much was added.
00282 
00283         //Get some counter variables ready
00284         long locPacketRemaining = inOggPacket->packetSize();
00285         unsigned long locPacketStartPoint = 0;
00286         unsigned long locConsumed = 0;
00287 
00288         //debugLog<<"addPacketToPage : Packet size = "<<locPacketRemaining<<endl;
00289 
00290         //While there is still more packet not added to the page add as much as it will take.
00291         while (locPacketRemaining > 0) {
00292 
00293 
00294                 locConsumed = addAsMuchPacketAsPossible(inOggPacket, locPacketStartPoint, locPacketRemaining);
00295 
00296                 //debugLog<<"addPacketToPage : Packet consumed = "<<locPacketRemaining<<endl;
00297 
00298                 locPacketStartPoint += locConsumed;
00299                 locPacketRemaining -= locConsumed;
00300                 //debugLog<<"addPacketToPage : Packet remaining = "<<locPacketRemaining<<endl;
00301                 //debugLog<<"addPacketToPage : Packet part start at = "<<locPacketStartPoint<<endl;
00302         }
00303 
00304 
00305 
00306 
00307         //This will ensure that any header packet appears on it's own page...
00308         //
00309 
00310         //Every header gets it's own page.
00311         if (((mPacketCount < mSettings->mNumHeaders) || ((mSettings->mMaxPacksPerPage != 0) && (mPacketCount >= mSettings->mMaxPacksPerPage))) && (mPendingPageHasData)) {
00312                 //debugLog<<"addPacketToPage : Cond Deliv : Packet Count = "<<mPacketCount<<endl;
00313                 //debugLog<<"addPacketToPage : Cond Deliv : Num Headers = "<<mSettings->mNumHeaders<<endl;
00314                 //debugLog<<"addPacketToPage : Cond Deliv : Max Pack per page = "<<mSettings->mMaxPacksPerPage<<endl;
00315                 
00316                 deliverCurrentPage();
00317         }
00318         mPacketCount++;
00319         return true;
00320 }
00321 
00322 
00323 unsigned long OggPaginator::addAsMuchPacketAsPossible(StampedOggPacket* inOggPacket, unsigned long inStartAt, long inRemaining) 
00324 {
00325         //debugLog<<"Remains in packet = "<<inRemaining<<endl;
00326         //debugLog<<"Start at = "<<inStartAt<<endl;
00327         //debugLog<<"Segtable size = "<<mSegmentTableSize<<endl;
00328         //debugLog<<"Max page size = "<<mSettings->mMaxPageSize<<endl;
00329         //debugLog<<"Current page size = "<<mCurrentPageSize<<endl;
00330 
00331         //debugLog<<endl;
00332         //debugLog<<"addAsMuchPacketAsPossible : "<<endl;
00333         //debugLog<<"addAsMuchPacketAsPossible : Start At = "<<inStartAt<<endl;
00334         //debugLog<<"addAsMuchPacketAsPossible : Remaining = "<<inRemaining<<endl;
00335         //debugLog<<"addAsMuchPacketAsPossible : Segtable size = "<<mSegmentTableSize<<endl;
00336         //debugLog<<"addAsMuchPacketAsPossible : Current Page Size = "<<mCurrentPageSize<<endl;
00337         
00338         
00339         //The amount of space left in the page is the minimum of
00340         // a) The (number of segments left * 255) take 1.
00341         // b) The number of bytes less than the desired maximum page size.
00342 
00343         
00344         //***** WARNING 4018!!!!!! ::: TODO::: What happens when mSegmentTableSize is 255 ?
00345 
00346         //Take 1 so when it adds the packet it doesn't try to consume one extra segment which doesn't exist.
00347     unsigned long locSpaceLeft =        MIN(((255 - mSegmentTableSize) * 255) - 1, mSettings->mMaxPageSize - mCurrentPageSize);
00348 
00349         //debugLog<<"addAsMuchPacketAsPossible : Space left = "<<locSpaceLeft<<endl;
00350         //debugLog<<"Space left = "<<locSpaceLeft<<endl;
00351         //debugLog<<"Space left = "<<locSpaceLeft<<endl;
00352         //Round down to nearest multiple of 255
00353         //
00354 
00355         //This is important when the packet gets broken because inRemaining is gt locSpace left
00356         // In this case where the packet gets broken the final segment on the page must be 255.
00357         locSpaceLeft -= (locSpaceLeft % 255);
00358         //debugLog<<"addAsMuchPacketAsPossible : Space left = "<<locSpaceLeft<<endl;
00359         //ASSERT(locSpaceLeft >=0);
00360 
00361         //debugLog<<"Adjust space left = "<<locSpaceLeft<<endl;
00362 
00363         //How much we add is the minimum of
00364         // a) How much space is left
00365         // b) The amount of packet remaining.
00366 
00367         //**** WARING 4018 !!!! TODO::: Are we sure inRemaining can never be < 0
00368         //If (a) is the minimum then we know that the how much we are adding is a multiple of 255.
00369         unsigned long locHowMuchToAdd = MIN(locSpaceLeft, inRemaining);
00370 
00371         //debugLog<<"addAsMuchPacketAsPossible : How much to add = "<<locHowMuchToAdd<<endl;
00372         
00373         //mPending page has data is useless, it was set before this function is called... need to fix that. maybe move into add part of pack into apge
00374         if ((!mPendingPageHasData) && (inStartAt != 0)) {
00375                 //debugLog<<"addAsMuchPacketAsPossible : Setting continuation flag"<<endl;
00376                 mPendingPage->header()->setHeaderFlags((unsigned char)(mPendingPage->header()->HeaderFlags() | OggPageHeader::CONTINUATION));   
00377                 
00378         }
00379 
00380         if (locHowMuchToAdd > 0) {
00381                 //debugLog<<"addAsMuchPacketAsPossible : Adding from "<<inStartAt<<" for "<<locHowMuchToAdd<<endl;
00382                 addPartOfPacketToPage(inOggPacket, inStartAt, locHowMuchToAdd);
00383         }
00384 
00385 
00386         //This puts only a single packet on the first page...
00387         if ((mCurrentPageSize >= mSettings->mMinPageSize) || (mPendingPage->header()->PageSequenceNo() == 0) || (locHowMuchToAdd == 0)) {
00388                 //debugLog<<"addAsMuchPacketAsPossible : Cond Deliv : Probably shouldn't be ehre."<<endl;
00389                 deliverCurrentPage();
00390         }
00391         return locHowMuchToAdd;
00392 
00393 }
00394 
00395 bool OggPaginator::addPartOfPacketToPage(StampedOggPacket* inOggPacket, unsigned long inStartFrom, unsigned long inLength) {
00396         //debugLog<<endl;
00397         //debugLog<<"addPartOfPacketToPage : "<<endl;
00398         //debugLog<<"addPartOfPacketToPage : Add from "<<inStartFrom<< " to "<<inLength<<endl;
00399         
00400         //Buffer the amount of the packet we are going to add.
00401         unsigned char* locBuff = new unsigned char[inLength];                   //Given to constructor of stampedpacket.
00402         memcpy((void*)locBuff, (const void*)(inOggPacket->packetData() + inStartFrom), inLength);
00403 
00404         //unsigned long locBytesOfPacketRemaining = inOggPacket->packetSize() - (((locNumSegsNeeded - (255 - mSegmentTableSize)) * 255);
00405         //unsigned long locRemainingPacketStartsAt = inOggPacket->packetSize() - locBytesOfPacketRemaining + 1;
00406         //
00407 
00408         //Its the last part of the packet start point plus how much we are adding of it is the same
00409         // as the total packet size.
00410         bool locIsLastOfPacket = (inStartFrom + inLength == inOggPacket->packetSize());
00411 
00412         //debugLog<<"addPartOfPacketToPage : This is the last bit of the packet..."<<endl;
00413         //Create a new packet
00414         StampedOggPacket* locPartialPacket = new StampedOggPacket(      locBuff, 
00415                                                                                                                                 inLength, 
00416                                                                                                                                 locIsLastOfPacket,
00417                                                                                                                                 false,   //Not continuation
00418                                                                                                                                 inOggPacket->startTime(), 
00419                                                                                                                                 inOggPacket->endTime(), 
00420                                                                                                                                 inOggPacket->mStampType);               //Given to page.
00421 
00422         //debugLog<<"addPartOfPacketToPage : Adding Partial Packet to page"<<endl;
00423         //Add the packet to the page.
00424         mPendingPage->addPacket(locPartialPacket);
00425 
00426         //CASES
00427         //========
00428         //length                 segs           segs if not end
00429         //  0                     1                   N/A
00430         //  1                     1                   N/A
00431         // 255                    2                    1
00432         // 256                    2
00433         // 510                    3                    2
00434         //  n                     (n / 255) + 1
00435 
00436         //Now do the segment table bookkeeping.
00437         unsigned long locNumSegsNeeded = (inLength / 255);
00438         //debugLog<<"addPartOfPacketToPage : Num 255 segs to add = "<<locNumSegsNeeded<<" ("<<inLength<<")"<<endl;
00439 
00440         //Always do one less than the total... the last segment is a special case
00441         //We fill all but the last segemnt with 255
00442         for (unsigned long i = 0; i < locNumSegsNeeded; i++) {
00443                 mSegmentTable[mSegmentTableSize] = 255;
00444                 mSegmentTableSize++;
00445         }
00446 
00447         //If it's not the last of the packet, it will be a multiple of 255, hence we don't put a terminating 0 on.
00448         //If it is the last of the packet this last segment will be between 0 and 254 inclusive.
00449         if (locIsLastOfPacket) {
00450                 //Its the last part of the packet... so we need one extra segemnt... to hold the last part.
00451                 // The last part will be between 0-254
00452                 
00453                 //debugLog<<"addPartOfPacketToPage : Adding last seg = "<<(unsigned long)(inLength % 255)<<endl;
00454                 mSegmentTable[mSegmentTableSize] = (unsigned char)(inLength % 255);
00455                 mSegmentTableSize++;
00456 
00457                 //This is used in a calculation below.
00458                 locNumSegsNeeded++;
00459         } else {
00460                 //If it's not the last part of the packet it should be a multiple of 255. the calling function needs to ensure this.
00461                 //Since if it was the last part of the packet we've already added all the segments, then we do nothing.
00462 
00463                 //ASSERT((inLength % 255) == 0);
00464                 if ((inLength % 255) != 0) {
00465                         //debugLog<<"addPartOfPacketToPage : ASSERTION FAILED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
00466                 }
00467                 //mSegmentTable[mSegmentTableSize] = (unsigned char)(255);
00468                 //mSegmentTableSize++;
00469                 //locNumSegsNeeded++;
00470         }
00471                 
00472 
00473 
00474 
00475         mCurrentPageSize += (locNumSegsNeeded + inLength);
00476         //debugLog<<"addPartOfPacketToPage : Current Page Size = "<<mCurrentPageSize<<endl;
00477 
00478 
00479         if (locIsLastOfPacket) {
00480                 //debugLog<<"addPartOfPacketToPage : Updating gran pos to : "<<inOggPacket->endTime()<<endl;
00481                 mPendingPage->header()->setGranulePos(inOggPacket->endTime());
00482         }
00483 
00484         return true;
00485 }
00486 
00487 
00488 
00489 
00490         
00491 
00492 
00493 bool OggPaginator::setPageCallback(IOggCallback* inPageCallback) {
00494         mPageCallback = inPageCallback;
00495         return true;
00496 }
00497 
00498 void OggPaginator::setNumHeaders(unsigned long inNumHeaders) {
00499         mSettings->mNumHeaders = inNumHeaders;
00500 }
00501 unsigned long OggPaginator::numHeaders() {
00502         return mSettings->mNumHeaders;
00503 
00504 }

Generated on Tue Feb 15 14:54:21 2005 for oggdsf by  doxygen 1.3.9