8

H.264 streamSDKを使用してDVRからを受信して​​います。メモリリークがあり、すべてのリークの原因はSDKだと思いました。しかし、ストリームを記録し、ディスクから1つずつフレームを読み取って再生すると(サードパーティのdllが関与していない場合)、問題はdllではなくストリーム自体にあることに気付きました。

奇妙なことにDivX H264 Decoder、メモリリークを引き起こさない唯一のコーデックですが、ストリームが長時間実行されると、DivXデコーダーもクラッシュすることがあります。使用したいMicrosoft DTV-DVD Video Decoderのですが、大量のメモリリークが発生し、多くのフレームがドロップされます。私が試した他の多くのH.264デコーダーも同じように動作します。

h.264 frames他の問題のないストリームと比較していくつかを使用して調べましたh.264 parsersが、ログから明らかなことは何もわかりませんでした。

私の問題はh.264フレーム構造に関するものなので、FramesFromFileSourceFilter以下からダウンロードできるという名前のソースフィルターを用意しました。

http://www.akaydin.com/directshow/FramesFromFileSourceFilter.zip

これはVisual Studio 2008プロジェクトであり、すべての依存関係は、比較的配置されたフォルダー(h.264フレームを含む)のzipファイルに含まれています。したがって、必要なのは、プロジェクトをコンパイルし、出力をに登録し、regsvr32.exeGraphEditまたはGraphStudioから必要なh.264デコーダーでフィルターを実行することだけです。グラフの例を以下に示します。

DivXを使用したFramesFromFileSourceFilter

FramesFromFileSourceFilterとMicrosoftDTV-DVDビデオデコーダー

また、h264フレームは、以下のリンクで単一の生のh264ファイルとして利用できます。これはVLCで再生できます(元のFPSは12 FPSであったため、FPSが間違っています)。

http://www.akaydin.com/directshow/stream.zip

質問:

DivXデコーダーを除く多くの有名なH264デコーダーでメモリリークの問題を引き起こしている可能性があります。このストリームの何が問題になっていますか?

アップデート1

データスレッドの読み取りは削除され、機能はバッファとフラグを使用せずにFillBufferに移動されます。問題は同じままです。

http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate1.zip

アップデート2

Update1は、いくつかの問題を引き起こしていた関数で使用Sleep()していました。FillBuffer()今、私はを削除しSleep()、以前SetTime()は〜12FPSでした。これによりMicrosoft DTV-DVD Video Decoder、フレームのドロップの問題も解決されましたが、メモリの問題は解決されませんでした。

http://www.akaydin.com/directshow/FramesFromFileSourceFilterUpdate2.zip

メモリの増加はでWorking Setのみ発生します。Virtual Bytes安定してPrivate Bytesいるようです。でのみ発生する継続的なWorking Setメモリ増分の原因は何でしょうMicrosoft DTV-DVD Video Decoderか?

4

1 に答える 1

3

変数の周りで同期を行いません

BYTE* m_buffer;
DWORD m_bufferSize;
bool isFrameReady;

そして、それらは2つの同時スレッドから使​​用されます。この不正確な割り当て/割り当て解除によってメモリをリークしたり、アクセス違反でコードをクラッシュさせたりするだけです。DLLのデバッグビルドは、テストの実行時に「ヒープ破損」アラートを表示することでこれを示します。実行時の動作はデコーダーや環境によって異なる場合がありますが、これは間違いなく修正すべき重大なバグです。

たとえば、CAutoLock cAutoLock(m_pLock);バッファをいっぱいにするスレッドで使用して、ファイルからデータを読み取っているときにスレッドアクセスがストリーミングされないようにすることができます。

以前に割り当てられたメモリが解放されているかどうかをチェックせずに次のフレームを同じバッファポインタに読み込むことに注意してください。ポインタを上書きするだけで、リークが残る可能性があります。

メモリリーク/ワーキングセットの更新:コードの問題が整理されると、不要なランタイム動作がWorking Setサイズの増加になります。これはリークではありません。これは、Windowsがプロセスを一種の優先順位と見なし(なぜそうではないのか?アクティブでメモリを処理する)、パフォーマンスを向上させるためにこのプロセスに向けてより多くの実際のページをスローすることを示しています。プロセスメモリメトリックがアプリケーションのメモリリークにどのように対応するかについての適切な説明については、この回答を参照してください。

表示されるデコーダー間の違いは、一部のデコーダーがバッファーの量が少ない場合に適している、またはそれらをより積極的に再利用するという事実によって引き起こされる可能性があります。たとえば、1つずつ選択するのではなく、プールから同じバッファーを取り出すことを好みます。利用可能なすべてを通して。

于 2012-06-28T13:02:29.813 に答える