Problem mit DirectShow
-
Hallo zusammen
Ich habe ein Problem mit DirectShow, bei dem ich einfach nicht weiterkomme:// define some symbols const uint32 cxSvr = CLSCTX_INPROC_SERVER; const Guid idFgr = CLSID_FilterGraph; const Guid idVm9 = CLSID_VideoMixingRenderer9; // try to create a graphbuilder and throw an exception on failure hRst = CoCreateInstance(idFgr,0x00,cxSvr,IID_IGraphBuilder,reinterpret_cast<void**>(&this->pGbu)); if(hRst != S_OK) throw LowLevelException(FNC,"CoCreateInstance: CLSID_FilterGraph",hRst); // try to obtain the extended filter graph interface and throw an exception on failure hRst = this->pGbu->QueryInterface(IID_IFilterGraph2,reinterpret_cast<void**>(&this->pFgr)); if(hRst != S_OK) throw LowLevelException(FNC,"IUnknown::QueryInterface : IID_IFilterGaph2",hRst); // try to create a video mixing renderer for incorporation with the Direct3D9 library hRst = CoCreateInstance(idVm9,0x00,cxSvr,IID_IBaseFilter,reinterpret_cast<void**>(&this->bfVm9)); if(hRst != S_OK) throw LowLevelException(FNC,"CoCreateInstance: CLSID_VideoMixingRenderer9",hRst); // add the VMR-9 filter to the graph this->pGbu->AddFilter(this->bfVm9,L"VMR9"); // change the rendering mode of the VMR-9 filter to renderless // (we do not want the movie being rendered into a separate window, but in a texture instead) IVMRFilterConfig9 *pCfg = 0x00; this->bfVm9->QueryInterface(IID_IVMRFilterConfig9,reinterpret_cast<void**>(&pCfg)); pCfg->SetRenderingMode(VMR9Mode_Renderless); pCfg->Release(); // assign our custom concrete implementation of the // IVMRSurfaceAllocator9 interface to the VMR-9 filter IVMRSurfaceAllocatorNotify9 *pSan = 0x00; this->bfVm9->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,reinterpret_cast<void**>(&pSan)); pSan->AdviseSurfaceAllocator(0,this); // Dieser Aufruf fürt zu einer Speicherschutzverletzung this->AdviseNotify(pSan); // Dieser Aufruf ebenfalls :-( pSan->Release();
Der Header sieht im Moment folgendermassen aus:
// ###################################### define all needed classes ###################################### // ************************************ class "DirectShowMediaService" *********************************** // This class is a concrete implementation of the IMediaService interface and uses DirectShow for // streaming music and video files. // Author: Samuel Lörtscher // ******************************************************************************************************* class DirectShowMediaService:public IMediaService,public IVMRSurfaceAllocator9,public IVMRImagePresenter9{ private: // --------------------------------------- private dynamic members -------------------------------------- IGraphBuilder *pGbu; // a filter graph builder IFilterGraph2 *pFgr; // an extended filter graph interface IMediaControl *mcMov; // a media controller for the active movie IBaseFilter *bfSrc; // the source filter IBaseFilter *bfVm9; // the video mixing renderer // ------------------------------------------------------------------------------------------------------ public: // --------------------------------- public constructors and destructor --------------------------------- DirectShowMediaService(void){} ~DirectShowMediaService(void){} // ------------------------------------------------------------------------------------------------------ // --------------------------------------- public dynamic methods --------------------------------------- /* void Update(float32 Time); void Render(float32 Time){}*/ string *GetName(void) const; // ------------------------------------------------------------------------------------------------------ private: // --------------------------------------- private dynamic methods -------------------------------------- void Init(void); void Deinit(void); HResult __stdcall AdviseNotify(IVMRSurfaceAllocatorNotify9 *Notify); // ------------------------------------------------------------------------------------------------------ }; // ******************************************************************************************************* // #######################################################################################################
Weiss vielleicht jemand von euch, was ich falsch mache? Ich zweifle ja stark daran, dass man COM Interfaces einfach so vererben kann, wie ich es getan habe, die Frage wäre dann allerdings, wie wird es richtig gemacht?
-
Ishildur schrieb:
Weiss vielleicht jemand von euch, was ich falsch mache?
Jap. Du stellst Fragen die nicht Standard-C++ betreffen im falschen Forum. Vermutlich schlägt der Aufruf an QueryInterface fehl, du solltest ggf. danach den Pointer nochmal überprüfen - oder den Rückgabewert der Funktion, falls es einen gibt.
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Vermutlich schlägt der Aufruf an QueryInterface fehl, du solltest ggf. danach den Pointer nochmal überprüfen
Das habe ich natürlich getan, daran liegts nicht
-
Vielleicht liegt es daran, dass ich praktisch keine der Interface Methoden implementiere? Aber wieso sagt dann der Kompiler nichts?
Ich habe nun meinen DirectShowMediaService folgendermassen erweitert und sehe mal, obs dann läuft:
private: // --------------------------------------- private dynamic methods -------------------------------------- void Init(void); void Deinit(void); // ------------------------------------------------------------------------------------------------------ public: // ---------------------- public dynamic DirectShow specific COM Interface methods ---------------------- HResult __stdcall QueryInterface(REFIID Riid,void **Object); uint32 __stdcall AddRef(void); uint32 __stdcall Release(void); HResult __stdcall AdviseNotify(IVMRSurfaceAllocatorNotify9 *Notify); HResult __stdcall GetSurface(uint32 UserID,uint32 Index,uint32 Flags,IDirect3DSurface9 **Surface); HResult __stdcall InitializeDevice(uint32 UserID,VMR9AllocationInfo *Info,uint32 SurfaceCount); HResult __stdcall TerminateDevice(uint32 UseriD); HResult __stdcall PresentImage(uint32 UserID,VMR9PresentationInfo *Info); HResult __stdcall StartPresenting(uint32 UserID); HResult __stdcall EndPresenting(uint32 UserID); // ------------------------------------------------------------------------------------------------------
-
ich hab auch mal bissl recherschiert ... ohne jemals damit was gemacht zu haben.
Der 2. Parameter von AdviseSurfaceAllocator erwartet ja nen Pointer auf IVMRSurfaceAllocator9
Da bin ich dann zur Verwendung von CComQIPtr gekommen
// Let the allocator and the notify know about each other CComQIPtr<IVMRSurfaceAllocatorNotify9> notify(mVMR9); CComQIPtr<IVMRSurfaceAllocator9> alloc(mAllocatorPresenter); hr |= notify->AdviseSurfaceAllocator(VMR9AllocatorPresenter::mUserId, alloc); hr |= mAllocatorPresenter->AdviseNotify(notify);
zu finden in einem ähnlichen Codeschnipsel von jemand völlig anderem
vielleicht hilft es dir ja weiter, wenn nicht, hab ich umsonst gegoogelt
-
@BasicMan01
Herzlichen Dank für deinen Einsatz
Also wenn mich nicht alles täuscht, ist CComQIPtr ein Typ aus der Active Template Library kurz ATL, welche wir jedoch in unserem Projekt nicht verwenden
-
Ich habe mich heute noch einmal an dieses DirectShow Teil herangewagt und einige bestehende Beispiele aus dem WindowSDK studiert. Hierbei habe ich folgendes herausgefunden:
// ----------------------------- public COM interface method "QueryInterface" ---------------------------- // This method returns a pointer to the desired interface if it's provided or null otherwise. // Author: Samuel Lörtscher // ------------------------------------------------------------------------------------------------------- HResult __stdcall DirectShowMediaService::QueryInterface(REFIID Riid,void **Object){ // return an error if the parametric Object pointer turns out to be a null pointer if(!Object) return E_POINTER; // THIS DOESN't WORK FOR SOME REASON /* // check if desired interface is one of those this class provides if(Riid == IID_IUnknown || Riid == IID_IVMRSurfaceAllocator9 || Riid == IID_IVMRImagePresenter9){ // assign a pointer to this class and return S_OK *Object = this; return S_OK; }*/ // THIS DOESN't WORK FOR SOME REASON // This shit seems to work but whyyyy???? Are the methods of IUnkwown not defined as virtual??? if(Riid == IID_IVMRSurfaceAllocator9){ *Object = static_cast<IVMRSurfaceAllocator9*>(this); return S_OK; } else if(Riid == IID_IVMRImagePresenter9){ *Object = static_cast<IVMRImagePresenter9*>(this); return S_OK; } else if(Riid == IID_IUnknown){ *Object = static_cast<IUnknown*>(static_cast<IVMRSurfaceAllocator9*>(this)); return S_OK; } // otherwise return that this class does not provide the desired interface else return E_NOINTERFACE; } // ------------------------------------------------------------------------------------------------------
Wieso muss ich ein static_cast machen? Ich verstehe überhaupt nichts mehr, es sei denn COM verwendet keine Laufzeitpolymorphie, aber das ist doch nicht ihr ernst oder? Oder hat das vielleicht etwas mit der Kompatibilität mit C zu tun?
Mfg Samuel