CMMLDump.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Copyright (C) 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 
00035 #include "stdafx.h"
00036 
00037 #include <libOOOgg/libOOOgg.h>
00038 #include <libOOOgg/dllstuff.h>
00039 #include <libCMMLTags/libCMMLTags.h>
00040 #include <libCMMLParse/libCMMLParse.h>
00041 #include <libCMMLParse/CMMLParser.h>
00042 
00043 #include <iostream>
00044 #include <fstream>
00045 
00046 #include <string.h>
00047 
00048 using namespace std;
00049 
00050 
00051 class OggDataBufferProcessor
00052         : public IOggCallback
00053 {
00054 public:
00055         OggDataBufferProcessor(void);
00056 
00057         enum eDemuxState {
00058                 SEEN_NOTHING,
00059                 SEEN_CMML_BOS,
00060                 INVALID = 100
00061         };
00062 
00063         eDemuxState mDemuxState;
00064 
00065         unsigned long mCMMLSerialNumber;
00066 
00067         virtual bool acceptOggPage(OggPage* inOggPage);
00068 };
00069 
00070 
00071 OggDataBufferProcessor::OggDataBufferProcessor (void)
00072         :       mDemuxState(SEEN_NOTHING)
00073         ,       mCMMLSerialNumber(0)
00074 {
00075 }
00076 
00077 bool OggDataBufferProcessor::acceptOggPage (OggPage* inOggPage)
00078 {
00079         switch (mDemuxState)
00080         {
00081                 case SEEN_NOTHING:
00082                 {
00083                         // Haven't seen anything yet: look for the CMML BOS page
00084 
00085                         if (            (inOggPage->numPackets() == 1)
00086                                         &&      (inOggPage->header()->isBOS())
00087                                         &&      (strncmp((char*)inOggPage->getPacket(0)->packetData(), "AnxData", 7) == 0)
00088 #ifdef WIN32
00089                                         &&  (  _strnicmp((char*) &(inOggPage->getPacket(0)->packetData()[28]), "Content-type: text/x-cmml", 25) == 0)   ) {
00090 #else  /* assume POSIX */
00091                                         &&  (strncasecmp((char*) &(inOggPage->getPacket(0)->packetData()[28]), "Content-type: text/x-cmml", 25) == 0)   ) {
00092 #endif
00093                                 // We've hit a BOS page: advance the state and remember the serial number
00094                                 
00095                                 mDemuxState = SEEN_CMML_BOS;
00096 
00097                                 mCMMLSerialNumber = inOggPage->header()->StreamSerialNo();
00098                         }
00099 
00100                         break;
00101                 }
00102                 case SEEN_CMML_BOS:
00103                 {
00104                         // We've seen the CMML BOS now, so every CMML page after this one (including the secondary
00105                         // header) will be CMML data.
00106 
00107                         if (inOggPage->header()->StreamSerialNo() == mCMMLSerialNumber) {
00108                                 unsigned long locPackets = inOggPage->numPackets();
00109 
00110                                 for (unsigned long i = 0; i < locPackets; i++) {
00111                                         OggPacket *locPacket = inOggPage->getPacket(i);
00112 
00113                                         unsigned long locPacketSize = locPacket->packetSize();
00114                                         char *locPacketData = (char *) inOggPage->getPacket(i)->packetData();
00115 
00116                                         // Add a terminating '\0'
00117                                         char *locMyPacketData = new char[locPacketSize + 1];
00118                                         (void) memcpy(locMyPacketData, locPacketData, locPacketSize);
00119                                         locMyPacketData[locPacketSize] = '\0';
00120 
00121                                         // Get the packet's time in seconds
00122                                         LOOG_INT64 locPacketGranulePos = inOggPage->header()->GranulePos();
00123                                         float locPacketStartTimeInSeconds = (float) locPacketGranulePos/ (float) 1000;
00124 
00125                                         // Let's make the CMML parsing library decide whether it's a <head>
00126                                         // or <clip> tag -- after all, that's what it's there for :)
00127                                         
00128                                         wstring locPacketDataWString = StringHelper::toWStr(locMyPacketData);
00129 
00130                                         CMMLParser locCMMLParser;
00131                                         C_CMMLTag *locCMMLTag = NULL;
00132 
00133                                         // Try parsing it as a <head> tag
00134                                         C_HeadTag *locHeadTag = new C_HeadTag;
00135                                         bool locDidParseHead = 
00136                                                 locCMMLParser.parseHeadTag(locPacketDataWString, locHeadTag);
00137                                         if (locDidParseHead) {
00138                                                 locCMMLTag = locHeadTag;
00139                                         }
00140 
00141                                         // Try parsing it as a <clip> tag
00142                                         C_ClipTag *locClipTag = new C_ClipTag;
00143                                         bool locDidParseClip = 
00144                                                 locCMMLParser.parseClipTag(locPacketDataWString, locClipTag);
00145                                         if (locDidParseClip) {
00146                                                 // Only succeed if parsing it as a <head> tag didn't work
00147                                                 if (!locDidParseHead) {
00148                                                         locCMMLTag = locClipTag;
00149                                                 } else {
00150                                                         cout << "Parsed successfully as both a <clip> and <head>:" << endl;
00151                                                         wcout << locPacketDataWString << endl;
00152                                                 }
00153                                         }
00154 
00155                                         if (locCMMLTag == NULL) {
00156                                                 cout << "Couldn't parse as either <clip> or <head>:" << endl;
00157                                                 wcout << locPacketDataWString << endl;
00158                                         }
00159 
00160                                         if (locDidParseClip) {
00161                                                 cout << locPacketStartTimeInSeconds << " seconds:" << endl;
00162                                         }
00163                                         wcout << locCMMLTag->toString() << endl;
00164 
00165                                         delete locCMMLTag;
00166                                         delete locMyPacketData;
00167                                 }
00168                         }
00169 
00170                         break;
00171                 }
00172         }
00173 
00174         delete inOggPage;
00175 
00176         return true;
00177 }
00178 
00179 
00180 #ifdef WIN32
00181 int __cdecl _tmain(int argc, _TCHAR* argv[])
00182 #else
00183 int main(int argc, char * argv[])
00184 #endif
00185 {
00186         if (argc < 2) {
00187                 cout << "Usage: " << argv[0] << " <input_filename>" << endl;
00188                 return 1;
00189         }
00190 
00191         // Somebody set us up the bomb
00192 
00193         OggDataBuffer locDataBuffer;
00194 
00195         OggDataBufferProcessor *locDataBufferProcessor;
00196         locDataBufferProcessor = new OggDataBufferProcessor;
00197         locDataBuffer.registerVirtualCallback(locDataBufferProcessor);
00198 
00199         fstream locInputFile;
00200 
00201         // Let's go!
00202 
00203         const unsigned short BUFF_SIZE = 8092;
00204         char* locBuff = new char[BUFF_SIZE];
00205         
00206         locInputFile.open(argv[1], ios_base::in | ios_base::binary);
00207         for (;;) {
00208                 locInputFile.read(locBuff, BUFF_SIZE);
00209                 unsigned long locBytesRead = locInputFile.gcount();
00210                 if (locBytesRead <= 0) {
00211                         break;
00212                 }
00213         locDataBuffer.feed((const unsigned char*)locBuff, locBytesRead);
00214         }
00215 
00216         // Tidy up
00217 
00218         locInputFile.close();
00219 
00220         delete locDataBufferProcessor;
00221 
00222         return 0;
00223 }
00224 

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