gpt4 book ai didi

c++ - 在 DirectShow 中保持纵横比? (窗口)C++

转载 作者:行者123 更新时间:2023-11-28 05:03:14 25 4
gpt4 key购买 nike

编辑:更新了代码,调用 DLL 的应用程序不再崩溃。

我希望 DirectShow 播放的视频在 show_video() 的第四个参数设置为 true 时保持其宽高比。这是我的 DLL 源代码:

#include <windows.h>
#include <dshow.h>

#pragma comment (lib, "strmiids.lib")
#define DLL extern "C" _declspec(dllexport)

wchar_t *convertCharArrayToLPCWSTR(const char* charArray) {
wchar_t* wString = new wchar_t[4096];

MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);

return wString;
}

DLL void show_video(double window1, HWND window2, char *fname, double keep_aspect_ratio) {
CoInitialize(NULL);

HRESULT hr = S_OK;

IGraphBuilder *pGraph = NULL;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
hr = pGraph->RenderFile(convertCharArrayToLPCWSTR(fname), NULL);

IBaseFilter *pVideoRenderer = NULL;
hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pVideoRenderer);

IVMRAspectRatioControl *pAspectRatio = NULL;
hr = pVideoRenderer->QueryInterface(IID_IVMRAspectRatioControl, (void**)&pAspectRatio);

if ((bool)keep_aspect_ratio == true) {
hr = pAspectRatio->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
}
else {
hr = pAspectRatio->SetAspectRatioMode(VMR_ARMODE_NONE);
}

IVideoWindow *pVidWin = NULL;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

RECT rect;
if ((HWND)(DWORD)window1 != NULL) {
SetWindowLong((HWND)(DWORD)window1, GWL_STYLE, GetWindowLong((HWND)(DWORD)window1, GWL_STYLE) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
hr = pVidWin->put_Owner((OAHWND)(HWND)(DWORD)window1);
GetClientRect((HWND)(DWORD)window1, &rect);
}
else {
SetWindowLong(window2, GWL_STYLE, GetWindowLong(window2, GWL_STYLE) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
hr = pVidWin->put_Owner((OAHWND)window2);
GetClientRect(window2, &rect);
}

hr = pVidWin->SetWindowPosition(0, 0, rect.right - rect.left, rect.bottom - rect.top);
hr = pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
hr = pVidWin->SetWindowForeground(OATRUE);
hr = pVidWin->HideCursor(OATRUE);

IMediaControl *pControl = NULL;
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
hr = pControl->Run();

IMediaEvent *pEvent = NULL;
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
long evCode;

hr = pEvent->WaitForCompletion(INFINITE, &evCode);

hr = pControl->Stop();
hr = pVidWin->put_Visible(OAFALSE);
hr = pVidWin->put_Owner(NULL);

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

pAspectRatio->Release();
pVideoRenderer->Release();
pGraph->Release();

CoUninitialize();
}

就目前而言,从我的应用程序调用 DLL,我为第三个参数选择的视频播放正常,但视频不保持其原始纵横比。有谁知道我做错了什么?

最佳答案

找到解决方案。初始化 pVideoRenderer 后,我需要添加以下行:

pGraph->FindFilterByName(L"Video Renderer", &pVideoRenderer);

因此生成的代码如下所示:

#include <windows.h>
#include <dshow.h>

#pragma comment (lib, "strmiids.lib")
#define DLL extern "C" _declspec(dllexport)

wchar_t *convertCharArrayToLPCWSTR(const char* charArray) {
wchar_t* wString = new wchar_t[4096];

MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);

return wString;
}

DLL void show_video(double window1, HWND window2, char *fname, double keep_aspect_ratio) {
CoInitialize(NULL);

HRESULT hr = S_OK;

IGraphBuilder *pGraph = NULL;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
hr = pGraph->RenderFile(convertCharArrayToLPCWSTR(fname), NULL);

IBaseFilter *pVideoRenderer = NULL;
hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pVideoRenderer);
pGraph->FindFilterByName(L"Video Renderer", &pVideoRenderer);

IVMRAspectRatioControl *pAspectRatio = NULL;
hr = pVideoRenderer->QueryInterface(IID_IVMRAspectRatioControl, (void**)&pAspectRatio);

if ((bool)keep_aspect_ratio == true) {
hr = pAspectRatio->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
}
else {
hr = pAspectRatio->SetAspectRatioMode(VMR_ARMODE_NONE);
}

IVideoWindow *pVidWin = NULL;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

RECT rect;
if ((HWND)(DWORD)window1 != NULL) {
SetWindowLong((HWND)(DWORD)window1, GWL_STYLE, GetWindowLong((HWND)(DWORD)window1, GWL_STYLE) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
hr = pVidWin->put_Owner((OAHWND)(HWND)(DWORD)window1);
GetClientRect((HWND)(DWORD)window1, &rect);
}
else {
SetWindowLong(window2, GWL_STYLE, GetWindowLong(window2, GWL_STYLE) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
hr = pVidWin->put_Owner((OAHWND)window2);
GetClientRect(window2, &rect);
}

hr = pVidWin->SetWindowPosition(0, 0, rect.right - rect.left, rect.bottom - rect.top);
hr = pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
hr = pVidWin->SetWindowForeground(OATRUE);
hr = pVidWin->HideCursor(OATRUE);

IMediaControl *pControl = NULL;
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
hr = pControl->Run();

IMediaEvent *pEvent = NULL;
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
long evCode;

hr = pEvent->WaitForCompletion(INFINITE, &evCode);

hr = pControl->Stop();
hr = pVidWin->put_Visible(OAFALSE);
hr = pVidWin->put_Owner(NULL);

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

pAspectRatio->Release();
pVideoRenderer->Release();
pGraph->Release();

CoUninitialize();
}

问题解决了! :D

关于c++ - 在 DirectShow 中保持纵横比? (窗口)C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45428431/

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