CMMLRecomposer.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2005 Zentaro Kavanagh
00003 //Copyright (C) 2005 Commonwealth Scientific and Industrial Research
00004 //                   Organisation (CSIRO) Australia
00005 //
00006 //Redistribution and use in source and binary forms, with or without
00007 //modification, are permitted provided that the following conditions
00008 //are met:
00009 //
00010 //- Redistributions of source code must retain the above copyright
00011 //  notice, this list of conditions and the following disclaimer.
00012 //
00013 //- Redistributions in binary form must reproduce the above copyright
00014 //  notice, this list of conditions and the following disclaimer in the
00015 //  documentation and/or other materials provided with the distribution.
00016 //
00017 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00018 //  may be used to endorse or promote products derived from this software 
00019 //  without specific prior written permission.
00020 //
00021 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00024 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00025 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00026 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00027 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //===========================================================================
00033 
00034 
00035 #include "stdafx.h"
00036 
00037 #include <libOOOggChef/AnnodexRecomposer.h>
00038 #include <libOOOggChef/CMMLRecomposer.h>
00039 #include <libOOOggChef/utils.h>
00040 
00041 #include <libilliCore/StringHelper.h>
00042 #include <libOOOgg/libOOOgg.h>
00043 #include <libCMMLTags/libCMMLTags.h>
00044 #include <libTemporalURI/C_TimeStamp.h>
00045 #include <libCMMLParse/CMMLParser.h>
00046 #include <libCMMLParse/CMMLTagUtils.h>
00047 
00048 #include <fstream>
00049 #include <iostream>
00050 #include <string>
00051 #include <vector>
00052 
00053 using namespace std;
00054 
00055 #undef DEBUG
00056 
00057 CMMLRecomposer::CMMLRecomposer(string inFilename, BufferWriter inBufferWriter, void* inBufferWriterUserData)
00058         :       mCMMLFilename(inFilename)
00059         ,       mBufferWriter(inBufferWriter)
00060         ,       mBufferWriterUserData(inBufferWriterUserData)
00061 {
00062 }
00063 
00064 
00065 CMMLRecomposer::~CMMLRecomposer(void)
00066 {
00067 }
00068 
00069         
00070 bool CMMLRecomposer::recomposeStreamFrom(double inStartingTimeOffset, const vector<string>* inWantedMIMETypes)
00071 {
00072         // If the only wants just zee basic CMML, well, just serve out the CMML
00073         if (wantOnlyCMML(inWantedMIMETypes) && inStartingTimeOffset == 0) {
00074                 sendFile(mCMMLFilename, mBufferWriter, mBufferWriterUserData);
00075                 return true;
00076         }
00077 
00078 #ifdef DEBUG
00079         mDebugFile.open("G:\\Logs\\CMMLRecomposer.log", ios_base::out);
00080         mDebugFile << "CMMLRecomposer 1 " << endl;
00081 #endif
00082 
00083         // Parse in the CMML into a C_CMMLDoc class
00084         C_CMMLDoc *locCMML = new C_CMMLDoc;
00085         CMMLParser locCMMLParser;
00086         locCMMLParser.parseDocFromFile(StringHelper::toWStr(mCMMLFilename), locCMML);
00087 
00088         // We assume that CMML recomposition fails unless explicitly set otherwise
00089         bool locReturnValue = false;
00090 
00091         // We need to declare and initialise all our variables here, because
00092         // in the presence of errors, we may be deleting variables which haven't
00093         // been initialised yet ...
00094         C_CMMLRootTag *locCMMLRoot = NULL;
00095         C_StreamTag *locStream = NULL;
00096 
00097         if (locCMML == NULL) {
00098                 goto cleanup;
00099         }
00100 
00101         // No matter what the output type is, we always have to read & parse the stream
00102         // and head tags anyway, so do that now
00103 
00104         // If we don't have a root tag at all, we're pretty screwed: fail with prejudice
00105         locCMMLRoot = locCMML->root();
00106         if (locCMMLRoot == NULL) {
00107                 goto cleanup;
00108         }
00109 
00110         // It's not catastrophic if we don't have <stream>, <head>, or even <clip> tags
00111         locStream = locCMMLRoot->stream();
00112 #if 0
00113         C_HeadTag *locHead = locCMMLRoot->head();
00114         C_ClipTagList *locClipList = locCMMLRoot->clipList();
00115 #endif
00116 
00117         // If our final output type is CMML, we deal with it (otherwise we hand off the
00118         // recomposition to AnnodexRecomposer -- see below)
00119 
00120         // XXX: Checking for * / * is a pretty dodgy hack ...
00121         if (wantOnlyCMML(inWantedMIMETypes) || inWantedMIMETypes->at(0) == "*/*") {
00122                 C_CMMLDoc* locCMMLDoc = locCMML->clone();
00123 
00124                 // If the clip list exists ...
00125                 if (locCMMLDoc && locCMMLDoc->root() && locCMMLDoc->root()->clipList()) {
00126                         // ... we need to replace it with only the clips during or after
00127                         // the user's requested time
00128 
00129 #ifdef DEBUG
00130                         mDebugFile << "Got here 1" << endl;
00131 #endif
00132 
00133                         // Convert the requested time from a double to an int64
00134                         C_TimeStamp locTimeStamp;
00135                         locTimeStamp.parseTimeStamp(inStartingTimeOffset);
00136                         LOOG_INT64 locTime = locTimeStamp.toHunNanos();
00137 
00138 #ifdef DEBUG
00139                         mDebugFile << "locTime: " << locTime << endl;
00140 #endif
00141 
00142                         // Get the clip tags during or after the wanted time
00143                         C_ClipTagList *locRequestedClips =
00144                                 CMMLTagUtils::getClipsFrom(locCMMLDoc->root()->clipList(), locTime);
00145 
00146                         // Replace the clip list in our new CMML document.  We don't need to
00147                         // delete the old clip list before doing this, since the setClipList()
00148                         // method takes care of that for us.
00149                         locCMMLDoc->root()->setClipList(locRequestedClips);
00150                 }
00151 
00152                 // Pump out the newly created CMML document
00153                 string locCMMLDocString =
00154                         StringHelper::toNarrowStr(locCMMLDoc->toString());
00155                 mBufferWriter((unsigned char *) locCMMLDocString.c_str(),
00156                         (unsigned long) locCMMLDocString.size(), mBufferWriterUserData);
00157 
00158                 // Indicate success to our callee
00159                 locReturnValue = true;
00160         } else {
00161                 // The user didn't want CMML, i.e. they'll be wanting media.  We scan the
00162                 // CMML file for the <stream> tag, to see if it imports any media -- if it
00163                 // does, we'll have to figure out what MIME types the media files are (and
00164                 // perhaps mux them) so that the the user gets it in the form they want.
00165                 //
00166                 // e.g. if the user requests an application/x-annodex file, the CMML
00167                 // <stream> tag has an import expression pointing to a Vorbis file, and
00168                 // another import expression pointing to a Theora file, we need to mux
00169                 // those two files together, add an empty CMML track (so it's a valid
00170                 // Annodex file), and then send that to the user -- possibly only from
00171                 // a particular time offset.  Fun!
00172 
00173 
00174         }
00175 
00176 #if 0
00177         C_ImportTagList *locImportTagList = locStream->importList();
00178         if (locImportTagList == NULL) {
00179                 goto cleanup;
00180         }
00181 #endif
00182 
00183 cleanup:
00184         if (locCMML) {
00185                 delete locCMML;
00186                 locCMML = NULL;
00187         }
00188 
00189 #ifdef DEBUG
00190         mDebugFile.close();
00191 #endif
00192 
00193         return locReturnValue;
00194 }
00195 
00196 
00197 bool CMMLRecomposer::acceptOggPage(OggPage*)
00198 {
00199         return true;
00200 }
00201 

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