2012-06-18 45 views
8

Tôi nhận được H.264 stream từ DVR sử dụng SDK của nó. Đã có rò rỉ bộ nhớ và tôi nghĩ rằng đó là SDK gây ra tất cả các rò rỉ. Nhưng khi tôi ghi lại các dòng và chơi các khung một đọc một từ đĩa (mà không có bất kỳ dlls bên thứ 3 tham gia), tôi nhận thấy rằng vấn đề không phải là dll nhưng dòng chính nó.Bộ nhớ H.264 Bộ nhớ bị rò rỉ với một số bộ giải mã

Đủ lạ, DivX H264 Decoder là codec duy nhất không gây rò rỉ bộ nhớ nhưng khi luồng chạy trong một thời gian dài, đôi khi bộ giải mã DivX gặp sự cố. Tôi muốn sử dụng Microsoft DTV-DVD Video Decoder nhưng nó gây ra rò rỉ bộ nhớ rất lớn và giảm rất nhiều khung hình. Nhiều bộ giải mã H.264 khác mà tôi đã thử cũng hoạt động theo cùng một cách.

Tôi đã kiểm tra h.264 frames sử dụng một số h.264 parsers so sánh với một số luồng không có vấn đề khác nhưng tôi không nhận thấy bất kỳ điều gì rõ ràng từ nhật ký.

Vì vấn đề của tôi là cấu trúc khung hình h.264, tôi đã chuẩn bị bộ lọc nguồn có tên FramesFromFileSourceFilter mà bạn có thể tải xuống bên dưới.

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

Đó là một dự án Visual Studio 2008 và tất cả phụ thuộc có trong file zip trong các thư mục tương đối nằm (bao gồm cả khung h.264). Vì vậy, tất cả những gì bạn cần làm là biên dịch dự án, đăng ký đầu ra với regsvr32.exe và chạy bộ lọc với bất kỳ bộ giải mã h.264 nào bạn muốn từ GraphEdit hoặc GraphStudio. Biểu đồ ví dụ bên dưới.

FramesFromFileSourceFilter with DivX

FramesFromFileSourceFilter with Microsoft DTV-DVD Video Decoder

Cũng khung h264 có sẵn dưới dạng tập tin h264 liệu duy nhất tại liên kết dưới đây để có thể phát bằng VLC (với sai FPS kể từ khi ban đầu là 12 FPS).

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

Câu hỏi:

gì có thể gây ra những vấn đề rò rỉ bộ nhớ với nhiều Decoders H264 nổi tiếng trừ DivX giải mã. Điều gì là sai với dòng này?

Cập nhật 1

Đọc chủ đề dữ liệu được lấy ra và chức năng di chuyển vào FillBuffer mà không sử dụng bất kỳ bộ đệm và cờ. Vấn đề vẫn như cũ.

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

Cập nhật 2

Update1 đã sử dụng Sleep() trong FillBuffer() chức năng được gây ra một số vấn đề. Bây giờ tôi đã xóa Sleep() và sử dụng SetTime() để có ~ 12 FPS. Điều này cũng giải quyết được vấn đề về khung rơi của Microsoft DTV-DVD Video Decoder nhưng không giải quyết được vấn đề về bộ nhớ.

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

Memory tăng xảy ra ở chỉ Working Set. Virtual BytesPrivate Bytes dường như ổn định.Điều gì có thể gây ra việc tăng thêm bộ nhớ liên tục Working Set chỉ xảy ra với Microsoft DTV-DVD Video Decoder?

Trả lời

3

Bạn không làm bất kỳ đồng bộ xung quanh các biến của bạn

BYTE* m_buffer; 
DWORD m_bufferSize; 
bool isFrameReady; 

Và chúng được sử dụng từ hai đề cùng lúc. Bạn chỉ cần rò rỉ bộ nhớ của bạn bằng cách phân bổ không chính xác/deallocation AND/HOẶC cho phép mã của bạn sụp đổ về vi phạm truy cập. Gỡ lỗi xây dựng của DLL của bạn chỉ ra điều này bằng cách hiển thị cho bạn "heap tham nhũng" cảnh báo khi bạn chạy thử nghiệm của bạn. Các hành vi thời gian chạy có thể khác nhau với bộ giải mã và môi trường, tuy nhiên điều này chắc chắn là một lỗi nghiêm trọng để được cố định. Ví dụ:

Ví dụ: bạn có thể sử dụng CAutoLock cAutoLock(m_pLock); trong chuỗi của mình để lấp đầy bộ đệm để ngăn truy cập luồng trực tuyến trong khi bạn đang đọc dữ liệu từ tệp. Lưu ý rằng bạn đọc khung tiếp theo vào cùng một con trỏ đệm mà không kiểm tra xem bộ nhớ được cấp phát trước đó có được giải phóng hay không, bạn chỉ ghi đè lên con trỏ có thể để lại rò rỉ.

Cập nhật bộ nhớ/làm việc bộ nhớ: Bây giờ, khi các vấn đề về mã được sắp xếp, hành vi thời gian chạy không mong muốn là tăng kích thước Working Set. Đây không phải là rò rỉ. Nó là một dấu hiệu cho thấy Windows xem xét quy trình như là một loại ưu tiên (tại sao không? Nó hoạt động và hoạt động với bộ nhớ) và ném nhiều trang thực hơn vào quá trình này để tạo điều kiện cho hiệu suất của nó. Xem this answer về cách giải thích tốt về cách các chỉ số bộ nhớ xử lý tương ứng với rò rỉ bộ nhớ trong một ứng dụng.

Sự khác biệt giữa bộ giải mã mà bạn có thể thấy có thể do thực tế là một số bộ giải mã tốt với số lượng bộ đệm nhỏ hơn hoặc sử dụng lại chúng tích cực hơn, ví dụ: thích lấy cùng một bộ đệm ra khỏi một hồ bơi thay vì chọn từng cái một thông qua tất cả có sẵn.

+0

Thực ra, bộ lọc thực của tôi có cơ chế tốt hơn, đây là cơ chế đơn giản nhất. nhưng vì có một giấc ngủ như 83 miliseconds giữa các khung hình, nên không phải là trường hợp đồng thời ở đây. Ngoài ra, Bộ giải mã DivX không gây ra bất kỳ rò rỉ bộ nhớ nào. tôi vẫn tin rằng các luồng đang gây ra vấn đề này. Ngoài ra, cùng một bộ lọc hoạt động tốt với các luồng h.264 khác từ các thiết bị khác mà không có bất kỳ rò rỉ bộ nhớ nào có cùng bộ giải mã. –

+0

Có lẽ bộ lọc thực sự của bạn làm tốt hơn, nhưng mã này gây ra tham nhũng đống. Trên một lần chạy khác khi nó quản lý để đi qua, tôi đã không nhận thấy bất kỳ rò rỉ (với MS DTV-DVD Decoder), làm thế nào để bạn biết nếu rò rỉ đã diễn ra? Bộ nhớ –

+0

tiếp tục tăng trong suốt quá trình miễn là bộ lọc chạy. tất nhiên trong ví dụ này có số khung giới hạn. nhưng khi làm việc với luồng trực tiếp, mức sử dụng bộ nhớ đạt đến gigabyte sau một vài giờ. sao bạn không nhận thấy bất kỳ sự gia tăng bộ nhớ của GraphEdit/GraphStudio khi bạn chạy bộ lọc với MS DTV-DVD Video Decoder? nếu vậy, hệ điều hành của bạn là gì? Tôi đã treid này trên Win7 32 bit. –