Skip to content

Commit a0d7bc5

Browse files
committed
sample: drivers: video: capture: add support for the video shell
Modify the capture sample to only run the video shell when the user enables it with -DCONFIG_VIDEO_SHELL=y, as an alternative way to trigger captures. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent de11aec commit a0d7bc5

File tree

4 files changed

+91
-15
lines changed

4 files changed

+91
-15
lines changed

drivers/video/video_shell.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ static int cmd_video_stop(const struct shell *sh, size_t argc, char **argv)
127127
return 0;
128128
}
129129

130+
static void video_shell_print_buffer(const struct shell *sh, struct video_buffer *vbuf,
131+
struct video_format *fmt, int i, uint32_t num_buffer,
132+
uint32_t frmrate_fps, uint32_t frmival_msec)
133+
{
134+
uint32_t line_offset = vbuf->line_offset;
135+
uint32_t byte_offset = line_offset * fmt->pitch;
136+
uint32_t bytes_in_buf = vbuf->bytesused;
137+
uint32_t lines_in_buf = vbuf->bytesused / fmt->pitch;
138+
139+
shell_print(sh, "Buffer %u/%u at %u ms, Bytes %u-%u/%u, Lines %u-%u/%u, Rate %u FPS %u ms",
140+
/* Buffer */ i + 1, num_buffer, vbuf->timestamp,
141+
/* Bytes */ byte_offset, byte_offset + bytes_in_buf, fmt->height * fmt->pitch,
142+
/* Lines */ line_offset, line_offset + lines_in_buf, fmt->height,
143+
/* Rate */ frmrate_fps, frmival_msec);
144+
}
145+
130146
static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
131147
{
132148
const struct device *dev;
@@ -140,7 +156,7 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
140156
uint32_t frmival_msec;
141157
uint32_t frmrate_fps;
142158
size_t buf_size;
143-
unsigned long num_frames;
159+
unsigned long num_buffers;
144160
int ret;
145161

146162
dev = device_get_binding(argv[1]);
@@ -155,7 +171,7 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
155171
return ret;
156172
}
157173

158-
num_frames = strtoull(arg2, &arg2, 10);
174+
num_buffers = strtoull(arg2, &arg2, 10);
159175
if (*arg2 != '\0') {
160176
shell_error(sh, "Invalid integer '%s' for this type", argv[1]);
161177
return -EINVAL;
@@ -180,7 +196,7 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
180196
}
181197
}
182198

183-
shell_print(sh, "Starting the capture of %lu frames from %s", num_frames, dev->name);
199+
shell_print(sh, "Starting the capture of %lu buffers from %s", num_buffers, dev->name);
184200

185201
ret = video_stream_start(dev);
186202
if (ret != 0) {
@@ -190,7 +206,7 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
190206

191207
first_uptime = prev_uptime = this_uptime = k_uptime_get_32();
192208

193-
for (unsigned long i = 0; i < num_frames;) {
209+
for (unsigned long i = 0; i < num_buffers;) {
194210
ret = video_dequeue(dev, VIDEO_EP_OUT, &vbuf, K_FOREVER);
195211
if (ret != 0) {
196212
shell_error(sh, "Failed to dequeue this buffer: %s", strerror(-ret));
@@ -202,12 +218,7 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
202218
frmrate_fps = (frmival_msec == 0) ? (UINT32_MAX) : (MSEC_PER_SEC / frmival_msec);
203219
prev_uptime = this_uptime;
204220

205-
shell_print(sh, "Frame %3lu/%lu, Bytes %u-%u/%u, Lines %u-%u/%u, %u ms %u FPS",
206-
i, num_frames, vbuf->line_offset * fmt.pitch,
207-
vbuf->line_offset * fmt.pitch + vbuf->bytesused, vbuf->size,
208-
vbuf->line_offset,
209-
vbuf->line_offset + vbuf->bytesused / fmt.pitch, fmt.height,
210-
frmival_msec, frmrate_fps);
221+
video_shell_print_buffer(sh, vbuf, &fmt, i, num_buffers, frmrate_fps, frmival_msec);
211222

212223
/* Only increment the frame counter on the beginning of a new frame */
213224
i += (vbuf->line_offset == 0);
@@ -221,10 +232,10 @@ static int cmd_video_capture(const struct shell *sh, size_t argc, char **argv)
221232

222233
frmival_msec = this_uptime - first_uptime;
223234
frmrate_fps =
224-
(frmival_msec == 0) ? (UINT32_MAX) : (num_frames * MSEC_PER_SEC / frmival_msec);
235+
(frmival_msec == 0) ? (UINT32_MAX) : (num_buffers * MSEC_PER_SEC / frmival_msec);
225236

226-
shell_print(sh, "Capture of %lu frames in %u ms in total, %u FPS on average, stopping %s",
227-
num_frames, frmival_msec, frmrate_fps, dev->name);
237+
shell_print(sh, "Capture of %lu buffers in %u ms in total, %u FPS on average, stopping %s",
238+
num_buffers, frmival_msec, frmrate_fps, dev->name);
228239

229240
end:
230241
video_stream_stop(dev);
@@ -1021,8 +1032,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_video_cmds,
10211032
"Usage: video stop <device>",
10221033
cmd_video_stop, 2, 0),
10231034
SHELL_CMD_ARG(capture, &dsub_video_dev,
1024-
"Capture a given number of frames from a device\n"
1025-
"Usage: video capture <device> <num-frames>",
1035+
"Capture a given number of buffers from a device\n"
1036+
"Usage: video capture <device> <num-buffers>",
10261037
cmd_video_capture, 3, 0),
10271038
SHELL_CMD_ARG(format, &dsub_video_format_dev,
10281039
"Query or set the video format of a device\n"

samples/drivers/video/capture/README.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,29 @@ using the :ref:`dvp_20pin_ov7670` and :ref:`lcd_par_s035` connected to the board
8383
:goals: build
8484
:compact:
8585

86+
For :ref:`native_sim`, build this sample application with the following commands:
87+
88+
.. zephyr-app-commands::
89+
:zephyr-app: samples/drivers/video/capture
90+
:board: native_sim
91+
:goals: build
92+
:compact:
93+
8694
For testing purpose without the need of any real video capture and/or display hardwares,
8795
a video software pattern generator is supported by the above build commands without
8896
specifying the shields.
8997

98+
For controlling the camera device using shell commands instead of continuously capturing the data,
99+
append ``-DCONFIG_VIDEO_SHELL=y`` to the build command:
100+
101+
.. zephyr-app-commands::
102+
:zephyr-app: samples/drivers/video/capture
103+
:board: mimxrt1064_evk
104+
:shield: dvp_fpc24_mt9m114,rk043fn66hs_ctg
105+
:gen-args: -DCONFIG_VIDEO_SHELL=y
106+
:goals: build
107+
:compact:
108+
90109
Sample Output
91110
=============
92111

@@ -118,6 +137,28 @@ Sample Output
118137
119138
<repeats endlessly>
120139
140+
If using the shell, the capture would not start, and instead it is possible to access the shell
141+
142+
.. code-block:: console
143+
144+
uart:~$ video
145+
video - Video driver commands
146+
Subcommands:
147+
start : Start a video device and its sources
148+
Usage: video start <device>
149+
stop : Stop a video device and its sources
150+
Usage: video stop <device>
151+
capture : Capture a given number of frames from a device
152+
Usage: video capture <device> <num-frames>
153+
format : Query or set the video format of a device
154+
Usage: video format <device> <ep> [<fourcc> <width>x<height>]
155+
frmival : Query or set the video frame rate/interval of a device
156+
Usage: video frmival <device> <ep> [<n>fps|<n>ms|<n>us]
157+
ctrl : Query or set video controls of a device
158+
Usage: video ctrl <device> [<ctrl> <value>]
159+
uart:~$
160+
161+
121162
References
122163
**********
123164

samples/drivers/video/capture/sample.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,21 @@ tests:
3636
integration_platforms:
3737
- mimxrt1064_evk
3838
- mimxrt1170_evk/mimxrt1176/cm7
39+
sample.video.capture.shell:
40+
tags:
41+
- video
42+
- samples
43+
- shell
44+
extra_configs:
45+
- CONFIG_VIDEO_SHELL=y
46+
- CONFIG_FPU=y
47+
- CONFIG_DISPLAY=n
48+
harness: console
49+
harness_config:
50+
type: one_line
51+
regex:
52+
- "Letting the user control the device with the video shell"
53+
platform_allow:
54+
- native_sim/native/64
55+
integration_platforms:
56+
- native_sim/native/64

samples/drivers/video/capture/src/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ int main(void)
100100
int i = 0;
101101
int err;
102102

103+
/* When the video shell is enabled, do not run the capture loop */
104+
if (IS_ENABLED(CONFIG_VIDEO_SHELL)) {
105+
LOG_INF("Letting the user control the device with the video shell");
106+
return 0;
107+
}
108+
103109
#if DT_HAS_CHOSEN(zephyr_camera)
104110
const struct device *const video_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
105111

0 commit comments

Comments
 (0)