OggFLAC_1_0_Stream.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 "OggFLAC_1_0_Stream.h"
00034 //#include "FLACMath.h"
00035 
00036 OggFLAC_1_0_Stream::OggFLAC_1_0_Stream(OggPage* inBOSPage, OggDemuxSourceFilter* inOwningFilter, bool inAllowSeek)
00037         :       OggStream(inBOSPage, inOwningFilter, inAllowSeek)
00038         ,       mFLACFormatBlock(NULL)
00039         ,       mIsFixedNumHeaders(false)
00040         //,     mNumHeaderPackets(0)
00041 {
00042         InitCodec(inBOSPage->getStampedPacket(0));
00043 }
00044 
00045 OggFLAC_1_0_Stream::~OggFLAC_1_0_Stream(void)
00046 {
00047         delete mFLACFormatBlock;
00048 }
00049 
00050 bool OggFLAC_1_0_Stream::InitCodec(StampedOggPacket* inOggPacket) {
00051         //Can probably abstract this out of here too !
00052         mCodecHeaders = new StreamHeaders;
00053         mCodecHeaders->mCodecType = StreamHeaders::FLAC;
00054         mCodecHeaders->addPacket((StampedOggPacket*)inOggPacket->clone());
00055         //What to do with commment fields ??
00056         //We set this to 1... and we override the header processor
00057         //When we see the last header packet ie starts with 1xxxxxxx then we decrement it.
00058         
00059         //NEW::: Since the ogg flac 1.0 mapping there's now another option... if the new first header
00060         // specifies the number of headers, we can count directly, otherwise we stll use the old
00061         // method for maximum compatability.
00062         mNumHeadersNeeded = iBE_Math::charArrToUShort(inOggPacket->packetData() + 7);
00063         //debugLog<<"Num FLAC Headers needed = "<<mNumHeadersNeeded<<endl;
00064         if (mNumHeadersNeeded == 0) {
00065                 //Variable number
00066                 // Use the old method of setting this to 1, and then decrementing it when we see the last one.
00067                 mNumHeadersNeeded = 1;
00068                 mIsFixedNumHeaders = false;
00069         } else {
00070                 mIsFixedNumHeaders = true;
00071         }
00072         return true;
00073 }
00074 
00075 wstring OggFLAC_1_0_Stream::getPinName() {
00076         wstring locName = L"FLAC Out";
00077         return locName;
00078 }
00079 
00080 bool OggFLAC_1_0_Stream::createFormatBlock() {
00081         const unsigned char FLAC_CHANNEL_MASK = 14;  //00001110
00082         const unsigned char FLAC_BPS_START_MASK = 1; //00000001
00083         const unsigned char FLAC_BPS_END_MASK = 240;  //11110000
00084         mFLACFormatBlock = new sFLACFormatBlock;
00085         //Fix the format block data... use header version and other version.
00086         //mFLACFormatBlock->FLACVersion = FLACMath::charArrToULong(mCodecHeaders->getPacket(1)->packetData() + 28);
00087         mFLACFormatBlock->numChannels = (((mCodecHeaders->getPacket(0)->packetData()[29]) & FLAC_CHANNEL_MASK) >> 1) + 1;
00088         mFLACFormatBlock->samplesPerSec = (iBE_Math::charArrToULong(mCodecHeaders->getPacket(0)->packetData() + 27)) >> 12;
00089         
00090         mFLACFormatBlock->numBitsPerSample =    (((mCodecHeaders->getPacket(0)->packetData()[29] & FLAC_BPS_START_MASK) << 4)   |
00091                                                                                         ((mCodecHeaders->getPacket(0)->packetData()[30] & FLAC_BPS_END_MASK) >> 4)) + 1;        
00092         return true;
00093 }
00094 BYTE* OggFLAC_1_0_Stream::getFormatBlock() {
00095 
00096         return (BYTE*)mFLACFormatBlock;
00097 
00098 
00099 }
00100 unsigned long OggFLAC_1_0_Stream::getFormatBlockSize() {
00101         //Do something
00102         return sizeof(sFLACFormatBlock);
00103 }
00104 GUID OggFLAC_1_0_Stream::getFormatGUID() {
00105         return FORMAT_FLAC;
00106 }
00107 GUID OggFLAC_1_0_Stream::getSubtypeGUID() {
00108         return MEDIASUBTYPE_FLAC;
00109 }
00110 GUID OggFLAC_1_0_Stream::getMajorTypeGUID() {
00111         return MEDIATYPE_Audio;
00112 }
00113 
00114 unsigned long OggFLAC_1_0_Stream::getNumBuffers() {
00115         return OGG_FLAC_1_0_NUM_BUFFERS;
00116 }
00117 unsigned long OggFLAC_1_0_Stream::getBufferSize() {
00118         return OGG_FLAC_1_0_BUFFER_SIZE;
00119 }
00120 
00121 //Need to override from oggstream because we have variable number of headers
00122 bool OggFLAC_1_0_Stream::processHeaderPacket(StampedOggPacket* inPacket) {
00123         //FIX::: Return values
00124         const unsigned char MORE_HEADERS_MASK = 128;   //10000000
00125         //We don't delete the packet... the codecheader list will delete when it's done.
00126         //StampedOggPacket* locPacket = processPacket(inPacket);
00127         if (inPacket != NULL) {
00128                 //We got a comlpete packet
00129                 mCodecHeaders->addPacket(inPacket);
00130                 if (mIsFixedNumHeaders) {
00131                         mNumHeadersNeeded--;
00132                 } else {
00133                         if ((inPacket->packetData()[0] & MORE_HEADERS_MASK) != 0) {
00134                                 mNumHeadersNeeded--;
00135                                 //mNumHeaderPackets++;
00136                         }
00137                 }
00138         }
00139         return true;
00140 }
00141 void OggFLAC_1_0_Stream::setLastEndGranPos(__int64 inPos) {
00142         mLastEndGranulePos = (inPos * (__int64)mFLACFormatBlock->samplesPerSec)/ UNITS;
00143 }
00144 bool OggFLAC_1_0_Stream::deliverCodecHeaders() {
00145         //debugLog<<"Delivering Codec Headers... "<<mCodecHeaders->numPackets()<<endl;
00146         StampedOggPacket* locPacket = NULL;
00147         for (unsigned long i = 0; i < mCodecHeaders->numPackets(); i++) {
00148                 if (i==0) {
00149                         //Need to reconstruct what the meta-data blocks look like in naked flac,
00150                         // so strip away most of the new header.
00151                         //
00152                         //New part of ogg header is 9 bytes
00153                         //old flac ident is 4 bytes
00154                         //StreamInfoHeader is 38 bytes
00155                         //
00156                         //So we discard the first 9 bytes, and keep the next 42 bytes.
00157                         unsigned char* locPackBuf = new unsigned char[42];                      //Given away to the StampedPacket
00158                         
00159                         //locPacket = (StampedOggPacket*)mCodecHeaders->getPacket(0)->clone();
00160                         memcpy((void*)locPackBuf, (const void*)(mCodecHeaders->getPacket(0)->packetData() + 9), 42);
00161                         locPacket = new StampedOggPacket(locPackBuf, 42, false, false, 0, 0, StampedOggPacket::OGG_END_ONLY);
00162                 } else {
00163                         locPacket->merge(mCodecHeaders->getPacket(i));
00164                 }
00165         }
00166         if (mCodecHeaders->numPackets() > 0) {
00167                 dispatchPacket(locPacket);
00168         }
00169         return true;
00170 }
00171 
00172 LONGLONG OggFLAC_1_0_Stream::getCurrentPos() {
00173         return (mLastEndGranulePos * UNITS) / mFLACFormatBlock->samplesPerSec;
00174 }
00175 
00176 //unsigned long OggFLAC_1_0_Stream::numCodecHeaders() {
00177 //      return mNumHeaderPackets;  //is this even needed ?
00178 //}

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