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
00036
00037
00038 #include "stdafx.h"
00039 #include <libOOOgg/libOOOgg.h>
00040 #include <libOOOgg/dllstuff.h>
00041 #include <libOOOggSeek/AutoAnxSeekTable.h>
00042
00043 #include <iostream>
00044 #include <fstream>
00045
00046 typedef pair<unsigned long, unsigned long> tSerial_HeadCountPair;
00047
00048 unsigned long bytePos;
00049
00050 bool gotAllHeaders;
00051
00052 fstream outputFile;
00053 vector<tSerial_HeadCountPair> theStreams;
00054
00055 using namespace std;
00056
00057 enum eDemuxState {
00058 SEEN_NOTHING,
00059 SEEN_ANNODEX_BOS,
00060 SEEN_ANNODEX_EOS,
00061 SEEN_ALL_CODEC_HEADERS,
00062 INVALID = 100
00063 };
00064
00065 eDemuxState demuxState;
00066
00067 unsigned long annodexSerialNo;
00068
00069 bool writePageToOutputFile(OggPage* inOggPage) {
00070 outputFile.write((char*)inOggPage->createRawPageData(), inOggPage->pageSize());
00071 return true;
00072 }
00073
00074 unsigned long headerCount(OggPacket* inPacket) {
00075 const unsigned short NUM_SEC_HEADERS_OFFSET = 24;
00076 return iLE_Math::charArrToULong(inPacket->packetData() + NUM_SEC_HEADERS_OFFSET);
00077
00078 }
00079
00080 bool pageCB(OggPage* inOggPage, void* ) {
00081
00082 bool allEmpty = true;
00083
00084 switch (demuxState) {
00085
00086 case SEEN_NOTHING:
00087 if ( (inOggPage->numPackets() == 1)
00088 && (inOggPage->header()->isBOS())
00089 && (strncmp((char*)inOggPage->getPacket(0)->packetData(), "Annodex\0", 8) == 0)) {
00090
00091
00092 demuxState = SEEN_ANNODEX_BOS;
00093
00094
00095 annodexSerialNo = inOggPage->header()->StreamSerialNo();
00096
00097
00098 writePageToOutputFile(inOggPage);
00099 } else {
00100
00101 demuxState = INVALID;
00102 }
00103
00104 break;
00105 case SEEN_ANNODEX_BOS:
00106 if ( (inOggPage->numPackets() == 1)
00107 && (inOggPage->header()->isBOS())
00108 && (strncmp((char*)inOggPage->getPacket(0)->packetData(), "AnxData\0", 8) == 0)) {
00109
00110
00111
00112 tSerial_HeadCountPair locMap;
00113 locMap.first = inOggPage->header()->StreamSerialNo();
00114 locMap.second = headerCount(inOggPage->getPacket(0));
00115
00116
00117 theStreams.push_back(locMap);
00118
00119
00120 writePageToOutputFile(inOggPage);
00121 } else if ( (inOggPage->header()->isEOS())
00122 && (inOggPage->header()->StreamSerialNo() == annodexSerialNo)) {
00123
00124
00125 demuxState = SEEN_ANNODEX_EOS;
00126 writePageToOutputFile(inOggPage);
00127 } else {
00128 demuxState = INVALID;
00129 }
00130 break;
00131 case SEEN_ANNODEX_EOS:
00132 for (unsigned int i = 0; i < theStreams.size(); i++) {
00133 if (theStreams[i].first == inOggPage->header()->StreamSerialNo()) {
00134 if (theStreams[i].second >= 1) {
00135 theStreams[i].second--;
00136 writePageToOutputFile(inOggPage);
00137 } else {
00138 demuxState = INVALID;
00139 }
00140 }
00141 }
00142
00143
00144 for (unsigned int i = 0; i < theStreams.size(); i++) {
00145 if (theStreams[i].second != 0) {
00146 allEmpty = false;
00147 }
00148 }
00149
00150 if (allEmpty) {
00151
00152 demuxState = SEEN_ALL_CODEC_HEADERS;
00153 }
00154 break;
00155 case SEEN_ALL_CODEC_HEADERS:
00156 {
00157
00158 unsigned long packetsInThisPage = inOggPage->numPackets();
00159 for (unsigned long i = 0; i < packetsInThisPage; i++)
00160 {
00161 StampedOggPacket *packet = inOggPage->getStampedPacket(i);
00162 cout << "Packet " << i << " start time: " << packet->startTime() << endl;
00163 }
00164 break;
00165 }
00166 case INVALID:
00167 break;
00168 default:
00169 break;
00170 }
00171
00172
00173 if (demuxState == INVALID) {
00174 cout << "Invalid file. Broken = very yes."<<endl;
00175 }
00176 delete inOggPage;
00177
00178 return true;
00179 }
00180
00181 #ifdef WIN32
00182 int __cdecl _tmain(int argc, _TCHAR* argv[])
00183 #else
00184 int main(int argc, char * argv[])
00185 #endif
00186 {
00187 demuxState = SEEN_NOTHING;
00188
00189 bytePos = 0;
00190 gotAllHeaders = false;
00191
00192 if (argc < 4) {
00193 cout << "Usage : AnxCutter <input_filename> <output_filename> <start_time>" << endl;
00194 } else {
00195 OggDataBuffer testOggBuff;
00196
00197 testOggBuff.registerStaticCallback(&pageCB, NULL);
00198
00199 fstream inputFile;
00200
00201 inputFile.open(argv[1], ios_base::in | ios_base::binary);
00202 outputFile.open(argv[2], ios_base::out | ios_base::binary);
00203
00204 const unsigned short BUFF_SIZE = 8092;
00205 char* locBuff = new char[BUFF_SIZE];
00206 while (demuxState < SEEN_ALL_CODEC_HEADERS) {
00207 inputFile.read(locBuff, BUFF_SIZE);
00208 unsigned long locBytesRead = inputFile.gcount();
00209 testOggBuff.feed((const unsigned char*)locBuff, locBytesRead);
00210 }
00211 inputFile.close();
00212
00213
00214 AutoAnxSeekTable *locSeekTable = new AutoAnxSeekTable(argv[1]);
00215 locSeekTable->buildTable();
00216
00217
00218 LOOG_UINT64 locStartTime = StringHelper::stringToNum(argv[3]);
00219 OggSeekTable::tSeekPair locSeekResult = locSeekTable->getStartPos(locStartTime);
00220 cout << "Seek result for " << locStartTime << " * 100 nanoseconds: " << locSeekResult.first << " at " << locSeekResult.second << " bytes" << endl;
00221
00222
00223 inputFile.open(argv[1], ios_base::in | ios_base::binary);
00224 inputFile.seekg(locSeekResult.second);
00225 for (;;)
00226 {
00227 inputFile.read(locBuff, BUFF_SIZE);
00228 unsigned long locBytesRead = inputFile.gcount();
00229 if (locBytesRead == 0) break;
00230 outputFile.write(locBuff, locBytesRead);
00231 }
00232
00233 outputFile.close();
00234
00235 delete[] locBuff;
00236 }
00237
00238 return 0;
00239 }
00240