Skip to content

WIP/Experiment - Camera Viewport and Snapshot #172

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 82 additions & 7 deletions libraries/Camera/src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
}
}


bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byte_swap) {
return begin(width, height, width, height, pixformat, byte_swap);
}

bool Camera::begin(uint32_t width, uint32_t height, uint32_t crop_width, uint32_t crop_height, uint32_t pixformat, bool byte_swap) {
#if DT_HAS_CHOSEN(zephyr_camera)
this->vdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
#endif
Expand Down Expand Up @@ -75,14 +80,14 @@
return false;
}

for (size_t i=0; caps.format_caps[i].pixelformat != NULL; i++) {
for (size_t i=0; caps.format_caps[i].pixelformat != 0; i++) {
const struct video_format_cap *fcap = &caps.format_caps[i];
if (fcap->width_min == width &&
fcap->height_min == height &&
if (fcap->width_min <= width && fcap->width_max >= width &&
fcap->height_min <= height && fcap->height_max >= height &&
fcap->pixelformat == pixformat) {
break;
}
if (caps.format_caps[i+1].pixelformat == NULL) {
if (caps.format_caps[i+1].pixelformat == 0) {
Serial.println("The specified format is not supported");
return false;
}
Expand All @@ -101,6 +106,24 @@
return false;
}

// optionally set the crop values
if (width != crop_width || height != crop_height) {
struct video_selection vselCrop;
vselCrop.type = VIDEO_BUF_TYPE_OUTPUT;
vselCrop.target = VIDEO_SEL_TGT_CROP;
vselCrop.rect.left = (width - crop_width) / 2;
vselCrop.rect.top = (height - crop_height) / 2;
vselCrop.rect.width = crop_width;
vselCrop.rect.height = crop_height;;

int ret;
if ((ret = setSelection(&vselCrop)) != 0) {
printk("ERROR: %d\n", ret);
}
}
// this should compute the sizes needed.
video_get_format(this->vdev, &fmt);

// Allocate video buffers.
for (size_t i = 0; i < ARRAY_SIZE(this->vbuf); i++) {
this->vbuf[i] = video_buffer_aligned_alloc(fmt.pitch * fmt.height,
Expand All @@ -126,11 +149,11 @@
if (this->vdev == NULL) {
return false;
}

//printk("Camera::grabFrame called\n");
if (video_dequeue(this->vdev, &fb.vbuf, K_MSEC(timeout))) {
return false;
}

//printk("video_dequeue returned :%p\n", fb.vbuf->buffer);
if (this->byte_swap) {
uint16_t *pixels = (uint16_t *) fb.vbuf->buffer;
for (size_t i=0; i<fb.vbuf->bytesused / 2; i++) {
Expand All @@ -154,7 +177,10 @@
return false;
}

if (video_enqueue(this->vdev, fb.vbuf)) {
int ret;
//printk("Camera::ReleaseFrame called\n");
if (ret = video_enqueue(this->vdev, fb.vbuf)) {
printk("Failed to enqueue buffer %d\n", ret);
return false;
}

Expand All @@ -170,3 +196,52 @@
struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = mirror_enable};
return video_set_ctrl(this->vdev, &ctrl) == 0;
}

int Camera::setSelection(struct video_selection *sel) {
return video_set_selection(vdev, sel);
}

/**
* @brief Get video selection (crop/compose).
*
* Retrieve the current settings related to the crop and compose of the video device.
* This can also be used to read the native size of the input stream of the video
* device.
* This function can be used to read crop / compose capabilities of the device prior
* to performing configuration via the @ref video_set_selection api.
*
* @param sel Pointer to a video selection structure, @c type and @c target set by the caller
*
* @retval 0 Is successful.
* @retval -EINVAL If parameters are invalid.
* @retval -ENOTSUP If format is not supported.
* @retval -EIO General input / output error.
*/
int Camera::getSelection(struct video_selection *sel) {
return video_get_selection(vdev, sel);
}

/**
* @brief returns if snapshot mode is turned on or off.
*
* @param snapshot_mode pointer to Turn Snaphsot mode on or off..
*/
int Camera::getSnapshotMode(bool *snapshot_mode) {

Check failure on line 229 in libraries/Camera/src/camera.cpp

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: trailing whitespace
#if DT_HAS_CHOSEN(zephyr_camera)
this->vdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
#endif
return video_get_snapshot_mode(vdev, snapshot_mode);
}

/**
* @brief Function pointer type for video_set_snapshot_mode()
*
* @param snapshot_mode Turn Snaphsot mode on or off..
*/
int Camera::setSnapshotMode(bool snapshot_mode) {
#if DT_HAS_CHOSEN(zephyr_camera)
this->vdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
#endif
return video_set_snapshot_mode(vdev, snapshot_mode);
}

72 changes: 71 additions & 1 deletion libraries/Camera/src/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,19 @@
friend class Camera;
};


// bugbug temporary
#include <zephyr/drivers/video.h>

/**
* @class Camera
* @brief The main class for controlling a camera.
*/
class Camera {
private:
const struct device *vdev;

Check failure on line 75 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

WARNING: please, no spaces at the start of a line

Check failure on line 75 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible
bool byte_swap;
bool yuv_to_gray;
const struct device *vdev;
struct video_buffer *vbuf[CONFIG_VIDEO_BUFFER_POOL_NUM_MAX];

public:
Expand All @@ -90,6 +94,19 @@
*/
bool begin(uint32_t width, uint32_t height, uint32_t pixformat = CAMERA_RGB565, bool byte_swap = false);

/**

Check failure on line 97 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible
* @brief Initialize the camera.

Check failure on line 98 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible
*

Check failure on line 99 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible

Check failure on line 99 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: trailing whitespace
* @param width Frame width in pixels.

Check failure on line 100 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible
* @param height Frame height in pixels.

Check failure on line 101 in libraries/Camera/src/camera.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: code indent should use tabs where possible
* @param crop_width crop width in pixels.
* @param crop_height crop height in pixels.
* @param pixformat Initial pixel format (default: CAMERA_RGB565).
* @param byte_swap Enable byte swapping (default: false).
* @return true if the camera is successfully initialized, otherwise false.
*/
bool begin(uint32_t width, uint32_t height, uint32_t crop_width, uint32_t crop_height, uint32_t pixformat = CAMERA_RGB565, bool byte_swap = false);

/**
* @brief Capture a frame.
*
Expand Down Expand Up @@ -122,6 +139,59 @@
* @return true on success, false on failure.
*/
bool setHorizontalMirror(bool mirror_enable);


/* Experiments to be able to set crop and the like */
/**
* @brief Set video selection (crop/compose).
*
* Configure the optional crop and compose feature of a video device.
* Crop is first applied on the input frame, and the result of that crop is applied
* to the compose. The result of the compose (width/height) is equal to the format
* width/height given to the @ref video_set_format function.
*
* Some targets are inter-dependents. For instance, setting a @ref VIDEO_SEL_TGT_CROP will
* reset @ref VIDEO_SEL_TGT_COMPOSE to the same size.
*
* @param sel Pointer to a video selection structure
*
* @retval 0 Is successful.
* @retval -EINVAL If parameters are invalid.
* @retval -ENOTSUP If format is not supported.
* @retval -EIO General input / output error.
*/
int setSelection(struct video_selection *sel);
/**
* @brief Get video selection (crop/compose).
*
* Retrieve the current settings related to the crop and compose of the video device.
* This can also be used to read the native size of the input stream of the video
* device.
* This function can be used to read crop / compose capabilities of the device prior
* to performing configuration via the @ref video_set_selection api.
*
* @param sel Pointer to a video selection structure, @c type and @c target set by the caller
*
* @retval 0 Is successful.
* @retval -EINVAL If parameters are invalid.
* @retval -ENOTSUP If format is not supported.
* @retval -EIO General input / output error.
*/
int getSelection(struct video_selection *sel);

/**
* @brief returns if snapshot mode is turned on or off.
*
* @param snapshot_mode pointer to Turn Snaphsot mode on or off..
*/
int getSnapshotMode(bool *snapshot_mode);

/**
* @brief Function pointer type for video_set_snapshot_mode()
*
* @param snapshot_mode Turn Snaphsot mode on or off..
*/
int setSnapshotMode(bool snapshot_mode);
};

#endif // __CAMERA_H__
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y

CONFIG_VIDEO=y
CONFIG_VIDEO_LOG_LEVEL_DBG=y
CONFIG_VIDEO_LOG_LEVEL_DBG=n
CONFIG_VIDEO_STM32_DCMI=y
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=3
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=1
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=614400
CONFIG_VIDEO_BUFFER_POOL_ALIGN=32
CONFIG_VIDEO_BUFFER_USE_SHARED_MULTI_HEAP=y
Expand All @@ -61,6 +61,7 @@ CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_PERIODIC=y
CONFIG_BT_CTLR_DTM_HCI=y
CONFIG_CYW4343W_MURATA_1DX=y
CONFIG_BT_HCI_DRIVER_LOG_LEVEL_DBG=n
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_BT_RX_STACK_SIZE=4096
CONFIG_BT_HCI_TX_STACK_SIZE=4096
Loading