first commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
esp_video/examples/uvc:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32p4"
|
||||
reason: only support on esp32p4
|
||||
depends_components:
|
||||
- esp_video
|
||||
- esp_cam_sensor
|
||||
- esp_sccb_intf
|
||||
@@ -0,0 +1,7 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
project(uvc)
|
||||
@@ -0,0 +1,219 @@
|
||||
# USB Video Class Example
|
||||
|
||||
(See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples.)
|
||||
|
||||
This example demonstrates the following:
|
||||
|
||||
- How to initialize esp_video with specific parameters
|
||||
- How to open camera interface video device and capture video stream from this device
|
||||
- How to open H.264 or JPEG video device and encode video stream by this device
|
||||
- How to initialize USB video class and see video on the PC
|
||||
|
||||
## How to use example
|
||||
|
||||
### Software Required
|
||||
|
||||
* `potplay` APP for PC on Windows OS
|
||||
|
||||
### Configure the Project
|
||||
|
||||
Configure camera hardware data interface based on development kit:
|
||||
|
||||
#### MIPI-CSI Development Kit
|
||||
|
||||
```
|
||||
Example Configuration --->
|
||||
Camera sensor interface (MIPI-CSI) --->
|
||||
(X) MIPI-CSI
|
||||
(0) MIPI CSI SCCB I2C Port Number
|
||||
(8) MIPI CSI SCCB I2C SCL Pin
|
||||
(7) MIPI CSI SCCB I2C SDA Pin
|
||||
|
||||
Component config --->
|
||||
Espressif Camera Sensors Configurations --->
|
||||
[*] SC2336 ---->
|
||||
Default format select for MIPI (RAW8 1280x720 30fps, MIPI 2lane 24M input) --->
|
||||
(X) RAW8 1280x720 30fps, MIPI 2lane 24M input
|
||||
|
||||
USB Device UVC --->
|
||||
USB Cam1 Config --->
|
||||
UVC Default Resolution (HD 1280x720) --->
|
||||
(X) HD 1280x720
|
||||
(30) Frame Rate (FPS)
|
||||
(1280) Cam1 Frame Width
|
||||
(720) Cam1 Frame Height
|
||||
```
|
||||
Note: For custom development boards, please update the I2C pins configuration in the `Example Configuration` menu.
|
||||
|
||||
#### DVP Development Kit
|
||||
|
||||
```
|
||||
Example Configuration --->
|
||||
Camera sensor interface (DVP) --->
|
||||
(X) DVP
|
||||
(1) DVP SCCB I2C Port Number (NEW)
|
||||
(33) DVP SCCB I2C SCL Pin (NEW)
|
||||
(32) DVP SCCB I2C SDA Pin (NEW)
|
||||
|
||||
Component config --->
|
||||
Espressif Camera Sensors Configurations --->
|
||||
[*] OV2640 --->
|
||||
Default format select (RGB565 640x480 6fps, DVP 8bit 20M input) --->
|
||||
(X) RGB565 640x480 6fps, DVP 8bit 20M input
|
||||
|
||||
USB Device UVC --->
|
||||
USB Cam1 Config --->
|
||||
Default Resolution (VGA 640x480) --->
|
||||
(X) VGA 640x480
|
||||
(6) Frame Rate (FPS)
|
||||
(640) Cam1 Frame Width
|
||||
(480) Cam1 Frame Height
|
||||
```
|
||||
|
||||
#### Select USB video class output video format
|
||||
|
||||
##### JPEG
|
||||
|
||||
```
|
||||
component config --->
|
||||
USB Device UVC --->
|
||||
USB Cam1 Config --->
|
||||
Cam1 Format (MJPEG) --->
|
||||
(X) MJPEG
|
||||
```
|
||||
|
||||
##### H.264
|
||||
|
||||
```
|
||||
component config --->
|
||||
USB Device UVC --->
|
||||
USB Cam1 Config --->
|
||||
UVC Cam1 Format (H264) --->
|
||||
(X) H264
|
||||
```
|
||||
|
||||
***Please note that the OV2640 doesn't support H.264 format, it only supports the JPEG format***.
|
||||
|
||||
### Build and Flash
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py set-target esp32p4
|
||||
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [ESP-IDF Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
Running this example, you will see the following log output on the serial monitor:
|
||||
|
||||
#### MIPI-CSI Development Kit
|
||||
|
||||
```
|
||||
...
|
||||
I (1641) main_task: Calling app_main()
|
||||
I (1641) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (1651) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (1661) sc2336: Detected Camera sensor PID=0xcb3a
|
||||
I (1741) example: version: 0.5.1
|
||||
I (1741) example: driver: MIPI-CSI
|
||||
I (1741) example: card: MIPI-CSI
|
||||
I (1741) example: bus: esp32p4:MIPI-CSI
|
||||
I (1741) example: capabilities:
|
||||
I (1751) example: VIDEO_CAPTURE
|
||||
I (1751) example: STREAMING
|
||||
I (1761) example: device capabilities:
|
||||
I (1761) example: VIDEO_CAPTURE
|
||||
I (1761) example: STREAMING
|
||||
I (1771) example: version: 0.5.1
|
||||
I (1771) example: driver: H.264
|
||||
I (1781) example: card: H.264
|
||||
I (1781) example: bus: esp32p4:H.264
|
||||
I (1781) example: capabilities:
|
||||
I (1791) example: STREAMING
|
||||
I (1791) example: device capabilities:
|
||||
I (1801) example: STREAMING
|
||||
I (1801) example: Format List
|
||||
I (1801) example: Format(1) = H.264
|
||||
I (1811) example: Frame List
|
||||
I (1811) example: Frame(1) = 1280 * 720 @30fps
|
||||
I (1821) usbd_uvc: UVC Device Start, Version: 1.1.0
|
||||
I (1821) main_task: Returned from app_main()
|
||||
I (2031) usbd_uvc: Mount
|
||||
I (3281) usbd_uvc: Suspend
|
||||
...
|
||||
```
|
||||
|
||||
#### DVP Development Kit
|
||||
|
||||
```
|
||||
...
|
||||
I (1164) main_task: Calling app_main()
|
||||
I (1164) gpio: GPIO[32]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (1174) gpio: GPIO[33]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||
I (1194) ov2640: Detected Camera sensor PID=0x26
|
||||
I (1274) example: version: 0.5.1
|
||||
I (1274) example: driver: DVP
|
||||
I (1274) example: card: DVP
|
||||
I (1274) example: bus: esp32p4:DVP
|
||||
I (1274) example: capabilities:
|
||||
I (1284) example: VIDEO_CAPTURE
|
||||
I (1284) example: STREAMING
|
||||
I (1284) example: device capabilities:
|
||||
I (1294) example: VIDEO_CAPTURE
|
||||
I (1294) example: STREAMING
|
||||
I (1304) example: version: 0.5.1
|
||||
I (1304) example: driver: JPEG
|
||||
I (1304) example: card: JPEG
|
||||
I (1314) example: bus: esp32p4:JPEG
|
||||
I (1314) example: capabilities:
|
||||
I (1314) example: STREAMING
|
||||
I (1324) example: device capabilities:
|
||||
I (1324) example: STREAMING
|
||||
I (1334) example: Format List
|
||||
I (1334) example: Format(1) = MJPEG
|
||||
I (1334) example: Frame List
|
||||
I (1344) example: Frame(1) = 640 * 480 @6fps
|
||||
I (1344) usbd_uvc: UVC Device Start, Version: 1.1.0
|
||||
I (1354) main_task: Returned from app_main()
|
||||
I (1564) usbd_uvc: Mount
|
||||
I (2824) usbd_uvc: Suspend
|
||||
...
|
||||
```
|
||||
|
||||
Open potplay APP and select follow option in menu:
|
||||
|
||||
```
|
||||
PotPlayer -->
|
||||
Open -->
|
||||
Camera/Other Device
|
||||
```
|
||||
|
||||
You can see following log on the serial monitor and video in potlayer display window:
|
||||
|
||||
```
|
||||
I (192121) usbd_uvc: Resume
|
||||
I (192411) usbd_uvc: bFrameIndex: 1
|
||||
I (192411) usbd_uvc: dwFrameInterval: 333333
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* If the console log shows as follows, it means your ESP32-P4 chip version is v0.0, and it is not supported by default configuration, please configure the right version by menuconfig:
|
||||
|
||||
```txt
|
||||
A fatal error occurred: bootloader/bootloader.bin requires chip revision in range [v0.1 - v0.99] (this chip is revision v0.0). Use --force to flash anyway
|
||||
```
|
||||
|
||||
menuconfig:
|
||||
```
|
||||
Component config --->
|
||||
Hardware Settings --->
|
||||
Chip revision --->
|
||||
Minimum Supported ESP32-P4 Revision (Rev v0.1) --->
|
||||
(X) Rev v0.0
|
||||
```
|
||||
@@ -0,0 +1,145 @@
|
||||
dependencies:
|
||||
espressif/cmake_utilities:
|
||||
component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.1'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.5.3
|
||||
espressif/esp_cam_sensor:
|
||||
component_hash: 7b110b08542aeae833895dacd74425e926dd36eed68ae1a26f2b6109e04ea984
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: espressif/esp_sccb_intf
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=0.0.2'
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 0.9.0
|
||||
espressif/esp_h264:
|
||||
component_hash: 7599170f185871bfde69aa0213dfc7f12d45e7dedfd85247be08d6decd34e476
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32s3
|
||||
- esp32p4
|
||||
version: 1.1.2
|
||||
espressif/esp_ipa:
|
||||
component_hash: 7547b050a99351a85aaba8ba38211c36fd4769c2ae3e570fa330dc90dfd2704c
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.4'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 0.2.0
|
||||
espressif/esp_sccb_intf:
|
||||
component_hash: 71e3def402f6193a23c599bdde4fa0b544ca2b1f63608b6d0ec2bee3cd9a1c33
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.0.5
|
||||
espressif/esp_video:
|
||||
component_hash: 37f7a3b16aa842e612180d5a4698db1c3bc36142a0b78664eb4ffe67c8cd0510
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: espressif/esp_cam_sensor
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.9.*
|
||||
- name: espressif/esp_h264
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=1.0.3'
|
||||
- name: espressif/esp_ipa
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.2.*
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.4'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 0.8.0~3
|
||||
espressif/tinyusb:
|
||||
component_hash: 214989d502fc168241a4a4f83b097d8ac44a93cd6f1787b4ac10069a8b3bebd3
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32p4
|
||||
version: 0.15.0~10
|
||||
espressif/usb_device_uvc:
|
||||
component_hash: c14907ba235d9c1292de13f64d465ee6ff9483b9509b4e01123ad0774161c0f5
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '*'
|
||||
- name: espressif/tinyusb
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=0.15.0~10'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32p4
|
||||
version: 1.1.2
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.0
|
||||
direct_dependencies:
|
||||
- espressif/esp_video
|
||||
- espressif/tinyusb
|
||||
- espressif/usb_device_uvc
|
||||
manifest_hash: 9fb4947fc8d76b823256c2b1c4e3be1949536cea28581179f094368f47f66df8
|
||||
target: esp32p4
|
||||
version: 2.0.0
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "uvc_example.c")
|
||||
@@ -0,0 +1,191 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
choice EXAMPLE_CAM_SENSOR_INTERFACE
|
||||
prompt "Camera sensor interface"
|
||||
default EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
help
|
||||
Select camera sensor interface based on development board.
|
||||
|
||||
config EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
bool "MIPI-CSI"
|
||||
depends on ESP_VIDEO_ENABLE_MIPI_CSI_VIDEO_DEVICE
|
||||
|
||||
config EXAMPLE_CAM_SENSOR_DVP
|
||||
bool "DVP"
|
||||
depends on ESP_VIDEO_ENABLE_DVP_VIDEO_DEVICE
|
||||
endchoice
|
||||
|
||||
if EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
config EXAMPLE_MIPI_CSI_SCCB_I2C_PORT
|
||||
int "MIPI CSI SCCB I2C Port Number"
|
||||
default 0
|
||||
range 0 1
|
||||
|
||||
config EXAMPLE_MIPI_CSI_SCCB_I2C_SCL_PIN
|
||||
int "MIPI CSI SCCB I2C SCL Pin"
|
||||
default 34
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_MIPI_CSI_SCCB_I2C_SDA_PIN
|
||||
int "MIPI CSI SCCB I2C SDA Pin"
|
||||
default 31
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_MIPI_CSI_SCCB_I2C_FREQ
|
||||
int "MIPI CSI SCCB I2C Frequency"
|
||||
default 100000
|
||||
range 100000 400000
|
||||
help
|
||||
Increasing this value can reduce the initialization time of the camera sensor.
|
||||
Please refer to the relevant instructions of the camera sensor to adjust the value.
|
||||
|
||||
config EXAMPLE_MIPI_CSI_CAM_SENSOR_RESET_PIN
|
||||
int "MIPI CSI Camera Sensor Reset Pin"
|
||||
default -1
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_MIPI_CSI_CAM_SENSOR_PWDN_PIN
|
||||
int "MIPI CSI Camera Sensor Power Down Pin"
|
||||
default -1
|
||||
range -1 56
|
||||
endif
|
||||
|
||||
if EXAMPLE_CAM_SENSOR_DVP
|
||||
config EXAMPLE_DVP_SCCB_I2C_PORT
|
||||
int "DVP SCCB I2C Port Number"
|
||||
default 1
|
||||
range 0 1
|
||||
|
||||
config EXAMPLE_DVP_SCCB_I2C_SCL_PIN
|
||||
int "DVP SCCB I2C SCL Pin"
|
||||
default 33
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_DVP_SCCB_I2C_SDA_PIN
|
||||
int "DVP SCCB I2C SDA Pin"
|
||||
default 32
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_DVP_SCCB_I2C_FREQ
|
||||
int "DVP SCCB I2C Frequency"
|
||||
default 100000
|
||||
range 100000 400000
|
||||
help
|
||||
Increasing this value can reduce the initialization time of the camera sensor.
|
||||
Please refer to the relevant instructions of the camera sensor to adjust the value.
|
||||
|
||||
config EXAMPLE_DVP_CAM_SENSOR_RESET_PIN
|
||||
int "DVP Camera Sensor Reset Pin"
|
||||
default -1
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_DVP_CAM_SENSOR_PWDN_PIN
|
||||
int "DVP Camera Sensor Power Down Pin"
|
||||
default -1
|
||||
range -1 56
|
||||
|
||||
config EXAMPLE_DVP_XCLK_FREQ
|
||||
int "DVP XCLK Frequency"
|
||||
default 20000000
|
||||
|
||||
config EXAMPLE_DVP_XCLK_PIN
|
||||
int "DVP XCLK Pin"
|
||||
range 0 56
|
||||
default 20
|
||||
|
||||
config EXAMPLE_DVP_PCLK_PIN
|
||||
int "DVP PCLK Pin"
|
||||
range 0 56
|
||||
default 21
|
||||
|
||||
config EXAMPLE_DVP_VSYNC_PIN
|
||||
int "DVP VSYNC Pin"
|
||||
range 0 56
|
||||
default 23
|
||||
|
||||
config EXAMPLE_DVP_DE_PIN
|
||||
int "DVP DE Pin"
|
||||
range 0 56
|
||||
default 22
|
||||
|
||||
config EXAMPLE_DVP_D0_PIN
|
||||
int "DVP D0 Pin"
|
||||
range 0 56
|
||||
default 53
|
||||
|
||||
config EXAMPLE_DVP_D1_PIN
|
||||
int "DVP D1 Pin"
|
||||
range 0 56
|
||||
default 54
|
||||
|
||||
config EXAMPLE_DVP_D2_PIN
|
||||
int "DVP D2 Pin"
|
||||
range 0 56
|
||||
default 52
|
||||
|
||||
config EXAMPLE_DVP_D3_PIN
|
||||
int "DVP D3 Pin"
|
||||
range 0 56
|
||||
default 1
|
||||
|
||||
config EXAMPLE_DVP_D4_PIN
|
||||
int "DVP D4 Pin"
|
||||
range 0 56
|
||||
default 0
|
||||
|
||||
config EXAMPLE_DVP_D5_PIN
|
||||
int "DVP D5 Pin"
|
||||
range 0 56
|
||||
default 45
|
||||
|
||||
config EXAMPLE_DVP_D6_PIN
|
||||
int "DVP D6 Pin"
|
||||
range 0 56
|
||||
default 46
|
||||
|
||||
config EXAMPLE_DVP_D7_PIN
|
||||
int "DVP D7 Pin"
|
||||
range 0 56
|
||||
default 47
|
||||
endif
|
||||
|
||||
if FORMAT_MJPEG_CAM1
|
||||
config EXAMPLE_JPEG_COMPRESSION_QUALITY
|
||||
int "JPEG Compression Quality"
|
||||
default 80
|
||||
range 1 100
|
||||
help
|
||||
JPEG compression quality, higher value means higher output
|
||||
image quality.
|
||||
endif
|
||||
|
||||
if FORMAT_H264_CAM1
|
||||
config EXAMPLE_H264_I_PERIOD
|
||||
int "H.264 Intra Frame period"
|
||||
default 120
|
||||
range 1 120
|
||||
help
|
||||
H.264 I-Frame period.
|
||||
|
||||
config EXAMPLE_H264_BITRATE
|
||||
int "H.264 Bitrate"
|
||||
default 1000000
|
||||
range 25000 2500000
|
||||
help
|
||||
H.264 bitrate.
|
||||
|
||||
config EXAMPLE_H264_MIN_QP
|
||||
int "H.264 Minimum Quality"
|
||||
default 25
|
||||
range 1 51
|
||||
help
|
||||
H.264 minimum quality, the value should be less than H.264 maximum quality.
|
||||
|
||||
config EXAMPLE_H264_MAX_QP
|
||||
int "H.264 Maximum Quality"
|
||||
default 26
|
||||
range 1 51
|
||||
help
|
||||
H.264 maximum quality, the value should be larger than H.264 minimum quality.
|
||||
endif
|
||||
endmenu
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencies:
|
||||
esp_video:
|
||||
version: "0.8.*"
|
||||
usb_device_uvc:
|
||||
version: "1.1.*"
|
||||
espressif/tinyusb:
|
||||
version: "0.15.0~10"
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: ESPRESSIF MIT
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "linux/videodev2.h"
|
||||
#include "esp_video_init.h"
|
||||
#include "esp_video_device.h"
|
||||
#include "usb_device_uvc.h"
|
||||
#include "uvc_frame_config.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
#define CAM_DEV_PATH ESP_VIDEO_MIPI_CSI_DEVICE_NAME
|
||||
#elif CONFIG_EXAMPLE_CAM_SENSOR_DVP
|
||||
#define CAM_DEV_PATH ESP_VIDEO_DVP_DEVICE_NAME
|
||||
#endif
|
||||
|
||||
#if CONFIG_FORMAT_MJPEG_CAM1
|
||||
#define ENCODE_DEV_PATH ESP_VIDEO_JPEG_DEVICE_NAME
|
||||
#define UVC_OUTPUT_FORMAT V4L2_PIX_FMT_JPEG
|
||||
#elif CONFIG_FORMAT_H264_CAM1
|
||||
#if CONFIG_EXAMPLE_H264_MAX_QP <= CONFIG_EXAMPLE_H264_MIN_QP
|
||||
#error "CONFIG_EXAMPLE_H264_MAX_QP should larger than CONFIG_EXAMPLE_H264_MIN_QP"
|
||||
#endif
|
||||
|
||||
#define ENCODE_DEV_PATH ESP_VIDEO_H264_DEVICE_NAME
|
||||
#define UVC_OUTPUT_FORMAT V4L2_PIX_FMT_H264
|
||||
#endif
|
||||
|
||||
#define BUFFER_COUNT 2
|
||||
|
||||
typedef struct uvc {
|
||||
int cap_fd;
|
||||
uint32_t format;
|
||||
uint8_t *cap_buffer[BUFFER_COUNT];
|
||||
|
||||
int m2m_fd;
|
||||
uint8_t *m2m_cap_buffer;
|
||||
|
||||
uvc_fb_t fb;
|
||||
} uvc_t;
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
#if CONFIG_EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
static const esp_video_init_csi_config_t csi_config[] = {
|
||||
{
|
||||
.sccb_config = {
|
||||
.init_sccb = true,
|
||||
.i2c_config = {
|
||||
.port = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_PORT,
|
||||
.scl_pin = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SCL_PIN,
|
||||
.sda_pin = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SDA_PIN,
|
||||
},
|
||||
.freq = CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_FREQ,
|
||||
},
|
||||
.reset_pin = CONFIG_EXAMPLE_MIPI_CSI_CAM_SENSOR_RESET_PIN,
|
||||
.pwdn_pin = CONFIG_EXAMPLE_MIPI_CSI_CAM_SENSOR_PWDN_PIN,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CAM_SENSOR_DVP
|
||||
static const esp_video_init_dvp_config_t dvp_config[] = {
|
||||
{
|
||||
.sccb_config = {
|
||||
.init_sccb = true,
|
||||
.i2c_config = {
|
||||
.port = CONFIG_EXAMPLE_DVP_SCCB_I2C_PORT,
|
||||
.scl_pin = CONFIG_EXAMPLE_DVP_SCCB_I2C_SCL_PIN,
|
||||
.sda_pin = CONFIG_EXAMPLE_DVP_SCCB_I2C_SDA_PIN,
|
||||
},
|
||||
.freq = CONFIG_EXAMPLE_DVP_SCCB_I2C_FREQ,
|
||||
},
|
||||
.reset_pin = CONFIG_EXAMPLE_DVP_CAM_SENSOR_RESET_PIN,
|
||||
.pwdn_pin = CONFIG_EXAMPLE_DVP_CAM_SENSOR_PWDN_PIN,
|
||||
.dvp_pin = {
|
||||
.data_width = CAM_CTLR_DATA_WIDTH_8,
|
||||
.data_io = {
|
||||
CONFIG_EXAMPLE_DVP_D0_PIN, CONFIG_EXAMPLE_DVP_D1_PIN, CONFIG_EXAMPLE_DVP_D2_PIN, CONFIG_EXAMPLE_DVP_D3_PIN,
|
||||
CONFIG_EXAMPLE_DVP_D4_PIN, CONFIG_EXAMPLE_DVP_D5_PIN, CONFIG_EXAMPLE_DVP_D6_PIN, CONFIG_EXAMPLE_DVP_D7_PIN,
|
||||
},
|
||||
.vsync_io = CONFIG_EXAMPLE_DVP_VSYNC_PIN,
|
||||
.de_io = CONFIG_EXAMPLE_DVP_DE_PIN,
|
||||
.pclk_io = CONFIG_EXAMPLE_DVP_PCLK_PIN,
|
||||
.xclk_io = CONFIG_EXAMPLE_DVP_XCLK_PIN,
|
||||
},
|
||||
.xclk_freq = CONFIG_EXAMPLE_DVP_XCLK_FREQ,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static const esp_video_init_config_t cam_config = {
|
||||
#if CONFIG_EXAMPLE_CAM_SENSOR_MIPI_CSI
|
||||
.csi = csi_config,
|
||||
#endif
|
||||
#if CONFIG_EXAMPLE_CAM_SENSOR_DVP
|
||||
.dvp = dvp_config,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void print_video_device_info(const struct v4l2_capability *capability)
|
||||
{
|
||||
ESP_LOGI(TAG, "version: %d.%d.%d", (uint16_t)(capability->version >> 16),
|
||||
(uint8_t)(capability->version >> 8),
|
||||
(uint8_t)capability->version);
|
||||
ESP_LOGI(TAG, "driver: %s", capability->driver);
|
||||
ESP_LOGI(TAG, "card: %s", capability->card);
|
||||
ESP_LOGI(TAG, "bus: %s", capability->bus_info);
|
||||
ESP_LOGI(TAG, "capabilities:");
|
||||
if (capability->capabilities & V4L2_CAP_VIDEO_CAPTURE) {
|
||||
ESP_LOGI(TAG, "\tVIDEO_CAPTURE");
|
||||
}
|
||||
if (capability->capabilities & V4L2_CAP_READWRITE) {
|
||||
ESP_LOGI(TAG, "\tREADWRITE");
|
||||
}
|
||||
if (capability->capabilities & V4L2_CAP_ASYNCIO) {
|
||||
ESP_LOGI(TAG, "\tASYNCIO");
|
||||
}
|
||||
if (capability->capabilities & V4L2_CAP_STREAMING) {
|
||||
ESP_LOGI(TAG, "\tSTREAMING");
|
||||
}
|
||||
if (capability->capabilities & V4L2_CAP_META_OUTPUT) {
|
||||
ESP_LOGI(TAG, "\tMETA_OUTPUT");
|
||||
}
|
||||
if (capability->capabilities & V4L2_CAP_DEVICE_CAPS) {
|
||||
ESP_LOGI(TAG, "device capabilities:");
|
||||
if (capability->device_caps & V4L2_CAP_VIDEO_CAPTURE) {
|
||||
ESP_LOGI(TAG, "\tVIDEO_CAPTURE");
|
||||
}
|
||||
if (capability->device_caps & V4L2_CAP_READWRITE) {
|
||||
ESP_LOGI(TAG, "\tREADWRITE");
|
||||
}
|
||||
if (capability->device_caps & V4L2_CAP_ASYNCIO) {
|
||||
ESP_LOGI(TAG, "\tASYNCIO");
|
||||
}
|
||||
if (capability->device_caps & V4L2_CAP_STREAMING) {
|
||||
ESP_LOGI(TAG, "\tSTREAMING");
|
||||
}
|
||||
if (capability->device_caps & V4L2_CAP_META_OUTPUT) {
|
||||
ESP_LOGI(TAG, "\tMETA_OUTPUT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t init_capture_video(uvc_t *uvc)
|
||||
{
|
||||
int fd;
|
||||
struct v4l2_capability capability;
|
||||
|
||||
fd = open(CAM_DEV_PATH, O_RDONLY);
|
||||
assert(fd >= 0);
|
||||
|
||||
ESP_ERROR_CHECK(ioctl(fd, VIDIOC_QUERYCAP, &capability));
|
||||
print_video_device_info(&capability);
|
||||
|
||||
uvc->cap_fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_err_t init_codec_video(uvc_t *uvc)
|
||||
{
|
||||
int fd;
|
||||
const char *devpath = ENCODE_DEV_PATH;
|
||||
struct v4l2_capability capability;
|
||||
struct v4l2_ext_controls controls;
|
||||
struct v4l2_ext_control control[1];
|
||||
|
||||
fd = open(devpath, O_RDONLY);
|
||||
assert(fd >= 0);
|
||||
|
||||
ESP_ERROR_CHECK(ioctl(fd, VIDIOC_QUERYCAP, &capability));
|
||||
print_video_device_info(&capability);
|
||||
|
||||
#if CONFIG_FORMAT_MJPEG_CAM1
|
||||
controls.ctrl_class = V4L2_CID_JPEG_CLASS;
|
||||
controls.count = 1;
|
||||
controls.controls = control;
|
||||
control[0].id = V4L2_CID_JPEG_COMPRESSION_QUALITY;
|
||||
control[0].value = CONFIG_EXAMPLE_JPEG_COMPRESSION_QUALITY;
|
||||
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &controls) != 0) {
|
||||
ESP_LOGW(TAG, "failed to set JPEG compression quality");
|
||||
}
|
||||
#elif CONFIG_FORMAT_H264_CAM1
|
||||
controls.ctrl_class = V4L2_CID_CODEC_CLASS;
|
||||
controls.count = 1;
|
||||
controls.controls = control;
|
||||
control[0].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
|
||||
control[0].value = CONFIG_EXAMPLE_H264_I_PERIOD;
|
||||
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &controls) != 0) {
|
||||
ESP_LOGW(TAG, "failed to set H.264 intra frame period");
|
||||
}
|
||||
|
||||
controls.ctrl_class = V4L2_CID_CODEC_CLASS;
|
||||
controls.count = 1;
|
||||
controls.controls = control;
|
||||
control[0].id = V4L2_CID_MPEG_VIDEO_BITRATE;
|
||||
control[0].value = CONFIG_EXAMPLE_H264_BITRATE;
|
||||
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &controls) != 0) {
|
||||
ESP_LOGW(TAG, "failed to set H.264 bitrate");
|
||||
}
|
||||
|
||||
controls.ctrl_class = V4L2_CID_CODEC_CLASS;
|
||||
controls.count = 1;
|
||||
controls.controls = control;
|
||||
control[0].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
|
||||
control[0].value = CONFIG_EXAMPLE_H264_MIN_QP;
|
||||
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &controls) != 0) {
|
||||
ESP_LOGW(TAG, "failed to set H.264 minimum quality");
|
||||
}
|
||||
|
||||
controls.ctrl_class = V4L2_CID_CODEC_CLASS;
|
||||
controls.count = 1;
|
||||
controls.controls = control;
|
||||
control[0].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
|
||||
control[0].value = CONFIG_EXAMPLE_H264_MAX_QP;
|
||||
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &controls) != 0) {
|
||||
ESP_LOGW(TAG, "failed to set H.264 maximum quality");
|
||||
}
|
||||
#endif
|
||||
|
||||
uvc->format = UVC_OUTPUT_FORMAT;
|
||||
uvc->m2m_fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_err_t video_start_cb(uvc_format_t uvc_format, int width, int height, int rate, void *cb_ctx)
|
||||
{
|
||||
int type;
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_format format;
|
||||
struct v4l2_requestbuffers req;
|
||||
uvc_t *uvc = (uvc_t *)cb_ctx;
|
||||
uint32_t capture_fmt = 0;
|
||||
|
||||
ESP_LOGD(TAG, "UVC start");
|
||||
|
||||
if (uvc->format == V4L2_PIX_FMT_JPEG) {
|
||||
int fmt_index = 0;
|
||||
const uint32_t jpeg_input_formats[] = {
|
||||
V4L2_PIX_FMT_RGB565,
|
||||
V4L2_PIX_FMT_YUV422P,
|
||||
V4L2_PIX_FMT_RGB24,
|
||||
V4L2_PIX_FMT_GREY
|
||||
};
|
||||
int jpeg_input_formats_num = sizeof(jpeg_input_formats) / sizeof(jpeg_input_formats[0]);
|
||||
|
||||
while (!capture_fmt) {
|
||||
struct v4l2_fmtdesc fmtdesc = {
|
||||
.index = fmt_index++,
|
||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
};
|
||||
|
||||
if (ioctl(uvc->cap_fd, VIDIOC_ENUM_FMT, &fmtdesc) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < jpeg_input_formats_num; i++) {
|
||||
if (jpeg_input_formats[i] == fmtdesc.pixelformat) {
|
||||
capture_fmt = jpeg_input_formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!capture_fmt) {
|
||||
ESP_LOGI(TAG, "The camera sensor output pixel format is not supported by JPEG");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
capture_fmt = V4L2_PIX_FMT_YUV420;
|
||||
}
|
||||
|
||||
/* Configure camera interface capture stream */
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
format.fmt.pix.width = width;
|
||||
format.fmt.pix.height = height;
|
||||
format.fmt.pix.pixelformat = capture_fmt;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_S_FMT, &format));
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.count = BUFFER_COUNT;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_REQBUFS, &req));
|
||||
|
||||
for (int i = 0; i < BUFFER_COUNT; i++) {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = i;
|
||||
ESP_ERROR_CHECK (ioctl(uvc->cap_fd, VIDIOC_QUERYBUF, &buf));
|
||||
|
||||
uvc->cap_buffer[i] = (uint8_t *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, uvc->cap_fd, buf.m.offset);
|
||||
assert(uvc->cap_buffer[i]);
|
||||
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_QBUF, &buf));
|
||||
}
|
||||
|
||||
/* Configure codec output stream */
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
format.fmt.pix.width = width;
|
||||
format.fmt.pix.height = height;
|
||||
format.fmt.pix.pixelformat = capture_fmt;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_S_FMT, &format));
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.count = 1;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
req.memory = V4L2_MEMORY_USERPTR;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_REQBUFS, &req));
|
||||
|
||||
/* Configure codec capture stream */
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
format.fmt.pix.width = width;
|
||||
format.fmt.pix.height = height;
|
||||
format.fmt.pix.pixelformat = uvc->format;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_S_FMT, &format));
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.count = 1;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_REQBUFS, &req));
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = 0;
|
||||
ESP_ERROR_CHECK (ioctl(uvc->m2m_fd, VIDIOC_QUERYBUF, &buf));
|
||||
|
||||
uvc->m2m_cap_buffer = (uint8_t *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, uvc->m2m_fd, buf.m.offset);
|
||||
assert(uvc->m2m_cap_buffer);
|
||||
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_QBUF, &buf));
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_STREAMON, &type));
|
||||
type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_STREAMON, &type));
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_STREAMON, &type));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void video_stop_cb(void *cb_ctx)
|
||||
{
|
||||
int type;
|
||||
uvc_t *uvc = (uvc_t *)cb_ctx;
|
||||
|
||||
ESP_LOGD(TAG, "UVC stop");
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ioctl(uvc->cap_fd, VIDIOC_STREAMOFF, &type);
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
ioctl(uvc->m2m_fd, VIDIOC_STREAMOFF, &type);
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ioctl(uvc->m2m_fd, VIDIOC_STREAMOFF, &type);
|
||||
}
|
||||
|
||||
static uvc_fb_t *video_fb_get_cb(void *cb_ctx)
|
||||
{
|
||||
int64_t us;
|
||||
uvc_t *uvc = (uvc_t *)cb_ctx;
|
||||
struct v4l2_format format;
|
||||
struct v4l2_buffer cap_buf;
|
||||
struct v4l2_buffer m2m_out_buf;
|
||||
struct v4l2_buffer m2m_cap_buf;
|
||||
|
||||
ESP_LOGD(TAG, "UVC get");
|
||||
|
||||
memset(&cap_buf, 0, sizeof(cap_buf));
|
||||
cap_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
cap_buf.memory = V4L2_MEMORY_MMAP;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_DQBUF, &cap_buf));
|
||||
|
||||
memset(&m2m_out_buf, 0, sizeof(m2m_out_buf));
|
||||
m2m_out_buf.index = 0;
|
||||
m2m_out_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
m2m_out_buf.memory = V4L2_MEMORY_USERPTR;
|
||||
m2m_out_buf.m.userptr = (unsigned long)uvc->cap_buffer[cap_buf.index];
|
||||
m2m_out_buf.length = cap_buf.bytesused;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_QBUF, &m2m_out_buf));
|
||||
|
||||
memset(&m2m_cap_buf, 0, sizeof(m2m_cap_buf));
|
||||
m2m_cap_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
m2m_cap_buf.memory = V4L2_MEMORY_MMAP;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_DQBUF, &m2m_cap_buf));
|
||||
|
||||
ESP_ERROR_CHECK(ioctl(uvc->cap_fd, VIDIOC_QBUF, &cap_buf));
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_DQBUF, &m2m_out_buf));
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_G_FMT, &format));
|
||||
|
||||
uvc->fb.buf = uvc->m2m_cap_buffer;
|
||||
uvc->fb.len = m2m_cap_buf.bytesused;
|
||||
uvc->fb.width = format.fmt.pix.width;
|
||||
uvc->fb.height = format.fmt.pix.height;
|
||||
uvc->fb.format = format.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG ? UVC_FORMAT_JPEG : UVC_FORMAT_H264;
|
||||
|
||||
us = esp_timer_get_time();
|
||||
uvc->fb.timestamp.tv_sec = us / 1000000UL;;
|
||||
uvc->fb.timestamp.tv_usec = us % 1000000UL;
|
||||
|
||||
return &uvc->fb;
|
||||
}
|
||||
|
||||
static void video_fb_return_cb(uvc_fb_t *fb, void *cb_ctx)
|
||||
{
|
||||
struct v4l2_buffer m2m_cap_buf;
|
||||
uvc_t *uvc = (uvc_t *)cb_ctx;
|
||||
|
||||
ESP_LOGD(TAG, "UVC return");
|
||||
|
||||
m2m_cap_buf.index = 0;
|
||||
m2m_cap_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
m2m_cap_buf.memory = V4L2_MEMORY_MMAP;
|
||||
ESP_ERROR_CHECK(ioctl(uvc->m2m_fd, VIDIOC_QBUF, &m2m_cap_buf));
|
||||
}
|
||||
|
||||
static esp_err_t init_uvc(uvc_t *uvc)
|
||||
{
|
||||
int index = 0;
|
||||
uvc_device_config_t config = {
|
||||
.start_cb = video_start_cb,
|
||||
.fb_get_cb = video_fb_get_cb,
|
||||
.fb_return_cb = video_fb_return_cb,
|
||||
.stop_cb = video_stop_cb,
|
||||
.cb_ctx = (void *)uvc,
|
||||
};
|
||||
|
||||
config.uvc_buffer_size = UVC_FRAMES_INFO[index][0].width * UVC_FRAMES_INFO[index][0].height;
|
||||
config.uvc_buffer = malloc(config.uvc_buffer_size);
|
||||
assert(config.uvc_buffer);
|
||||
|
||||
ESP_LOGI(TAG, "Format List");
|
||||
ESP_LOGI(TAG, "\tFormat(1) = %s", uvc->format == V4L2_PIX_FMT_JPEG ? "MJPEG" : "H.264");
|
||||
ESP_LOGI(TAG, "Frame List");
|
||||
ESP_LOGI(TAG, "\tFrame(1) = %d * %d @%dfps", UVC_FRAMES_INFO[index][0].width, UVC_FRAMES_INFO[index][0].height, UVC_FRAMES_INFO[index][0].rate);
|
||||
|
||||
ESP_ERROR_CHECK(uvc_device_config(index, &config));
|
||||
ESP_ERROR_CHECK(uvc_device_init());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
uvc_t *uvc = calloc(1, sizeof(uvc_t));
|
||||
assert(uvc);
|
||||
|
||||
ESP_ERROR_CHECK(esp_video_init(&cam_config));
|
||||
ESP_ERROR_CHECK(init_capture_video(uvc));
|
||||
ESP_ERROR_CHECK(init_codec_video(uvc));
|
||||
ESP_ERROR_CHECK(init_uvc(uvc));
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32p4"
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SCL_PIN=8
|
||||
CONFIG_EXAMPLE_MIPI_CSI_SCCB_I2C_SDA_PIN=7
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_SPEED_200M=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3584
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
|
||||
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=3584
|
||||
CONFIG_CAMERA_OV5647=y
|
||||
CONFIG_CAMERA_OV5647_MIPI_RAW10_1920x1080_30FPS=y
|
||||
CONFIG_ESP_VIDEO_ENABLE_DVP_VIDEO_DEVICE=n
|
||||
CONFIG_ESP_VIDEO_ENABLE_HW_H264_VIDEO_DEVICE=y
|
||||
CONFIG_ESP_VIDEO_ENABLE_HW_JPEG_VIDEO_DEVICE=y
|
||||
CONFIG_FRAMESIZE_FHD=y
|
||||
CONFIG_UVC_CAM1_FRAMERATE=30
|
||||
CONFIG_UVC_MULTI_FRAME_WIDTH_1=1280
|
||||
CONFIG_UVC_MULTI_FRAME_HEIGHT_1=720
|
||||
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||
@@ -0,0 +1,7 @@
|
||||
CONFIG_CAMERA_SC2336=y
|
||||
|
||||
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||
|
||||
CONFIG_SPIRAM=y
|
||||
|
||||
CONFIG_SPIRAM_SPEED_200M=y
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user