アプリ版:「スタンプのみでお礼する」機能のリリースについて

DirectShowにてビデオキャプチャデバイスから
ファイルに保存する(プレビューウィンドウ付き)で
普通にAVIファイルには保存できますがフィルターのMicrosoft Video 1を追加して圧縮をして保存するようにしたいと思います。
(上記フィルタは本当に圧縮かどうかはわかりませんが。。。
GraphEditで確認したところ圧縮(保存ファイルサイズが激減)したようでしたので。。)
現在のフィルターグラフにMicrosoft Video 1を追加する方法をご教示願えればと思います。
初心者なのでMSDNなど見てもいまいち理解できません。
簡単なサンプルなどあれば助かります。
よろしくお願い致します。

A 回答 (1件)

 こんばんは。

以下のURLが参考になります。

 http://msdn.microsoft.com/ja-jp/library/cc973418 …
 http://msdn.microsoft.com/ja-jp/library/cc353106 …
 http://www.codeguru.com/forum/showthread.php?t=3 …

 圧縮コーデックの一覧から、Microsoft Video 1を探し出して見つかればフィルタを作成して、SplitterとMuxの間に挟み込めばOK見たいです。
 大分乱暴なコードですが、以下で圧縮が出来ました。参考程度に。

#include <stdio.h>
#include <dshow.h>
#include <qedit.h>

#pragma comment(lib, "strmiids.lib")

//コーデックを探す
static IBaseFilter* FindCodec(BSTR bstrDesire)
{
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IBaseFilter *pFilter = NULL;

HRESULT hr = ::CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);
if(FAILED(hr))
return pFilter;

hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnum, 0);
if(hr != S_OK)
return pFilter;

while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);
VARIANT var;
::VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if(SUCCEEDED(hr))
{
::wprintf(L"[codec %s]\n", var.bstrVal);

//見つかったのでフィルタを作成する
if(::lstrcmp(var.bstrVal, bstrDesire) == 0)
{
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
}
}
::VariantClear(&var);
pPropBag->Release();
pMoniker->Release();

//見つかっているのでループから抜ける
if(pFilter)break;
}

//最後の後始末
pSysDevEnum->Release();
pEnum->Release();
return pFilter;
}

int main()
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;

::CoInitialize(NULL);

//グラフの作成
::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

//コントロールとイベントの作成
pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

//グラフビルダーの作成
ICaptureGraphBuilder2* pBuilder = NULL;
::CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&pBuilder);

//フィルタの作成
IBaseFilter *pFileSource;
pGraph->AddSourceFilter( L"test.avi", L"Source", &pFileSource);

IBaseFilter *pAviSplit;
::CoCreateInstance(CLSID_AviSplitter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviSplit);

IBaseFilter *pAviMux;
::CoCreateInstance(CLSID_AviDest, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviMux);

IBaseFilter *pWriter;
::CoCreateInstance(CLSID_FileWriter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWriter);

IBaseFilter *pMSVideo1 = ::FindCodec(L"Microsoft Video 1");

//出力先の設定
IFileSinkFilter *pSink= NULL;
pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pSink);
pSink->SetFileName(L"testresult.avi", NULL);
pSink->Release();

//フィルタを追加
pGraph->AddFilter(pFileSource, L"AVI Source");
pGraph->AddFilter(pAviSplit, L"AVI Splitter");
pGraph->AddFilter(pAviMux, L"AVI MUX");
pGraph->AddFilter(pWriter, L"AVI Writer");
pGraph->AddFilter(pMSVideo1, L"Microsoft Video 1");

//フィルタ同士の接続
pBuilder->SetFiltergraph(pGraph);
pBuilder->RenderStream(0, 0, pFileSource, 0, pAviSplit);
pBuilder->RenderStream(0, &MEDIATYPE_Video, pAviSplit, pMSVideo1, pAviMux);//split⇔mux間にMS Video1を挟み込む
pBuilder->RenderStream(0, &MEDIATYPE_Audio, pAviSplit, 0, pAviMux);
pBuilder->RenderStream(0, 0, pAviMux, 0, pWriter);

//書き込みスタート
pControl->Run();

//達成まで待つ
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);

//停止 此れがないと駄目
pControl->Stop();

//始末
pControl->Release();
pEvent->Release();
pGraph->Release();
pFileSource->Release();
pAviSplit->Release();
pAviMux->Release();
pWriter->Release();
pMSVideo1->Release();
pBuilder->Release();
return 0;
}
    • good
    • 0
この回答へのお礼

大変細かな親切なご回答本当にありがとうございます。
とても分かりやすく、すぐにできました。
ありがとうございました。

お礼日時:2009/07/27 13:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!