gpt4 book ai didi

c++ - 视频窗口无响应,窗口模式,DirectShow

转载 作者:行者123 更新时间:2023-11-28 06:16:47 28 4
gpt4 key购买 nike

我想使用 Vmr 9 而不是默认的 Vmr 7,所以我使用 CoCreateInstance 创建它并使用 AddFilter 方法添加到图表中。接下来,我使用 RenderFile 方法构建图形。现在渲染器已连接,所以我查询 IVideoWindow 接口(interface)并使用在子线程中创建的窗口句柄调用 put_Owner 方法。当调用 Run 方法时,视频显示在窗口中,但窗口不处理消息,因此您不能移动它或调整它的大小。无窗口模式工作正常。为什么窗口会这样?

#include <dshow.h>

#include <D3D9.h>
#include <Vmr9.h>

#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "D3d9.lib")

#define WM_GRAPHNOTIFY WM_APP + 1

DWORD HandleGraphEvent(IMediaEventEx* media_event)
{
long EvCode;
LONG_PTR param1, param2;
while (media_event->GetEvent(&EvCode, &param1, &param2, 0) == S_OK)
{
media_event->FreeEventParams(EvCode, param1, param2);
switch (EvCode)
{
case EC_COMPLETE:
printf("All data is rendered\n");
return 0;
case EC_USERABORT:
printf("User has closed the window\n");
return 0;
case EC_ERRORABORT:
printf("Error occured\n");
return 0;
}
}

return 1;
}

struct WindowThreadParam
{
HANDLE event;
HWND window;

IMediaEventEx* media_event;
};

LRESULT WINAPI WindowProcedure(HWND window, unsigned int msg, WPARAM wp, LPARAM lp)
{
WindowThreadParam* param = (WindowThreadParam*)lp;

switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_GRAPHNOTIFY:
HandleGraphEvent(param->media_event);
default:
return DefWindowProc(window, msg, wp, lp);
}
}

DWORD WINAPI WindowThread(WindowThreadParam* param)
{
LPCWSTR myclass = TEXT("myclass");

WNDCLASSEX wndclass =
{ sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
0, 0, GetModuleHandle(0), LoadIcon(0, IDI_APPLICATION),
LoadCursor(0, IDC_ARROW), HBRUSH(COLOR_WINDOW + 1),
0, myclass, LoadIcon(0, IDI_APPLICATION) };

HWND window = NULL;

if (RegisterClassEx(&wndclass))
{
window = CreateWindowEx(0, myclass, TEXT("title"),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0);

if (window)
{
ShowWindow(window, SW_SHOWDEFAULT);

param->window = window;
SetEvent(param->event);

MSG msg;
while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
}
else SetEvent(param->event);

UnregisterClass(myclass, GetModuleHandle(0));
}
else SetEvent(param->event);

return 0;
}

void _tmain(int argc, _TCHAR* argv[])
{
HANDLE event_handle;
event_handle = CreateEvent(NULL, 0, 0, NULL); // auto, unsignaled

WindowThreadParam param;
ZeroMemory(&param, sizeof(param));
param.event = event_handle;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WindowThread, &param, 0, NULL);

IMediaControl *pControl = NULL;
IMediaEventEx *pEvent = NULL;

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}

IGraphBuilder* graph_builder;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&graph_builder);

IBaseFilter* Vrm;
hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&Vrm);
hr = graph_builder->AddFilter(Vrm, L"Video Mixing Renderer");

hr = graph_builder->RenderFile(L"anim.avi", NULL);

hr = graph_builder->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = graph_builder->QueryInterface(IID_IMediaEventEx, (void **)&pEvent);

IVideoWindow* VideoWindow;
RECT window_client_area;

WaitForSingleObject(param.event, INFINITE);
if (param.window)
{
// set window
hr = graph_builder->QueryInterface(IID_IVideoWindow, (void**)&VideoWindow);
hr = VideoWindow->put_Owner((OAHWND)param.window);
hr = VideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
// set video position
GetClientRect(param.window, &window_client_area);
hr = VideoWindow->SetWindowPosition(0, 0, window_client_area.right, window_client_area.bottom);

param.media_event = pEvent;
hr = pEvent->SetNotifyWindow((OAHWND)param.window, WM_GRAPHNOTIFY, (LONG_PTR)&param);
}

hr = pControl->Run();

// allow child thread to run
getchar();

pControl->Release();
pEvent->Release();
graph_builder->Release();

CoUninitialize();
}

最佳答案

您的主线程在 getchar(); 中休眠当它应该实现消息泵和传递窗口消息时,既作为 COM 要求,又作为 VMR 在主线程中创建的帮助程序窗口。

您的后台线程在这里无关紧要,因为您控制的 DirectShow 事件发生在 _tmain 中.

关于c++ - 视频窗口无响应,窗口模式,DirectShow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30128907/

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