Infognition forum
February 11, 2012, 06:52:32 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Last GraphEditPlus version: 1.4.0   Last Video Enhancer version: 1.9.7
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Generated code for rendering an MP3 doesn't work, no pins for mp3dmo (C++)  (Read 953 times)
jsidlosky
Newbie
*

Karma: +0/-0
Posts: 2


View Profile
« on: August 06, 2010, 12:45:01 AM »

Drop an mp3 in, generate C++, fix up the hrcheck() with char * so it compiles...

Now, it builds fine.  But when running it, there are NO pins found for CLSID_MP3DecoderDMO.  So of course it can't find the in0 pin!

I'm on Windows 7, below is the pasted generated code, building on Visual Studio 2005:



//Don't forget to change project settings:
//1. C++: add include path to DirectShow include folder (such as c:\dxsdk\include)
//2. Link: add link path to DirectShow lib folder (such as c:\dxsdk\lib).
//3. Link: add strmiids.lib and quartz.lib

#include "stdafx.h"
#include <DShow.h>
#include <atlbase.h>
#include <initguid.h>
#include <dvdmedia.h>

BOOL hrcheck(HRESULT hr, char* errtext)
{
   if (hr >= S_OK)
      return FALSE;
   TCHAR szErr[MAX_ERROR_TEXT_LEN];
   DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
   if (res)
      printf("Error %x: %s\n%s\n",hr, errtext,szErr);
   else
      printf("Error %x: %s\n", hr, errtext);
   return TRUE;
}

//change this macro to fit your style of error handling
#define CHECK_HR(hr, msg) if (hrcheck(hr, msg)) return hr;

CComPtr<IPin> GetPin(IBaseFilter *pFilter, LPCOLESTR pinname)
{
   CComPtr<IEnumPins>  pEnum;
   CComPtr<IPin>       pPin;

   HRESULT hr = pFilter->EnumPins(&pEnum);
   if (hrcheck(hr, "Can't enumerate pins."))
      return NULL;

   while(pEnum->Next(1, &pPin, 0) == S_OK)
   {
      PIN_INFO pinfo;
      pPin->QueryPinInfo(&pinfo);
      BOOL found = !wcsicmp(pinname, pinfo.achName);
      if (pinfo.pFilter) pinfo.pFilter->Release();
      if (found)
         return pPin;
      pPin.Release();
   }
   printf("Pin not found!\n");
   return NULL; 
}

// {94297043-BD82-4DFD-B0DE-8177739C6D20}
DEFINE_GUID(CLSID_MP3DecoderDMO,
         0x94297043, 0xBD82, 0x4DFD, 0xB0, 0xDE, 0x81, 0x77, 0x73, 0x9C, 0x6D, 0x20); //qasf.dll




HRESULT BuildGraph(IGraphBuilder *pGraph, LPCOLESTR srcFile1)
{
   HRESULT hr = S_OK;

   //graph builder
   CComPtr<ICaptureGraphBuilder2> pBuilder;
   hr = pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
   CHECK_HR(hr, "Can't create Capture Graph Builder");
   hr = pBuilder->SetFiltergraph(pGraph);
   CHECK_HR(hr, "Can't SetFiltergraph");

   //add File Source (Async.)
   CComPtr<IBaseFilter> pFileSourceAsync;
   hr = pFileSourceAsync.CoCreateInstance(CLSID_AsyncReader);
   CHECK_HR(hr, "Can't create File Source (Async.)");
   hr = pGraph->AddFilter(pFileSourceAsync, L"File Source (Async.)");
   CHECK_HR(hr, "Can't add File Source (Async.) to graph");
   //set source filename
   CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> pFileSourceAsync_src(pFileSourceAsync);
   if (!pFileSourceAsync_src)
      CHECK_HR(E_NOINTERFACE, "Can't get IFileSourceFilter");
   hr = pFileSourceAsync_src->Load(srcFile1, NULL);
   CHECK_HR(hr, "Can't load file");


   //add MPEG-I Stream Splitter
   CComPtr<IBaseFilter> pMPEGIStreamSplitter;
   hr = pMPEGIStreamSplitter.CoCreateInstance(CLSID_MPEG1Splitter);
   CHECK_HR(hr, "Can't create MPEG-I Stream Splitter");
   hr = pGraph->AddFilter(pMPEGIStreamSplitter, L"MPEG-I Stream Splitter");
   CHECK_HR(hr, "Can't add MPEG-I Stream Splitter to graph");


   //connect File Source (Async.) and MPEG-I Stream Splitter
   hr = pGraph->ConnectDirect(GetPin(pFileSourceAsync, L"Output"), GetPin(pMPEGIStreamSplitter, L"Input"), NULL);
   CHECK_HR(hr, "Can't connect File Source (Async.) and MPEG-I Stream Splitter");


   //add MP3 Decoder DMO
   CComPtr<IBaseFilter> pMP3DecoderDMO;
   hr = pMP3DecoderDMO.CoCreateInstance(CLSID_MP3DecoderDMO);
   CHECK_HR(hr, "Can't create MP3 Decoder DMO");
   hr = pGraph->AddFilter(pMP3DecoderDMO, L"MP3 Decoder DMO");
   CHECK_HR(hr, "Can't add MP3 Decoder DMO to graph");


   //connect MPEG-I Stream Splitter and MP3 Decoder DMO
   hr = pGraph->ConnectDirect(GetPin(pMPEGIStreamSplitter, L"Audio"), GetPin(pMP3DecoderDMO, L"in0"), NULL);
   CHECK_HR(hr, "Can't connect MPEG-I Stream Splitter and MP3 Decoder DMO");


   //add Default DirectSound Device
   CComPtr<IBaseFilter> pDefaultDirectSoundDevice;
   hr = pDefaultDirectSoundDevice.CoCreateInstance(CLSID_DSoundRender);
   CHECK_HR(hr, "Can't create Default DirectSound Device");
   hr = pGraph->AddFilter(pDefaultDirectSoundDevice, L"Default DirectSound Device");
   CHECK_HR(hr, "Can't add Default DirectSound Device to graph");


   //connect MP3 Decoder DMO and Default DirectSound Device
   hr = pGraph->ConnectDirect(GetPin(pMP3DecoderDMO, L"out0"), GetPin(pDefaultDirectSoundDevice, L"Audio Input pin (rendered)"), NULL);
   CHECK_HR(hr, "Can't connect MP3 Decoder DMO and Default DirectSound Device");


   return S_OK;
}

//int _tmain(int argc, _TCHAR* argv[]) //use this line in VS2008
int main(int argc, char* argv[])
{
   CoInitialize(NULL);
   CComPtr<IGraphBuilder> graph;
   graph.CoCreateInstance(CLSID_FilterGraph);

   printf("Building graph...\n");
   HRESULT hr = BuildGraph(graph, L"C:\\Tmp\\mp3.mp3");
   if (hr==S_OK) {
      printf("Running");
      CComQIPtr<IMediaControl, &IID_IMediaControl> mediaControl(graph);
      hr = mediaControl->Run();
      CHECK_HR(hr, "Can't run the graph");
      CComQIPtr<IMediaEvent, &IID_IMediaEvent> mediaEvent(graph);
      BOOL stop = FALSE;
      MSG msg;
      while(!stop)
      {
         long ev=0, p1=0, p2=0;
         Sleep(500);
         printf(".");
         while(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
            DispatchMessage(&msg);
         while (mediaEvent->GetEvent(&ev, &p1, &p2, 0)==S_OK)
         {
            if (ev == EC_COMPLETE || ev == EC_USERABORT)
            {
               printf("Done!\n");
               stop = TRUE;
            }
            else
               if (ev == EC_ERRORABORT)
               {
                  printf("An error occured: HRESULT=%x\n", p1);
                  mediaControl->Stop();
                  stop = TRUE;
               }
               mediaEvent->FreeEventParams(ev, p1, p2);
         }
      }
   }
   CoUninitialize();
   return 0;
}
Logged
jsidlosky
Newbie
*

Karma: +0/-0
Posts: 2


View Profile
« Reply #1 on: August 06, 2010, 01:02:14 AM »

I realize, it might have something to do with this: http://forum.infognition.com/index.php?topic=104.0

That many filters have the same CLSID, and they have to be enumerated differently to get the pins. 

Can anyone confirm?
Logged
Dee Mon
Administrator
Hero Member
*****

Karma: +8/-0
Posts: 517



View Profile WWW
« Reply #2 on: August 09, 2010, 11:00:56 AM »

DMO filters should be created via DMO wrapper:
http://msdn.microsoft.com/en-us/library/dd407273%28VS.85%29.aspx

Code generator in GEP doesn't know this yet, but it will be fixed in the next version.
Logged
thesane
Newbie
*

Karma: +1/-0
Posts: 1


View Profile
« Reply #3 on: August 29, 2010, 05:02:37 AM »

Thanks for the tip. it really helped
just a little snippet of the code that's might help others
Code:
DirectShowLib.DMO.IEnumDMO pEnumAudioDMO;
            hr = DirectShowLib.DMO.DMOUtils.DMOEnum(DirectShowLib.DMO.DMOCategory.AudioDecoder, DirectShowLib.DMO.DMOEnumerator.IncludeKeyed, 0, null, 0, null, out pEnumAudioDMO);
            Guid[] pAudioClasses = new Guid[1];
            Guid wantedAudioCLSID = new Guid();
            string[] pAudioNames = new string[1];
            IntPtr fetched = Marshal.AllocCoTaskMem(4);
            while (pEnumAudioDMO.Next(1, pAudioClasses, pAudioNames, fetched) == 0)
            {
                bool found = (pAudioNames[0] == "WMAudio Decoder DMO");
                if (found)
                {
                    wantedAudioCLSID = pAudioClasses[0];
                    break;
                }
            }

            IBaseFilter pWMAudioDecoderDMO = (IBaseFilter)new DMOWrapperFilter();
            IDMOWrapperFilter dmoWrapperFilter = (IDMOWrapperFilter)pWMAudioDecoderDMO;
            hr = dmoWrapperFilter.Init(wantedAudioCLSID, DirectShowLib.DMO.DMOCategory.AudioDecoder);
« Last Edit: August 29, 2010, 05:04:14 AM by thesane » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!