DSPlayer.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 #include "stdafx.h"
00033 #include ".\dsplayer.h"
00034 
00035 
00036 
00037 
00038 DSPlayer::DSPlayer(void) 
00039         :       mGraphBuilder(NULL)
00040         ,       mMediaControl(NULL)
00041         ,       mMediaSeeking(NULL)
00042         ,       mMediaEvent(NULL)
00043         ,       mEventHandle(INVALID_HANDLE_VALUE)
00044         ,       mCMMLCallback(NULL)
00045         ,       mMediaEventNotify(NULL)
00046         //,     mDNCMMLCallbacks(NULL)
00047         //,     mDNMediaEvent(NULL)
00048         ,       mCMMLAppControl(NULL)
00049 {
00050         CoInitialize(NULL);
00051         //mCMMLProxy = new CMMLCallbackProxy;                   //Need to delete this !
00052         
00053         debugLog.open("G:\\logs\\DSPlayer.log", ios_base::out);
00054 
00055         //Something about the way the activeX control links won't let us do the normal
00056         // DEFINE_GUID macro... so this is manually assigning it to a memeber variable so it links.
00057         Y_IID_ICMMLAppControl.Data1 = 0x6188ad0c;
00058         Y_IID_ICMMLAppControl.Data2 = 0x62cb;
00059         Y_IID_ICMMLAppControl.Data3 = 0x4658;
00060         Y_IID_ICMMLAppControl.Data4[0] = 0xa1;
00061         Y_IID_ICMMLAppControl.Data4[1] = 0x4e;
00062         Y_IID_ICMMLAppControl.Data4[2] = 0xcd;
00063         Y_IID_ICMMLAppControl.Data4[3] = 0x23;
00064         Y_IID_ICMMLAppControl.Data4[4] = 0xcf;
00065         Y_IID_ICMMLAppControl.Data4[5] = 0x84;
00066         Y_IID_ICMMLAppControl.Data4[6] = 0xec;
00067         Y_IID_ICMMLAppControl.Data4[7] = 0x31;
00068 
00069 }
00070 //              // {6188AD0C-62CB-4658-A14E-CD23CF84EC31}
00071 //DEFINE_GUID(Y_IID_ICMMLAppControl, 
00072 //0x6188ad0c, 0x62cb, 0x4658, 0xa1, 0x4e, 0xcd, 0x23, 0xcf, 0x84, 0xec, 0x31);
00073 //}
00074 
00075 bool DSPlayer::checkEvents() {
00076         const DWORD TIMEOUT_WAIT = 0;  //Wait this many ms for handle
00077         long locEventCode = 0;
00078         long locParam1 = 0;
00079         long locParam2 = 0;
00080         HRESULT locHR = S_OK;
00081 
00082         if (WAIT_OBJECT_0 == WaitForSingleObject(mEventHandle, TIMEOUT_WAIT))   { 
00083                         while (locHR = mMediaEvent->GetEvent(&locEventCode, &locParam1, &locParam2, 0), SUCCEEDED(locHR)) 
00084                         {
00085                     
00086                                 debugLog<<"Event : "<<locEventCode<<" Params : "<<locParam1<<", "<<locParam2<<endl;
00087                                 
00088                                 
00089                                 if (mMediaEventNotify != NULL) {
00090                                         mMediaEventNotify->eventNotification(locEventCode, locParam1, locParam2);
00091                                 }
00092 
00093                                 mMediaEvent->FreeEventParams(locEventCode, locParam1, locParam2);
00094                         }
00095         }
00096         return true;
00097 }
00098 
00099 
00100 DSPlayer::~DSPlayer(void) {
00101         debugLog<<"Killing DSPlayer"<<endl;
00102         debugLog.close();
00103         
00104         releaseInterfaces();
00105         CoUninitialize();
00106 }
00107 
00108 void DSPlayer::releaseInterfaces() {
00109         debugLog<<"Releasing interfaces"<<endl;
00110         ULONG numRef = 0;
00111         if (mMediaControl != NULL) {
00112                 numRef = 
00113                         mMediaControl->Release();
00114                 debugLog<<"Media Control count = "<<numRef<<endl;
00115                 mMediaControl = NULL;
00116         }
00117 
00118         if (mMediaSeeking != NULL) {
00119                 numRef = 
00120                         mMediaSeeking->Release();
00121 
00122                 debugLog<<"Media Seeking count = "<<numRef<<endl;
00123                 mMediaSeeking = NULL;
00124         }
00125 
00126         if (mMediaEvent != NULL) {
00127                 numRef = 
00128                         mMediaEvent->Release();
00129 
00130                 debugLog<<"Media Event count = "<<numRef<<endl;
00131                 mMediaEvent = NULL;
00132         }
00133 
00134         if (mCMMLAppControl != NULL) {
00135                 numRef = 
00136                         mCMMLAppControl->Release();
00137 
00138                 debugLog<<"CMML App control count = "<<numRef<<endl;
00139                 mCMMLAppControl = NULL;
00140         }
00141 
00142         debugLog<<"Before Graph release..."<<endl;
00143         if (mGraphBuilder != NULL) {
00144                 numRef =
00145             mGraphBuilder->Release();
00146 
00147                 debugLog<<"Graph Builder count = "<<numRef<<endl;
00148                 mGraphBuilder = NULL;
00149         }
00150 
00151 
00152         debugLog<<"After graph release>.."<<endl;
00153         //TODO::: Release everything !
00154 }
00155 wstring DSPlayer::toWStr(string inString) {
00156         wstring retVal;
00157 
00158         //LPCWSTR retPtr = new wchar_t[retVal.length() + 1];
00159         for (std::string::const_iterator i = inString.begin(); i != inString.end(); i++) {
00160                 retVal.append(1, *i);
00161         }
00162         
00163 
00164         return retVal;
00165 }
00166 
00167 bool DSPlayer::loadFile(wstring inFileName, HWND inWindow, int inLeft, int inTop, int inWidth, int inHeight) {
00168         //Debugging only
00169         ULONG numRef = 0;
00170         //
00171 
00172 
00173         releaseInterfaces();
00174         HRESULT locHR = S_OK;
00175 
00176         
00177         //debugLog<<"File = "<<inFileName<<endl;
00178         wstring locWFileName = inFileName; //toWStr(inFileName);
00179         
00180         
00181         
00182 
00183         //Have to use a local pointer or taking the adress of a member function makes the second level
00184         // of indirection a __gc pointer.
00185         IGraphBuilder* locGraphBuilder = NULL;
00186         locHR = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&locGraphBuilder);
00187         mGraphBuilder = locGraphBuilder;
00188         
00189         if (locHR != S_OK) {
00190                 mIsLoaded = false;
00191                 debugLog<<"Faild to make graph"<<endl;
00192                 return false;
00193         }
00194         
00195         
00196         //If it's an annodex file, then put the VMR 9 in the graph.
00197         if (isFileAnnodex(inFileName)) {
00198                 debugLog<<"Is annodex"<<endl;
00199                 IBaseFilter* locVMR9 = NULL;
00200 
00201                 HRESULT locHR2 = S_OK;
00202                 locHR2 = mGraphBuilder->FindFilterByName(L"Video Mixing Renderer 9", &locVMR9);
00203                 if (locVMR9 == NULL) {
00204                         debugLog<<"Not in graph... making it !"<<endl;
00205                         locHR2= CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&locVMR9);
00206                         if (locHR2 == S_OK) {
00207                                 locHR2 = mGraphBuilder->AddFilter(locVMR9, L"Video Mixing Renderer 9");
00208                                 numRef =
00209                                         locVMR9->Release();
00210                                 debugLog<<"VMR9 ref count = "<<numRef<<endl;
00211                                 
00212                         }
00213                 } else {
00214                         numRef =
00215                                 locVMR9->Release();
00216 
00217                         debugLog<<"VMR9 ref count = "<<numRef<<endl;
00218                 }
00219 
00220 
00221                 
00222 
00223         }
00224 
00225         debugLog<<"About to call render on "<<endl;
00226         //Build the graph
00227         locHR = mGraphBuilder->RenderFile(locWFileName.c_str(), NULL);
00228         debugLog<<"After render call..."<<endl;
00229         if (locHR != S_OK) {
00230                 debugLog<<"Render File FAILED !!"<<endl;
00231                 mIsLoaded = false;
00232                 return false;
00233         }
00234 
00235 
00236         //CHANGES HERE FOR EMBEDDED WINDOW
00237         debugLog<<"Looking for IVideo Window"<<endl;
00238         IVideoWindow* locVW = NULL;
00239         locHR = locGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&locVW);
00240 
00241         if (locHR == S_OK) {
00242                 debugLog<<"We got the IVideoWindow"<<endl;
00243 
00244                 
00245                 //locVW->put_MessageDrain((OAHWND)inWindow);
00246 
00247                 
00248                 locVW->put_Owner((OAHWND)inWindow);
00249                 debugLog<<"Setting stuff..."<<endl;
00250                 locVW->SetWindowPosition(inLeft, inTop, inWidth, inHeight);
00251                 debugLog<<"Releasing windows"<<endl;
00252                 locVW->Release();
00253 
00254                 debugLog<<"Post release"<<endl;
00255         }
00256 
00257         //
00258 
00259         debugLog<<"Render must have been ok"<<endl;
00260         if (isFileAnnodex(inFileName)) {
00261                 debugLog<<"Is annodex"<<endl;
00262                 //Get the app control interface for CMML.
00263                 IBaseFilter* locCMMLFilter = NULL;
00264                 locHR = mGraphBuilder->FindFilterByName(L"CMML Decode Filter", &locCMMLFilter);
00265                 
00266 
00267                 if (locCMMLFilter != NULL) {
00268                         ICMMLAppControl* locCMMLAppControl = NULL;
00269                         
00270                         locHR = locCMMLFilter->QueryInterface(Y_IID_ICMMLAppControl, (void**)&locCMMLAppControl);
00271                         if (locCMMLAppControl != NULL) {
00272                                 mCMMLAppControl = locCMMLAppControl;
00273                                 
00274                                 mCMMLAppControl->setCallbacks(mCMMLCallback);
00275                         }
00276                         numRef = 
00277                 locCMMLFilter->Release();
00278 
00279                         debugLog<<"CMML Filter ref Count = "<<numRef<<endl;
00280                 }
00281 
00282         }
00283         debugLog<<"After CMML Code..."<<endl;
00284 
00285         //Get the media control interface
00286         IMediaControl* locMediaControl = NULL;
00287         locHR = mGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&locMediaControl);
00288         mMediaControl = locMediaControl;
00289 
00290         if (locHR != S_OK) {
00291                 mIsLoaded = false;
00292                 return false;
00293         } else {
00294                 mIsLoaded = true;
00295         }
00296 
00297         //get the media seeking interface if its available.
00298         IMediaSeeking* locMediaSeeking = NULL;
00299         locHR = mGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)&locMediaSeeking);
00300         mMediaSeeking = locMediaSeeking;
00301 
00302         //Get the media event interface
00303         IMediaEvent* locMediaEvent = NULL;
00304         locHR = locGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&locMediaEvent);
00305 
00306         if (locHR == S_OK) {
00307                 mMediaEvent = locMediaEvent;
00308                 HANDLE locEventHandle = INVALID_HANDLE_VALUE;
00309                 locHR = locMediaEvent->GetEventHandle((OAEVENT*)&locEventHandle);
00310                 mEventHandle = locEventHandle;
00311         }
00312 
00313 //      if (FAILED(hr))
00314 
00315         return true;
00316 }
00317 bool DSPlayer::loadFile(wstring inFileName) {
00318 
00319         //Debugging only
00320         ULONG numRef = 0;
00321         //
00322 
00323 
00324         releaseInterfaces();
00325         HRESULT locHR = S_OK;
00326 
00327         
00328         //debugLog<<"File = "<<inFileName<<endl;
00329         wstring locWFileName = inFileName; //toWStr(inFileName);
00330         
00331         
00332         
00333 
00334         //Have to use a local pointer or taking the adress of a member function makes the second level
00335         // of indirection a __gc pointer.
00336         IGraphBuilder* locGraphBuilder = NULL;
00337         locHR = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&locGraphBuilder);
00338         mGraphBuilder = locGraphBuilder;
00339         
00340         if (locHR != S_OK) {
00341                 mIsLoaded = false;
00342                 return false;
00343         }
00344         
00345         
00346         //If it's an annodex file, then put the VMR 9 in the graph.
00347         if (isFileAnnodex(inFileName)) {
00348                 debugLog<<"Is annodex"<<endl;
00349                 IBaseFilter* locVMR9 = NULL;
00350 
00351                 HRESULT locHR2 = S_OK;
00352                 locHR2 = mGraphBuilder->FindFilterByName(L"Video Mixing Renderer 9", &locVMR9);
00353                 if (locVMR9 == NULL) {
00354                         debugLog<<"Not in graph... making it !"<<endl;
00355                         locHR2= CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&locVMR9);
00356                         if (locHR2 == S_OK) {
00357                                 locHR2 = mGraphBuilder->AddFilter(locVMR9, L"Video Mixing Renderer 9");
00358                                 numRef =
00359                                         locVMR9->Release();
00360                                 debugLog<<"VMR9 ref count = "<<numRef<<endl;
00361                                 
00362                         }
00363                 } else {
00364                         numRef =
00365                                 locVMR9->Release();
00366 
00367                         debugLog<<"VMR9 ref count = "<<numRef<<endl;
00368                 }
00369 
00370 
00371                 
00372 
00373         }
00374 
00375         debugLog<<"About to call render on "<<endl;
00376         //Build the graph
00377         locHR = mGraphBuilder->RenderFile(locWFileName.c_str(), NULL);
00378 
00379         if (locHR != S_OK) {
00380                 debugLog<<"Render File FAILED !!"<<endl;
00381                 mIsLoaded = false;
00382                 return false;
00383         }
00384 
00385         debugLog<<"Render must have been ok"<<endl;
00386         if (isFileAnnodex(inFileName)) {
00387                 debugLog<<"Is annodex"<<endl;
00388                 //Get the app control interface for CMML.
00389                 IBaseFilter* locCMMLFilter = NULL;
00390                 locHR = mGraphBuilder->FindFilterByName(L"CMML Decode Filter", &locCMMLFilter);
00391                 
00392 
00393                 if (locCMMLFilter != NULL) {
00394                         ICMMLAppControl* locCMMLAppControl = NULL;
00395                         
00396                         locHR = locCMMLFilter->QueryInterface(Y_IID_ICMMLAppControl, (void**)&locCMMLAppControl);
00397                         if (locCMMLAppControl != NULL) {
00398                                 mCMMLAppControl = locCMMLAppControl;
00399                                 
00400                                 mCMMLAppControl->setCallbacks(mCMMLCallback);
00401                         }
00402                         numRef = 
00403                 locCMMLFilter->Release();
00404 
00405                         debugLog<<"CMML Filter ref Count = "<<numRef<<endl;
00406                 }
00407 
00408         }
00409         debugLog<<"After CMML Code..."<<endl;
00410 
00411         //Get the media control interface
00412         IMediaControl* locMediaControl = NULL;
00413         locHR = mGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&locMediaControl);
00414         mMediaControl = locMediaControl;
00415 
00416         if (locHR != S_OK) {
00417                 mIsLoaded = false;
00418                 return false;
00419         } else {
00420                 mIsLoaded = true;
00421         }
00422 
00423         //get the media seeking interface if its available.
00424         IMediaSeeking* locMediaSeeking = NULL;
00425         locHR = mGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)&locMediaSeeking);
00426         mMediaSeeking = locMediaSeeking;
00427 
00428         //Get the media event interface
00429         IMediaEvent* locMediaEvent = NULL;
00430         locHR = locGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&locMediaEvent);
00431 
00432         if (locHR == S_OK) {
00433                 mMediaEvent = locMediaEvent;
00434                 HANDLE locEventHandle = INVALID_HANDLE_VALUE;
00435                 locHR = locMediaEvent->GetEventHandle((OAEVENT*)&locEventHandle);
00436                 mEventHandle = locEventHandle;
00437         }
00438 
00439 //      if (FAILED(hr))
00440 
00441         return true;
00442 
00443 
00444 }
00445 
00446 //bool DSPlayer::setCMMLCallbacks(IDNCMMLCallbacks* inCMMLCallbacks) {
00447 //      return mCMMLProxy->setManagedDelegate(inCMMLCallbacks);
00448 //}
00449 
00450 bool DSPlayer::isLoaded() {
00451         return mIsLoaded;
00452 }
00453 bool DSPlayer::play() {
00454         if (mIsLoaded) {
00455                 HRESULT locHR = mMediaControl->Run();
00456                 if (SUCCEEDED(locHR)) {
00457                         return false;
00458                 } else {
00459                         return true;
00460                 }
00461         } else {
00462                 return false;
00463         }
00464 }
00465 
00466 bool DSPlayer::pause() {
00467         if (mIsLoaded) {
00468                 HRESULT locHR = mMediaControl->Pause();
00469                 if (locHR != S_OK) {
00470                         return false;
00471                 } else {
00472                         return true;
00473                 }
00474         } else {
00475                 return false;
00476         }
00477 }
00478 
00479 bool DSPlayer::stop() {
00480         if (mIsLoaded) {
00481                 HRESULT locHR = mMediaControl->Stop();
00482                 if (locHR != S_OK) {
00483                         return false;
00484                 } else {
00485                         return true;
00486                 }
00487         } else {
00488                 return false;
00489         }
00490 }
00491 
00492 __int64 DSPlayer::seek(__int64 inTime) {
00493         if (mIsLoaded && (mMediaSeeking != NULL)) {
00494                 LONGLONG locCurrent = inTime;
00495                 LONGLONG locStop = 0;
00496                 HRESULT locHR = mMediaSeeking->SetPositions(&locCurrent, AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime, 
00497                                                                                                         &locStop, AM_SEEKING_NoPositioning);
00498                 
00499                 if (SUCCEEDED(locHR)) {
00500                         return locCurrent;
00501                 } else {
00502                         return -1;
00503                 }
00504         } else {
00505                 return -1;
00506         }
00507         
00508 }
00509 
00510 __int64 DSPlayer::seekStart() {
00511         return 0;
00512 }
00513 
00514 __int64 DSPlayer::queryPosition() {
00515         return 0;
00516 }
00517 
00518 __int64 DSPlayer::fileSize() {
00519         return -1;
00520 }
00521 __int64 DSPlayer::fileDuration() {
00522         if (mIsLoaded && (mMediaSeeking != NULL)) {
00523                 LONGLONG locDuration = 0;
00524                 HRESULT locHR = mMediaSeeking->GetDuration(&locDuration);
00525 
00526                 if (locHR != S_OK) {
00527                         return -1;
00528                 } else {
00529                         return locDuration;
00530                 }
00531         } else {
00532                 return -1;
00533         }
00534 }
00535 
00536 bool DSPlayer::isFileAnnodex(wstring inFilename)
00537 {
00538         //BUG::: Case sensitive
00539         wstring locExt = inFilename.substr(inFilename.size() - 4, 4);
00540         
00541         if (locExt == L".anx") {
00542                 return true;
00543         } else {
00544                 return false;
00545         }
00546 }
00547 
00548 bool DSPlayer::setMediaEventCallback(IMediaEventNotification* inMediaEventCallback) {
00549         mMediaEventNotify = inMediaEventCallback;
00550         return true;
00551 }
00552 IMediaEventNotification* DSPlayer::getMediaEventCallback() {
00553         return mMediaEventNotify;
00554 }
00555 
00556 
00557 

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