Jump to content
  • Advertisement
Sign in to follow this  
Gegenki

DirectShow Objects Overlapping

This topic is 3264 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!