DirectShow là framework xử lý đa phương tiện trên Windows, hỗ trợ thu phát luồng dữ liệu chất lượng cao.
Bộ lọc (Filter) là thành phần COM, đòi hỏi hiểu biết cơ bản về công nghệ COM - đối tượng C++ triển khai giao diện con trỏ ảo.
Lập trình viên ứng dụng cần nắm: khởi tạo COM, gọi giao diện, quản lý bộ đếm tham chiếu. Phát triển bộ lọc yêu cầu kiến thức sâu hơn.
Xác định vị trí bộ lọc trong Filter Graph: dữ liệu đầu vào/ra, số lượng pin. Vẽ sơ đồ thiết kế trước khi triển khai.
Lưu ý: Từ Windows 7, DirectShow SDK nằm trong Windows SDK (GRMSDK_EN_DVD.iso), không còn bộ cài riêng.
Thiết lập dự án trong VS2008
1. Tạo dự án Visual C++/Win32 (DLL), ví dụ:
2. Chọn loại ứng dụng: DLL (không dùng MFC/ATL)
3. Đổi tên file output: Property Pages → Linker → Output File →
AudioProcessor2. Chọn loại ứng dụng: DLL (không dùng MFC/ATL)
3. Đổi tên file output: Property Pages → Linker → Output File →
$(OutDir)/AudioProcessor.ax
Cấu hình mã nguồn
Thêm thư viện và header:
#include "streams.h"
#include "initguid.h"
// File .def
LIBRARY AudioProcessor.ax
EXPORTS
DllMain PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
Xử lý lỗi biên dịch phổ biến:
- Lỗi
AMovieDllRegisterServer2: Thêm#include "streams.h" - Lỗi liên kết: Thêm
strmbasd.libvàwinmm.lib - Lỗi
CBaseFilter: Chuyển Character Set sang "Use Multi-Byte"
Triển khai bộ lọc mẫu
File AudioProcessor.h:
DEFINE_GUID(CLSID_AudioProcessor,
0x33b57142, 0xbd07, 0x4a77, 0xae, 0x91, 0xa8, 0xf6, 0xc2, 0x4a, 0x8f, 0x40);
class CAudioProcessor: public CCritSec, public CBaseFilter {
public:
CAudioProcessor(TCHAR *name, LPUNKNOWN unk, HRESULT *hr);
static CUnknown* CreateInstance(LPUNKNOWN unk, HRESULT *hr);
CBasePin* GetPin(int index);
int GetPinCount();
};
File AudioProcessor.cpp:
// Cấu hình PIN
const AMOVIESETUP_PIN pinConfig[] = {
{ L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, L"Output", 1, &mediaType },
{ L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, L"Input", 1, &mediaType }
};
CFactoryTemplate templates[] = {
{ L"Audio Processor", &CLSID_AudioProcessor,
CAudioProcessor::CreateInstance, NULL, &filterConfig }
};
CAudioProcessor::CAudioProcessor(TCHAR *name, LPUNKNOWN unk, HRESULT *hr)
: CBaseFilter(NAME("Audio Processor"), unk, this, CLSID_AudioProcessor) {}
CBasePin* CAudioProcessor::GetPin(int index) { return NULL; }
int CAudioProcessor::GetPinCount() { return 0; }
Kiểm thử
1. Đăng ký bộ lọc:
2. Sử dụng công cụ GraphEdit (graphedt.exe):
- Chọn Graph → Insert Filters → DirectShow Filters
- Tìm tên bộ lọc đã đăng ký (vd: "Audio Processor")
regsvr32 AudioProcessor.ax2. Sử dụng công cụ GraphEdit (graphedt.exe):
- Chọn Graph → Insert Filters → DirectShow Filters
- Tìm tên bộ lọc đã đăng ký (vd: "Audio Processor")