Skip to content

Commit 6a9d199

Browse files
authored
Fix memory leak in DVR queue (#9)
The DVR queue was written into, even with DVR disabled.
1 parent d0dea5c commit 6a9d199

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

README.md

+36
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,39 @@ pixelpilot --help
6868

6969
1. Video is cropped when the fpv feed resolution is bigger than the screen mode.
7070
1. Crashes when video feed resolution is higher than the screen resolution.
71+
72+
## The way it works
73+
74+
It uses `mpp` library to decode MPEG frames using Rockchip hardware decoder.
75+
It uses `gstreamer` to read the RTP media stream from video UDP.
76+
It uses `mavlink` decoder to read Mavlink telemetry from telemetry UDP (if enabled), see `mavlink.c`
77+
It uses `cairo` library to draw OSD elements (if enabled), see `osd.c`.
78+
It uses [Direct Rendering Manager (DRM)](https://en.wikipedia.org/wiki/Direct_Rendering_Manager) to
79+
display video on the screen, see `drm.c`.
80+
It writes raw MPEG stream to file as DVR (if enabled) using `minimp4.h` library.
81+
82+
Pixelpilot starts several threads:
83+
84+
* main thread
85+
controls gstreamer which reads RTP, extracts MPEG frames and
86+
- feeds them to MPP hardware decoder
87+
- sends them to DVR thread via mutex-protected `std::queue` (if enabled)
88+
* DVR_THREAD (if enabled)
89+
reads frames from main thread via `std::queue` and writes them to disk using `minimp4` library
90+
it yields on a condition variable for DVR queue or `kill` signal variable
91+
* FRAME_THREAD
92+
reads decoded video frames from MPP hardware decoder and forwards them to `DISPLAY_THREAD`
93+
through DRM `output_list` protected by `video_mutex`
94+
Seems that thread vields on `mpi->decode_get_frame()` call waiting for HW decoder to return a new frame
95+
* DISPLAY_THREAD
96+
reads frames and OSD from `video_mutex`-protected `output_list` and calls `drm*` functions to
97+
render them on the screen
98+
The loop yields on `video_mutex` and `video_cond` waiting for a new frame to
99+
display from FRAME_THREAD
100+
* MAVLINK_THREAD (if OSD and mavlink configured)
101+
reads mavlink packets from UDP, decodes and updates `osd_vars` (without any mutex)
102+
The loop yields on UDP read
103+
* OSD_THREAD (if OSD is enabled)
104+
takes `drm_fd` and `output_list` as thread parameters
105+
draws telemetry on a buffer inside `output_list` based on `osd_vars` using Cairo library
106+
The loop yelds on explicit `sleep` to control refresh rate

src/main.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,11 @@ bool feed_packet_to_decoder(MppPacket *packet,void* data_p,int data_len){
415415
}
416416

417417
uint64_t first_frame_ms=0;
418-
void read_gstreamerpipe_stream(MppPacket *packet, int gst_udp_port, const VideoCodec& codec){
418+
void read_gstreamerpipe_stream(MppPacket *packet, int gst_udp_port, int dvr_enabled, const VideoCodec& codec){
419419
GstRtpReceiver receiver(gst_udp_port, codec);
420420
long long bytes_received = 0;
421421
uint64_t period_start=0;
422-
auto cb=[&packet,&decoder_stalled_count, &bytes_received, &period_start](std::shared_ptr<std::vector<uint8_t>> frame){
422+
auto cb=[&packet,&decoder_stalled_count, &bytes_received, &period_start, &dvr_enabled](std::shared_ptr<std::vector<uint8_t>> frame){
423423
// Let the gst pull thread run at quite high priority
424424
static bool first= false;
425425
if(first){
@@ -436,7 +436,9 @@ void read_gstreamerpipe_stream(MppPacket *packet, int gst_udp_port, const VideoC
436436
}
437437
feed_packet_to_decoder(packet,frame->data(),frame->size());
438438

439-
enqueueDvrPacket(frame);
439+
if (dvr_enabled) {
440+
enqueueDvrPacket(frame);
441+
}
440442
};
441443
receiver.start_receiving(cb);
442444
while (!signal_flag){
@@ -727,7 +729,7 @@ int main(int argc, char **argv)
727729
}
728730

729731
////////////////////////////////////////////// MAIN LOOP
730-
read_gstreamerpipe_stream((void**)packet, listen_port, codec);
732+
read_gstreamerpipe_stream((void**)packet, listen_port, dvr_file != NULL, codec);
731733

732734
////////////////////////////////////////////// MPI CLEANUP
733735

0 commit comments

Comments
 (0)