Skip to content

VIDEO: GC2145/stm32_dcmi support for CROP/Snapshot #93797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KurtE
Copy link
Contributor

@KurtE KurtE commented Jul 29, 2025

Added support to video_stm32_dcmi for the new
set and get selection. These implementations simply forward the message to the underlying
camera object if they support these messages.

Also added support for a snapshot mode instead of
always using continuous capture mode. Tried
to make it semi-transparent when you desire it to be

The stm32_dcmi code now also allows you to work
with only one buffer. This will force it into snap shot mode. There is also new calls added to the api for: video_get_snapshot_mode and video_set_snapshot_mode.

That allows you to set it with more than one buffer and query what mode you are in.

GC2145 was updated first to try out these changes. The camera now allows me to follow the call order
that @josuah mentioned in another pr/issue.

With this driver I also updated it to allow more or less any video resolution:
{
.pixelformat = format, .width_min = width_l, .width_max = width_h,
.height_min = height_l, .height_max = height_h, .width_step = 0, .height_step = 0,
}

static const struct video_format_cap fmts[] = {
	GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200, VIDEO_PIX_FMT_RGB565),
	GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200, VIDEO_PIX_FMT_YUYV),

When resolution is set, it computes the scale factor. If you then later call set_crop, the same code is
used except it uses the ratios computed from the set_resolution.

With these changes: I was able to setup a test app, for the Arduino Nicla vision and send out a 480x320 image over USB.

More to come

Note: this is a replacement for #91975

My current test sketch/app is up at:
https://github.com/KurtE/zephyr_test_sketches/tree/master/camera_capture_to_usb
built using:

west build -p -b arduino_nicla_vision//m7
west flash

I am using the Arducam viewer with this on my PC. I am using the one at:
https://github.com/mjs513/Teensy_Camera/tree/main/extras/host_app

Picture using GC2145 on Arduino Nicla Vision shown on Arducam mini viewer.
image

Edit: current summary of changes:
There are several changes some of which will likely change if/when code reviews happen. Things like:
a) The stm_dcmi driver handles the get/set selection APIs and if the camera has also implemented these APIs, it
forwards the messages to them, else return error not implemented.

a1) GC2145 camera implements them.

b) Currently I allow arbitrary size of the frame GC2145, that is I have one fmt (per RGB...) which sets min and max versus the
ones where it current code which has 3 arbitrary sizes (1600x1200 - ratio 1, 640x480 ratio 2, 320x240 ratio 3). I instead
compute ratio and allow you to choose for example 800x600 which is less arbitrary than the 640x480... Note 320x240
computes ratio=5, except I currently limit to max ratio=3 per seeing other implementations that do so... Maybe should
make that max configurable.

c) Setting to allow the code to run in SNAPSHOT mode, which starts the camera, waits for one frame to come back and then deactivates.

This is the way that Arduino library works at least on MBED. Note snapshot mode also has some ability to recover from
failures...

d) Allow you to configure to only have one buffer, before it required at least two, If set to 1, it set forces SNAPSHOT mode.

With this running on Zephyr, I for example was able to program a Nicla Vision, which has no SDRAM and output at
480x320 over USB to an Arducam viewer. My test sketch (not sure what to call them on Zephyr)
is up at https://github.com/KurtE/zephyr_test_sketches/tree/master/camera_capture_to_usb

Also have others that output to Portenta H7 to an ST7796 display...

@KurtE KurtE force-pushed the camera_snapshot branch 13 times, most recently from 558b218 to aa416e3 Compare July 30, 2025 13:58
@KurtE
Copy link
Contributor Author

KurtE commented Jul 30, 2025

@josuah @mjs513 @dkalowsk @iabdalkader and all:

As @josuah mentioned in my previous PR:
#91975 (comment)
Which I closed as per his earlier comments about using the new set/get selection video stuff.

This might make more sense when considering there is only one particular order users are expected to follow:

  1. Set the format with video_set_format()
  2. Set the cropping region with video_set_selection(dev, VIDEO_SET_TGT_CROP)
  3. Set the scaling parameter with video_set_selection(dev, VIDEO_SET_TGT_COMPOSE)
    Every step reset the values of what is below it: "select the native size, remove margins, and scale it up/down" always in this order.

Which makes sense: But now wondering about a few details. In my own test case app I have:

	LOG_INF("- Video format: %s %ux%u",
		VIDEO_FOURCC_TO_STR(fmt.pixelformat), fmt.width, fmt.height);

	if (video_set_format(video_dev, &fmt)) {
		LOG_ERR("Unable to set format");
		return 0;
	}

#if CONFIG_VIDEO_FRAME_HEIGHT || CONFIG_VIDEO_FRAME_WIDTH
#if CONFIG_VIDEO_FRAME_HEIGHT
	fmt.height = CONFIG_VIDEO_FRAME_HEIGHT;
#endif

#if CONFIG_VIDEO_FRAME_WIDTH
	fmt.width = CONFIG_VIDEO_FRAME_WIDTH;
#endif
#endif	

	/* First set the format which has the size of the frame defined */
	LOG_INF("video_set_format: %u %u", fmt.width, fmt.height);
	if (video_set_format(video_dev, &fmt)) {
		LOG_ERR("Unable to set format");
		return 0;
	}

	/* initialize the bsize to the size of the frame */
	bsize = fmt.width * fmt.height * 2;
	/* Set the crop setting if necessary */
#if CONFIG_VIDEO_SOURCE_CROP_WIDTH && CONFIG_VIDEO_SOURCE_CROP_HEIGHT
	sel.target = VIDEO_SEL_TGT_CROP;
	sel.rect.left = CONFIG_VIDEO_SOURCE_CROP_LEFT;
	sel.rect.top = CONFIG_VIDEO_SOURCE_CROP_TOP;
	sel.rect.width = CONFIG_VIDEO_SOURCE_CROP_WIDTH;
	sel.rect.height = CONFIG_VIDEO_SOURCE_CROP_HEIGHT;
	LOG_INF("video_set_selection: VIDEO_SEL_TGT_CROP(%u, %u, %u, %u)", 
			sel.rect.left, sel.rect.top, sel.rect.width, sel.rect.height);
	if (video_set_selection(video_dev, &sel)) {
		LOG_ERR("Unable to set selection crop  (%u,%u)/%ux%u",
			sel.rect.left, sel.rect.top, sel.rect.width, sel.rect.height);
		return 0;
	}
	LOG_INF("Selection crop set to (%u,%u)/%ux%u",
		sel.rect.left, sel.rect.top, sel.rect.width, sel.rect.height);
	bsize = sel.rect.width * sel.rect.height * 2;
#endif

	if (video_get_format(video_dev, &fmt)) {
		LOG_ERR("Unable to retrieve video format");
		return 0;
	}
	LOG_INF("video_get_format: ret fmt:%u w:%u h:%u pitch:%u",fmt.pixelformat, fmt.width, fmt.height, fmt.pitch);

And the CONF file has:

CONFIG_VIDEO_FRAME_WIDTH=800
CONFIG_VIDEO_FRAME_HEIGHT=600
CONFIG_VIDEO_SOURCE_CROP_WIDTH=480
CONFIG_VIDEO_SOURCE_CROP_HEIGHT=320

But if I was not using my updated fmts, which allows more resolutions, I would have done FRAME_WIDTH=640 and HEIGHT=480

So now assume:

CONFIG_VIDEO_FRAME_WIDTH=640
CONFIG_VIDEO_FRAME_HEIGHT=480

With this, the call to video_set_format would have a width=640 and height= 480
Which internally sets the ratio (scaling to 2) and crop to 640x480.

Note: If you now (first commit) call video_get_selection with VIDEO_SEL_TGT_NATIVE_SIZE, it will return 800x600

So now to do step 2) to crop it to 480x320 - Currently I ignore the passed in top and left in the crop rectangle, but that
is what I wish to update in the next commit, The current code sets the crop rectangle top=0, left=0. However internally
it actually sets the crop to (80,60, 640, 480) to center the image in the sensor.

So with this setup, I would expect on the TGT_CROP that I should be able to pass in rectangles in the range:
(0, 0, 480, 320) - Upper left area of sensor. to
(159, 139, 480, 320) - lower right (not sure about if 159 or 160...)
Which would allow you to pan over the entire sensor...

But in this case: should step 1) have set the top=0, left=0 or should it instead of set it to 80,60?
Should the sketch calling the setting the TGT_CROP compute this themself, that is currently if you set it to 0, 0
it would be at one end of the sensor? Should there be a default value?

Thanks
Kurt

@KurtE
Copy link
Contributor Author

KurtE commented Jul 30, 2025

Having problems with this PR first commit on getting signoff to be accepted:

I actually copy/pasted the signoff line from previous PRS which worked then but not on this one?

Signed-off-by: Kurt Eckhardt <kurte@rockisland.com>
I tried using:
Signed-off-by: Kurt E <kurte@rockisland.com>
which I had changed my profile to have: Kurt E instead of KurtE for profile name...
I tried what: git commit -s added:
`Signed-off-by: KurtE kurte@rockisland.com

All of which failed like:

  -- Run compliance checks on patch series (PR): Identity.txt#L0See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for more details 52ea30be81e17759c1725a3ef7e7c2c64d6ed5c0: Signed-off-by line (Signed-off-by: Kurt Eckhardt ) does not follow the syntax: First Last .  


[Run compliance checks on patch series (PR): Identity.txt#L0](https://github.com//pull/93797/files#annotation_37244444845) See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for more details

52ea30be81e17759c1725a3ef7e7c2c64d6ed5c0: Signed-off-by line (Signed-off-by: Kurt Eckhardt kurte@rockisland.com) does not follow the syntax: First Last .

@KurtE KurtE force-pushed the camera_snapshot branch 2 times, most recently from f1d99dd to acb2521 Compare July 30, 2025 16:03
@KurtE
Copy link
Contributor Author

KurtE commented Jul 31, 2025

More mumbling to self ;)
Reworking some of this, based on what was done elsewhere including our Teensy_camera code.

With this, the call to video_set_format would have a width=640 and height= 480 Which internally sets the ratio (scaling to 2) and crop to 640x480.

Note: If you now (first commit) call video_get_selection with VIDEO_SEL_TGT_NATIVE_SIZE, it will return 800x600

Reworking: Currently I have the crop code recalculate most of the window and crop registers. Will instead have it
only update the crop registers... As such if you passed in 640x480 on set_format, that is what you are limited to.
So VIDEO_SEL_TGT_NATIVE_SIZE will return 640x480, so I need to save that away and/or grab it from registers.

As the setting the crop updates the fmt structure:

		drv_data->fmt.width = drv_data->crop.width;
		drv_data->fmt.height = drv_data->crop.height;
		drv_data->fmt.pitch = drv_data->fmt.width
			* video_bits_per_pixel(drv_data->fmt.pixelformat) / BITS_PER_BYTE;

Why? Because the buffer management code requires the buffers to be that size:

static int video_stm32_dcmi_enqueue(const struct device *dev, struct video_buffer *vbuf)
{
	struct video_stm32_dcmi_data *data = dev->data;
	const uint32_t buffer_size = data->fmt.pitch * data->fmt.height;

	if (buffer_size > vbuf->size) {
		return -EINVAL;
	}
...

So for example if I setup for the GC2145 camera to output 480x320 the buffer size needed is: 307200 bytes
which the STM32H747 like the Nicla Vision can hold in its memory. Now if the buffer size calculation is based on:
640x480 (614400 bytes) or worse 800x600 (960000 bytes), won't fit in memory.

This also effects the range of crop LEFT and TOP to fit the 480x320 within the range of 640x480...

@KurtE KurtE force-pushed the camera_snapshot branch 4 times, most recently from 3b43aca to 019f84b Compare August 6, 2025 02:26
KurtE added a commit to KurtE/ArduinoCore-zephyr that referenced this pull request Aug 6, 2025
Note: this all uses the Zephyr updates from my PR
zephyrproject-rtos/zephyr#93797

Which I added to the STM dcmi driver the ability to have the camera work in snapshot mode
instead of in continuous video mode.  This allows for example that we start the camera
it grabs a frame and stops, we then take the buffer and process it, and repeat this.
This helps minimize how much the SDRAM gets used concurrently.

In addition, I added to the VIDEO_STM32_DCMI and GC2145 the ability to use some of the
new set_selection and get_selection code that was added for the DCMIPP.  In particular
the DCMI simply forwards these messages to the camera if it defined thise apis...

And with this it allows you to setup a viewport into the frame.  For example:
You can setup the frame on the GC2145 to be 800x600 and then define a view port
to be 480x320 to fill an ST7796/ILI9486 tft display or you could do it 400x240 to half fill
the GIGA display.  You can also move that view port around within the frame (pan)
I have examples that do this on Portenta H7 on the ST7796 display and another one
that does this on the GIGA display shield.

Still WIP as we probably need to refine the APIS and the like
@KurtE KurtE force-pushed the camera_snapshot branch 2 times, most recently from 0cb0ea4 to 74b3afe Compare August 6, 2025 20:28
@KurtE KurtE marked this pull request as ready for review August 6, 2025 20:28
@zephyrbot zephyrbot added the platform: STM32 ST Micro STM32 label Aug 6, 2025
@avolmat-st
Copy link

Thanks @KurtE. Before going into the review of the commits, I am wondering about the 2 new API get_snapshot_mode and set_snapshot_mode especially since you indicate that now the driver is now updated in order to work with only a single buffer.
In such case, would it be enough to automatically capture in snapshot more if there is only a single buffer queued into the driver and thus not having to say, from an application point of view, if we want to capture in snapshot or continuous ?

@KurtE
Copy link
Contributor Author

KurtE commented Aug 7, 2025

Thanks @KurtE. Before going into the review of the commits, I am wondering about the 2 new API get_snapshot_mode and set_snapshot_mode especially since you indicate that now the driver is now updated in order to work with only a single buffer. In such case, would it be enough to automatically capture in snapshot more if there is only a single buffer queued into the driver and thus not having to say, from an application point of view, if we want to capture in snapshot or continuous ?

Thanks @avolmat-st - I am in a high percentage agreement with you, that we probably don't need those two APIs in the zephyr world, as when you setup your application, you probably know how you want it to work.

Where it becomes less clear to me, is when you then add on the ArduinoCore-zephyr layer on top of it.

As it is currently setup, the camera configuration setup is defined as part of building the "bootloader". Which if you use
the Arduino releases in the Board Manager, the settings for which camera and what settings it has is configured once as per
board release. So I was trying to add in some flexibility.

But probably that can be controlled by, how many buffers are defined as MAX and/or if at least two were defined
when/if you call video_stream_start.

So I believe these could be removed. Not sure if zephyr apps might want to know if the captures are done continuous or
not? i.e. having some form of query? My guess is that on Arduino side, we can probably have method that can deduce it.

Note: I believe in most cases on these STM32ST... Arduino boards, they will likely always run in snapshot mode.
The only possible exception would be if you you restrict max image size to 320x240 (maybe slightly bigger if Monochrome camera) and can define the main camera buffer to be in processor memory (not SDRAM), as so far I have found that
using SDRAM for the camera can be problematic, especially if other things are also using SDRAM.

So if you prefer I can remove these APIS.

Thanks

@ngphibang
Copy link
Contributor

ngphibang commented Aug 7, 2025

Yes, I think we don't need an API for this too. In case you really need to have some control on it on the application side, we can make it vendor private control ID, something like ?

#define VIDEO_CID_DCMI_SNAPSHOT (VIDEO_CID_PRIVATE_BASE + 0x01)

Added support to video_stm32_dcmi for the new
set and get selection.  These implementations simply
forward the message to the underlying camera object
if they support these messages.

Also added support for a snapshot mode instead of
always using continuous capture mode.  Tried
to make it semi-transparent when you desire it to be

The stm32_dcmi code now also allows you to work
with only one buffer.  This will force it into snapshot
mode.  There is also new calls added to the api for:
video_get_snapshot_mode and
video_set_snapshot_mode.

That allows you to set it with more than one buffer and
query what mode you are in.

GC2145 was updated first to try out these changes.
The camera now allows me to follow the call order
that @josuah mentioned in another pr/issue.

With this driver I also updated it to allow any resolution from
the displays min to max limits.
static const struct video_format_cap fmts[] = {
  GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200,
                              VIDEO_PIX_FMT_RGB565),
GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200,
                              VIDEO_PIX_FMT_YUYV),

It also still retains the other resolutions as some
software does not check if it is within a range but
only against the min value.

When the resolution is set, it computes the scale factor.
If you then later call set_crop, the same code is used
except it uses the ratios computed from the set_resolution.

Currently it clamps the ratio to a max of 3 as some other
drivers limit it saying it helps with frame rates.

With these changes: I was able to setup a test app, for the
Arduino Nicla vision and send out a 480x320 image over USB.

Video: GC2145 update set Format/Crop as mentioned

As such if you passed in 640x480 on set_format, that is what you are
limited to.

So VIDEO_SEL_TGT_NATIVE_SIZE will return 640x480, so
I need to save that away and/or grab it from registers.

As the setting the crop updates the fmt structure:

Also limited ratio in set resolution to 3 as it was mentioned
in other implementations to help with frame rate.

Signed-off-by: Kurt Eckhardt <kurte@rockisland.com>
@KurtE KurtE force-pushed the camera_snapshot branch from 74b3afe to 5b0bc4b Compare August 7, 2025 17:26
Copy link

sonarqubecloud bot commented Aug 7, 2025

@avolmat-st
Copy link

Thanks @KurtE. Before going into the review of the commits, I am wondering about the 2 new API get_snapshot_mode and set_snapshot_mode especially since you indicate that now the driver is now updated in order to work with only a single buffer. In such case, would it be enough to automatically capture in snapshot more if there is only a single buffer queued into the driver and thus not having to say, from an application point of view, if we want to capture in snapshot or continuous ?

Thanks @avolmat-st - I am in a high percentage agreement with you, that we probably don't need those two APIs in the zephyr world, as when you setup your application, you probably know how you want it to work.

Where it becomes less clear to me, is when you then add on the ArduinoCore-zephyr layer on top of it.

As it is currently setup, the camera configuration setup is defined as part of building the "bootloader". Which if you use the Arduino releases in the Board Manager, the settings for which camera and what settings it has is configured once as per board release. So I was trying to add in some flexibility.

But probably that can be controlled by, how many buffers are defined as MAX and/or if at least two were defined when/if you call video_stream_start.

So I believe these could be removed. Not sure if zephyr apps might want to know if the captures are done continuous or not? i.e. having some form of query? My guess is that on Arduino side, we can probably have method that can deduce it.

Note: I believe in most cases on these STM32ST... Arduino boards, they will likely always run in snapshot mode. The only possible exception would be if you you restrict max image size to 320x240 (maybe slightly bigger if Monochrome camera) and can define the main camera buffer to be in processor memory (not SDRAM), as so far I have found that using SDRAM for the camera can be problematic, especially if other things are also using SDRAM.

So if you prefer I can remove these APIS.

Thanks

Ok thanks for the explanation. Yeah to me running in snapshot or continuous is really an IP level thing, continuous being actually simply that the driver had an available buffer prior to the VSYNC, so I doubt this should be exposed to the application.

Copy link

@avolmat-st avolmat-st left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @KurtE, I did the review of the gc2145 part. I will do the review of the dcmi part also.

In a further update could you also split your commit ? gc2145 and dcmi are unrelated hence should be in separate commits. This help latter on when doing bisect or doing revert , fixes as well as backporting.

*/
typedef int (*video_api_set_snapshot_mode_t)(const struct device *dev, bool snapshot_mode);


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding based on the conversation is that those modifications within video.h shouldn't be necessary, right ?


return api->set_snapshot_mode(dev, snapshot_mode);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well.

/*{0x05, 0x01}, */
/*{0x06, 0x1C}, */
/*{0x07, 0x00}, */
/*{0x08, 0x32}, */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are the Horizontal / Vertical blanking registers, could you explain the reason for changing them ?

.pixelformat = format, .width_min = width, .width_max = width, \
.height_min = height, .height_max = height, .width_step = 0, .height_step = 0, \
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid having twice the almost same macro what about having GC2145_VIDEO_FORMAT_CAP relying on GC2145_VIDEO_FORMAT_CAP_HL ?

Something like:

#define GC2145_VIDEO_FORMAT_CAP(width, height, format)   GC2145_VIDEO_FORMAT_CAP_HL(width, width, height, height, format)

@@ -792,6 +809,9 @@ static const struct video_format_cap fmts[] = {
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_QVGA_W, RESOLUTION_QVGA_H, VIDEO_PIX_FMT_YUYV),
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_VGA_W, RESOLUTION_VGA_H, VIDEO_PIX_FMT_YUYV),
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_UXGA_W, RESOLUTION_UXGA_H, VIDEO_PIX_FMT_YUYV),
/* Add catchall resolution */
GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200, VIDEO_PIX_FMT_RGB565),
GC2145_VIDEO_FORMAT_CAP_HL(128, 1600, 128, 1200, VIDEO_PIX_FMT_YUYV),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to have macros for min width / min height, max width, max height instead of magic numbers here

@@ -1171,12 +1274,57 @@ static int gc2145_set_ctrl(const struct device *dev, uint32_t id)
}
}

static int gc2145_set_selection(const struct device *dev, struct video_selection *sel)
{
LOG_DBG("called: (%p, %p: %u %u)", dev, sel, sel->type, sel->target);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure printing the dev and sel pointers really help here. Type are target values are fine.

return -EINVAL;
}

if (sel->target == VIDEO_SEL_TGT_CROP) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about doing all the error / parameters checking first and then doing valid things are the end ?

if (sel->target != VIDEO_SEL_TGT_CROP) {
    return -EINVAL;
}

return gc2145_set_crop(...)


static int gc2145_get_selection(const struct device *dev, struct video_selection *sel)
{
LOG_DBG("called: (%p, %p: %u %u)", dev, sel, sel->type, sel->target);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for set_selection

struct gc2145_data *drv_data = dev->data;

switch (sel->target) {
case VIDEO_SEL_TGT_COMPOSE:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_selection and set_selection should be consistent I think. if there is a TGT_COMPOSE get then there should also be one for set. But it depend if you want to make this controllable by the application. Here compose would basically be to be able to manually control the ratio, but since it is already computed by the set_fmt, that is probably not needed.

.width = RESOLUTION_VGA_W,
.height = RESOLUTION_VGA_H,
.width = RESOLUTION_QVGA_W,
.height = RESOLUTION_QVGA_H,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, when introducing the CSI support of the GC2145 I changed the default from QVGA to VGA since currently QVGA is not working in CSI. So moving it again would lead to breaking the CSI default now.

I need to check if everything is ok in CSI as well, CSI has some handling of internal FIFO that need to be computed and I am worrying that currently computation is ok for the VGA and UXGA but that's all ;(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Video Video subsystem platform: STM32 ST Micro STM32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants