皓月云天

紧张中保持一份松弛

松弛中保持一份紧张

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Win7下 directshow 窗口模式退出全屏后黑屏,使用的方法是put_FullScreenMode,据说是因为win7的桌面组合效果导致的。

解决方法:改为无窗口或仿真全屏。

HRESULT PlayVideo::PutFullScreen(HWND ghApp)
{
HRESULT hr
=S_OK;


if (!bFullscreen)
{
// Save current message drain
pVidWin->get_MessageDrain((OAHWND)NULL);

// Set message drain to application main window
pVidWin->put_MessageDrain((OAHWND) ghApp);
pVidWin
->put_Owner( (OAHWND) NULL);

pVidWin
->put_WindowStyle(0);

pVidWin
->put_WindowStyleEx(WS_EX_TOPMOST | WS_POPUP);
pVidWin
->SetWindowPosition(0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
//全屏显示
bFullscreen = TRUE;
}
else
{
pVidWin
->put_MessageDrain((OAHWND)NULL);
pVidWin
->put_Visible(OAFALSE);
pVidWin
->put_Owner((OAHWND)Owner);
pVidWin
->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
pVidWin
->SetWindowForeground(OATRUE);
OnSize();
//调整视频窗口大小
bFullscreen = FALSE;
}

return hr;
}
void PlayVideo::OnSize()
{
HWND hwnd;
CWnd
*pcwnd;
CRect rect;
pVidWin
->get_Owner((OAHWND*)&hwnd);
pcwnd
=CWnd::FromHandle(hwnd);
pcwnd
->GetClientRect(&rect);
pVidWin
->SetWindowPosition(rect.left ,rect.top ,
rect.right ,rect.bottom );
}

http://blog.csdn.net/watzds/article/details/6618594#

http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/b8bf047d-8353-4b32-89a5-776bec85cb17/

Using Windowless Mode

http://msdn.microsoft.com/en-us/library/dd407299(VS.85).aspx

About Video Rendering in DirectShow

http://msdn.microsoft.com/en-us/library/dd373407(VS.85).aspx

http://alax.info/blog/tag/directshow

HRESULT ToggleFullScreen(void)
{
HRESULT hr
=S_OK;
LONG lMode;
static HWND hDrain=0;

// Don't bother with full-screen for audio-only files
if ((g_bAudioOnly) || (!pVW))
return S_OK;

CComPtr
<IBaseFilter> pVideoRender;
LIF(GetVideoRenderer(pGB, pVideoRender));


if (FALSE == g_bFullscreen)
{
// Save current message drain
LIF(pVW->get_MessageDrain((OAHWND *) &hDrain));

//Switch into the FullScren mode.

RECT rcMonitor
= {};
LIF(GetCurrentMonitorSize(rcMonitor, pVideoRender));

// Switch to full-screen mode
LIF(pVW->put_Visible(OAFALSE));

LIF(pVW
->put_Owner( (OAHWND) NULL));

LIF(pVW
->put_WindowStyle(0));

LIF(pVW
->put_WindowStyleEx(WS_EX_TOPMOST | WS_POPUP));

LIF(pVW
->SetWindowPosition(rcMonitor.left, rcMonitor.top,<br/> rcMonitor.right - rcMonitor.left, rcMonitor.bottom - rcMonitor.top));

LIF(CorrectAspectRatio(pVideoRender));

LIF(pVW
->put_Visible(OATRUE));

// Set message drain to application main window
LIF(pVW->put_MessageDrain((OAHWND) ghApp));

g_bFullscreen
= TRUE;
}
else
{
// Switch back to windowed mode

LIF(pVW
->put_Visible(OAFALSE));

LIF(pVW
->put_Owner((OAHWND)ghApp));

LIF(pVW
->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS));

LIF(pVW
->put_WindowStyleEx(0));


RECT client
={};
GetClientRect(ghApp,
&client);
LIF(pVW
->SetWindowPosition(client.left, client.top, client.right, client.bottom));


LIF(CorrectAspectRatio(pVideoRender));

// Undo change of message drain
LIF(pVW->put_MessageDrain((OAHWND) hDrain));

LIF(pVW
->put_Visible(OATRUE));

// Reset video window
LIF(pVW->SetWindowForeground(-1));

// Reclaim keyboard focus for player application
UpdateWindow(ghApp);
SetForegroundWindow(ghApp);
SetFocus(ghApp);
g_bFullscreen
= FALSE;
}

return hr;
}
And are help functions:

HRESULT GetVideoRenderer(IGraphBuilder
*pGraphBuilder, CComPtr<IBaseFilter>& pVideoRender)
{
pVideoRender.Release();
CheckPointer(pGraphBuilder, E_POINTER);
HRESULT hr
= S_FALSE; //The renderer is not found.
CComPtr<IEnumFilters> pEnum;
CComPtr
<IBaseFilter> pFilter;

ULONG ulFetched
= 0;

// Get filter enumerator
hr = pGraphBuilder->EnumFilters(&pEnum);
if (FAILED(hr)){
return hr;
}

hr
= pEnum->Reset();
if (FAILED(hr)){
return hr;
}

// Enumerate all filters in the graph
while( (pEnum->Next(1, &pFilter, &ulFetched) == S_OK))
{
CComPtr
<IBasicVideo> pIBasicVideo;
hr
= pFilter->QueryInterface(IID_IBasicVideo, reinterpret_cast<void**>(&pIBasicVideo));
if(SUCCEEDED(hr))
{
pVideoRender
= pFilter;
return S_OK;
}

pFilter.Release();
}

return E_NOTIMPL;
}

HRESULT GetCurrentMonitorSize(RECT
& rcMonitor, CComPtr<IBaseFilter>& pVideoRender)
{
CheckPointer(pVideoRender, E_POINTER);
HRESULT hr
= S_OK;

CComPtr
<IVMRMonitorConfig9> pVMRMonitorConfig9;
hr
= pVideoRender ->QueryInterface(IID_IVMRMonitorConfig9, reinterpret_cast<void**>(&pVMRMonitorConfig9));
if(SUCCEEDED(hr))
{
VMR9MonitorInfo vMonInfo[
16] = {}; // Array of VMR9MonitorInfo structures.
DWORD dwNumMonitors = 0; // Number of attached monitors.
UINT dwCutrrentMonitorIndex = 0;
LIF( pVMRMonitorConfig9
->GetAvailableMonitors(vMonInfo, 16, &dwNumMonitors) );
rcMonitor
= vMonInfo[dwCutrrentMonitorIndex].rcMonitor;
}
else
{
CComPtr
<IVMRMonitorConfig> pVMRMonitorConfig;
hr
= pVideoRender->QueryInterface(IID_IVMRMonitorConfig, reinterpret_cast<void**>(&pVMRMonitorConfig));
if(FAILED(hr)){
return hr;
}
VMRMONITORINFO vMonInfo[
16] = {}; // Array of VMRMONITORINFO structures.
DWORD dwNumMonitors = 0; // Number of attached monitors.
UINT dwCutrrentMonitorIndex = 0;
LIF( pVMRMonitorConfig
->GetAvailableMonitors(vMonInfo, 16, &dwNumMonitors) );
rcMonitor
= vMonInfo[dwCutrrentMonitorIndex].rcMonitor;
}

return S_OK;
}

HRESULT CorrectAspectRatio(CComPtr
<IBaseFilter>& pVideoRender)
{
CheckPointer(pVideoRender, E_POINTER);
HRESULT hr
= S_OK;
CComPtr
<IVMRAspectRatioControl9> pIVMRAspectRatioControl9;
hr
= pVideoRender ->QueryInterface(IID_IVMRAspectRatioControl9, reinterpret_cast<void**>(&pIVMRAspectRatioControl9));
if(SUCCEEDED(hr))
{
LIF( pIVMRAspectRatioControl9
->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX) );
}
else
{
CComPtr
<IVMRAspectRatioControl> pIVMRAspectRatioControl;
hr
= pVideoRender ->QueryInterface(IID_IVMRAspectRatioControl, reinterpret_cast<void**>(&pIVMRAspectRatioControl));
if(FAILED(hr)){
return hr;
}
LIF( pIVMRAspectRatioControl
->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX) );
}
return S_OK;
}

IVideoWindow FullScreen Vista Issues

http://social.msdn.microsoft.com/forums/en-US/windowsdirectshowdevelopment/thread/cd515f32-87f4-4726-a07d-f995fa521e1f/

1. DirectX Summer 2004 SDK has the most samples (recommended for this and other reasons on my site):
    C:\DXSDK\9_0\Samples\C++\DirectShow\Players\PlayWnd
2.  VMR7 and VMR9 are not obsolete.  However, some of us have written our own custom renderers because the stock renderers have limitations that we cannot live with.  EVR has its limitations too.
3.  The full screen vs. creating a borderless window the size of the screen comes up from time to time.  I prefer the latter because fullscreen mode has issues.  In the old days, when graphics cards had more problems stretching video in windowed mode, it was good to have fullscreen alternative.

http://tmhare.mvps.org/