00001 //=========================================================================== 00002 //Copyright (C) 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 ".\flacheadertweaker.h" 00034 00035 FLACHeaderTweaker::FLACHeaderTweaker(void) 00036 : mSeenAllHeaders(false) 00037 00038 { 00039 //debugLog.open("G:\\logs\\flactweaker.log", ios_base::out); 00040 00041 } 00042 00043 FLACHeaderTweaker::~FLACHeaderTweaker(void) 00044 { 00045 00046 //debugLog<<"Pre delete old..."<<endl; 00047 deleteOldHeaders(); 00048 //debugLog<<"Pre delete new..."<<endl; 00049 deleteNewHeaders(); 00050 //debugLog<<"Post delete..."<<endl; 00051 //debugLog.close(); 00052 } 00053 00054 FLACHeaderTweaker::eFLACAcceptHeaderResult FLACHeaderTweaker::acceptHeader(OggPacket* inHeader) { 00055 //debugLog<<endl<<"Accepting header.."<<endl; 00056 //debugLog<<inHeader->toPackDumpString()<<endl; 00057 const unsigned char MORE_HEADERS_MASK = 128; 00058 if (!mSeenAllHeaders) { 00059 //debugLog<<"Still tweaking... adding to old list..."<<endl; 00060 00061 00062 mOldHeaderList.push_back(inHeader); 00063 if ((inHeader->packetData()[0] & MORE_HEADERS_MASK) != 0) { 00064 //debugLog<<"This is the last header..."<<endl; 00065 //Last header 00066 mSeenAllHeaders = true; 00067 if (createNewHeaderList()) { 00068 //debugLog<<"Create new headers OK"<<endl; 00069 return LAST_HEADER_ACCEPTED; 00070 } else { 00071 //debugLog<<"Create new headers FAILED"<<endl; 00072 return HEADER_ERROR; 00073 } 00074 } else { 00075 //debugLog<<"Still need more ehaders..."<<endl; 00076 //Still more headers to come... 00077 return HEADER_ACCEPTED; 00078 } 00079 } else { 00080 //debugLog<<"All headers already seen"<<endl; 00081 return ALL_HEADERS_ALREADY_SEEN; 00082 } 00083 00084 } 00085 00086 bool FLACHeaderTweaker::createNewHeaderList() { 00087 00088 //debugLog<<"Create new header list method"<<endl; 00089 00090 //debugLog<<"Filling first pack"<<endl; 00091 unsigned char* locFirstPackBuff = new unsigned char[51]; 00092 locFirstPackBuff[0] = '\177'; 00093 locFirstPackBuff[1] = 'F'; 00094 locFirstPackBuff[2] = 'L'; 00095 locFirstPackBuff[3] = 'A'; 00096 locFirstPackBuff[4] = 'C'; 00097 locFirstPackBuff[5] = 1; 00098 locFirstPackBuff[6] = 0; 00099 locFirstPackBuff[7] = 0; //Num header HIGH BYTE 00100 00101 //*** VERIFY ::: Is this even safe ie -2 ... are we sure this can't go negative ???? 00102 locFirstPackBuff[8] = mOldHeaderList.size() - 2; //Num headers LOW BYTE 00103 locFirstPackBuff[9] = 'f'; 00104 locFirstPackBuff[10] = 'L'; 00105 locFirstPackBuff[11] = 'a'; 00106 locFirstPackBuff[12] = 'C'; 00107 00108 //debugLog<<"Copying in packet data"<<endl; 00109 memcpy((void*)(locFirstPackBuff + 13), (const void*) mOldHeaderList[1]->packetData(), 38); 00110 00111 mNewHeaderList.empty(); 00112 mNewHeaderList.clear(); 00113 //debugLog<<"Putting first header into new list"<<endl; 00114 mNewHeaderList.push_back(new OggPacket(locFirstPackBuff, 51, false, false)); 00115 locFirstPackBuff = NULL; 00116 00117 bool locFoundComment = false; 00118 int locCommentNo = -1; 00119 00120 //Start at 2, 0 is just fLaC, 1 is the stream info 00121 for (size_t i = 2; i < mOldHeaderList.size(); i++) { 00122 //Loop through to find the comment packet... 00123 //debugLog<<"Scanning old header "<<i<<endl; 00124 if ( ((mOldHeaderList[i]->packetData()[0]) & 127) == 4) { 00125 //It's the comment packet. 00126 //debugLog<<"Found a comment packet..."<<endl; 00127 locFoundComment = true; 00128 locCommentNo = (int)i; 00129 mNewHeaderList.push_back(mOldHeaderList[i]->clone()); 00130 } 00131 } 00132 00133 if (locFoundComment != true) { 00134 //debugLog<<"No comments present... FATALITY !"<<endl; 00135 //Maybe make one... for now bail out ! 00136 throw 0; 00137 } 00138 00139 for (size_t i = 2; i < mOldHeaderList.size(); i++) { 00140 00141 //**** WARNING ::: Leave this unless you check it ! 00142 if (i != locCommentNo) { 00143 //debugLog<<"Adding another ehader..."<<endl; 00144 //If it's not the comment packet we already added, put it in the list. 00145 mNewHeaderList.push_back(mOldHeaderList[i]->clone()); 00146 } 00147 } 00148 00149 for (size_t i = 1; i < mNewHeaderList.size(); i++) { 00150 //Loop through the new headers and make sure the flags are set right. 00151 if (i != mNewHeaderList.size() -1) { 00152 //Clear the first bit 00153 //debugLog<<"Clearing header bit "<<i<<endl; 00154 mNewHeaderList[i]->packetData()[0] = mNewHeaderList[i]->packetData()[0] & 127; 00155 } else { 00156 //debugLog<<"Setting header bit "<<i<<endl; 00157 //Set the first bit on the last header 00158 mNewHeaderList[i]->packetData()[0] = mNewHeaderList[i]->packetData()[0] | 128; 00159 } 00160 } 00161 00162 //debugLog<<"Deleting old headers..."<<endl; 00163 deleteOldHeaders(); 00164 00165 return true; 00166 00167 00168 } 00169 00170 void FLACHeaderTweaker::deleteOldHeaders() { 00171 size_t locSize = mOldHeaderList.size(); 00172 //debugLog<<"Num old headers... = "<<locSize<<endl; 00173 for (size_t i = 0; i < locSize; i++) { 00174 delete mOldHeaderList[i]; 00175 } 00176 //debugLog<<"Post old delete loop..."<<endl; 00177 mOldHeaderList.clear(); 00178 00179 } 00180 00181 void FLACHeaderTweaker::deleteNewHeaders() { 00182 size_t locSize = mNewHeaderList.size(); 00183 //debugLog<<"Num new headers... = "<<locSize<<endl; 00184 for (size_t i = 0; i < locSize; i++) { 00185 delete mNewHeaderList[i]; 00186 } 00187 //debugLog<<"Post new delete loop"<<endl; 00188 00189 mNewHeaderList.clear(); 00190 } 00191 00192 unsigned long FLACHeaderTweaker::numNewHeaders() { 00193 return (unsigned long)mNewHeaderList.size(); 00194 } 00195 OggPacket* FLACHeaderTweaker::getHeader(unsigned long inHeaderNo) { 00196 if (inHeaderNo < mNewHeaderList.size() ) { 00197 return mNewHeaderList[inHeaderNo]->clone(); 00198 } else { 00199 return NULL; 00200 } 00201 }