我使用msdn sample中的大部分代码在我的媒体会话中使用Sample Grabber Sink。
在OnProcessSample方法中,我将数据存储到媒体缓冲区,将其附加到MFSample并将其放入主进程指针。问题是我在ntdll.dll
中遇到内存泄漏或崩溃ntdll.dll!@ RtlpLowFragHeapFree @ 8()未知
SampleGrabberSink:
OnProcessSample(...)
{
MFCreateMemoryBuffer(dwSampleSize,&tmpBuff);
tmpBuff->Lock(&data,NULL,NULL);
memcpy(data,pSampleBuffer,dwSampleSize); tmpBuff->Unlock();
MFCreateSample(&tmpSample);
tmpSample->AddBuffer(tmpBuff);
while(!(*Free) && (*pSample)!=NULL)
{
Sleep(1);
}
(*Free)=false;
(*pSample)=tmpSample;
(*Free)=true;
SafeRelease(&tmpBuff);
}
主线程中的
ReadSample()
{
if(pSample==NULL)
return;
while(!Free)
Sleep(1);
Free=false;
//process sample into dx surface//
SafeRelease(&pSample);
Free=true;
}
// hr检查省略// 使用此代码,我在播放几个视频后得到ntdll.dll错误。 我还尝试在qeue中推送样本,因此OnProcess不必等待,但是在视频结束后,一些内存没有释放。 (即使现在它实际上不等待,会话速率为1,主进程可以读取超过60fps)
编辑:这是线程同步问题。感谢Roman R。使用critical section解决了这个问题。
答案 0 :(得分:1)
从代码片段中看不容易,但我想你是在一个流线程上烧掉循环(你已经调用了你的回调),直到全局/共享变量为NULL
然后你复制了那里的媒体样本。
您需要查看同步API并序列化对共享变量的访问。你不这样做,最终要么你正在访问释放的内存或破坏COM对象的引用计数。
当你准备接受来自回调的新缓冲区时,你需要一个外部事件集,然后回调看到事件,进入关键部分(或读者/作者锁定),那里你的*pSample
魔法,退出临界区并设置另一个事件,指示缓冲区的可用性。