AnxPacketMaker.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Copyright (C) 2003, 2004 Commonwealth Scientific and Industrial Research
00005 //   Organisation (CSIRO) Australia
00006 //
00007 //Redistribution and use in source and binary forms, with or without
00008 //modification, are permitted provided that the following conditions
00009 //are met:
00010 //
00011 //- Redistributions of source code must retain the above copyright
00012 //  notice, this list of conditions and the following disclaimer.
00013 //
00014 //- Redistributions in binary form must reproduce the above copyright
00015 //  notice, this list of conditions and the following disclaimer in the
00016 //  documentation and/or other materials provided with the distribution.
00017 //
00018 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00019 //  may be used to endorse or promote products derived from this software 
00020 //  without specific prior written permission.
00021 //
00022 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00025 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00026 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00028 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 //===========================================================================
00034 #include "stdafx.h"
00035 #include ".\anxpacketmaker.h"
00036 
00037 
00038 
00039 AnxPacketMaker::AnxPacketMaker(void)
00040 {
00041 }
00042 
00043 AnxPacketMaker::~AnxPacketMaker(void)
00044 {
00045 }
00046 
00047 OggPage* AnxPacketMaker::makeAnnodexBOS_2_0     (                                       unsigned long inSerialNo
00048                                                                                                                 ,       unsigned short inVersionMajor
00049                                                                                                                 ,       unsigned short inVersionMinor
00050                                                                                                                 ,       unsigned __int64 inTimebaseNum
00051                                                                                                                 ,       unsigned __int64 inTimebaseDenom
00052                                                                                                                 ,       const unsigned char* inUTC
00053                                                                                                                 
00054                                                                                                         )
00055 {
00056         unsigned char* locBuff = NULL;
00057         StampedOggPacket* locPack = NULL;
00058         OggPage* retPage = NULL;
00059         unsigned char* locSegTable = NULL;
00060         switch (inVersionMajor) {
00061                 case 2:
00062                         locBuff = new unsigned char[ANX_2_0_ANNODEX_BOS_SIZE];
00063 
00064                         //      0       -       7               Annodex\0
00065                         //  8   -   9           Version Major
00066                         // 10   -  11           Version Minor
00067                         // 12   -  19           Timebase Num
00068                         // 20   -  27           Timebase Denom
00069                         // 28   =  48           UTC
00070                         locBuff[0] = 'A';
00071                         locBuff[1] = 'n';
00072                         locBuff[2] = 'n';
00073                         locBuff[3] = 'o';
00074                         locBuff[4] = 'd';
00075                         locBuff[5] = 'e';
00076                         locBuff[6] = 'x';
00077                         locBuff[7] = 0;
00078                         iLE_Math::UShortToCharArr(inVersionMajor, locBuff + 8);
00079                         iLE_Math::UShortToCharArr(inVersionMinor, locBuff + 10);
00080                         iLE_Math::Int64ToCharArr(inTimebaseNum, locBuff + 12);
00081                         iLE_Math::Int64ToCharArr(inTimebaseDenom, locBuff + 20);
00082                         for (int i = 0; i < 20; i++) {
00083                                 locBuff[28 + i] = inUTC[i];
00084                         }
00085                         
00086                         locPack = new StampedOggPacket(locBuff, ANX_2_0_ANNODEX_BOS_SIZE, false, false, 0, 0, StampedOggPacket::OGG_END_ONLY);
00087 
00088                         retPage = new OggPage;
00089                         retPage->header()->setHeaderFlags(2);
00090                         retPage->header()->setGranulePos((__int64)0);
00091                         retPage->header()->setNumPageSegments( 1);
00092                         locSegTable = new unsigned char[1];
00093                         locSegTable[0] = ANX_2_0_ANNODEX_BOS_SIZE;
00094                         retPage->header()->setSegmentTable(locSegTable, 1);
00095                         retPage->header()->setHeaderSize(28);
00096                         retPage->header()->setDataSize(ANX_2_0_ANNODEX_BOS_SIZE);
00097 
00098                         retPage->header()->setStreamSerialNo(inSerialNo);
00099                         retPage->addPacket(locPack);
00100 
00101                         setChecksum(retPage);
00102                         
00103                         return retPage;
00104 
00105                 default:
00106                         return NULL;
00107 
00108 
00109         }
00110 }
00111 
00112         //Checksum tables from libogg
00113 static unsigned long anx_crc_lookup[256]={
00114   0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
00115   0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
00116   0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
00117   0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
00118   0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
00119   0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
00120   0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
00121   0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
00122   0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
00123   0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
00124   0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
00125   0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
00126   0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
00127   0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
00128   0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
00129   0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
00130   0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
00131   0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
00132   0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
00133   0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
00134   0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
00135   0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
00136   0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
00137   0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
00138   0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
00139   0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
00140   0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
00141   0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
00142   0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
00143   0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
00144   0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
00145   0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
00146   0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
00147   0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
00148   0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
00149   0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
00150   0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
00151   0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
00152   0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
00153   0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
00154   0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
00155   0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
00156   0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
00157   0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
00158   0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
00159   0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
00160   0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
00161   0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
00162   0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
00163   0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
00164   0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
00165   0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
00166   0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
00167   0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
00168   0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
00169   0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
00170   0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
00171   0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
00172   0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
00173   0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
00174   0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
00175   0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
00176   0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
00177   0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4
00178 };
00179 
00180   //End libogg tables
00181 
00182 bool AnxPacketMaker::setChecksum(OggPage* inOggPage) 
00183 {
00184         unsigned long locChecksum = 0;
00185         unsigned long locTemp = 0;
00186 
00187         unsigned char* locHeaderBuff = new unsigned char[300];
00188         if (inOggPage != NULL) {
00189                 //Set the checksum to NULL for the checksumming process.
00190                 inOggPage->header()->setCRCChecksum((unsigned long)0);
00191                 inOggPage->header()->rawData(locHeaderBuff, 300);
00192 
00193                 for(unsigned long i = 0; i < inOggPage->headerSize(); i++) {
00194                         //Create the index we use for the lookup
00195                         locTemp = ((locChecksum >> 24) & 0xff) ^ locHeaderBuff[i];
00196                         //XOR the lookup value with the the current checksum shifted left 8 bits.
00197                         locChecksum=(locChecksum << 8) ^ anx_crc_lookup[locTemp];
00198                 }
00199 
00200 
00201 
00202                 unsigned char* locBuff = NULL;
00203                 for(unsigned long i = 0; i < inOggPage->numPackets(); i++) {
00204                         locBuff = inOggPage->getPacket(i)->packetData();                        //View only don't delete.
00205 
00206                         for (unsigned long j = 0; j < inOggPage->getPacket(i)->packetSize(); j++) {
00207                                 locTemp = ((locChecksum >> 24) & 0xff) ^ locBuff[j];
00208                 locChecksum = (locChecksum << 8) ^ anx_crc_lookup[locTemp];
00209                         }
00210                 }
00211 
00212                 inOggPage->header()->setCRCChecksum(locChecksum);
00213         }
00214 
00215         delete[] locHeaderBuff;
00216         return true;
00217 
00218 }
00219 
00220 StampedOggPacket* AnxPacketMaker::makeAnxData_2_0       (                       unsigned short inVersionMajor
00221                                                                                                                 ,       unsigned short inVersionMinor
00222                                                                                                                 ,       unsigned __int64 inGranuleRateNum
00223                                                                                                                 ,       unsigned __int64 inGranuleRateDenom
00224                                                                                                                 ,       unsigned long inNumSecHeaders
00225                                                                                                                 ,       vector<string> inMessageHeaders
00226                                                                                                 )
00227 {
00228 
00229         StampedOggPacket* locPack = NULL;
00230         //OggPage* retPage = NULL;
00231         unsigned char* locBuff = NULL;
00232         unsigned long locUpto = 0;
00233         unsigned long locPacketSize = 0;
00234         switch (inVersionMajor) {
00235                 case 2:
00236                         //ASSERT(inMessageHeaders.size() > 0)
00237                         //THere has to be a content type field.
00238 
00239                         locPacketSize = 28;  //Base header size
00240                         for (size_t i = 0; i < inMessageHeaders.size(); i++) {
00241                                 //2 is the crlf
00242                                 locPacketSize += (unsigned long)(inMessageHeaders[i].size() + 2);
00243                         }
00244 
00245                         //terminating crlf
00246                         //locPacketSize += 2;
00247 
00248                         locBuff = new unsigned char[locPacketSize];
00249 
00250                         locBuff[0] = 'A';
00251                         locBuff[1] = 'n';
00252                         locBuff[2] = 'x';
00253                         locBuff[3] = 'D';
00254                         locBuff[4] = 'a';
00255                         locBuff[5] = 't';
00256                         locBuff[6] = 'a';
00257                         locBuff[7] = 0;
00258 
00259                         iLE_Math::Int64ToCharArr(inGranuleRateNum, locBuff + 8);
00260                         iLE_Math::Int64ToCharArr(inGranuleRateDenom, locBuff + 16);
00261                         iLE_Math::ULongToCharArr(inNumSecHeaders, locBuff + 24);
00262                         locUpto = 28;
00263                         for (size_t i = 0; i < inMessageHeaders.size(); i++) {
00264                                 memcpy((void*)(locBuff + locUpto), (const void*)(inMessageHeaders[i].c_str()), inMessageHeaders[i].size());
00265                                 locUpto += (unsigned long)(inMessageHeaders[i].size());
00266                                 //TODO::: How terminated ??
00267                                 locBuff[locUpto++] = '\r';      
00268                                 locBuff[locUpto++] = '\n';
00269                         }
00270 
00271                         //locBuff[locUpto++] = '\r';
00272                         //locBuff[locUpto++] = '\n';
00273                         
00274                         locPack = new StampedOggPacket(locBuff, locPacketSize, false, false, 0, 0, StampedOggPacket::OGG_END_ONLY);
00275                         return locPack;
00276 
00277                         
00278 
00279 
00280                 default:
00281                         return NULL;
00282         }
00283 }
00284 
00285 //StampedOggPacket* AnxPacketMaker::makeAnxData_2_0 (OggMuxStream* inMuxStream, OggPaginator* inPaginator) 
00286 //{
00287 //      return makeAnxData_2_0(         2
00288 //                                                      ,       0
00289 //                                                      ,       inMuxStream->granuleNumerator()
00290 //                                                      ,       inMuxStream->granuleDenominator()
00291 //                                                      ,       inPaginator->numHeaders()
00292 //                                                      ,       makeMessageHeaders(inMuxStream));
00293 //}
00294 
00295 //StreamHeaders::eCodecType AnxPacketMaker::IdentifyCodec(OggPacket* inOggPacket) {
00296 //      if (strncmp((char*)inOggPacket->packetData(), "\001vorbis", 7) == 0) {
00297 //              return StreamHeaders::VORBIS;
00298 //      } else if (strncmp((char*)inOggPacket->packetData(), "Speex   ", 8) == 0) {
00299 //              return StreamHeaders::SPEEX;
00300 //      } else if ((strncmp((char*)inOggPacket->packetData(), "fLaC", 4)) == 0) {
00301 //              return StreamHeaders::FLAC;
00302 //      } else if ((strncmp((char*)inOggPacket->packetData(), "\177FLAC", 5)) == 0) {
00303 //              return StreamHeaders::OGG_FLAC_1_0;
00304 //      } else if ((strncmp((char*)inOggPacket->packetData(), "\200theora", 7)) == 0) {
00305 //              return StreamHeaders::THEORA;
00306 //      } else if ((strncmp((char*)inOggPacket->packetData(), "\001video\000\000\000", 9)) == 0) {
00307 //              return StreamHeaders::FFDSHOW_VIDEO;
00308 //      }
00309 //      
00310 //      return StreamHeaders::NONE;
00311 //      
00312 //}
00313 
00314 
00315 //vector<string> AnxPacketMaker::makeMessageHeaders(OggMuxStream* inMuxStream) {
00316 //      string locTempString = "";
00317 //      vector<string> retVector;
00318 //      switch(IdentifyCodec(inMuxStream->peekFront()->getPacket(0))) {
00319 //              case StreamHeaders::VORBIS:
00320 //                      locTempString = "Content-type: audio/x-vorbis";
00321 //                      retVector.push_back(locTempString);
00322 //                      break;
00323 //              case StreamHeaders::SPEEX:
00324 //                      locTempString = "Content-type: audio/x-speex";
00325 //                      retVector.push_back(locTempString);
00326 //                      break;
00327 //              case StreamHeaders::FLAC:
00328 //                      locTempString = "Content-type: audio/x-flac";
00329 //                      retVector.push_back(locTempString);
00330 //                      break;
00331 //              case StreamHeaders::OGG_FLAC_1_0:
00332 //                      locTempString = "Content-type: audio/x-flac_1_0";
00333 //                      retVector.push_back(locTempString);
00334 //                      break;
00335 //              case StreamHeaders::THEORA:
00336 //                      locTempString = "Content-type: video/x-theora";
00337 //                      retVector.push_back(locTempString);
00338 //                      break;
00339 //              case StreamHeaders::FFDSHOW_VIDEO:
00340 //                      locTempString = "Content-type: video/x-ogm";
00341 //                      retVector.push_back(locTempString);
00342 //                      break;
00343 //              case StreamHeaders::NONE:
00344 //              default:
00345 //                      break;
00346 //      }
00347 //
00348 //      return retVector;
00349 //}
00350 
00351 
00352 vector<string> AnxPacketMaker::makeMessageHeaders(StreamHeaders::eCodecType inCodecType) {
00353         string locTempString = "";
00354         vector<string> retVector;
00355         switch(inCodecType) {
00356                 case StreamHeaders::VORBIS:
00357                         locTempString = "Content-Type: audio/x-vorbis";
00358                         retVector.push_back(locTempString);
00359                         break;
00360                 case StreamHeaders::SPEEX:
00361                         locTempString = "Content-Type: audio/x-speex";
00362                         retVector.push_back(locTempString);
00363                         break;
00364                 case StreamHeaders::FLAC:
00365                         locTempString = "Content-Type: audio/x-flac";
00366                         retVector.push_back(locTempString);
00367                         break;
00368                 case StreamHeaders::OGG_FLAC_1_0:
00369                         locTempString = "Content-Type: audio/x-flac_1_0";
00370                         retVector.push_back(locTempString);
00371                         break;
00372                 case StreamHeaders::THEORA:
00373                         locTempString = "Content-Type: video/x-theora";
00374                         retVector.push_back(locTempString);
00375                         break;
00376                 case StreamHeaders::FFDSHOW_VIDEO:
00377                         locTempString = "Content-Type: video/x-ogm";
00378                         retVector.push_back(locTempString);
00379                         break;
00380                 case StreamHeaders::CMML:
00381                         locTempString = "Content-Type: text/x-cmml";
00382                         retVector.push_back(locTempString);
00383                         break;
00384                 case StreamHeaders::NONE:
00385                 default:
00386                         break;
00387         }
00388 
00389         return retVector;
00390 }

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