gpt4 book ai didi

c++ - DirectShow:视频预览和图像(带有工作代码)

转载 作者:太空宇宙 更新时间:2023-11-04 12:26:11 25 4
gpt4 key购买 nike

问题/问题

  • 如果有人可以向我推荐一个好的免费托管网站,我可以提供整个项目文件。
  • 如下文所述,TakePicture() 方法在 HTC HD 2 设备上无法正常工作。如果有人可以查看下面的代码并告诉我我正在做的事情是对还是错,那就太好了。

简介

我最近问了一个question关于显示视频预览、拍摄相机图像和使用 DirectShow 旋转视频流。关于该主题的棘手之处在于,很难找到好的示例和文档,而框架本身对于一般不熟悉 Windows 编程和 C++ 的人来说很难理解。

尽管如此,我还是设法创建了一个类来实现其中的大部分功能,并且可能适用于大多数移动设备。可能是因为 DirectShow 的实现在很大程度上取决于设备本身。我只能用 HTC HD 和 HTC HD2 测试它,它们被称为非常不兼容。

宏达高清

  • 工作:视频预览,将照片写入文件
  • 不工作:设置视频分辨率(崩溃),设置照片分辨率(低质量)

宏达高清 2

  • 工作:设置视频分辨率,设置照片分辨率
  • 有问题:视频预览旋转
  • 不工作:将照片写入文件

为了通过提供一个工作示例让其他人更容易,我决定在下面分享我目前所掌握的一切。为了简单起见,我删除了所有错误处理。就文档而言,我建议您阅读 MSDN documentation ,之后的代码就非常简单了。

void Camera::Init()
{
CreateComObjects();

_captureGraphBuilder->SetFiltergraph(_filterGraph);

InitializeVideoFilter();
InitializeStillImageFilter();
}

显示视频预览(适用于任何经过测试的手持设备):

void Camera::DisplayVideoPreview(HWND windowHandle)
{
IVideoWindow *_vidWin;

_filterGraph->QueryInterface(IID_IMediaControl,(void **) &_mediaControl);
_filterGraph->QueryInterface(IID_IVideoWindow, (void **) &_vidWin);
_videoCaptureFilter->QueryInterface(IID_IAMVideoControl,
(void**) &_videoControl);

_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, _videoCaptureFilter, NULL, NULL);

CRect rect;
long width, height;

GetClientRect(windowHandle, &rect);

_vidWin->put_Owner((OAHWND)windowHandle);
_vidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

_vidWin->get_Width(&width);
_vidWin->get_Height(&height);
height = rect.Height();

_vidWin->put_Height(height);
_vidWin->put_Width(rect.Width());
_vidWin->SetWindowPosition(0,0, rect.Width(), height);

_mediaControl->Run();
}

HTC HD2:如果设置 SetPhotoResolution() 被调用,FindPin 将返回 E_FAIL。如果不是,它将创建一个充满空字节的文件。 HTC 高清:工作

void Camera::TakePicture(WCHAR *fileName)
{
CComPtr<IFileSinkFilter> fileSink;
CComPtr<IPin> stillPin;
CComPtr<IUnknown> unknownCaptureFilter;
CComPtr<IAMVideoControl> videoControl;

_imageSinkFilter.QueryInterface(&fileSink);
fileSink->SetFileName(fileName, NULL);

_videoCaptureFilter.QueryInterface(&unknownCaptureFilter);

_captureGraphBuilder->FindPin(unknownCaptureFilter, PINDIR_OUTPUT,
&PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0, &stillPin);

_videoCaptureFilter.QueryInterface(&videoControl);
videoControl->SetMode(stillPin, VideoControlFlag_Trigger);
}

设置分辨率:在 HTC HD2 上效果很好。 HTC HD 不允许 SetVideoResolution() 并且只提供一种低分辨率照片分辨率:

void Camera::SetVideoResolution(int width, int height)
{
SetResolution(true, width, height);
}

void Camera::SetPhotoResolution(int width, int height)
{
SetResolution(false, width, height);
}


void Camera::SetResolution(bool video, int width, int height)
{
IAMStreamConfig *config;
config = NULL;

if (video)
{
_captureGraphBuilder->FindInterface(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, _videoCaptureFilter, IID_IAMStreamConfig,
(void**) &config);
}
else
{
_captureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL,
&MEDIATYPE_Video, _videoCaptureFilter, IID_IAMStreamConfig,
(void**) &config);

}

int resolutions, size;
VIDEO_STREAM_CONFIG_CAPS caps;
config->GetNumberOfCapabilities(&resolutions, &size);

for (int i = 0; i < resolutions; i++)
{
AM_MEDIA_TYPE *mediaType;
if (config->GetStreamCaps(i, &mediaType,
reinterpret_cast<BYTE*>(&caps)) == S_OK )
{
int maxWidth = caps.MaxOutputSize.cx;
int maxHeigth = caps.MaxOutputSize.cy;

if(maxWidth == width && maxHeigth == height)
{
VIDEOINFOHEADER *info =
reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);

info->bmiHeader.biWidth = maxWidth;
info->bmiHeader.biHeight = maxHeigth;
info->bmiHeader.biSizeImage = DIBSIZE(info->bmiHeader);
config->SetFormat(mediaType);

DeleteMediaType(mediaType);
break;

}

DeleteMediaType(mediaType);
}
}
}

用于构建过滤器图和创建 COM 对象的其他方法:

void Camera::CreateComObjects()
{
CoInitialize(NULL);

CoCreateInstance(CLSID_CaptureGraphBuilder, NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **) &_captureGraphBuilder);

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **) &_filterGraph);

CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**) &_videoCaptureFilter);

CoCreateInstance(CLSID_IMGSinkFilter, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**) &_imageSinkFilter);
}

void Camera::InitializeVideoFilter()
{
_videoCaptureFilter->QueryInterface(&_propertyBag);

wchar_t deviceName[MAX_PATH] = L"\0";
GetDeviceName(deviceName);
CComVariant comName = deviceName;

CPropertyBag propertyBag;
propertyBag.Write(L"VCapName", &comName);
_propertyBag->Load(&propertyBag, NULL);

_filterGraph->AddFilter(_videoCaptureFilter,
L"Video Capture Filter Source");
}

void Camera::InitializeStillImageFilter()
{
_filterGraph->AddFilter(_imageSinkFilter, L"Still image filter");

_captureGraphBuilder->RenderStream(&PIN_CATEGORY_STILL,
&MEDIATYPE_Video, _videoCaptureFilter, NULL, _imageSinkFilter);
}

void Camera::GetDeviceName(WCHAR *deviceName)
{
HRESULT hr = S_OK;
HANDLE handle = NULL;
DEVMGR_DEVICE_INFORMATION di;
GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93, 0x3E,
0x4D, 0x7E, 0x3C, 0x86 };

di.dwSize = sizeof(di);

handle = FindFirstDevice(DeviceSearchByGuid, &guidCamera, &di);
StringCchCopy(deviceName, MAX_PATH, di.szLegacyName);
}

完整头文件:

#ifndef __CAMERA_H__
#define __CAMERA_H__

class Camera
{
public:
void Init();
void DisplayVideoPreview(HWND windowHandle);
void TakePicture(WCHAR *fileName);
void SetVideoResolution(int width, int height);
void SetPhotoResolution(int width, int height);

private:
CComPtr<ICaptureGraphBuilder2> _captureGraphBuilder;
CComPtr<IGraphBuilder> _filterGraph;
CComPtr<IBaseFilter> _videoCaptureFilter;
CComPtr<IPersistPropertyBag> _propertyBag;
CComPtr<IMediaControl> _mediaControl;
CComPtr<IAMVideoControl> _videoControl;
CComPtr<IBaseFilter> _imageSinkFilter;

void GetDeviceName(WCHAR *deviceName);
void InitializeVideoFilter();
void InitializeStillImageFilter();
void CreateComObjects();
void SetResolution(bool video, int width, int height);
};

#endif

最佳答案

很遗憾,由于法律原因,我不能在这里分享解决方案。

尽管如此,我可以告诉您,在不使用 HTC HD 特定库的情况下,可以在 HTC HD 2 上以全分辨率支持拍摄视频和图像。

提示:您可能需要一个 NULL 渲染器。

关于c++ - DirectShow:视频预览和图像(带有工作代码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2371891/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com