CMMLDecodeFilter.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 
00035 #include "stdafx.h"
00036 
00037 #include "cmmldecodefilter.h"
00038 
00039 //COM Factory Template
00040 CFactoryTemplate g_Templates[] = 
00041 {
00042     { 
00043                 L"CMML Decode Filter",                                  // Name
00044             &CLSID_CMMLDecodeFilter,                            // CLSID
00045             CMMLDecodeFilter::CreateInstance,           // Method to create an instance of Speex Decoder
00046         NULL,                                                                   // Initialization function
00047         NULL                                                                    // Set-up information (for filters)
00048     }
00049 
00050 };
00051 
00052 // Generic way of determining the number of items in the template
00053 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
00054 
00055 //-----------------------------------------------------------
00056 CMMLDecodeFilter::CMMLDecodeFilter(void)
00057         :       CTransformFilter(NAME("CMML Decoder"), NULL, CLSID_CMMLDecodeFilter)
00058         
00059         ,       mCMMLParser(NULL)
00060         ,       mSeenHead(false)
00061         ,       mHeadTag(NULL)
00062         ,       mCMMLCallbacks(NULL)
00063 {
00064         //debugLog.open("G:\\logs\\cmml_decode.logs", ios_base::out);
00065                 mCMMLParser = new CMMLParser;
00066         //debugLog.open("C:\\Temp\\cmmlfilter.log", ios_base::out);
00067         //debugLog<<"*** Log Begins ***"<<endl;
00068 }
00069 
00070 CMMLDecodeFilter::~CMMLDecodeFilter(void)
00071 {
00072         //debugLog<<"*** Log Ends ***"<<endl;
00073         //debugLog.close();
00074         delete mCMMLParser;
00075 }
00076 
00077 CUnknown* WINAPI CMMLDecodeFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00078 {
00079         //This routine is the COM implementation to create a new Filter
00080         CMMLDecodeFilter *pNewObject = new CMMLDecodeFilter();
00081     if (pNewObject == NULL) {
00082         *pHr = E_OUTOFMEMORY;
00083     }
00084         return pNewObject;
00085 } 
00086 
00087 STDMETHODIMP CMMLDecodeFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00088         if (riid == IID_ICMMLAppControl) {
00089                 *ppv = (ICMMLAppControl*)this;
00090                 ((IUnknown*)*ppv)->AddRef();
00091                 return NOERROR;
00092         }
00093 
00094         return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
00095 }
00096 
00097 HRESULT CMMLDecodeFilter::CheckInputType(const CMediaType* inInputMediaType) {
00098         if (    (inInputMediaType->majortype == MEDIATYPE_Text) &&
00099                         (inInputMediaType->subtype == MEDIASUBTYPE_CMML) &&
00100                         (inInputMediaType->formattype == FORMAT_CMML) ){
00101 
00102                 //debugLog<<"Input Type Accepted"<<endl;
00103                 return S_OK;
00104         } else {
00105                 return VFW_E_TYPE_NOT_ACCEPTED;
00106         }
00107 }
00108 HRESULT CMMLDecodeFilter::CheckTransform(const CMediaType* inInputMediaType, const CMediaType* inOutputMediaType) {
00109         if (    (inInputMediaType->majortype == MEDIATYPE_Text) &&
00110                         (inInputMediaType->subtype == MEDIASUBTYPE_CMML) &&
00111                         (inInputMediaType->formattype == FORMAT_CMML) &&
00112                         (inOutputMediaType->majortype == MEDIATYPE_Text) &&
00113                         (inOutputMediaType->subtype == MEDIASUBTYPE_SubtitleVMR9) ){
00114 
00115                 //debugLog << "Transform Accepted"<<endl;
00116                 return S_OK;
00117         } else {
00118                 return VFW_E_TYPE_NOT_ACCEPTED;
00119         }
00120         
00121 }
00122 HRESULT CMMLDecodeFilter::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest) {
00123         //FIX::: Abstract this out properly     
00124 
00125         HRESULT locHR = S_OK;
00126 
00127         ALLOCATOR_PROPERTIES locReqAlloc;
00128         ALLOCATOR_PROPERTIES locActualAlloc;
00129 
00130         const unsigned long MIN_BUFFER_SIZE = 1024;                     
00131         const unsigned long DEFAULT_BUFFER_SIZE = 4096;
00132         const unsigned long MIN_NUM_BUFFERS = 10;
00133         const unsigned long DEFAULT_NUM_BUFFERS = 15;
00134 
00135         
00136         
00137         
00138         if (inPropertyRequest->cbAlign <= 0) {
00139                 locReqAlloc.cbAlign = 1;
00140         } else {
00141                 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00142         }
00143 
00144         
00145         if (inPropertyRequest->cbBuffer < MIN_BUFFER_SIZE) {
00146                 locReqAlloc.cbBuffer = DEFAULT_BUFFER_SIZE;
00147         } else {
00148                 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00149         }
00150 
00151         
00152         if (inPropertyRequest->cbPrefix < 0) {
00153                         locReqAlloc.cbPrefix = 0;
00154         } else {
00155                 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00156         }
00157 
00158         
00159         if (inPropertyRequest->cBuffers < MIN_NUM_BUFFERS) {
00160                 locReqAlloc.cBuffers = DEFAULT_NUM_BUFFERS;
00161         } else {
00162                 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00163         }
00164 
00165         
00166         locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00167 
00168         if (locHR != S_OK) {
00169                 return locHR;
00170         }
00171         
00172         locHR = inAllocator->Commit();
00173 
00174         return locHR;
00175 }
00176 HRESULT CMMLDecodeFilter::GetMediaType(int inPosition, CMediaType* outMediaType) {
00177         if (inPosition < 0) {
00178                 return E_INVALIDARG;
00179         } else if (inPosition == 0) {
00180                 outMediaType->majortype = MEDIATYPE_Text;
00181                 outMediaType->subtype = MEDIASUBTYPE_SubtitleVMR9;
00182                 return S_OK;
00183         } else {
00184                 return VFW_S_NO_MORE_ITEMS;
00185         }
00186 }
00187 HRESULT CMMLDecodeFilter::Transform(IMediaSample* inSample, IMediaSample* outSample) {
00188         //inSample->AddRef();
00189         //debugLog<<"In sample ref count = "<<inSample->Release();
00190 
00191         //outSample->AddRef();
00192         //debugLog<<"Out sample ref count = "<<outSample->Release();
00193 
00194         unsigned long locSize = inSample->GetActualDataLength();
00195         char* locCMML = NULL;
00196         BYTE* locInBuff = NULL;
00197         BYTE* locOutBuff = NULL;
00198         HRESULT locHR = S_FALSE;
00199         wstring locWCMML;
00200         char* locText = NULL;
00201         string locTextStr;
00202         unsigned long locTextSize = 0;
00203         //outSample->SetMediaTime(NULL, NULL);
00204 
00205         LONGLONG locStart, locEnd;
00206         inSample->GetTime(&locStart, &locEnd);
00207         //debugLog<<"Input Sample Time : "<<locStart<<" to "<<locEnd<<endl;
00208         LONGLONG locSampleTime = locStart;
00209         inSample->GetMediaTime(&locStart, &locEnd);
00210         //debugLog<<"Input Sample Media Time : "<<locStart<<" to "<<locEnd<<endl;
00211         locSampleTime -= locStart;
00212         //debugLog<<"Corrected Sample time = "<<locSampleTime<<endl;
00213         //debugLog<<"Transform : Input Sample Size = "<<locSize<<endl;
00214         if (locSize > 0) {
00215                 locCMML = new char[locSize+1];
00216                 locCMML[locSize] = '\0';
00217                 
00218                 locHR = inSample->GetPointer(&locInBuff);
00219                 memcpy((void*)locCMML, (const void*) locInBuff, locSize);
00220                 //debugLog<<"           : Sample Text = "<<locCMML<<endl<<endl;
00221                 locWCMML = toWStr(locCMML);
00222                 if (mSeenHead == false) {
00223                         //debugLog << "           : Processing a head tag"<<endl;
00224                         //Head tag... needs error checks
00225                         mSeenHead = true;
00226                         mHeadTag = new C_HeadTag;
00227                         bool locParseOK = mCMMLParser->parseHeadTag(locWCMML, mHeadTag);
00228                         if (locParseOK) {
00229                                 //debugLog<<"          : Parse OK"<<endl;
00230 
00231                                 //:::Comment out the subtitle sending for now.
00232                                 //------------------------------------------------------------
00233                                 //locHR = outSample->GetPointer(&locOutBuff);
00234                                 //locTextSize = mHeadTag->title()->text().size();
00235                                 //locTextStr = mHeadTag->title()->text();
00236                                 //
00238                                 //memcpy((void*)locOutBuff, (const void*) locTextStr.c_str(), locTextSize);
00239                                 //locOutBuff[locTextSize] = '\0';
00240                                 //outSample->SetActualDataLength(locTextSize + 1);
00241                                 //------------------------------------------------------------
00242                                 outSample->SetActualDataLength(0);
00243                                 //------------------------------------------------------------
00244                                 
00245 
00246                                 if (mCMMLCallbacks != NULL) {
00247                                         mCMMLCallbacks->headCallback(mHeadTag->clone());
00248                                 }
00249                         } else {
00250                                 //debugLog<<"          : Parse FAILED"<<endl;
00251                         }
00252 
00253                 } else {
00254                         //Clip Tag... needs error checks
00255                         //debugLog << "           : Processing a clip tag"<<endl;
00256                         C_ClipTag locClipTag;
00257                         bool locParseOK = mCMMLParser->parseClipTag(locWCMML, &locClipTag);
00258                         if (locParseOK) {
00259                                 //debugLog<<"          : Parse OK"<<endl;
00260                         
00261                                 //::: Comment out the subtitle part for now
00262                                 //------------------------------------------------------------
00263                                 //locHR = outSample->GetPointer(&locOutBuff);
00264                                 //locTextSize = locClipTag.anchor()->text().size();
00265                                 //locTextStr = locClipTag.anchor()->text();
00266                                 //memcpy((void*)locOutBuff, (const void*) locTextStr.c_str(), locTextSize);
00267                                 //
00269                                 //locOutBuff[locTextSize] = '\0';
00270                                 //outSample->SetActualDataLength(locTextSize + 1);
00273                                 //outSample->SetTime(&locSampleTime, &locSampleTime);
00274                                 //outSample->SetMediaTime(NULL, NULL);
00275                                 //outSample->SetSyncPoint(TRUE);
00276                                 //outSample->SetDiscontinuity(FALSE);
00277                                 //outSample->SetPreroll(FALSE);
00278                                 //------------------------------------------------------------
00279                                 outSample->SetActualDataLength(0);
00280                                 //------------------------------------------------------------
00281                                 if (mCMMLCallbacks != NULL) {
00282                                         mCMMLCallbacks->clipCallback(locClipTag.clone());
00283                                 }
00284 
00285                         } else {
00286                                 //debugLog<<"          : Parse FAILED"<<endl;
00287                                 delete[] locCMML;
00288                                 return S_FALSE;
00289                         }
00290                 }
00291 
00292                 //debugLog<<"Returning... "<<endl<<endl;
00293                 delete[] locCMML;
00294                 return S_OK;
00295 
00296         } else {
00297                 //Zero length Sample... Blank out... Don't send.
00298                 //debugLog<<"Zero length sample..."<<endl;
00299                 outSample->SetActualDataLength(0);
00300                 //debugLog<<"Setting Sample time "<<locClipTag.start()<<endl;
00301                 //LONGLONG locSampleTime = ;
00302                 outSample->SetTime(&locSampleTime, &locSampleTime);
00303                 outSample->SetMediaTime(NULL, NULL);
00304                 outSample->SetSyncPoint(TRUE);
00305                 outSample->SetDiscontinuity(FALSE);
00306                 outSample->SetPreroll(FALSE);
00307                 return S_OK;
00308         }
00309 }
00310 
00311 wstring CMMLDecodeFilter::toWStr(string inString) {
00312         wstring retVal;
00313 
00314         //LPCWSTR retPtr = new wchar_t[retVal.length() + 1];
00315         for (std::string::const_iterator i = inString.begin(); i != inString.end(); i++) {
00316                 retVal.append(1, *i);
00317         }
00318         
00319 
00320         return retVal;
00321 }
00322 
00323 //Implementation of ICMMLAppControl
00324 STDMETHODIMP_(bool) CMMLDecodeFilter::setCallbacks(ICMMLCallbacks* inCallbacks) {
00325         mCMMLCallbacks = inCallbacks;
00326         return true;
00327 }
00328 STDMETHODIMP_(ICMMLCallbacks*) CMMLDecodeFilter::getCallbacks() {
00329         return mCMMLCallbacks;
00330 }
00331 

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