Sign in to follow this  
Gegenki

DirectShow Objects Overlapping

Recommended Posts

Ok This is my Directshow source file. It just loads an mp3 based on the file path given to it in Filename. And the StopTrack function should stop it.
Quote:
#include "DSMusic.h" HRESULT Result; IGraphBuilder *g_pGraphBuilder; IMediaControl *g_pMediaControl; IMediaSeeking *g_pMediaSeeking; IMediaEventEx *g_pMediaEventEx; IBaseFilter *g_pTrack; IBaseFilter *LoadAudioFile(LPCWSTR Filename); DSMusic::DSMusic(void) { std::cout << "Setting up DirectShow\n"; ::CoInitialize(NULL); std::cout << "Creating Graph Builder\n"; Result = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&g_pGraphBuilder); if (FAILED(Result)) { // Just an idea about restarting the server on its own when there is a fatal error. Is no good for debugging purposes as the monitored thread is gone std::cout << "***Failed to create Graph Builder\n"; } std::cout << "Creating Media Seeking Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void **)&g_pMediaSeeking); if (FAILED(Result)) { std::cout << "***Failed to create Seek Interface\n"; } std::cout << "Creating Media Control Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&g_pMediaControl); if (FAILED(Result)) { std::cout << "***Failed to create Media Control Interface\n"; } std::cout << "Creating Media EventEx Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&g_pMediaEventEx); if (FAILED(Result)) { std::cout << "***Failed to create Media EventEx Interface\n"; } std::cout << "Setting Event Notify Window\n"; //Result = g_pMediaEventEx->SetNotifyWindow( (OAHWND)hWnd, WM_APP, 0); std::cout << "W**Notify Window not set as we don't have a window handle\n";// may need to create child window for this purpose if (FAILED(Result)) { std::cout << "***Failed to Set Notify Window\n"; } } DSMusic::~DSMusic(void) { g_pMediaEventEx->Release(); g_pMediaEventEx = NULL; g_pMediaControl->Release(); g_pMediaControl = NULL; g_pMediaSeeking->Release(); g_pMediaSeeking = NULL; g_pGraphBuilder->Release(); g_pGraphBuilder = NULL; } int DSMusic::PlayTrack(LPCWSTR FileName) { IPin *pPin = NULL; IEnumFilters *pFilterEnum = NULL; IBaseFilter **ppFilters; IBaseFilter *pFilterTemp = NULL; int iFiltCount; int iPos; g_pTrack = LoadAudioFile(FileName); g_pTrack->FindPin(L"Output", &pPin); ////////////////////////////////////////////////////////////////////// g_pGraphBuilder->EnumFilters(&pFilterEnum); for (iFiltCount = 0; pFilterEnum->Skip(1) == S_OK; iFiltCount++) ; // Allocate space, then pull out all of the ppFilters = (IBaseFilter **)_alloca(sizeof(IBaseFilter *) * iFiltCount); pFilterEnum->Reset(); for (iPos = 0; pFilterEnum->Next(1, &ppFilters[iPos], NULL) == S_OK; iPos++) ; pFilterEnum->Release(); for (iPos = 0; iPos < iFiltCount; iPos++) { g_pGraphBuilder->RemoveFilter(ppFilters[iPos]); //put the filter back? g_pGraphBuilder->AddFilter(ppFilters[iPos], NULL); ppFilters[iPos]->Release(); } //////////////////////////////////////////////////////*/ //We have the new output pin apparently - render it g_pGraphBuilder->Render(pPin); pPin->Release(); //Reseek the graph to the beginning LONGLONG llPos = 0; g_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning, &llPos, AM_SEEKING_NoPositioning); //Start the Graph g_pMediaControl->Run(); return 0; } int DSMusic::StopTrack() { if (g_pMediaControl != NULL) g_pMediaControl->Stop(); return 0; } IBaseFilter *LoadAudioFile(LPCWSTR Filename) { IBaseFilter *pSource; std::cout << "Attempting to load track\n"; Result = g_pGraphBuilder->AddSourceFilter(Filename, Filename, &pSource); if (FAILED(Result)){ printf("Failed to load track with error: %X\n", Result); return NULL; } return pSource; }
And this is the header file
Quote:
#pragma once #include <iostream> #include <windows.h> #include <windowsx.h> #include <dshow.h> #pragma comment (lib, "strmiids.lib") class DSMusic { public: DSMusic(); ~DSMusic(); int PlayTrack(LPCWSTR FileName); int StopTrack(); private: };
The problem is that in my program if I run
Quote:
DSMusic Main; // Sets up Direct Show Main.PlayTrack(Library[track].Path); //Loads and plays track DSMusic Second; // Sets up Direct Show Second.PlayTrack(Library[track].Path); //Loads and plays track Main.StopTrack();
The program will stop the 2nd track. It always stops the 2nd track even though I told it to stop the first. After loading the second track it seems I have no control over the first. Normally I would presume it is because "IMediaControl *g_pMediaControl;" relates to a pointer and thus when the second track is loaded the memory in the address changes but I thought that because I am using DSMusic as an object there should be 2 separate instances and thus should not affect each other. This is the first time I've attempted to use classes properly. You can tell by my comments that I'm not too sure about the filter graph idea either. I followed a tutorial on that front. [Edited by - Gegenki on August 14, 2009 11:40:20 AM]

Share this post


Link to post
Share on other sites
First, I'm not familiar with DirectShow.

However, with regard to the DSMusic class - you have 2 instances of DSMusic but you only have 1 instance of the pointer to the media controller, which is global.

It appears that each instance of DSMusic should have it's own pointers. Try making the pointers to the the graph and media stuff as class variables rather than global (i.e., declare them inside the class).

EDIT:
Quote:
Normally I would presume it is because "IMediaControl *g_pMediaControl;" relates to a pointer and thus when the second track is loaded the memory in the address changes


[SMILE] Exactly what's happening! DSMusic Main sets the variable. DSMusic Second comes along and changes it. DSMusic Main comes along and uses the pointer that Second created!

Share this post


Link to post
Share on other sites
Excellent, works perfectly; I didn't know that putting the variables in the source file made them global.

Thankyou =)
+rep

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this