00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "stdafx.h"
00036 #include <libOOOgg/libOOOgg.h>
00037 #include <libOOOgg/dllstuff.h>
00038 #include <libilliCore/iBE_Math.h>
00039 #include <libilliCore/iLE_Math.h>
00040
00041 #include "OggFileWriter.h"
00042 #include <iostream>
00043 #include <fstream>
00044
00045 unsigned long bytePos;
00046
00047 OggPageInterleaver* interleaver;
00048
00049 OggFileWriter* fileWriter;
00050
00051 OggPage* pendingPage = NULL;
00052 OggMuxStream* pendingStream = NULL;
00053 bool isFirstPage = true;
00054 bool hasPageWaiting = false;
00055
00056 unsigned long granFixCount = 0;
00057
00058 struct sStreamInfo {
00059 unsigned long mSerialNo;
00060 unsigned long mUptoSeqNo;
00061 OggMuxStream* mMuxStream;
00062
00063 };
00064
00065 vector<sStreamInfo*> streamList;
00066
00067
00068 bool fixifyPage(OggPage* inOggPage, sStreamInfo* inStreamInfo)
00069 {
00070
00071 if (inOggPage->numPackets() == 1) {
00072 if ((inOggPage->getPacket(0)->isTruncated()) && (inStreamInfo->mUptoSeqNo < inStreamInfo->mMuxStream->numHeaders())) {
00073
00074 inOggPage->header()->setGranulePos(-1);
00075 }
00076 }
00077
00078
00079 inOggPage->header()->setPageSequenceNo(inStreamInfo->mUptoSeqNo++);
00080
00081
00082 inOggPage->computeAndSetCRCChecksum();
00083
00084 return true;
00085 }
00086
00087
00088 bool setMuxState(OggPage* inOggPage, OggMuxStream* inMuxStream)
00089 {
00090 if (strncmp((const char*)inOggPage->getPacket(0)->packetData(), "\001vorbis", 7) == 0) {
00091 inMuxStream->setConversionParams(iLE_Math::charArrToULong(inOggPage->getPacket(0)->packetData() + 12), 1, 10000000);
00092 inMuxStream->setNumHeaders(3);
00093 return true;
00094 } else if ((strncmp((char*)inOggPage->getPacket(0)->packetData(), "\200theora", 7)) == 0){
00095
00096 inMuxStream->setConversionParams(
00097 iBE_Math::charArrToULong(inOggPage->getPacket(0)->packetData() + 22)
00098 , iBE_Math::charArrToULong(inOggPage->getPacket(0)->packetData() + 26)
00099 , 10000000
00100 , (((inOggPage->getPacket(0)->packetData()[40]) % 4) << 3) + ((inOggPage->getPacket(0)->packetData()[41]) >> 5));
00101 inMuxStream->setNumHeaders(3);
00102 return true;
00103 } else {
00104 return false;
00105 }
00106
00107 }
00108
00109
00110 bool pageCB(OggPage* inOggPage, void* )
00111 {
00112 sStreamInfo* locCurrentInfo = NULL;
00113 if (inOggPage->header()->isBOS()) {
00114 sStreamInfo* locStreamInfo = new sStreamInfo;
00115 locStreamInfo->mSerialNo = inOggPage->header()->StreamSerialNo();
00116 locStreamInfo->mUptoSeqNo = 0;
00117 locStreamInfo->mMuxStream = interleaver->newStream();
00118 locStreamInfo->mMuxStream->setIsActive(true);
00119 streamList.push_back(locStreamInfo);
00120
00121 if (!setMuxState(inOggPage, locStreamInfo->mMuxStream)) {
00122 cout<<"Only handles theora and vorbis... ABORT ABORT ABORT!!"<<endl;
00123 throw 0;
00124 }
00125
00126 locCurrentInfo = locStreamInfo;
00127
00128
00129 } else {
00130 for (size_t i = 0; i < streamList.size(); i++) {
00131 if (streamList[i]->mSerialNo == inOggPage->header()->StreamSerialNo()) {
00132 locCurrentInfo = streamList[i];
00133 break;
00134 }
00135 }
00136 }
00137
00138 if (locCurrentInfo == NULL) {
00139 throw 0;
00140 }
00141
00142 fixifyPage(inOggPage, locCurrentInfo);
00143
00144
00145
00146 if (isFirstPage) {
00147 if (strncmp((const char*)inOggPage->getPacket(0)->packetData(), "\001vorbis", 7) == 0) {
00148
00149
00150
00151 pendingPage = inOggPage;
00152 pendingStream = locCurrentInfo->mMuxStream;
00153 isFirstPage = false;
00154 hasPageWaiting = true;
00155 }
00156 } else {
00157 if (hasPageWaiting) {
00158 if ((strncmp((char*)inOggPage->getPacket(0)->packetData(), "\200theora", 7)) == 0) {
00159
00160 locCurrentInfo->mMuxStream->acceptOggPage(inOggPage);
00161 pendingStream->acceptOggPage(pendingPage);
00162 } else {
00163
00164 pendingStream->acceptOggPage(pendingPage);
00165 locCurrentInfo->mMuxStream->acceptOggPage(inOggPage);
00166 }
00167
00168 hasPageWaiting = false;
00169 pendingPage = NULL;
00170 } else {
00171 locCurrentInfo->mMuxStream->acceptOggPage(inOggPage);
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 return true;
00201 }
00202
00203
00204 #ifdef WIN32
00205 int __cdecl _tmain(int argc, _TCHAR* argv[])
00206 #else
00207 int main (int argc, char * argv[])
00208 #endif
00209 {
00210
00211
00212
00213
00214
00215
00216 bytePos = 0;
00217
00218 if (argc < 3) {
00219 cout<<"Usage : OOOggDump <filename>"<<endl;
00220 } else {
00221
00222 int x;
00223 cin>>x;
00224
00225 string locOutFilename = argv[2];
00226 fileWriter = new OggFileWriter(locOutFilename);
00227 interleaver = new OggPageInterleaver(fileWriter, fileWriter);
00228
00229 OggDataBuffer testOggBuff;
00230
00231
00232
00233 testOggBuff.registerStaticCallback(&pageCB, NULL);
00234
00235 fstream testFile;
00236 testFile.open(argv[1], ios_base::in | ios_base::binary);
00237
00238 const unsigned short BUFF_SIZE = 8092;
00239 char* locBuff = new char[BUFF_SIZE];
00240 while (!testFile.eof()) {
00241 testFile.read(locBuff, BUFF_SIZE);
00242 unsigned long locBytesRead = testFile.gcount();
00243 testOggBuff.feed((const unsigned char*)locBuff, locBytesRead);
00244 }
00245
00246 delete[] locBuff;
00247
00248 delete interleaver;
00249 delete fileWriter;
00250
00251 }
00252
00253 return 0;
00254 }
00255