Skip to content

Commit 536f483

Browse files
authored
feat: Add video scaling via --video-scale CLI arg and gsmenu slider (#103)
* video resize via CRTC scaling * added setting video scale parameter through agradd through arg * added video scale factor slider to gsmenu * move video_scale_factor variable into main function --------- Co-authored-by: Dmtry Antonov <[email protected]>
1 parent 406a5b5 commit 536f483

File tree

8 files changed

+54
-16
lines changed

8 files changed

+54
-16
lines changed

debian/manpage.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pixelpilot-rk - OpenIPC video display client for wfb-ng
8181
8282
--video-plane-id - Override default drm plane used for video by plane-id
8383
84+
--video-scale <factor> - Scale video output size (0.5 <= factor <= 1.0) (Default: 1.0)
85+
8486
--osd-plane-id - Override default drm plane used for osd by plane-id
8587
8688
--disable-vsync - Disable VSYNC commits
@@ -163,6 +165,9 @@ a complete description, see the **info**(1) files.
163165
**--video-plane-id**
164166
: Override default drm plane used for video by plane-id
165167

168+
**--video-scale \<factor\>**
169+
: Scale video output size (0.5 <= factor <= 1.0) (Default: 1.0)
170+
166171
**--osd-plane-id**
167172
: Override default drm plane used for osd by plane-id
168173

debian/pixelpilot-rk.pixelpilot.default

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
CONFIG=/etc/pixelpilot/pixelpilot.yaml
55
OSD_PATH=/etc/pixelpilot/config_osd.json
66
SCREEN_MODE=1920x1080@60
7+
VIDEO_SCALE=1.0
78
DVR_FPS=60
89
DVR_PATH=/var/dvr
910
DVR_TEMPLATE=record_%Y-%m-%d_%H-%M-%S.mp4

debian/pixelpilot-rk.pixelpilot.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ After=wifibroadcast.service
66
[Service]
77
Type=simple
88
EnvironmentFile=/etc/default/pixelpilot
9-
ExecStart=/usr/bin/pixelpilot --osd --osd-custom-message --osd-config ${OSD_PATH} --screen-mode ${SCREEN_MODE} --dvr-framerate ${DVR_FPS} --dvr-fmp4 --dvr-sequenced-files --dvr-template ${DVR_PATH}/${DVR_TEMPLATE} --config ${CONFIG} $EXTRA_OPTS
9+
ExecStart=/usr/bin/pixelpilot --osd --osd-custom-message --osd-config ${OSD_PATH} --screen-mode ${SCREEN_MODE} --video-scale ${VIDEO_SCALE} --dvr-framerate ${DVR_FPS} --dvr-fmp4 --dvr-sequenced-files --dvr-template ${DVR_PATH}/${DVR_TEMPLATE} --config ${CONFIG} $EXTRA_OPTS
1010
Restart=always
1111
# Sleep between 3 and 10 seconds between restart attempts; it will keep restarting forever
1212
RestartSec=3

gsmenu.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,9 @@ case "$@" in
566566
"values gs wfbng txpower")
567567
echo -n -e "1\n100"
568568
;;
569+
"values gs system video_scale")
570+
echo -n 0.5 1.0
571+
;;
569572
"values gs system resolution")
570573
drm_info -j /dev/dri/card0 2>/dev/null | jq -r '."/dev/dri/card0".connectors[1].modes[] | select(.name | contains("i") | not) | .name + "@" + (.vrefresh|tostring)' | sort | uniq | sed -z '$ s/\n$//'
571574
;;
@@ -606,6 +609,12 @@ case "$@" in
606609
: #noop
607610
fi
608611
;;
612+
"get gs system video_scale")
613+
grep "^video_scale =" /config/setup.txt | cut -d '=' -f2 | xargs
614+
;;
615+
"set gs system video_scale"*)
616+
sed -i "s/^video_scale =.*/video_scale = $5/" /config/setup.txt
617+
;;
609618
"get gs wifi hotspot")
610619
nmcli connection show --active | grep -q "Hotspot" && echo 1 || echo 0
611620
;;

src/drm.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,14 @@ void modeset_output_destroy(int fd, struct modeset_output *out)
441441
free(out);
442442
}
443443

444-
struct modeset_output *modeset_output_create(int fd, drmModeRes *res, drmModeConnector *conn, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id)
444+
struct modeset_output *modeset_output_create(int fd, drmModeRes *res, drmModeConnector *conn, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id, float video_scale_factor)
445445
{
446446
int ret;
447447
struct modeset_output *out;
448448

449449
out = malloc(sizeof(*out));
450450
memset(out, 0, sizeof(*out));
451+
out->video_scale_factor = video_scale_factor;
451452
out->connector.id = conn->connector_id;
452453

453454
if (conn->connection != DRM_MODE_CONNECTED) {
@@ -587,7 +588,7 @@ void *modeset_print_modes(int fd)
587588

588589
}
589590

590-
struct modeset_output *modeset_prepare(int fd, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id)
591+
struct modeset_output *modeset_prepare(int fd, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id, float video_scale_factor)
591592
{
592593
drmModeRes *res;
593594
drmModeConnector *conn;
@@ -609,7 +610,7 @@ struct modeset_output *modeset_prepare(int fd, uint16_t mode_width, uint16_t mod
609610
continue;
610611
}
611612

612-
out = modeset_output_create(fd, res, conn, mode_width, mode_height, mode_vrefresh, video_plane_id, osd_plane_id);
613+
out = modeset_output_create(fd, res, conn, mode_width, mode_height, mode_vrefresh, video_plane_id, osd_plane_id, video_scale_factor);
613614
drmModeFreeConnector(conn);
614615
if (out) {
615616
drmModeFreeResources(res);
@@ -671,16 +672,22 @@ int modeset_atomic_prepare_commit(int fd, struct modeset_output *out, drmModeAto
671672
if (set_drm_object_property(req, plane, "SRC_H", height << 16) < 0)
672673
return -1;
673674

674-
uint32_t crtcw = out->video_crtc_width;
675-
uint32_t crtch = out->video_crtc_height;
676-
float video_ratio = (float)width/height;
677-
if (crtcw / video_ratio > crtch) {
678-
crtcw = crtch * video_ratio;
679-
crtch = crtch;
675+
uint32_t orig_crtcw = out->video_crtc_width;
676+
uint32_t orig_crtch = out->video_crtc_height;
677+
float video_ratio = (float)width / height;
678+
if (orig_crtcw / video_ratio > orig_crtch) {
679+
orig_crtcw = orig_crtch * video_ratio;
680+
orig_crtch = orig_crtch;
680681
} else {
681-
crtcw = crtcw;
682-
crtch = crtcw / video_ratio;
682+
orig_crtcw = orig_crtcw;
683+
orig_crtch = orig_crtcw / video_ratio;
683684
}
685+
686+
687+
float scale_factor = out->video_scale_factor;
688+
uint32_t crtcw = (uint32_t)(orig_crtcw * scale_factor);
689+
uint32_t crtch = (uint32_t)(orig_crtch * scale_factor);
690+
684691
int crtcx = (out->video_crtc_width - crtcw) / 2;
685692
int crtcy = (out->video_crtc_height - crtch) / 2;
686693
if (set_drm_object_property(req, plane, "CRTC_X", crtcx) < 0)

src/drm.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct modeset_output {
6666
uint32_t video_frm_height;
6767
int video_fb_x, video_fb_y, video_fb_width, video_fb_height;
6868
int video_fb_id;
69+
float video_scale_factor;
6970

7071
// Used to calculate latency
7172
uint64_t decoding_pts;
@@ -103,9 +104,9 @@ int modeset_setup_framebuffers(int fd, drmModeConnector *conn, struct modeset_ou
103104

104105
void modeset_output_destroy(int fd, struct modeset_output *out);
105106

106-
struct modeset_output *modeset_output_create(int fd, drmModeRes *res, drmModeConnector *conn, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id);
107+
struct modeset_output *modeset_output_create(int fd, drmModeRes *res, drmModeConnector *conn, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id, float video_scale_factor);
107108

108-
struct modeset_output *modeset_prepare(int fd, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id);
109+
struct modeset_output *modeset_prepare(int fd, uint16_t mode_width, uint16_t mode_height, uint32_t mode_vrefresh, uint32_t video_plane_id, uint32_t osd_plane_id, float video_scale_factor);
109110

110111
void *modeset_print_modes(int fd);
111112

src/gsmenu/gs_system.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ lv_obj_t * resolution;
1414
lv_obj_t * rec_enabled;
1515
lv_obj_t * rec_fps;
1616
lv_obj_t * vsync_disabled;
17+
lv_obj_t * video_scale;
1718

1819
typedef struct Dvr* Dvr; // Forward declaration
1920
void dvr_start_recording(Dvr* dvr);
@@ -28,7 +29,7 @@ void gs_system_page_load_callback(lv_obj_t * page)
2829
reload_switch_value(page,gs_rendering);
2930
reload_dropdown_value(page,resolution);
3031
reload_dropdown_value(page,rec_fps);
31-
32+
reload_slider_value(page, video_scale);
3233
if (dvr_enabled) lv_obj_add_state(lv_obj_get_child_by_type(rec_enabled,0,&lv_switch_class), LV_STATE_CHECKED);
3334
else lv_obj_clear_state(lv_obj_get_child_by_type(rec_enabled,0,&lv_switch_class), LV_STATE_CHECKED);
3435

@@ -112,6 +113,8 @@ void create_gs_system_menu(lv_obj_t * parent) {
112113

113114
gs_rendering = create_switch(cont,LV_SYMBOL_SETTINGS,"GS Rendering","gs_rendering", menu_page_data,false);
114115
resolution = create_dropdown(cont,LV_SYMBOL_SETTINGS, "Resolution","","resolution",menu_page_data,false);
116+
video_scale = create_slider(cont, LV_SYMBOL_SETTINGS, "Video scale factor", "video_scale", menu_page_data, false, 2);
117+
115118
vsync_disabled = create_switch(cont,LV_SYMBOL_SETTINGS,"Disable VSYNC","disable_vsync", NULL,false);
116119
lv_obj_add_event_cb(lv_obj_get_child_by_type(vsync_disabled,0,&lv_switch_class), disable_vsync_cb, LV_EVENT_VALUE_CHANGED,NULL);
117120

src/main.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,8 @@ void printHelp() {
674674
" --screen-mode <mode> - Override default screen mode. <width>x<heigth>@<fps> ex: 1920x1080@120\n"
675675
"\n"
676676
" --video-plane-id - Override default drm plane used for video by plane-id\n"
677+
"\n"
678+
" --video-scale <factor> - Scale video output size (0.5 =< factor <= 1.0) (Default: 1.0)\n"
677679
"\n"
678680
" --osd-plane-id - Override default drm plane used for osd by plane-id\n"
679681
"\n"
@@ -717,6 +719,7 @@ int main(int argc, char **argv)
717719
std::ofstream pidFile(pidFilePath);
718720
pidFile << getpid();
719721
pidFile.close();
722+
float video_scale_factor = 1.0;
720723

721724
// Load console arguments
722725
__BeginParseConsoleArguments__(printHelp)
@@ -880,6 +883,15 @@ int main(int argc, char **argv)
880883
continue;
881884
}
882885

886+
__OnArgument("--video-scale") {
887+
video_scale_factor = atof(__ArgValue);
888+
if (video_scale_factor < 0.5 || video_scale_factor > 1.0) {
889+
fprintf(stderr, "Invalid video scale factor, should be (0.5 =< scale <= 1.0)\n");
890+
return -1;
891+
}
892+
continue;
893+
}
894+
883895
__EndParseConsoleArguments__
884896

885897
spdlog::set_level(log_level);
@@ -976,7 +988,7 @@ int main(int argc, char **argv)
976988
return 0;
977989
}
978990

979-
output_list = modeset_prepare(drm_fd, mode_width, mode_height, mode_vrefresh, video_plane_id_override, osd_plane_id_override);
991+
output_list = modeset_prepare(drm_fd, mode_width, mode_height, mode_vrefresh, video_plane_id_override, osd_plane_id_override, video_scale_factor);
980992
if (!output_list) {
981993
fprintf(stderr,
982994
"cannot initialize display. Is display connected? Is --screen-mode correct?\n");

0 commit comments

Comments
 (0)