TheoraStream.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 #include "stdafx.h"
00032 #include "theorastream.h"
00033 
00034 TheoraStream::TheoraStream(OggPage* inBOSPage, OggDemuxSourceFilter* inOwningFilter, bool inAllowSeek)
00035         :       OggStream(inBOSPage, inOwningFilter, inAllowSeek)
00036         ,       mTheoraFormatBlock(NULL)
00037 {
00038         InitCodec(inBOSPage->getStampedPacket(0));
00039         //debugLog.open("G:\\logs\\theorastream.log", ios_base::out);
00040 }
00041 
00042 TheoraStream::~TheoraStream(void)
00043 {
00044         delete mTheoraFormatBlock;
00045 }
00046 
00047 bool TheoraStream::InitCodec(StampedOggPacket* inOggPacket) {
00048         //Can probably abstract this out of here too !
00049         mCodecHeaders = new StreamHeaders;
00050         mCodecHeaders->mCodecType = StreamHeaders::THEORA;
00051         mCodecHeaders->addPacket((StampedOggPacket*)inOggPacket->clone());
00052         //What to do with commment fields ??
00053         mNumHeadersNeeded = 2;
00054         return true;
00055 }
00056 
00057 wstring TheoraStream::getPinName() {
00058         wstring locName = L"Theora Out";
00059         return locName;
00060 }
00061 
00062 bool TheoraStream::createFormatBlock() {
00063         mTheoraFormatBlock = new sTheoraFormatBlock;
00064         //Fix the format block data... use header version and other version.
00065         unsigned char* locIdentHeader = mCodecHeaders->getPacket(0)->packetData();
00066         //mTheoraFormatBlock->TheoraVersion = OggMath::charArrToULong(mCodecHeaders->getPacket(0)->packetData() + 28);
00067         //mTheoraFormatBlock->numChannels = OggMath::charArrToULong(mCodecHeaders->getPacket(0)->packetData() + 48);
00068         //mTheoraFormatBlock->samplesPerSec = OggMath::charArrToULong(mCodecHeaders->getPacket(0)->packetData() + 36);
00069 
00070         //0             -       55                      theora ident                                            0       -       6
00071         //56    -       63                      ver major                                                       7       -       7
00072         //64    -       71                      ver minor                                                       8       -       8
00073         //72    -       79                      ver subversion                                          9       =       9
00074         //80    -       95                      width/16                                                        10      -       11
00075         //96    -       111                     height/16                                                       12      -       13
00076         //112   -       135                     framewidth                                                      14      -       16
00077         //136   -       159                     frameheight                                                     17      -       19
00078         //160   -       167                     xoffset                                                         20      -       20
00079         //168   -       175                     yoffset                                                         21      -       21
00080         //176   -       207                     framerateNum                                            22      -       25
00081         //208   -       239                     frameratedenom                                          26      -       29
00082         //240   -       263                     aspectNum                                                       30      -       32
00083         //264   -       287                     aspectdenom                                                     33      -       35
00084         //288   -       295                     colourspace                                                     36      -       36
00085         //296   -       319                     targetbitrate                                           37      -       39
00086         //320   -       325                     targetqual                                                      40      -       40.75
00087         //326   -       330                     keyframintlog                                           40.75-  41.375
00088         mTheoraFormatBlock->theoraVersion = (iBE_Math::charArrToULong(locIdentHeader + 7)) >>8;
00089         mTheoraFormatBlock->outerFrameWidth = (iBE_Math::charArrToUShort(locIdentHeader + 10)) * 16;
00090         mTheoraFormatBlock->outerFrameHeight = (iBE_Math::charArrToUShort(locIdentHeader + 12)) * 16;
00091         mTheoraFormatBlock->pictureWidth = (iBE_Math::charArrToULong(locIdentHeader + 14)) >>8;
00092         mTheoraFormatBlock->pictureHeight = (iBE_Math::charArrToULong(locIdentHeader + 17)) >>8;
00093         mTheoraFormatBlock->xOffset = locIdentHeader[20];
00094         mTheoraFormatBlock->yOffset = locIdentHeader[21];
00095         mTheoraFormatBlock->frameRateNumerator = iBE_Math::charArrToULong(locIdentHeader + 22);
00096         mTheoraFormatBlock->frameRateDenominator = iBE_Math::charArrToULong(locIdentHeader + 26);
00097         mTheoraFormatBlock->aspectNumerator = (iBE_Math::charArrToULong(locIdentHeader + 30)) >>8;
00098         mTheoraFormatBlock->aspectDenominator = (iBE_Math::charArrToULong(locIdentHeader + 33)) >>8;
00099         mTheoraFormatBlock->colourSpace = locIdentHeader[36];
00100         mTheoraFormatBlock->targetBitrate = (iBE_Math::charArrToULong(locIdentHeader + 37)) >>8;
00101         mTheoraFormatBlock->targetQuality = (locIdentHeader[40]) >> 2;
00102 
00103         mTheoraFormatBlock->maxKeyframeInterval= (((locIdentHeader[40]) % 4) << 3) + (locIdentHeader[41] >> 5);
00104 
00105         return true;
00106 }
00107 
00108 void TheoraStream::setLastEndGranPos(__int64 inPos) {
00109         //debugLog<<"Theora inPos: "<<inPos<<endl;
00110         LONGLONG locFrameDuration = (UNITS * mTheoraFormatBlock->frameRateDenominator) / (mTheoraFormatBlock->frameRateNumerator);
00111 
00112         LONGLONG locAbsFramePos = inPos / locFrameDuration;
00113         //Timestamp hacks start here...
00114         unsigned long locMod = (unsigned long)pow(2, mTheoraFormatBlock->maxKeyframeInterval);
00115         mLastEndGranulePos = ((locAbsFramePos/locMod) << mTheoraFormatBlock->maxKeyframeInterval) + (locAbsFramePos % locMod);
00116         //unsigned long locInterFrameNo = (mLastSeenStartGranPos) % locMod);
00117         //LONGLONG locAbsFramePos = ((mLastSeenStartGranPos >> locFilter->mTheoraFormatInfo->maxKeyframeInterval) * locMod) + locInterFrameNo;
00118         //REFERENCE_TIME locTimeBase = ((locAbsFramePos * mFrameDuration) - locThis->mSeekTimeBase;
00119         //mLastEndGranulePos = (inPos * (__int64)mSpeexFormatBlock->samplesPerSec)/ UNITS;
00120         //debugLog<<"Theora sets End Gran : "<<mLastEndGranulePos<<endl;
00121 }
00122 BYTE* TheoraStream::getFormatBlock() {
00123 
00124         return (BYTE*)mTheoraFormatBlock;
00125 }
00126 
00127 GUID TheoraStream::getMajorTypeGUID() {
00128         return MEDIATYPE_Video;
00129 }
00130 unsigned long TheoraStream::getFormatBlockSize() {
00131         //Do something
00132         return sizeof(sTheoraFormatBlock);
00133 }
00134 GUID TheoraStream::getFormatGUID() {
00135         return FORMAT_Theora;
00136 }
00137 GUID TheoraStream::getSubtypeGUID() {
00138         return MEDIASUBTYPE_Theora;
00139 }
00140 
00141 LONGLONG TheoraStream::getCurrentPos() {
00142         return 0; //(mLastGranulePos * UNITS) / mVorbisFormatBlock->samplesPerSec;
00143 }
00144 
00145 unsigned long TheoraStream::getNumBuffers() {
00146         return THEORA_NUM_BUFFERS;
00147 }
00148 unsigned long TheoraStream::getBufferSize() {
00149         unsigned long locBuffSize = ((unsigned long)mTheoraFormatBlock->outerFrameHeight * (unsigned long)mTheoraFormatBlock->outerFrameWidth * 3) >> 3;
00150         if (locBuffSize < 65536) {
00151                 locBuffSize = 65536;
00152         }
00153         return locBuffSize;
00154 }

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