6

So basiclly I read this, http://www.gdcl.co.uk/2011/June/UnregisteredFilters.htm.

Which tells you how to use filters without registering them. There are two methods, new and using a private CoCreateInstance. Im trying to use the CoCreateInstance method.

In the sample from the site the code is listed as,

IUnknownPtr pUnk;
HRESULT hr = CreateObjectFromPath(TEXT("c:\\path\\to\\myfilter.dll"), IID_MyFilter, &pUnk);
if (SUCCEEDED(hr))
{
    IBaseFilterPtr pFilter = pUnk;
    pGraph->AddFilter(pFilter, L"Private Filter");
    pGraph->RenderFile(pMediaClip, NULL);
}

My code as follows,

IUnknownPtr pUnk;
HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4demux.dll"), IID_BaseFilter, &pUnk);
if (SUCCEEDED(hr))
{
  //add functionality
}

I'm guessing IID_BaseFilter is what Im supposed to use, its what I use for other filters. But I'm given the error 'ClassFactory cannot supply requested class'.

Am I missing something here? Any help would be greatly appreciated. Thanks in advance!

EDIT: code

IBaseFilter *pSrc = NULL, *pSrc2 = NULL, *pWaveDest = NULL, *pWriter = NULL;
IFileSinkFilter *pSink= NULL;
IGraphBuilder *pGraph;
ICaptureGraphBuilder2 *pBuild;
IMediaControl *pControl = NULL;
// This example omits error handling.

hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
    IID_ICaptureGraphBuilder2, (void**)&pBuild);

hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
//Initialize the Capture Graph Builder
hr = pBuild->SetFiltergraph(pGraph);

// Not shown: Use the System Device Enumerator to create the 
// audio capture filter.
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc);
hr = pGraph->AddFilter(pSrc, L"VideooCap");

hr = pMoniker2->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc2);
hr = pGraph->AddFilter(pSrc2, L"AudioCap");

IBaseFilter *pMux;
//IFileSinkFilter *pSink;
hr = pBuild->SetOutputFileName(
    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
    L"C:\\wav\\Example2.mp4", // File name.
    &pMux,              // Receives a pointer to the mux.
    NULL);              // (Optional) Receives a pointer to the file sink.

IUnknownPtr pUnk;
//static CLSID const clsid = { 0x025BE2E4, 0x1787, 0x4DA4, { 0xA5,0x85,0xC5,0xB2,0xB9,0xEE,0xB5,0x7C } };

static CLSID const clsid = { 0x5FD85181, 0xE542, 0x4e52, { 0x8D,0x9D,0x5D,0x61,0x3C,0x30,0x13,0x1B } };
//5FD85181-E542-4e52-8D9D5D613C30131B
HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4mux.dll"), clsid, &pUnk);
if (SUCCEEDED(hr))
{
    IBaseFilterPtr pFilter = pUnk;
    HRESULT hr = pGraph->AddFilter(pFilter, L"Private Filter");
}

hr = pBuild->RenderStream(
    NULL,//NULL,//&PIN_CATEGORY_CAPTURE, // Pin category.
    NULL,//&MEDIATYPE_Interleaved,//NULL,//&MEDIATYPE_Audio,      // Media type.
    pSrc,                  // Capture filter.
    NULL,                  // Intermediate filter (optional).
    pMux);                 // Mux or file sink filter.

hr = pBuild->RenderStream(
    NULL,//NULL,//&PIN_CATEGORY_CAPTURE, // Pin category.
    NULL,//&MEDIATYPE_Interleaved,//NULL,//&MEDIATYPE_Audio,      // Media type.
    pSrc2,                  // Capture filter.
    NULL,                  // Intermediate filter (optional).
    pMux);                 // Mux or file sink filter.

    IMediaControl *pMC = NULL;
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
    printf("START");  
    hr = pMC->Run();
    Sleep(4000);
      hr = pMC->Stop();
    printf("END");  
CoUninitialize();
    }
}
Erik Swansson
  • 147
  • 5
  • 16

1 Answers1

5

You should re-read Using Filters Without Registration. The second parameter is CLSID, the class identifier, not interface identifier (IBaseFilter).

For the GDCL MPEG-4 Demultiplexer, it is like this:

class __declspec(uuid("025BE2E4-1787-4DA4-A585-C5B2B9EEB57C")) GdclMp4Demux; // GDCL Mpeg-4 Demultiplexor
... = CreateObjectFromPath(..., __uuidof(GdclMp4Demux), ...);
Roman R.
  • 64,446
  • 5
  • 83
  • 139
  • Ah wow, I totally missed that. Sorry for my inexperience. Now I added the CLSID for the Multiplexer, which is the encoder if I'm not mistaken? It finds the filter and then I continue with IBaseFilterPtr pFilter = pUnk; pGraph->AddFilter(pFilter, L"Private Filter"); Now shouldn't that be enough to encode? The filesize is about the same as before. Or do I need to change something more like output type ( &MEDIASUBTYPE_Avi), is the current. Also thanks again Roman for you persistance in helping me, you are a hero :) – Erik Swansson Jun 25 '12 at 16:16
  • This is sufficient to add the filter and use it. I am not sure whether you are using it correctly - you need to explain what graph topology you have and the media types on pins. – Roman R. Jun 25 '12 at 16:26
  • Alright I added my code to the first post that shows everything. – Erik Swansson Jun 25 '12 at 16:37
  • This is a messy way: AVI is not MP4. If you are writing into MP4, build it all with `AddFilter` + `Connect`, without MEDIASUBTYPE_Avi etc. All you need is to complete your `RenderStream`s with adding File Writer on the output of MP4 Multiplexer filter (you can train in GraphEdit to see how it works). – Roman R. Jun 25 '12 at 17:31
  • Ok, thanks again for taking a look at my code. I will check out FileWriter and see if I can solve it :) – Erik Swansson Jun 25 '12 at 18:13
  • I suggest you branch it off into separate question. This one about filters without registration is perfectly complete. – Roman R. Jun 25 '12 at 18:23
  • Sorry for being back so fast. The thing with RenderStream is that it takes a IBaseFilter as sink or mux. And you can't set output with IBaseFilter as far as I can see. IFileSink can set output but then I can't use RenderStream? – Erik Swansson Jun 25 '12 at 19:03
  • `RenderStream` is nothing but a smart wrapper over `IGraphBuilder::Connect`. You can create your pipeline just by adding filters and connecting pins. – Roman R. Jun 25 '12 at 19:09
  • I took your advice and created a new question, whenever you got time I'd be incredible thankful if you could borrow me some of your wisdom :) http://stackoverflow.com/questions/11203063/how-to-render-and-save-captured-video-audio-into-a-custom-file-filter-format-in – Erik Swansson Jun 26 '12 at 08:04