最近使用directshow 做了一个摄像头视频的采集模块,录制视频后同步进行压缩,主要有两种压缩方法,一种是调用x264进行每一帧数据的压缩,一种是创建一个Filter进行压缩。记录下主要的实现过程。
首先,枚举当前支持的摄像头详细信息,主要是通过枚举设备信息,然后返回每个设备的描述信息给用户界面:
static TCHAR ** EnumAllDevices(int *num)
{
CoInitialize(NULL);
int nCaptureDeviceNumber = 0; //Device Count
TCHAR **pCapDeviceName = (TCHAR **)malloc(10 * sizeof(TCHAR *));//先初始化二维数组的行
for (int i = 0; i<10; i++)//再初始化二维数组的列
pCapDeviceName[i] = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));
ICreateDevEnum *pDevEnum;
IEnumMoniker *pEnumMon;
IMoniker *pMoniker;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return 0;
}
pEnumMon->Reset();
ULONG cFetched;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
VARIANT varTemp;
varTemp.vt = VT_BSTR;
hr = pProBag->Read(L"FriendlyName",&varTemp,NULL);
if (SUCCEEDED(hr))
{
StringCchCopy(pCapDeviceName[nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal);
wprintf(L"[%d] %s\n", nCaptureDeviceNumber, pCapDeviceName[nCaptureDev