Невозможно использовать WaitForCompletion () в #include - PullRequest
0 голосов
/ 07 марта 2019

Я использую Qt patch в visual studio 2008. Я пытаюсь запустить видео, используя #include <dshow.h>. Я могу успешно запустить видео, но при использовании WaitForCompletion() мое видео зависает. вот мой код: -

MediaPlayer = new Media(ui.stackedWidget->currentWidget());
connect(ui.stackedWidget->currentWidget(), SIGNAL(videograph()), MediaPlayer,SLOT(HandleGraphEvent()));
MediaPlayer->pMediaControl->Run();
long evCode;
MediaPlayer->g_pEvent1->WaitForCompletion(INFINITE,&evCode);

Мой заголовочный файл: -

Media.cpp

#include <dshow.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
#include <tchar.h>
//#include <atlbase.h>

#include "Media.h"
#include <qtconcurrentrun.h>

Media::Media(QWidget *parent)
{

    HRESULT hr;
    CoInitialize(NULL);
    hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr); 
    hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pWc); 
    hr = pWc->SetNumberOfStreams(2);
    hr = pVmr->QueryInterface(IID_IVMRMixerBitmap,(void **)&pBitMAp);

    if(SUCCEEDED(hr))
    {
        hr = pWc->SetRenderingMode(VMRMode_Windowless);
        hr = pWc->SetRenderingPrefs( RenderPrefs_ForceOffscreen| RenderPrefs_AllowOffscreen );
        pWc->Release();
    }
    if(SUCCEEDED(hr))
    {
        hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWl);
        if(SUCCEEDED(hr))
            hr = pWl->SetVideoClippingWindow(parent->winId()); 
    }

    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraph->QueryInterface(IID_IMediaEventEx, (void **)&g_pEvent);

    pGraph->QueryInterface(IID_IBasicAudio,(void **)&pAudio);
    pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pMediaSeeking );
    pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMediaPosition);
    hr = pGraph->AddFilter(pVmr, L"Video Mixing Renderer"); 
    g_pEvent->SetNotifyWindow((OAHWND)parent->winId(), WM_GRAPHNOTIFY, 0);  
    RECT grc;
    GetWindowRect(parent->winId(), &grc);
    pGraph->RenderFile(L"/FlashDisk/test.mp4", NULL);
    long lWidth, lHeight; 
    hr = pWl->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL); 
    if (SUCCEEDED(hr))
    {
        SetRect(&g_rcSRc, 0, 0, lWidth, lHeight); 
        GetWindowRect(parent->winId(), &g_rcDest); 
        SetRect(&g_rcDest, 0, 0, g_rcDest.right, g_rcDest.bottom); 
    }
    video_rendered = 1;
    pWl->SetVideoPosition(&g_rcSRc, &g_rcDest);
}

Media::~Media()
{
    CleanUp();
}

void Media::HandleGraphEvent()
{
    if (g_pEvent == NULL)
        return;
    long evCode;
    LONG_PTR param1, param2;
    while (SUCCEEDED(g_pEvent->GetEvent(&evCode, &param1, &param2, 0)))
    {
        g_pEvent->FreeEventParams(evCode, param1, param2);
        switch (evCode)
        {
            case EC_STATE_CHANGE:           //ADDED for state change from pause to play to indiacte video paused.
                //SetEvent(sync_event);
                return;
            case EC_COMPLETE:  // Fall through.
                CleanUp();
                return;
            case EC_USERABORT: // Fall through.
            case EC_ERRORABORT: 
                CleanUp(); 
                //media.play_next_file();
                return;
        }
    } 
}
/*#######################################################################################
CleanUp
#######################################################################################*/
void Media::CleanUp(void)
{
    video_rendered = 0;
    g_pEvent->SetNotifyWindow(NULL, 0, 0);
    g_pEvent->Release();
    g_pEvent = NULL;
    pMediaControl->Release();
    pAudio->Release();
    pGraph->Release();
}

Media.h

#ifndef MEDIA_H
#define MEDIA_H
//#define max(a,b)            (((a) > (b)) ? (a) : (b))
//#define min(a,b)            (((a) < (b)) ? (a) : (b))
#include <windef.h>
#include <QObject>
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <QTimer>
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#include <Phonon>
#include <dshow.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
#include <tchar.h>
//#include <atlbase.h>
#include <qtconcurrentrun.h>
#pragma comment (lib, "strmiids.lib")
#define WM_GRAPHNOTIFY  WM_APP + 1
#define WM_AUDIOGRAPHNOTIFY WM_APP + 2

class Media: public QObject
{
    Q_OBJECT
public:
    Media(QWidget *parent);
    ~Media();
    IMediaControl         *pMediaControl;
    IMediaEventEx         *g_pEvent;
    IMediaEvent           *g_pEvent1;
    IVideoWindow          *pVidWin;
    IVMRMixerBitmap       *pBitMAp;
    IVMRMixerBitmap       *pBitMAp1;
    IMediaSeeking         *pMediaSeeking;
    IMediaPosition        *pMediaPosition;
    IVMRFilterConfig      *pWc;
    IBaseFilter           *pVmr;
    IVMRWindowlessControl *pWl;
    RECT                   g_rcSRc; 
    RECT                   g_rcDest; 
    IBasicAudio           *pAudio;
    IVMRMixerControl      *pVmc;
    IGraphBuilder         *pGraph;
    DWORD                  width;
    unsigned char          video_rendered;
    void CleanUp(void);
    public slots:
    void HandleGraphEvent(void);
};


#endif 

Пожалуйста, подскажите, что мне здесь не хватает.

1 Ответ

0 голосов
/ 07 марта 2019

В потоке COM STA вы отвечаете за отправку оконных сообщений, а WaitForCompletion является блокирующим вызовом без обещания реализовать цикл сообщений.

См. Образец кода DShow для воспроизведения видео не воспроизводит видео

Простой способ выяснить, является ли проблема №2, - это разместить MessageBox между Run и WaitForCompletion. MessageBox отправляет вам сообщения, и пока вы держите окно открытым, видео также воспроизводится (или начинает хорошо воспроизводиться и продолжает воспроизводиться даже после закрытия окна). Правильное решение - это ждать и отправлять сообщения в одно и то же время (WaitDispatchingMessages, этот вопрос SO или аналогичный).

Это относится и к вашему делу, перейдите на конечное время ожидания, отправьте сообщения и вернитесь к другой попытке ожидания.

...