Skip to content

Commit 48eb6bb

Browse files
authored
Fix osd flicker (#54)
* use video_cond to signal osd update * faster osd commits * make decoding_pts meaningful * add --disable-vsync option
1 parent 1eb91f2 commit 48eb6bb

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

src/main.cpp

+46-7
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,12 @@ int frm_eos = 0;
8080
int drm_fd = 0;
8181
pthread_mutex_t video_mutex;
8282
pthread_cond_t video_cond;
83-
83+
extern bool osd_update_ready;
8484
int video_zpos = 1;
8585

8686
bool mavlink_dvr_on_arm = false;
8787
bool osd_custom_message = false;
88+
bool disable_vsync = false;
8889

8990
VideoCodec codec = VideoCodec::H265;
9091
Dvr *dvr = NULL;
@@ -264,10 +265,11 @@ void *__DISPLAY_THREAD__(void *param)
264265

265266
while (!frm_eos) {
266267
int fb_id;
268+
bool osd_update;
267269

268270
ret = pthread_mutex_lock(&video_mutex);
269271
assert(!ret);
270-
while (output_list->video_fb_id==0) {
272+
while (output_list->video_fb_id==0 && !osd_update_ready) {
271273
pthread_cond_wait(&video_cond, &video_mutex);
272274
assert(!ret);
273275
if (output_list->video_fb_id == 0 && frm_eos) {
@@ -279,24 +281,33 @@ void *__DISPLAY_THREAD__(void *param)
279281
struct timespec ts, ats;
280282
clock_gettime(CLOCK_MONOTONIC, &ats);
281283
fb_id = output_list->video_fb_id;
284+
osd_update = osd_update_ready;
282285

283-
uint64_t decoding_pts=output_list->decoding_pts;
286+
uint64_t decoding_pts=fb_id != 0 ? output_list->decoding_pts : get_time_ms();
284287
output_list->video_fb_id=0;
288+
osd_update_ready = false;
285289
ret = pthread_mutex_unlock(&video_mutex);
286290
assert(!ret);
287291

292+
// create new video_request
293+
drmModeAtomicFree(output_list->video_request);
294+
output_list->video_request = drmModeAtomicAlloc();
295+
288296
// show DRM FB in plane
289-
drmModeAtomicSetCursor(output_list->video_request, 0);
290-
ret = set_drm_object_property(output_list->video_request, &output_list->video_plane, "FB_ID", fb_id);
291-
assert(ret>0);
297+
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
298+
if (fb_id != 0) {
299+
flags = disable_vsync ? DRM_MODE_ATOMIC_NONBLOCK : DRM_MODE_ATOMIC_ALLOW_MODESET;
300+
ret = set_drm_object_property(output_list->video_request, &output_list->video_plane, "FB_ID", fb_id);
301+
assert(ret>0);
302+
}
292303

293304
if(enable_osd) {
294305
ret = pthread_mutex_lock(&osd_mutex);
295306
assert(!ret);
296307
ret = set_drm_object_property(output_list->video_request, &output_list->osd_plane, "FB_ID", output_list->osd_bufs[output_list->osd_buf_switch].fb);
297308
assert(ret>0);
298309
}
299-
drmModeAtomicCommit(drm_fd, output_list->video_request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
310+
drmModeAtomicCommit(drm_fd, output_list->video_request, flags, NULL);
300311
ret = pthread_mutex_unlock(&osd_mutex);
301312
assert(!ret);
302313

@@ -368,6 +379,24 @@ void sigusr1_handler(int signum) {
368379
}
369380
}
370381

382+
void sigusr2_handler(int signum) {
383+
// Toggle the disable_vsync flag
384+
disable_vsync = disable_vsync ^ 1;
385+
386+
// Open the file for writing
387+
std::ofstream outFile("/run/pixelpilot.msg");
388+
if (!outFile.is_open()) {
389+
spdlog::error("Error opening file!");
390+
return; // Exit the function if the file cannot be opened
391+
}
392+
393+
// Write the formatted text to the file
394+
outFile << "disable_vsync: " << std::boolalpha << disable_vsync << std::endl;
395+
outFile.close();
396+
397+
// Log the new state of disable_vsync
398+
spdlog::info("disable_vsync: {}", disable_vsync);
399+
}
371400

372401
int decoder_stalled_count=0;
373402
bool feed_packet_to_decoder(MppPacket *packet,void* data_p,int data_len){
@@ -524,6 +553,8 @@ void printHelp() {
524553
"\n"
525554
" --screen-mode <mode> - Override default screen mode. <width>x<heigth>@<fps> ex: 1920x1080@120\n"
526555
"\n"
556+
" --disable-vsync - Disable VSYNC commits\n"
557+
"\n"
527558
" --screen-mode-list - Print the list of supported screen modes and exit.\n"
528559
"\n"
529560
" --version - Show program version\n"
@@ -702,6 +733,11 @@ int main(int argc, char **argv)
702733
continue;
703734
}
704735

736+
__OnArgument("--disable-vsync") {
737+
disable_vsync = true;
738+
continue;
739+
}
740+
705741
__OnArgument("--screen-mode-list") {
706742
print_modelist = 1;
707743
continue;
@@ -728,6 +764,8 @@ int main(int argc, char **argv)
728764

729765
printf("PixelPilot Rockchip %d.%d\n", APP_VERSION_MAJOR, APP_VERSION_MINOR);
730766

767+
spdlog::info("disable_vsync: {}", disable_vsync);
768+
731769
if (enable_osd == 0 ) {
732770
video_zpos = 4;
733771
}
@@ -786,6 +824,7 @@ int main(int argc, char **argv)
786824
if (dvr_template) {
787825
signal(SIGUSR1, sigusr1_handler);
788826
}
827+
signal(SIGUSR2, sigusr2_handler);
789828
//////////////////// THREADS SETUP
790829

791830
ret = pthread_mutex_init(&video_mutex, NULL);

src/osd.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ float rx_rate = 0;
4343
int hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
4444
char custom_msg[80];
4545
u_int custom_msg_refresh_count = 0;
46+
extern pthread_mutex_t video_mutex;
47+
extern pthread_cond_t video_cond;
48+
bool osd_update_ready = false;
4649

4750

4851
double getTimeInterval(struct timespec* timestamp, struct timespec* last_meansure_timestamp) {
@@ -1620,6 +1623,16 @@ void *__OSD_THREAD__(void *param) {
16201623
p->out->osd_buf_switch = buf_idx;
16211624
ret = pthread_mutex_unlock(&osd_mutex);
16221625
assert(!ret);
1626+
1627+
// tell the display thread that we have a update
1628+
ret = pthread_mutex_lock(&video_mutex);
1629+
assert(!ret);
1630+
osd_update_ready = true;
1631+
ret = pthread_cond_signal(&video_cond);
1632+
assert(!ret);
1633+
ret = pthread_mutex_unlock(&video_mutex);
1634+
assert(!ret);
1635+
16231636
last_display_at = std::chrono::steady_clock::now();
16241637
}
16251638
}

0 commit comments

Comments
 (0)