Passaggio 5: Aggiungere funzionalità video
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stato sostituito da MediaPlayer, IMFMediaEnginee Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di utilizzare il nuovo codice con MediaPlayer, IMFMediaEngine e Acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.
Questo argomento è il passaggio 5 del tutorial Riproduzione Audio/Video in DirectShow. Il codice completo è illustrato nell'argomento DirectShow Playback Example.
Per assicurarsi che il video venga visualizzato correttamente, l'applicazione deve rispondere ai messaggi WM_PAINT, WM_SIZEe WM_DISPLAYCHANGE come indicato di seguito.
Gestire i messaggi di WM_PAINT
Quando l'applicazione riceve un messaggio di WM_PAINT, il renderer video potrebbe dover ridisegnare l'ultimo fotogramma video. Per il filtro EVR (Enhanced Video Renderer), chiamare IMFVideoDisplayControl::RepaintVideo.
HRESULT CEVR::Repaint(HWND hwnd, HDC hdc)
{
if (m_pVideoDisplay)
{
return m_pVideoDisplay->RepaintVideo();
}
else
{
return S_OK;
}
}
Per il filtro Video Mixing Renderer 9 (VMR-9), chiamare IVMRWindowlessControl9::RepaintVideo.
HRESULT CVMR9::Repaint(HWND hwnd, HDC hdc)
{
if (m_pWindowless)
{
return m_pWindowless->RepaintVideo(hwnd, hdc);
}
else
{
return S_OK;
}
}
Per Video Mixing Renderer Filter 7 (VMR-7), chiamare IVMRWindowlessControl::RepaintVideo.
HRESULT CVMR7::Repaint(HWND hwnd, HDC hdc)
{
if (m_pWindowless)
{
return m_pWindowless->RepaintVideo(hwnd, hdc);
}
else
{
return S_OK;
}
}
Gestire i messaggi di WM_SIZE
Se le dimensioni della finestra video cambiano, inviare una notifica al renderer video per ridimensionare il video. Per EVR chiamare IMFVideoDisplayControl::SetVideoPosition.
HRESULT CEVR::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
if (m_pVideoDisplay == NULL)
{
return S_OK; // no-op
}
if (prc)
{
return m_pVideoDisplay->SetVideoPosition(NULL, prc);
}
else
{
RECT rc;
GetClientRect(hwnd, &rc);
return m_pVideoDisplay->SetVideoPosition(NULL, &rc);
}
}
Per VMR-9, chiamare IVMRWindowlessControl9::SetVideoPosition.
HRESULT CVMR9::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
if (m_pWindowless == NULL)
{
return S_OK; // no-op
}
if (prc)
{
return m_pWindowless->SetVideoPosition(NULL, prc);
}
else
{
RECT rc;
GetClientRect(hwnd, &rc);
return m_pWindowless->SetVideoPosition(NULL, &rc);
}
}
Per VMR-7, chiamare IVMRWindowlessControl::SetVideoPosition.
HRESULT CVMR7::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
if (m_pWindowless == NULL)
{
return S_OK; // no-op
}
if (prc)
{
return m_pWindowless->SetVideoPosition(NULL, prc);
}
else
{
RECT rc;
GetClientRect(hwnd, &rc);
return m_pWindowless->SetVideoPosition(NULL, &rc);
}
}
Gestire i messaggi di WM_DISPLAYCHANGE
Se la modalità di visualizzazione cambia, è necessario inviare una notifica al filtro VMR-9 o VMR-7. Per il VMR-9, chiamare IVMRWindowlessControl9::DisplayModeChanged.
HRESULT CVMR9::DisplayModeChanged()
{
if (m_pWindowless)
{
return m_pWindowless->DisplayModeChanged();
}
else
{
return S_OK;
}
}
Per VMR-7, chiamare IVMRWindowlessControl::DisplayModeChanged.
HRESULT CVMR7::DisplayModeChanged()
{
if (m_pWindowless)
{
return m_pWindowless->DisplayModeChanged();
}
else
{
return S_OK;
}
}
L'EVR non deve ricevere una notifica quando cambia la modalità di visualizzazione.
Avanti: Passaggio 6: Gestire eventi grafici.
Argomenti correlati