当前位置: 代码迷 >> 多媒体/流媒体开发 >> CSource Filter 与VMR9 Filter黑屏有关问题
  详细解决方案

CSource Filter 与VMR9 Filter黑屏有关问题

热度:4625   发布时间:2013-02-26 00:00:00.0
CSource Filter 与VMR9 Filter黑屏问题
各位大侠大家好!
  小弟目前遇到一个问题:
  我在写一个:CSource Filter(生成一个音频输出Pin和一个视频输出pin)继承关系是:
  SourceFilter :public CSource,
  输出Pin的继承关系是:
  VideoOutPutPin:public CSourceStream,
  AuiodOutPutPin:public CSourceStream,
  这样两个pin就使用各自的内部线程进行解码,将解码之后的数据(UYVY格式的)送给下一级Renderer Filter,这个Renderer Filter就是系统的:Video Mixing Renderer 9,我把它设置成无窗口模式的。
  音频解码之后与Default DirectSound Device链接,然后运行整个Graph,这样正个Filter链路就正确运行啦!输出视频数据与音频数据都是正常的。
  其它一些设置:Graph的参考时钟是Audio Renderer Filter,然后每一帧的视频数据就打上相应的时间戳代码如下:
  REFERENCE_TIME rtStart = m_LastSampleTime;
m_LastSampleTime += 400000; //就是说我一秒钟播放25帧
REFERENCE_TIME rtEnd = m_LastSampleTime;
hr = pSample->SetTime(&rtStart, &rtEnd);
  音频的每一帧的播放时间为32ms;
到这里整个运行过程都很流畅,也能够同步,但是接下来的问题就有啦:当我的系统进入屏保之后,这个时候声音还是正常播放的
,再进到桌面之后,声音也还是继续播放的,但是视频没有啦!当然我知道这个视频没有的原因:是因为没有调用Graph的VMR9的mVMRWindowlessControl9->RepaintVideo()函数,但是当我调用该函数之后,音视频就停止播放啦!这才是最严重的问题!这是为什么呢?它停止播放十几秒之后,双可以播放啦!
  我在程序中跟踪进去发现在重写输出Pin的DoBufferProcessingLoop函数中发生阻塞:
HRESULT VideoOutPutPin::DoBufferProcessingLoop(void)
{
OutputDebugString(L"CDecodedStream::DoBufferProcessingLoop(void) start\n");
Command com;
OnThreadStartPlay();

BOOL EOS_Flag = FALSE;
do 
{
while (!CheckRequest(&com)) 
{

IMediaSample *pSample;
HRESULT hr = GetDeliveryBuffer(&pSample, NULL, NULL, AM_GBF_NOWAIT);
//就是在这个函数中发生阻塞,本人怀凝在进入系统屏保之后与VMR9有一些关系,也有人曾经说重写SourceFilter的这个函数
////HRESULT GetState(DWORD dwMilliSecsTimeout,FILTER_STATE *State);函数体如下:还是不能够解决这个问题
if (FAILED(hr)) 
{
Sleep(1);
continue; // go round again. Perhaps the error will go away
// or the allocator is decommited & we will be asked to
// exit soon.
}

hr = DeliverCurrentPicture(pSample);

}

// For all commands sent to us there must be a Reply call!
if (com == CMD_RUN || com == CMD_PAUSE) 
{
Reply(NOERROR);
}
else if (com != CMD_STOP) 
{
Reply((DWORD) E_UNEXPECTED);
DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
}
} while (com != CMD_STOP);

OutputDebugString(L"FG_AV_VideoOutPutPin::DoBufferProcessingLoop(void) exit\n");
return S_FALSE;
}

HRESULT SourceFilter::GetState(DWORD dwMilliSecsTimeout,FILTER_STATE *State)
{
TRACE("FG_AV_SourceFilter::GetState\n");
CheckPointer(State, E_POINTER); 
*State=m_State; 
if(m_State==State_Paused)

return VFW_S_CANT_CUE; 
}
else

return S_OK; 


}
各位大哥有谁遇到个同样的问题呀?谢谢
 

------解决方案--------------------------------------------------------
一般视频不能显示和关键帧有关,不知LZ有没有检测关键帧,关键帧可以运用函数
SetSyncPoint(TRUE),SetDiscontinuity(TRUE)来标识一下。
GetDeliveryBuffer(&pSample, NULL, NULL, AM_GBF_NOWAIT); 发生阻塞有点奇怪,是用AM_GBF_NOWAIT标识啊?!
这个应该和VMR9没关系,要不LZ换老的renderer试试。

仅供参考!

  相关解决方案