2012-06-18 15 views
8

Otrzymuję H.264 stream z DVR za pomocą jej SDK. Nie było wycieków pamięci i myślałem, że to SDK powoduje wszystkie wycieki. Ale kiedy nagrałem strumień i odtworzyłem klatki jeden po drugim odczytując z dysku (bez żadnych zewnętrznych bibliotek dll), zauważyłem, że problemem nie jest dll, ale sam strumień.Wycieki pamięci ramek H.264 z niektórymi dekoderami

Dziwne, to jedyny kodek, który nie powoduje przecieku pamięci, ale gdy strumień działa przez długi czas, czasami dekoder DivX również ulega awarii. Wolałbym używać Microsoft DTV-DVD Video Decoder, ale powoduje to ogromne przecieki pamięci i upuszcza wiele ramek. Wiele innych dekoderów H.264, które wypróbowałem, zachowuje się w ten sam sposób.

Przeanalizowałem h.264 frames używając jakiegoś h.264 parsers w porównaniu z innymi bezproblemowymi strumieniami, ale nie zauważyłem niczego oczywistego z logów.

Ponieważ mój problem dotyczy struktury klatek h.264, przygotowałem filtr źródłowy o nazwie FramesFromFileSourceFilter, który można pobrać poniżej.

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

To Visual Studio 2008 projekt i wszystkie zależności są zawarte w pliku zip w stosunkowo położonych folderów (łącznie z ramkami H.264). Tak więc, wszystko, co musisz zrobić, to skompilować projekt, zarejestrować wyjście przy pomocy regsvr32.exe i uruchomić filtr z dowolnym dekoderem h.264, który chcesz z GraphEdit lub GraphStudio. Przykładowe wykresy znajdują się poniżej.

FramesFromFileSourceFilter with DivX

FramesFromFileSourceFilter with Microsoft DTV-DVD Video Decoder

także H264 ramki są dostępne jako pojedynczy surowego pliku h264 w linku poniżej, które mogą być odtwarzane przez VLC (z niewłaściwym FPS od oryginału było 12 FPS).

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

Pytanie:

Co może być przyczyną problemów wyciek pamięci z wieloma znanymi H264 Dekodery wyjątkiem dekodera DivX. Co jest nie tak z tym strumieniem?

Aktualizacja 1

Odczyt gwint dane usunięto i przeniesiono do FillBuffer funkcjonalność bez stosowania buforów i flag. Problem pozostaje ten sam.

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

Aktualizacja 2

Update1 używał Sleep() w FillBuffer() funkcji, który powoduje pewne problemy. Teraz usunąłem Sleep() i użyłem SetTime(), aby uzyskać ~ 12 FPS. Rozwiązało to również problemy z pomijaniem ramek, ale nie rozwiązało problemów z pamięcią.

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

wzrost następuje w pamięci tylko Working Set. Virtual Bytes i Private Bytes wydają się być stabilne.Co może powodować ciągły przyrost pamięci, który ma miejsce tylko w przypadku Microsoft DTV-DVD Video Decoder?

Odpowiedz

3

Nie rób żadnych synchronizacji wokół zmiennych

BYTE* m_buffer; 
DWORD m_bufferSize; 
bool isFrameReady; 

i są stosowane z dwóch równoległych nitek. Po prostu tracisz pamięć przez tę niedokładną alokację/dealokację i/LUB zezwolenie na awarię twojego kodu w przypadku naruszenia dostępu. Debugowanie kompilacji biblioteki DLL wskazuje na to, wyświetlając alert "usterka sterty" podczas uruchamiania testu. Zachowanie środowiska wykonawczego może się różnić w zależności od dekoderów i środowiska, ale jest to z pewnością poważny błąd, który należy naprawić.

Na przykład można użyć CAutoLock cAutoLock(m_pLock); w swoim wątku, który wypełnia bufor, aby uniemożliwić dostęp do wątków strumieniowych podczas odczytu danych z pliku.

Należy zauważyć, że czytasz następną ramkę w tym samym wskaźniku bufora bez sprawdzania, czy poprzednio przydzielona pamięć została zwolniona, czy nie, po prostu nadpisujesz wskaźnik prawdopodobnie pozostawiając wyciek.

Memory Leak/Working Set Aktualizacja: Teraz, kiedy kwestie kodu są uporządkowane, niechciane zachowanie środowiska wykonawczego jest wzrost Working Set wielkości. To nie jest przeciek. Wskazuje to, że Windows traktuje proces jako priorytet (dlaczego nie? Jest aktywny i współpracuje z pamięcią) i rzuca więcej prawdziwych stron w kierunku tego procesu, aby ułatwić jego działanie. Zobacz this answer na dobre wyjaśnienie, w jaki sposób dane pamięci procesowej odpowiadają wyciekom pamięci w aplikacji.

Różnica pomiędzy dekoderem, który prawdopodobnie widzisz, prawdopodobnie wynika z faktu, że niektóre dekodery są dobre z mniejszą ilością buforów lub bardziej aktywnie je wykorzystują, np. wolą brać ten sam bufor z puli zamiast wybierać jeden po drugim przez wszystkie dostępne.

+0

Właściwie mój prawdziwy filtr ma lepszy mechanizm, jest to uproszczony. ale ponieważ między klatkami jest taki sen, jak 83 milisekundy, nie powinno to dotyczyć współbieżności. plus, dekoder DivX nie powoduje żadnych wycieków pamięci. wciąż wierzę, że strumienie powodują ten problem. dodatkowo, ten sam filtr działa dobrze z innymi strumieniami h.264 z innych urządzeń bez wycieków pamięci z tymi samymi dekoderami. –

+0

Może twój prawdziwy filtr działa lepiej, ale ten kod powoduje uszkodzenie sterty. Przy innym uruchomieniu, gdy udało się przejść, nie zauważyłem żadnego wycieku (z MS DTV-DVD Decoder), jak się dowiedzieć, czy wyciek miał miejsce? –

+0

Pamięć stale się zwiększa, dopóki filtr działa. oczywiście w tym przykładzie jest ograniczona liczba ramek. ale podczas pracy ze strumieniem na żywo użycie pamięci osiąga gigabajty po kilku godzinach. czy nie zauważyłeś wzrostu pamięci programu GraphEdit/GraphStudio po uruchomieniu filtru z dekoderem wideo DTV-DVD firmy MS? jeśli tak, jaki jest twój system operacyjny? udało mi się to na Win7 32 bitów. –