-
Notifications
You must be signed in to change notification settings - Fork 7.8k
video: introduction of STM32 VENC driver for H264 hardware video compression #92884
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
base: main
Are you sure you want to change the base?
Changes from 6 commits
57454b2
b085c77
35bce9d
51ca23b
4cea4fa
4a1cde0
20d30f5
25ecf94
4419a21
ef412ab
58daa7c
a0908b1
75284f7
9465d39
5ffa36c
2878753
a32b1da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -58,6 +58,20 @@ config VIDEO_I2C_RETRY_NUM | |||||||||||||||||||||||
The default is to not retry. Board configuration files or user project can then | ||||||||||||||||||||||||
use the number of retries that matches their situation. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
config VIDEO_BUFFER_USE_MEM_ATTR_HEAP | ||||||||||||||||||||||||
bool "Use mem attr api for video buffer" | ||||||||||||||||||||||||
default n | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
config VIDEO_BUFFER_MEM_SW_ATTRIBUTE | ||||||||||||||||||||||||
int "Mem SW attribute for video buffer" | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
depends on VIDEO_BUFFER_USE_MEM_ATTR_HEAP | ||||||||||||||||||||||||
default 1 | ||||||||||||||||||||||||
help | ||||||||||||||||||||||||
Mem SW attribute for video buffer: | ||||||||||||||||||||||||
1: ATTR_SW_ALLOC_CACHE | ||||||||||||||||||||||||
2: ATTR_SW_ALLOC_NON_CACHE | ||||||||||||||||||||||||
4: ATTR_SW_ALLOC_DMA | ||||||||||||||||||||||||
Comment on lines
+70
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be best to avoid duplicating information from the header.
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
source "drivers/video/Kconfig.esp32_dvp" | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
source "drivers/video/Kconfig.mcux_csi" | ||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -26,6 +26,14 @@ LOG_MODULE_REGISTER(video_common, CONFIG_VIDEO_LOG_LEVEL); | |||||||||||||
#define VIDEO_COMMON_HEAP_ALLOC(align, size, timeout) \ | ||||||||||||||
shared_multi_heap_aligned_alloc(CONFIG_VIDEO_BUFFER_SMH_ATTRIBUTE, align, size) | ||||||||||||||
#define VIDEO_COMMON_FREE(block) shared_multi_heap_free(block) | ||||||||||||||
#elif defined(CONFIG_VIDEO_BUFFER_USE_MEM_ATTR_HEAP) | ||||||||||||||
#include <zephyr/mem_mgmt/mem_attr_heap.h> | ||||||||||||||
#include <zephyr/dt-bindings/memory-attr/memory-attr.h> | ||||||||||||||
|
||||||||||||||
#define VIDEO_COMMON_HEAP_ALLOC(align, size, timeout) \ | ||||||||||||||
mem_attr_heap_aligned_alloc((CONFIG_VIDEO_BUFFER_MEM_SW_ATTRIBUTE << \ | ||||||||||||||
DT_MEM_SW_ATTR_SHIFT), align, size) | ||||||||||||||
Comment on lines
+33
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
#define VIDEO_COMMON_FREE(block) mem_attr_heap_free(block) | ||||||||||||||
#else | ||||||||||||||
K_HEAP_DEFINE(video_buffer_pool, CONFIG_VIDEO_BUFFER_POOL_SZ_MAX*CONFIG_VIDEO_BUFFER_POOL_NUM_MAX); | ||||||||||||||
#define VIDEO_COMMON_HEAP_ALLOC(align, size, timeout) \ | ||||||||||||||
|
@@ -47,6 +55,9 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_tim | |||||||||||||
struct mem_block *block; | ||||||||||||||
int i; | ||||||||||||||
|
||||||||||||||
#if defined(CONFIG_VIDEO_BUFFER_USE_MEM_ATTR_HEAP) | ||||||||||||||
mem_attr_heap_pool_init(); | ||||||||||||||
#endif | ||||||||||||||
Comment on lines
+58
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: should check that return value is |
||||||||||||||
/* find available video buffer */ | ||||||||||||||
for (i = 0; i < ARRAY_SIZE(video_buf); i++) { | ||||||||||||||
if (video_buf[i].buffer == NULL) { | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,17 +205,25 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t | |
return; | ||
} | ||
|
||
/* | ||
* TODO - we only support 1 buffer formats for the time being, setting of | ||
* MEMORY_ADDRESS_1 and MEMORY_ADDRESS_2 required depending on the pixelformat | ||
* for Pipe1 | ||
*/ | ||
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, Pipe, DCMIPP_MEMORY_ADDRESS_0, | ||
(uint32_t)pipe->next->buffer); | ||
if (ret != HAL_OK) { | ||
LOG_ERR("Failed to update memory address"); | ||
return; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added the whole multi buffer support of DCMIPP as well as description in video.h in the following PR which is still currently in draft so that I can fully test it: |
||
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) { | ||
uint32_t addr = (uint32_t)pipe->next->buffer + | ||
pipe->fmt.width * pipe->fmt.height; | ||
|
||
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, Pipe, | ||
DCMIPP_MEMORY_ADDRESS_1, | ||
addr); | ||
if (ret != HAL_OK) { | ||
LOG_ERR("Failed to update second memory address"); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
#if defined(STM32_DCMIPP_HAS_CSI) | ||
|
@@ -432,6 +440,7 @@ static const struct stm32_dcmipp_mapping { | |
PIXEL_PIPE_FMT(RGB565, RGB565_1, 0, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(YUYV, YUV422_1, 0, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(YVYU, YUV422_1, 1, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(NV12, YUV420_2, 0, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(GREY, MONO_Y8_G8_1, 0, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(RGB24, RGB888_YUV444_1, 1, (BIT(1) | BIT(2))), | ||
PIXEL_PIPE_FMT(BGR24, RGB888_YUV444_1, 0, (BIT(1) | BIT(2))), | ||
|
@@ -460,7 +469,7 @@ static const struct stm32_dcmipp_mapping { | |
((fmt) == VIDEO_PIX_FMT_GREY || \ | ||
(fmt) == VIDEO_PIX_FMT_YUYV || (fmt) == VIDEO_PIX_FMT_YVYU || \ | ||
(fmt) == VIDEO_PIX_FMT_VYUY || (fmt) == VIDEO_PIX_FMT_UYVY || \ | ||
(fmt) == VIDEO_PIX_FMT_XYUV32) ? VIDEO_COLORSPACE_YUV : \ | ||
(fmt) == VIDEO_PIX_FMT_XYUV32 || (fmt) == VIDEO_PIX_FMT_NV12) ? VIDEO_COLORSPACE_YUV : \ | ||
\ | ||
VIDEO_COLORSPACE_RAW) | ||
|
||
|
@@ -481,6 +490,9 @@ static inline void stm32_dcmipp_compute_fmt_pitch(uint32_t pipe_id, struct video | |
{ | ||
fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; | ||
#if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) | ||
if (fmt->pixelformat == VIDEO_PIX_FMT_NV12) | ||
fmt->pitch = fmt->width; | ||
|
||
if (pipe_id == DCMIPP_PIPE1 || pipe_id == DCMIPP_PIPE2) { | ||
/* On Pipe1 and Pipe2, the pitch must be multiple of 16 bytes */ | ||
fmt->pitch = ROUND_UP(fmt->pitch, 16); | ||
|
@@ -1044,9 +1056,21 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) | |
} | ||
#if defined(STM32_DCMIPP_HAS_CSI) | ||
else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { | ||
ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id, DCMIPP_VIRTUAL_CHANNEL0, | ||
(uint32_t)pipe->next->buffer, | ||
DCMIPP_MODE_CONTINUOUS); | ||
uint32_t addr = (uint32_t)pipe->next->buffer; | ||
|
||
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) { | ||
DCMIPP_SemiPlanarDstAddressTypeDef spaddr; | ||
|
||
spaddr.YAddress = addr; | ||
spaddr.UVAddress = addr + pipe->fmt.width * pipe->fmt.height; | ||
ret = HAL_DCMIPP_CSI_PIPE_SemiPlanarStart(&dcmipp->hdcmipp, | ||
pipe->id, DCMIPP_VIRTUAL_CHANNEL0, | ||
&spaddr, DCMIPP_MODE_CONTINUOUS); | ||
} else { | ||
ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id, | ||
DCMIPP_VIRTUAL_CHANNEL0, | ||
addr, DCMIPP_MODE_CONTINUOUS); | ||
Comment on lines
+1066
to
+1072
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this manageable without Linux-style planar API? Otherwise we can introduce planar APIs to help with this. |
||
} | ||
} | ||
#endif | ||
else { | ||
|
@@ -1193,6 +1217,20 @@ static int stm32_dcmipp_enqueue(const struct device *dev, struct video_buffer *v | |
LOG_ERR("Failed to update memory address"); | ||
return -EIO; | ||
} | ||
|
||
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) { | ||
uint32_t addr = (uint32_t)pipe->next->buffer + | ||
pipe->fmt.width * pipe->fmt.height; | ||
|
||
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, pipe->id, | ||
DCMIPP_MEMORY_ADDRESS_1, | ||
addr); | ||
if (ret != HAL_OK) { | ||
LOG_ERR("Failed to update second memory address"); | ||
return -EIO; | ||
} | ||
} | ||
|
||
if (pipe->id == DCMIPP_PIPE0) { | ||
SET_BIT(dcmipp->hdcmipp.Instance->P0FCTCR, DCMIPP_P0FCTCR_CPTREQ); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1551,6 +1551,8 @@ int64_t video_get_csi_link_freq(const struct device *dev, uint8_t bpp, uint8_t l | |
*/ | ||
#define VIDEO_PIX_FMT_XYUV32 VIDEO_FOURCC('X', 'Y', 'U', 'V') | ||
|
||
#define VIDEO_PIX_FMT_NV12 VIDEO_FOURCC('N', 'V', '1', '2') | ||
|
||
/** | ||
* @} | ||
*/ | ||
|
@@ -1597,6 +1599,7 @@ static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) | |
case VIDEO_PIX_FMT_SGRBG12P: | ||
case VIDEO_PIX_FMT_SRGGB12P: | ||
case VIDEO_PIX_FMT_Y12P: | ||
case VIDEO_PIX_FMT_NV12: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added the whole multi buffer support of DCMIPP as well as description in video.h in the following PR which is still currently in draft so that I can fully test it: |
||
return 12; | ||
case VIDEO_PIX_FMT_SBGGR14P: | ||
case VIDEO_PIX_FMT_SGBRG14P: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -370,6 +370,11 @@ manifest: | |
- name: zcbor | ||
revision: 9b07780aca6fb21f82a241ba386ad9b379809337 | ||
path: modules/lib/zcbor | ||
- name: zephyr-isp | ||
url: [email protected]:AIS/mg-zephyr-isp.git | ||
revision: master | ||
path: Lib/zephyr-isp | ||
submodules: true | ||
Comment on lines
+373
to
+377
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Impacts the whole project, should be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dependency should be documented at board or sample level |
||
# zephyr-keep-sorted-stop | ||
|
||
self: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ maybe this should
depends on MEM_ATTR_HEAP