Sample Grabber Sink release()问题

时间:2013-03-11 14:37:23

标签: ms-media-foundation

我使用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解决了这个问题。

1 个答案:

答案 0 :(得分:1)

从代码片段中看不容易,但我想你是在一个流线程上烧掉循环(你已经调用了你的回调),直到全局/共享变量为NULL然后你复制了那里的媒体样本。

您需要查看同步API并序列化对共享变量的访问。你不这样做,最终要么你正在访问释放的内存或破坏COM对象的引用计数。

当你准备接受来自回调的新缓冲区时,你需要一个外部事件集,然后回调看到事件,进入关键部分(或读者/作者锁定),那里你的*pSample魔法,退出临界区并设置另一个事件,指示缓冲区的可用性。