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         ,       mInputPin(NULL)
00064 {
00065         //debugLog.open("G:\\logs\\cmml_decode.logs", ios_base::out);
00066                 mCMMLParser = new CMMLParser;
00067         //debugLog.open("C:\\Temp\\cmmlfilter.log", ios_base::out);
00068         //debugLog<<"*** Log Begins ***"<<endl;
00069 }
00070 
00071 CMMLDecodeFilter::~CMMLDecodeFilter(void)
00072 {
00073         //debugLog<<"*** Log Ends ***"<<endl;
00074         //debugLog.close();
00075         delete mCMMLParser;
00076 }
00077 
00078 CUnknown* WINAPI CMMLDecodeFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00079 {
00080         //This routine is the COM implementation to create a new Filter
00081         CMMLDecodeFilter *pNewObject = new CMMLDecodeFilter();
00082     if (pNewObject == NULL) {
00083         *pHr = E_OUTOFMEMORY;
00084     }
00085         return pNewObject;
00086 } 
00087 
00088 STDMETHODIMP CMMLDecodeFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00089         if (riid == IID_ICMMLAppControl) {
00090                 *ppv = (ICMMLAppControl*)this;
00091                 ((IUnknown*)*ppv)->AddRef();
00092                 return NOERROR;
00093         }
00094 
00095         return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
00096 }
00097 
00098 HRESULT CMMLDecodeFilter::CheckInputType(const CMediaType* inInputMediaType) 
00099 {
00100         return mInputPin->CheckMediaType(inInputMediaType);
00101         //if (  (inInputMediaType->majortype == MEDIATYPE_OggPacketStream)      &&
00102         //              (inInputMediaType->subtype == MEDIASUBTYPE_None) &&
00103         //              (inInputMediaType->formattype == FORMAT_OggIdentHeader) ){
00104 
00105         //      //debugLog<<"Input Type Accepted"<<endl;
00106         //      return S_OK;
00107         //} else {
00108         //      return VFW_E_TYPE_NOT_ACCEPTED;
00109         //}
00110 }
00111 HRESULT CMMLDecodeFilter::CheckTransform(const CMediaType* inInputMediaType, const CMediaType* inOutputMediaType) {
00112         //if (  (inInputMediaType->majortype == MEDIATYPE_Text) &&
00113         //              (inInputMediaType->subtype == MEDIASUBTYPE_CMML) &&
00114         //              (inInputMediaType->formattype == FORMAT_CMML) &&
00115         //              (inOutputMediaType->majortype == MEDIATYPE_Text) &&
00116         //              (inOutputMediaType->subtype == MEDIASUBTYPE_SubtitleVMR9) ){
00117 
00118         //      //debugLog << "Transform Accepted"<<endl;
00119                 return S_OK;
00120 //      } else {
00121 //              return VFW_E_TYPE_NOT_ACCEPTED;
00122 //      }
00123         
00124 }
00125 
00126 CBasePin* CMMLDecodeFilter::GetPin(int inPinNo)
00127 {
00128 
00129     HRESULT locHR = S_OK;
00130 
00131     // Create an input pin if necessary
00132 
00133     if (m_pInput == NULL) {
00134 
00135         m_pInput = new CMMLDecodeInputPin(this, &locHR);                //Deleted in base destructor
00136 
00137         
00138         if (m_pInput == NULL) {
00139             return NULL;
00140         }
00141 
00142                 mInputPin = (CMMLDecodeInputPin*)m_pInput;
00143         m_pOutput = new CTransformOutputPin(NAME("CMML Out"), this, &locHR, L"CMML Out");       //Deleted in base destructor
00144                         
00145 
00146         if (m_pOutput == NULL) {
00147             delete m_pInput;
00148             m_pInput = NULL;
00149         }
00150     }
00151 
00152     // Return the pin
00153 
00154     if (inPinNo == 0) {
00155         return m_pInput;
00156     } else if (inPinNo == 1) {
00157         return m_pOutput;
00158     } else {
00159         return NULL;
00160     }
00161 
00162 }
00163 HRESULT CMMLDecodeFilter::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest) {
00164         //FIX::: Abstract this out properly     
00165 
00166         HRESULT locHR = S_OK;
00167 
00168         ALLOCATOR_PROPERTIES locReqAlloc;
00169         ALLOCATOR_PROPERTIES locActualAlloc;
00170 
00171         const unsigned long MIN_BUFFER_SIZE = 1024;                     
00172         const unsigned long DEFAULT_BUFFER_SIZE = 4096;
00173         const unsigned long MIN_NUM_BUFFERS = 10;
00174         const unsigned long DEFAULT_NUM_BUFFERS = 15;
00175 
00176         
00177         
00178         
00179         if (inPropertyRequest->cbAlign <= 0) {
00180                 locReqAlloc.cbAlign = 1;
00181         } else {
00182                 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00183         }
00184 
00185         
00186         if (inPropertyRequest->cbBuffer < MIN_BUFFER_SIZE) {
00187                 locReqAlloc.cbBuffer = DEFAULT_BUFFER_SIZE;
00188         } else {
00189                 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00190         }
00191 
00192         
00193         if (inPropertyRequest->cbPrefix < 0) {
00194                         locReqAlloc.cbPrefix = 0;
00195         } else {
00196                 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00197         }
00198 
00199         
00200         if (inPropertyRequest->cBuffers < MIN_NUM_BUFFERS) {
00201                 locReqAlloc.cBuffers = DEFAULT_NUM_BUFFERS;
00202         } else {
00203                 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00204         }
00205 
00206         
00207         locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00208 
00209         if (locHR != S_OK) {
00210                 return locHR;
00211         }
00212         
00213         locHR = inAllocator->Commit();
00214 
00215         return locHR;
00216 }
00217 HRESULT CMMLDecodeFilter::GetMediaType(int inPosition, CMediaType* outMediaType) {
00218         if (inPosition < 0) {
00219                 return E_INVALIDARG;
00220         } else if (inPosition == 0) {
00221                 outMediaType->majortype = MEDIATYPE_Text;
00222                 outMediaType->subtype = MEDIASUBTYPE_SubtitleVMR9;
00223                 return S_OK;
00224         } else {
00225                 return VFW_S_NO_MORE_ITEMS;
00226         }
00227 }
00228 HRESULT CMMLDecodeFilter::Transform(IMediaSample* inSample, IMediaSample* outSample) {
00229         //inSample->AddRef();
00230         //debugLog<<"In sample ref count = "<<inSample->Release();
00231 
00232         //outSample->AddRef();
00233         //debugLog<<"Out sample ref count = "<<outSample->Release();
00234 
00235         unsigned long locSize = inSample->GetActualDataLength();
00236         char* locCMML = NULL;
00237         BYTE* locInBuff = NULL;
00238         BYTE* locOutBuff = NULL;
00239         HRESULT locHR = S_FALSE;
00240         wstring locWCMML;
00241         char* locText = NULL;
00242         string locTextStr;
00243         unsigned long locTextSize = 0;
00244         //outSample->SetMediaTime(NULL, NULL);
00245 
00246         LONGLONG locStart, locEnd;
00247         inSample->GetTime(&locStart, &locEnd);
00248         //debugLog<<"Input Sample Time : "<<locStart<<" to "<<locEnd<<endl;
00249         LONGLONG locSampleTime = locStart;
00250         inSample->GetMediaTime(&locStart, &locEnd);
00251         //debugLog<<"Input Sample Media Time : "<<locStart<<" to "<<locEnd<<endl;
00252         locSampleTime -= locStart;
00253         //debugLog<<"Corrected Sample time = "<<locSampleTime<<endl;
00254         //debugLog<<"Transform : Input Sample Size = "<<locSize<<endl;
00255         if (locSize > 0) {
00256                 locCMML = new char[locSize+1];
00257                 locCMML[locSize] = '\0';
00258                 
00259                 locHR = inSample->GetPointer(&locInBuff);
00260                 memcpy((void*)locCMML, (const void*) locInBuff, locSize);
00261                 //debugLog<<"           : Sample Text = "<<locCMML<<endl<<endl;
00262 
00263                 string locNarrowCMML = locCMML;
00264                 delete[] locCMML;
00265                 locWCMML = toWStr(locNarrowCMML);
00266                 if (mSeenHead == false) {
00267                         //debugLog << "           : Processing a head tag"<<endl;
00268                         //Head tag... needs error checks
00269                         mSeenHead = true;
00270                         mHeadTag = new C_HeadTag;
00271                         bool locParseOK = mCMMLParser->parseHeadTag(locWCMML, mHeadTag);
00272                         if (locParseOK) {
00273                                 //debugLog<<"          : Parse OK"<<endl;
00274 
00275                                 //:::Comment out the subtitle sending for now.
00276                                 //------------------------------------------------------------
00277                                 //locHR = outSample->GetPointer(&locOutBuff);
00278                                 //locTextSize = mHeadTag->title()->text().size();
00279                                 //locTextStr = mHeadTag->title()->text();
00280                                 //
00282                                 //memcpy((void*)locOutBuff, (const void*) locTextStr.c_str(), locTextSize);
00283                                 //locOutBuff[locTextSize] = '\0';
00284                                 //outSample->SetActualDataLength(locTextSize + 1);
00285                                 //------------------------------------------------------------
00286                                 outSample->SetActualDataLength(0);
00287                                 //------------------------------------------------------------
00288                                 
00289 
00290                                 if (mCMMLCallbacks != NULL) {
00291                                         mCMMLCallbacks->headCallback(mHeadTag->clone());
00292                                 }
00293                         } else {
00294                                 //debugLog<<"          : Parse FAILED"<<endl;
00295                         }
00296 
00297                 } else {
00298                         //Clip Tag... needs error checks
00299                         //debugLog << "           : Processing a clip tag"<<endl;
00300                         C_ClipTag locClipTag;
00301                         bool locParseOK = mCMMLParser->parseClipTag(locWCMML, &locClipTag);
00302                         if (locParseOK) {
00303                                 //debugLog<<"          : Parse OK"<<endl;
00304                         
00305                                 //::: Comment out the subtitle part for now
00306                                 //------------------------------------------------------------
00307                                 //locHR = outSample->GetPointer(&locOutBuff);
00308                                 //locTextSize = locClipTag.anchor()->text().size();
00309                                 //locTextStr = locClipTag.anchor()->text();
00310                                 //memcpy((void*)locOutBuff, (const void*) locTextStr.c_str(), locTextSize);
00311                                 //
00313                                 //locOutBuff[locTextSize] = '\0';
00314                                 //outSample->SetActualDataLength(locTextSize + 1);
00317                                 //outSample->SetTime(&locSampleTime, &locSampleTime);
00318                                 //outSample->SetMediaTime(NULL, NULL);
00319                                 //outSample->SetSyncPoint(TRUE);
00320                                 //outSample->SetDiscontinuity(FALSE);
00321                                 //outSample->SetPreroll(FALSE);
00322                                 //------------------------------------------------------------
00323                                 outSample->SetActualDataLength(0);
00324                                 //------------------------------------------------------------
00325                                 if (mCMMLCallbacks != NULL) {
00326                                         mCMMLCallbacks->clipCallback(locClipTag.clone());
00327                                 }
00328 
00329                         } else {
00330                                 //debugLog<<"          : Parse FAILED"<<endl;
00331                                 //delete[] locCMML;
00332                                 return S_FALSE;
00333                         }
00334                 }
00335 
00336                 //debugLog<<"Returning... "<<endl<<endl;
00337                 //delete[] locCMML;
00338                 return S_OK;
00339 
00340         } else {
00341                 //Zero length Sample... Blank out... Don't send.
00342                 //debugLog<<"Zero length sample..."<<endl;
00343                 outSample->SetActualDataLength(0);
00344                 //debugLog<<"Setting Sample time "<<locClipTag.start()<<endl;
00345                 //LONGLONG locSampleTime = ;
00346                 outSample->SetTime(&locSampleTime, &locSampleTime);
00347                 outSample->SetMediaTime(NULL, NULL);
00348                 outSample->SetSyncPoint(TRUE);
00349                 outSample->SetDiscontinuity(FALSE);
00350                 outSample->SetPreroll(FALSE);
00351                 return S_OK;
00352         }
00353 }
00354 
00355 wstring CMMLDecodeFilter::toWStr(string inString) {
00356         wstring retVal;
00357 
00358         //LPCWSTR retPtr = new wchar_t[retVal.length() + 1];
00359         for (std::string::const_iterator i = inString.begin(); i != inString.end(); i++) {
00360                 retVal.append(1, *i);
00361         }
00362         
00363 
00364         return retVal;
00365 }
00366 
00367 //Implementation of ICMMLAppControl
00368 STDMETHODIMP_(bool) CMMLDecodeFilter::setCallbacks(ICMMLCallbacks* inCallbacks) {
00369         mCMMLCallbacks = inCallbacks;
00370         return true;
00371 }
00372 STDMETHODIMP_(ICMMLCallbacks*) CMMLDecodeFilter::getCallbacks() {
00373         return mCMMLCallbacks;
00374 }
00375 

Generated on Thu Feb 16 23:47:59 2006 for oggdsf by  doxygen 1.3.9