Skip to content

Commit 4620ba6

Browse files
author
Alain Volmat
committed
video: shell: addition of video selection support
Add shell handling in order to interact with drivers via the set/get_selection APIs allowing to get/set crop / compose and get HW capabilities such as crop bound / compose bound or native size. Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
1 parent d6abcb1 commit 4620ba6

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

drivers/video/video_shell.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,156 @@ static void complete_video_format_dev(size_t idx, struct shell_static_entry *ent
10451045
}
10461046
SHELL_DYNAMIC_CMD_CREATE(dsub_video_format_dev, complete_video_format_dev);
10471047

1048+
/* Video selection handling */
1049+
1050+
static void video_shell_print_selection(const struct shell *sh, struct video_selection *sel)
1051+
{
1052+
shell_print(sh, "\tselection target: %s: (%u,%u)/%ux%u",
1053+
sel->target == VIDEO_SEL_TGT_CROP ? "crop" :
1054+
sel->target == VIDEO_SEL_TGT_CROP_BOUND ? "crop_bound" :
1055+
sel->target == VIDEO_SEL_TGT_NATIVE_SIZE ? "native_size" :
1056+
sel->target == VIDEO_SEL_TGT_COMPOSE ? "compose" : "unknown",
1057+
sel->rect.left, sel->rect.top, sel->rect.width, sel->rect.height);
1058+
}
1059+
1060+
static int video_shell_selection_parse_target(const struct shell *sh, char const *arg_target,
1061+
enum video_selection_target *sel_target)
1062+
{
1063+
if (strcmp(arg_target, "crop") == 0) {
1064+
*sel_target = VIDEO_SEL_TGT_CROP;
1065+
} else if (strcmp(arg_target, "crop_bound") == 0) {
1066+
*sel_target = VIDEO_SEL_TGT_CROP_BOUND;
1067+
} else if (strcmp(arg_target, "native_size") == 0) {
1068+
*sel_target = VIDEO_SEL_TGT_NATIVE_SIZE;
1069+
} else if (strcmp(arg_target, "compose") == 0) {
1070+
*sel_target = VIDEO_SEL_TGT_COMPOSE;
1071+
} else if (strcmp(arg_target, "compose_bound") == 0) {
1072+
*sel_target = VIDEO_SEL_TGT_COMPOSE_BOUND;
1073+
} else {
1074+
shell_error(sh,
1075+
"Target must be 'crop/crop_bound/native_size/compose or compose_bound");
1076+
return -EINVAL;
1077+
}
1078+
1079+
return 0;
1080+
}
1081+
1082+
static int video_shell_selection_parse_rect(const struct shell *sh, char const *arg_rect,
1083+
struct video_rect *rect)
1084+
{
1085+
char *end_size = (char *)arg_rect;
1086+
1087+
if (*end_size != '(') {
1088+
shell_error(sh,
1089+
"Invalid rectangle format (<left>,<top>)/<width>x<height> parameter %s",
1090+
arg_rect);
1091+
return -EINVAL;
1092+
}
1093+
end_size++;
1094+
1095+
rect->left = strtoul(end_size, &end_size, 10);
1096+
if (*end_size != ',') {
1097+
shell_error(sh,
1098+
"Invalid left value in rect <left>,<top>/<width>x<height> parameter %s",
1099+
arg_rect);
1100+
return -EINVAL;
1101+
}
1102+
end_size++;
1103+
1104+
rect->top = strtoul(end_size, &end_size, 10);
1105+
if (*end_size != ')') {
1106+
shell_error(sh,
1107+
"Invalid top value in rect <left>,<top>/<width>x<height> parameter %s",
1108+
arg_rect);
1109+
return -EINVAL;
1110+
}
1111+
end_size++;
1112+
1113+
if (*end_size != '/') {
1114+
shell_error(sh,
1115+
"Invalid rectangle format (<left>,<top>)/<width>x<height> parameter %s",
1116+
arg_rect);
1117+
return -EINVAL;
1118+
}
1119+
end_size++;
1120+
1121+
rect->width = strtoul(end_size, &end_size, 10);
1122+
if (*end_size != 'x' || rect->width == 0) {
1123+
shell_error(sh,
1124+
"Invalid width value in rect <left>,<top>/<width>x<height> parameter %s",
1125+
arg_rect);
1126+
return -EINVAL;
1127+
}
1128+
end_size++;
1129+
1130+
rect->height = strtoul(end_size, &end_size, 10);
1131+
if (*end_size != '\0' || rect->height == 0) {
1132+
shell_error(sh,
1133+
"Invalid height value in rect <left>,<top>/<width>x<height> parameter %s",
1134+
arg_rect);
1135+
return -EINVAL;
1136+
}
1137+
1138+
return 0;
1139+
}
1140+
1141+
static int cmd_video_selection(const struct shell *sh, size_t argc, char **argv)
1142+
{
1143+
const struct device *dev;
1144+
struct video_selection sel = {0};
1145+
char *arg_device = argv[1];
1146+
char *arg_in_out = argv[2];
1147+
char *arg_target = argv[3];
1148+
int ret;
1149+
1150+
dev = device_get_binding(arg_device);
1151+
ret = video_shell_check_device(sh, dev);
1152+
if (ret < 0) {
1153+
return ret;
1154+
}
1155+
1156+
ret = video_shell_parse_in_out(sh, arg_in_out, &sel.type);
1157+
if (ret < 0) {
1158+
return -ret;
1159+
}
1160+
1161+
ret = video_shell_selection_parse_target(sh, arg_target, &sel.target);
1162+
if (ret < 0) {
1163+
return ret;
1164+
}
1165+
1166+
switch (argc) {
1167+
case 4:
1168+
ret = video_get_selection(dev, &sel);
1169+
if (ret < 0) {
1170+
shell_error(sh, "Failed to get %s selection", dev->name);
1171+
return -ENODEV;
1172+
}
1173+
1174+
video_shell_print_selection(sh, &sel);
1175+
break;
1176+
case 5:
1177+
ret = video_shell_selection_parse_rect(sh, argv[4], &sel.rect);
1178+
if (ret < 0) {
1179+
return ret;
1180+
}
1181+
1182+
ret = video_set_selection(dev, &sel);
1183+
if (ret < 0) {
1184+
shell_error(sh, "Failed to set %s selection", dev->name);
1185+
return -ENODEV;
1186+
}
1187+
1188+
video_shell_print_selection(sh, &sel);
1189+
break;
1190+
default:
1191+
shell_error(sh, "Wrong parameter count");
1192+
return -EINVAL;
1193+
}
1194+
1195+
return 0;
1196+
}
1197+
10481198
/* Video shell commands declaration */
10491199

10501200
SHELL_STATIC_SUBCMD_SET_CREATE(sub_video_cmds,
@@ -1070,6 +1220,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_video_cmds,
10701220
SHELL_HELP("Query or set video controls of a device",
10711221
"<device> [<ctrl> <value>]"),
10721222
cmd_video_ctrl, 2, 2),
1223+
SHELL_CMD_ARG(selection, &dsub_video_format_dev,
1224+
SHELL_HELP("Query or set the video selection of a device",
1225+
"<device> <dir> <target> [<left>,<top>/<width>x<height>]"),
1226+
cmd_video_selection, 4, 1),
10731227
SHELL_SUBCMD_SET_END
10741228
);
10751229

0 commit comments

Comments
 (0)