代码之家  ›  专栏  ›  技术社区  ›  user4821390

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

  •  0
  • user4821390  · 技术社区  · 8 年前

    当show\u video()的第四个参数设置为true时,我希望DirectShow正在播放的视频保持其纵横比。这是我的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();
    }
    

    2 回复  |  直到 8 年前
        1
  •  1
  •   user4821390 user4821390    8 年前

    找到了解决方案。初始化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

        2
  •  0
  •   Roman Ryltsov    8 年前

    进程崩溃假设您可以提供其他详细信息,如崩溃点、异常详细信息等。

    可能的原因是 E_NOINTERFACE QueryInterface IVMRAspectRatioControl 指针。

    IVMRA频谱控制 查询接口 直接从它。

    CoCreateInstance 协同创建实例 总之,您不应该按名称查找过滤器-而是枚举过滤器,并通过查找实现所述接口的过滤器来识别您的虚拟现实。