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                                         wcout << locCMMLTag->toString() << endl;
00161 
00162                                         delete locCMMLTag;
00163                                         delete locMyPacketData;
00164                                 }
00165                         }
00166 
00167                         break;
00168                 }
00169         }
00170 
00171         delete inOggPage;
00172 
00173         return true;
00174 }
00175 
00176 
00177 #ifdef WIN32
00178 int __cdecl _tmain(int argc, _TCHAR* argv[])
00179 #else
00180 int main(int argc, char * argv[])
00181 #endif
00182 {
00183         if (argc < 2) {
00184                 cout << "Usage: " << argv[0] << " <input_filename>" << endl;
00185                 return 1;
00186         }
00187 
00188         // Somebody set us up the bomb
00189 
00190         OggDataBuffer locDataBuffer;
00191 
00192         OggDataBufferProcessor *locDataBufferProcessor;
00193         locDataBufferProcessor = new OggDataBufferProcessor;
00194         locDataBuffer.registerVirtualCallback(locDataBufferProcessor);
00195 
00196         fstream locInputFile;
00197 
00198         // Output XML preabmel
00199         cout << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" << endl;
00200         cout << "<!DOCTYPE cmml SYSTEM \"cmml.dtd\">" << endl;
00201 
00202         // Let's go!
00203 
00204         const unsigned short BUFF_SIZE = 8092;
00205         char* locBuff = new char[BUFF_SIZE];
00206         
00207         locInputFile.open(argv[1], ios_base::in | ios_base::binary);
00208         for (;;) {
00209                 locInputFile.read(locBuff, BUFF_SIZE);
00210                 unsigned long locBytesRead = locInputFile.gcount();
00211                 if (locBytesRead <= 0) {
00212                         break;
00213                 }
00214         locDataBuffer.feed((const unsigned char*)locBuff, locBytesRead);
00215         }
00216 
00217         // Tidy up
00218 
00219         locInputFile.close();
00220 
00221         delete locDataBufferProcessor;
00222 
00223         return 0;
00224 }
00225 

Generated on Thu Feb 16 23:48:19 2006 for oggdsf by  doxygen 1.3.9