DirectShowプログラミング開始

OpenCVとかKinectに行く前の下準備で、DirectShowをマスターすることにした。

この本を読みながら進めている。
VC2010 expressedition
を使う。

DirectShowのインストール?

VCとDirectXのバージョンによって情報が錯綜しているのだけど、
VC2010 expresseditionに関しては下記にdshow.hが存在した。
最初から入っているということでよさげ。

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include

動作確認

本の最初のDirectShowサンプルをC++風?に書いてみた。

#include <iostream>
#include <string>
#include <dshow.h>
#include <vector>
#pragma comment(lib, "strmiids")


class Com
{
public:
    Com()
    {
        CoInitialize(NULL);
    }

    ~Com()
    {
        CoUninitialize();
    }
};


class ComGraphBuilder
{
    IGraphBuilder *pigb;
public:
    ComGraphBuilder()
        : pigb(0)
    {
        HRESULT hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                IID_IGraphBuilder, (void**) &pigb);
    }

    ~ComGraphBuilder()
    {
        if(pigb){
            pigb->Release();
        }
    }

    bool RenderFile(const std::wstring &file)
    {
        return pigb->RenderFile(file.c_str(), NULL)==S_OK;
    }

    IGraphBuilder* Get(){ return pigb; }
};


class ComMediaControl
{
    IMediaControl *pimc;
public:
    ComMediaControl(IGraphBuilder *pigb)
        : pimc(0)
    {
        HRESULT hr=pigb->QueryInterface(IID_IMediaControl, (void**)&pimc);
    }

    ~ComMediaControl()
    {
        if(pimc){
            pimc->Release();
        }
    }

    void Run()
    {
        pimc->Run();
    }

    IMediaControl *Get(){ return pimc; }
};


static std::wstring to_WideChar(UINT uCodePage, const std::string &text)
{
    int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
    std::vector<wchar_t> buf(size);
    size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
    return std::wstring(buf.begin(), buf.begin()+size);
}


int main(int argc, char **argv)
{
    if(argc<2){
        std::cout << "usage: " << argv[0] << "  {file}" << std::endl;
        return 0;
    }

    Com com;

    ComGraphBuilder gb;
    if(!gb.Get()){
        return 1;
    }

    ComMediaControl mc(gb.Get());
    if(!mc.Get()){
        return 2;
    }

    if(!gb.RenderFile(to_WideChar(CP_OEMCP, argv[1]))){
        return 3;
    }

    mc.Run();

    std::cout << "hit any key" << std::endl;
    std::string line;
    std::getline(std::cin, line);

    return 0;
}