0

msdn サンプルのほとんどのコードを使用して、メディア セッションで Sample Grabber Sink を使用しています。

OnProcessSample メソッドでは、データをメディア バッファーに memcpy し、MFSample にアタッチして、これをメイン プロセス ポインターに配置します。問題は、ntdll.dll でメモリ リークまたはクラッシュが発生することです。

ntdll.dll!@RtlpLowFragHeapFree@8() 不明

サンプルグラバーシンク:

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 エラーが発生します。また、OnProcess が待機する必要がないように、サンプルをキューにプッシュしようとしましたが、ビデオが終了した後、一部のメモリが解放されませんでした。(今でもほとんど待たず、セッションレートは 1 で、メインプロセスは 60fps 以上を読み取ることができます)

編集:スレッド同期の問題でした。Roman R のおかげでクリティカル セクションを使用して解決しました。

4

1 に答える 1

1

コード スニペットから見るのは簡単ではありませんが、ストリーミング スレッド (コールバックが呼び出されている) で、グローバル/共有変数が存在するまでサイクルを焼き付けており、NULLそこにメディア サンプルを複製していると思います。

同期 API を見て、共有変数へのアクセスをシリアル化する必要があります。そうしないと、最終的には、解放されたメモリにアクセスするか、COM オブジェクトの参照カウントを壊します。

コールバックから新しいバッファを受け入れる準備ができたら、外部でイベントを設定する必要があります。その後、コールバックはイベントを確認し、クリティカル セクション (またはリーダー/ライター ロック) に入り、*pSampleそこで魔法を実行し、クリティカル セクションを終了し、別のイベントを設定します。バッファの可用性を示します。

于 2013-03-11T16:28:56.610 に答える