Ich erhalte ein H.264 stream
von einem DVR mit seinem SDK. Es gab Speicherverluste und ich dachte, dass es das SDK war, das alle Lecks verursachte. Aber als ich den Stream aufzeichnete und die Frames eins nach dem anderen abspielte (ohne irgendwelche Drittanbieter-DLLs), bemerkte ich, dass das Problem nicht die DLL ist, sondern der Stream selbst.
Seltsamerweise ist DivX H264 Decoder
der einzige Codec, der keinen Speicherverlust verursacht, aber wenn der Stream lange läuft, stürzt manchmal auch der DivX-Dekoder ab. Ich würde es vorziehen, Microsoft DTV-DVD Video Decoder
zu verwenden, aber es verursacht riesige Speicherlecks und lässt viele Frames fallen. Viele andere H.264-Decoder, die ich ausprobiert habe, verhalten sich genauso.
Ich habe die h.264 frames
mit einigen h.264 parsers
verglichen mit einigen anderen problemlosen Streams untersucht, aber ich habe nichts Logisches bemerkt.
Da mein Problem die Struktur der h.264-Frames ist, habe ich einen Quellfilter namens FramesFromFileSourceFilter
vorbereitet, den Sie unten herunterladen können.
Es ist ein Visual Studio 2008
-Projekt und alle Abhängigkeiten sind in der Zip-Datei in relativ lokalisierten Ordnern enthalten (einschließlich der h.264-Frames). Alles, was Sie tun müssen, ist das Projekt zu kompilieren, die Ausgabe mit regsvr32.exe
zu registrieren und den Filter mit einem beliebigen h.264-Decoder von GraphEdit oder GraphStudio auszuführen. Beispielgrafiken sind unten.
Auch h264-Frames sind als einzelne rohe h264-Datei unter dem Link verfügbar, der von VLC abgespielt werden kann (mit falschem FPS, da das Original 12 FPS hatte).
Frage:
Was bei vielen bekannten H264-Decodern mit Ausnahme des DivX-Decoders Probleme mit dem Speicherverlust verursachen könnte. Was stimmt nicht mit diesem Stream?
Update 1
Das Lesen des Datenthreads wird entfernt und die Funktionalität in FillBuffer verschoben, ohne Puffer und Flags zu verwenden. Das Problem bleibt gleich.
Update 2
Update1 verwendete Sleep()
in FillBuffer()
function, was einige Probleme verursachte. Jetzt habe ich Sleep()
entfernt und SetTime()
verwendet, um ~ 12 FPS zu haben. Dies löste auch die Drop-Frame-Probleme von Microsoft DTV-DVD Video Decoder
, löste jedoch keine Speicherprobleme.
Speichererhöhung tritt nur bei Working Set
auf. Virtual Bytes
und Private Bytes
scheinen stabil zu sein. Was könnte kontinuierliche Working Set
Speicherinkrement verursachen, was nur mit Microsoft DTV-DVD Video Decoder
passiert?
Sie führen keine Synchronisierung um Ihre Variablen durch
%Vor%Und sie werden von zwei gleichzeitigen Threads verwendet. Sie verlieren nur Ihren Speicher durch diese ungenaue Zuordnung / Freigabe AND / ODER lassen Sie Ihren Code bei Zugriffsverletzung abstürzen. Der Debug-Build Ihrer DLL zeigt dies an, indem Sie beim Ausführen des Tests die Warnung "Heap-Fehler" anzeigen. Das Laufzeitverhalten kann mit den Decodern und der Umgebung variieren, dies ist jedoch definitiv ein schwerwiegender Fehler, der behoben werden muss.
Sie können zum Beispiel CAutoLock cAutoLock(m_pLock);
in Ihrem Thread verwenden, der den Puffer füllt, um den Zugriff auf das Streaming-Thread zu verhindern, während Sie Daten aus der Datei lesen.
Beachten Sie, dass Sie den nächsten Frame in den gleichen Pufferzeiger lesen, ohne zu prüfen, ob zuvor zugewiesener Speicher freigegeben wurde oder nicht, Sie überschreiben einfach den Zeiger und hinterlassen möglicherweise ein Leck.
Memory Leak / Aktualisierung des Arbeitssatzes : Wenn nun Probleme mit dem Code behoben werden, ist das unerwünschte Laufzeitverhalten ein Anstieg in Working Set
size. Dies ist kein Leck. Es ist ein Hinweis darauf, dass Windows den Prozess als eine Art Priorität betrachtet (warum nicht? Er ist aktiv und arbeitet mit Speicher) und wirft mehr echte Seiten in diesen Prozess, um seine Leistung zu erleichtern. In dieser Antwort finden Sie eine gute Erklärung dafür, wie Prozessspeichermetriken Speicherlecks in einer Anwendung entsprechen.
Der Unterschied zwischen Decodern, den Sie sehen können, wird wahrscheinlich durch die Tatsache verursacht, dass einige Decoder mit einer kleineren Menge an Puffern gut sind oder sie aktiver wiederverwenden, z. ziehen es vor, den gleichen Puffer aus einem Pool zu nehmen, anstatt nacheinander durch alle verfügbaren zu picken.
Tags und Links memory-leaks stream video codec h.264