Memilih Filter Pemadatan
[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]
Beberapa jenis komponen perangkat lunak dapat melakukan kompresi video atau audio, seperti:
- Filter DirectShow asli
- Codec Video Compression Manager (VCM)
- Codec Audio Compression Manager (ACM)
- Objek Media DirectX (DMO)
Di DirectShow, codec VCM dibungkus oleh Filter Kompresor AVI, dan codec ACM dibungkus oleh Filter Pembungkus ACM. DMO dibungkus oleh Filter Pembungkus DMO. Enumerator perangkat sistem menyediakan cara yang konsisten untuk menghitung dan membuat salah satu jenis kompresor ini, tanpa khawatir tentang model yang mendasar.
Untuk detail tentang enumerator perangkat sistem, lihat Menggunakan Enumerator Perangkat Sistem. Secara singkat, semua filter DirectShow diklasifikasikan berdasarkan kategori, dan setiap kategori diidentifikasi oleh GUID. Untuk kompresor video, kategori GUID CLSID_VideoCompressorCategory. Untuk kompresor audio, CLSID_AudioCompressorCategory. Untuk menghitung kategori tertentu, enumerator perangkat sistem membuat objek enumerator yang mendukung antarmuka IEnumMoniker . Aplikasi ini menggunakan antarmuka ini untuk mengambil moniker perangkat, di mana setiap moniker perangkat mewakili instans filter DirectShow. Anda dapat menggunakan moniker untuk membuat filter, atau untuk mendapatkan nama perangkat yang mudah diingat tanpa membuat filter.
Untuk menghitung kompresor video atau audio yang tersedia di sistem pengguna, lakukan hal berikut:
- Panggil CoCreateInstance untuk membuat enumerator perangkat sistem, yang memiliki ID kelas CLSID_SystemDeviceEnum.
- Panggil ICreateDevEnum::CreateClassEnumerator dengan GUID kategori filter. Metode mengembalikan penunjuk antarmuka IEnumMoniker .
- Gunakan metode IEnumMoniker::Next untuk menghitung moniker perangkat. Metode ini mengembalikan antarmuka IMoniker , yang mewakili moniker.
Untuk mendapatkan nama yang mudah diingat dari moniker, lakukan hal berikut:
- Panggil metode IMoniker::BindToStorage . Metode ini mengembalikan penunjuk antarmuka IPropertyBag .
- Gunakan metode IPropertyBag::Read untuk membaca properti FriendlyName .
Biasanya, aplikasi akan menampilkan daftar kompresor, sehingga pengguna dapat memilihnya. Misalnya, kode berikut mengisi kotak daftar dengan nama kompresor video yang tersedia.
void OnInitDialog(HWND hDlg)
{
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pSysDevEnum);
if (FAILED(hr))
{
// Handle the error.
}
hr = pSysDevEnum->CreateClassEnumerator(
CLSID_VideoCompressorCategory, &pEnum, 0);
if (hr == S_OK) // S_FALSE means nothing in this category.
{
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))
{
LRESULT iSel = AddString(GetDlgItem(hDlg,
IDC_CODEC_LIST), var.bstrVal);
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
}
SendDlgItemMessage(hDlg, IDC_CODEC_LIST,
LB_SETCURSEL, 0, 0);
pSysDevEnum->Release();
pEnum->Release();
}
Untuk membuat instans filter dari moniker, panggil metode IMoniker::BindToObject . Metode mengembalikan penunjuk IBaseFilter .
IBaseFilter *pFilter = NULL;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)&pFilter);
if (SUCCEEDED(hr))
{
// Use the filter.
// Remember to release the IBaseFilter interface.
}
Untuk codec VCM, setiap moniker mewakili satu codec tertentu, meskipun semua codec dibungkus oleh filter Kompresi AVI yang sama. Memanggil BindToObject membuat instans filter ini, diinisialisasi untuk codec tersebut. Untuk alasan ini, Anda tidak dapat memanggil CoCreateInstance langsung pada filter Kompresi AVI. Anda harus melalui enumerator perangkat sistem.
Topik terkait