Windows Mobile で導入されているフィルタは(残念ながら)かなり少ない。MSDN の Encoded Media のページから辿って Supported Video Codecs をみると Windows Mobile 6 では MS RLE, WMV Encoder DMO だけである。 Audio も MPEG-1 Audio Layer 1,2…。
今回は導入されているフィルタを列挙するアプリを作ってみる。Windows の DirectShow であれば IFilterMapper2
が使えるが、Windows Mobile では前バージョンの IFilterMapper
を使う。
UI
画面内に列挙したフィルタ名を表示するためのリストボックスを追加する。180行付近にある WM_CREATE
で次のコードを追加する。
1 2 3 4 | g_hList = CreateWindow(L"LISTBOX", L"", WS_CHILD|WS_VISIBLE|
(LBS_NOTIFY | WS_VSCROLL | WS_BORDER)|LBS_HASSTRINGS,
8, 8, 450, 550, hWnd, NULL
,g_hInst, NULL);
|
g_hList は HWND 型のグローバル変数として宣言しておくこと。
リソースエディタで IDR_MENU に「フィルタ取得」のメニュー項目を作成する。プロパティウインドウを開いて ID を ID_ENUMFILTER と指定する。170行目付近の WM_COMMMAND 処理にコードを追加する。
1 2 | case ID_ENUMFILTER:
DoEnumFilter();
|
DoEnumFilter
FilterMapper を CoCreateInstance
で作成する。IFilterMapper::EnumMatchingFilters
を使って IEnumRegFilters
を取得する。このインターフェイスで 1 つずつフィルタを列挙できる。せっかくなのでカメラデバイスのフィルタも挙げてみた。(参考)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | int DoEnumFilter() {
HRESULT hr;
IFilterMapper *pMapper = NULL;
IEnumRegFilters *pEnum = NULL;
IBaseFilter * pFilter = NULL;
hr = CoCreateInstance(CLSID_FilterMapper, NULL, CLSCTX_INPROC, IID_IFilterMapper, (void **)&pMapper);
if(FAILED(hr)){
return 0;
}
hr = pMapper->EnumMatchingFilters(&pEnum,0,FALSE,GUID_NULL,GUID_NULL,FALSE,FALSE,GUID_NULL,GUID_NULL);
REGFILTER *pRF = NULL;
ULONG cFetched;
while (pEnum->Next(1, &pRF, &cFetched) == S_OK) {
SendMessage(g_hList,LB_ADDSTRING,0,(LPARAM)pRF->Name);
CoTaskMemFree(pRF);
hr = CoCreateInstance(pRF->Clsid, NULL, CLSCTX_INPROC
, IID_IBaseFilter, (void **)&pFilter);
SendMessage(g_hList,LB_ADDSTRING,0,(LPARAM)TEXT(" [IN]"));
EnumPins(pFilter,PINDIR_INPUT);
SendMessage(g_hList,LB_ADDSTRING,0,(LPARAM)TEXT(" [OUT]"));
EnumPins(pFilter,PINDIR_OUTPUT);
SAFE_RELEASE(pFilter);
}
// capture device
HANDLE handle = NULL;
DEVMGR_DEVICE_INFORMATION di={sizeof(di)};
GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A,0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 };
handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di );
if(( handle == NULL ) || ( di.hDevice == NULL )) {
}else{
SendMessage(g_hList,LB_ADDSTRING,0,(LPARAM)di.szLegacyName );
}
FindClose( handle );
return 1;
}
|
EnumPins の実装
フィルタに備わっているピンも表示させてみよう。ピンを列挙する EnumPins
関数を実装する。
フィルタの IBaseFilter::EnumPins
を呼び出してピンを列挙する。引数 dir で指定した入力ピン、出力ピンと一致していればピン名の文字列をリストボックスに追加する。ただし、このやり方では動的にピンの数が変化するようなフィルタの場合は有効に働かない。既定で備わってるピンのみ列挙される。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | HRESULT EnumPins(IBaseFilter *pFilter,PIN_DIRECTION dir) {
HRESULT retCode=E_FAIL;
HRESULT hr=NOERROR;
IEnumPins *e=NULL;
IPin *pPin=NULL;
hr=pFilter->EnumPins(&e);
if(FAILED(hr)){
return hr;
}
while (e->Next(1, &pPin, NULL) == S_OK){
PIN_DIRECTION PinDirThis;
hr=pPin->QueryDirection(&PinDirThis);
if (FAILED(hr)){
SAFE_RELEASE(pPin);
continue;
}
if (PinDirThis != dir){
SAFE_RELEASE(pPin);
continue;
}
PIN_INFO info;
hr=pPin->QueryPinInfo(&info);
if (FAILED(hr)){
SAFE_RELEASE(pPin);
continue;
}
WCHAR name[256];
_snwprintf(name,256,TEXT(" - %s"),info.achName);
SendMessage(g_hList,LB_ADDSTRING,0,(LPARAM)name);
SAFE_RELEASE(info.pFilter);
SAFE_RELEASE(pPin);
}
SAFE_RELEASE(e);
return retCode;
}
|
Comments
comments powered by Disqus