-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(uvc): Testable descriptor parsing
- Loading branch information
1 parent
5d1e75e
commit bea7249
Showing
20 changed files
with
910 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,10 @@ | ||
- [ ] Allow external events handling | ||
- [ ] Allow VID and PID to be 0 | ||
- [x] Allow VID and PID to be 0 | ||
- [x] 1 CTRL transfer for the driver? of 1 transfer for a device? | ||
- [ ] Mock USB host for descriptor parsing | ||
- [x] Mock USB host for descriptor parsing | ||
- [ ] Allow floating FPS | ||
- [ ] Allow setting of default | ||
- [ ] Add descriptor printing from UVC version 1 | ||
- [ ] Test reconnections | ||
- [ ] Test frequent stream pause/resume | ||
- [ ] Support bulk transfers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
host/class/uvc/usb_host_uvc_2/host_test/main/test_parsing_customer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/uvc_host.h" | ||
#include "uvc_descriptors_priv.h" | ||
|
||
#include "test_parsing_helpers.hpp" | ||
#include "descriptors/customer.hpp" | ||
using namespace customer_camera; | ||
|
||
SCENARIO("Camera descriptor parsing: Customer", "[customer][single]") | ||
{ | ||
const usb_config_desc_t *cfg = (const usb_config_desc_t *)cfg_desc; | ||
|
||
GIVEN("Customer MJPEG") { | ||
uvc_host_stream_format_t formats[] = { | ||
{1280, 720, 15, UVC_VS_FORMAT_MJPEG}, | ||
{1280, 720, 10, UVC_VS_FORMAT_MJPEG}, | ||
{800, 480, 20, UVC_VS_FORMAT_MJPEG}, | ||
{800, 480, 15, UVC_VS_FORMAT_MJPEG}, | ||
{640, 480, 25, UVC_VS_FORMAT_MJPEG}, | ||
{640, 480, 15, UVC_VS_FORMAT_MJPEG}, | ||
{480, 320, 25, UVC_VS_FORMAT_MJPEG}, | ||
{480, 320, 15, UVC_VS_FORMAT_MJPEG}, | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("Customer Unsupported") { | ||
uvc_host_stream_format_t formats[] = { | ||
{640, 480, 28, UVC_VS_FORMAT_MJPEG}, // Invalid FPS | ||
{645, 480, 25, UVC_VS_FORMAT_MJPEG}, // Invalid definition | ||
{640, 480, 20, UVC_VS_FORMAT_H264}, // Invalid format | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_NOT_SUPPORTED(cfg, this_format); | ||
} | ||
} | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
host/class/uvc/usb_host_uvc_2/host_test/main/test_parsing_customer_dual.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/uvc_host.h" | ||
#include "uvc_descriptors_priv.h" | ||
|
||
#include "test_parsing_helpers.hpp" | ||
#include "descriptors/customer_dual.hpp" | ||
using namespace customer_camera_dual; | ||
|
||
SCENARIO("Camera descriptor parsing: Customer dual", "[customer][dual]") | ||
{ | ||
const usb_config_desc_t *cfg = (const usb_config_desc_t *)cfg_desc; | ||
|
||
GIVEN("Customer dual MJPEG") { | ||
uvc_host_stream_format_t formats[] = { | ||
{720, 1280, 30, UVC_VS_FORMAT_MJPEG}, | ||
{720, 1280, 15, UVC_VS_FORMAT_MJPEG}, | ||
{720, 1280, 10, UVC_VS_FORMAT_MJPEG}, | ||
{720, 1280, 5, UVC_VS_FORMAT_MJPEG}, | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("Customer dual h265") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_H265_30_20_15(640, 480), | ||
{640, 480, 25, UVC_VS_FORMAT_H265}, | ||
|
||
FORMAT_H265_30_20_15(1280, 720), | ||
{1280, 720, 25, UVC_VS_FORMAT_H265}, | ||
|
||
FORMAT_H265_30_20_15(640, 480), | ||
{1920, 1080, 25, UVC_VS_FORMAT_H265}, | ||
|
||
FORMAT_H265_30_20_15(640, 480), | ||
{2560, 1440, 25, UVC_VS_FORMAT_H265}, | ||
|
||
FORMAT_H265_30_20_15(640, 480), | ||
{2304, 1296, 25, UVC_VS_FORMAT_H265}, | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
// Here we are testing uvc_index = 1 and expected_interface = 3 | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
uint8_t bInterfaceNumber = 0; | ||
uint16_t bcdUVC = 0; | ||
REQUIRE(ESP_OK == uvc_desc_get_streaming_interface_num(cfg, 1, &this_format, &bcdUVC, &bInterfaceNumber)); | ||
REQUIRE(bInterfaceNumber == 3); | ||
const usb_intf_desc_t *intf_desc = nullptr; | ||
const usb_ep_desc_t *ep_desc = nullptr; | ||
REQUIRE(ESP_OK == uvc_desc_get_streaming_intf_and_ep(cfg, bInterfaceNumber, &intf_desc, &ep_desc)); | ||
REQUIRE(intf_desc != nullptr); | ||
REQUIRE(ep_desc != nullptr); | ||
const uvc_format_desc_t *format_desc = nullptr; | ||
const uvc_frame_desc_t *frame_desc = nullptr; | ||
REQUIRE(ESP_OK == uvc_desc_get_frame_format_by_format(cfg, bInterfaceNumber, &this_format, &format_desc, &frame_desc)); | ||
REQUIRE(format_desc != nullptr); | ||
REQUIRE(frame_desc != nullptr); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("Customer dual Unsupported") { | ||
uvc_host_stream_format_t formats[] = { | ||
{640, 480, 28, UVC_VS_FORMAT_MJPEG}, // Invalid FPS | ||
{645, 480, 25, UVC_VS_FORMAT_MJPEG}, // Invalid definition | ||
{640, 480, 20, UVC_VS_FORMAT_H264}, // Invalid format | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_NOT_SUPPORTED(cfg, this_format); | ||
} | ||
} | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
host/class/uvc/usb_host_uvc_2/host_test/main/test_parsing_elp_h264.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/uvc_host.h" | ||
#include "uvc_descriptors_priv.h" | ||
|
||
#include "test_parsing_helpers.hpp" | ||
#include "descriptors/elp_h264.hpp" | ||
using namespace elp_h264; | ||
|
||
SCENARIO("Camera descriptor parsing: ELP h264", "[elp][h264]") | ||
{ | ||
const usb_config_desc_t *cfg = (const usb_config_desc_t *)cfg_desc; | ||
|
||
GIVEN("ELP h264 MJPEG") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_MJPEG_30_25_15(1920, 1080), | ||
FORMAT_MJPEG_30_25_15(1280, 720), | ||
FORMAT_MJPEG_30_25_15(800, 600), | ||
FORMAT_MJPEG_30_25_15(640, 480), | ||
FORMAT_MJPEG_30_25_15(640, 360), | ||
FORMAT_MJPEG_30_25_15(352, 288), | ||
FORMAT_MJPEG_30_25_15(320, 240), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h264 Uncompressed") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_UNCOMPRESSED_30_25_15(640, 480), | ||
{800, 600, 15, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
FORMAT_UNCOMPRESSED_30_25_15(352, 288), | ||
FORMAT_UNCOMPRESSED_30_25_15(320, 240), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h264 h264") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_H264_30_25_15(1920, 1080), | ||
FORMAT_H264_30_25_15(1280, 720), | ||
FORMAT_H264_30_25_15(800, 600), | ||
FORMAT_H264_30_25_15(640, 480), | ||
FORMAT_H264_30_25_15(640, 360), | ||
FORMAT_H264_30_25_15(352, 288), | ||
FORMAT_H264_30_25_15(320, 240), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 2); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h264 Unsupported") { | ||
uvc_host_stream_format_t formats[] = { | ||
{640, 480, 28, UVC_VS_FORMAT_MJPEG}, // Invalid FPS | ||
{645, 480, 25, UVC_VS_FORMAT_MJPEG}, // Invalid definition | ||
{640, 480, 20, UVC_VS_FORMAT_H265}, // Invalid format | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_NOT_SUPPORTED(cfg, this_format); | ||
} | ||
} | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
host/class/uvc/usb_host_uvc_2/host_test/main/test_parsing_elp_h265.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/uvc_host.h" | ||
#include "uvc_descriptors_priv.h" | ||
|
||
#include "test_parsing_helpers.hpp" | ||
#include "descriptors/elp_h265.hpp" | ||
using namespace elp_h265; | ||
|
||
SCENARIO("Camera descriptor parsing: ELP h265", "[elp][h265]") | ||
{ | ||
const usb_config_desc_t *cfg = (const usb_config_desc_t *)cfg_desc; | ||
|
||
GIVEN("ELP h265 MJPEG") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_MJPEG_30_20_15(640, 360), | ||
FORMAT_MJPEG_30_20_15(640, 480), | ||
FORMAT_MJPEG_30_20_15(960, 540), | ||
FORMAT_MJPEG_30_20_15(1024, 576), | ||
FORMAT_MJPEG_30_20_15(1280, 720), | ||
FORMAT_MJPEG_30_20_15(1920, 1080), | ||
FORMAT_MJPEG_30_20_15(2560, 1440), | ||
FORMAT_MJPEG_30_20_15(3840, 2160), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h265 h264") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_H264_30_20_15(640, 360), | ||
FORMAT_H264_30_20_15(640, 480), | ||
FORMAT_H264_30_20_15(960, 540), | ||
FORMAT_H264_30_20_15(1024, 576), | ||
FORMAT_H264_30_20_15(1280, 720), | ||
FORMAT_H264_30_20_15(1920, 1080), | ||
FORMAT_H264_30_20_15(2560, 1440), | ||
FORMAT_H264_30_20_15(3840, 2160), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h265 h265") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_H265_30_20_15(640, 360), | ||
FORMAT_H265_30_20_15(640, 480), | ||
FORMAT_H265_30_20_15(960, 540), | ||
FORMAT_H265_30_20_15(1024, 576), | ||
FORMAT_H265_30_20_15(1280, 720), | ||
FORMAT_H265_30_20_15(1920, 1080), | ||
FORMAT_H265_30_20_15(2560, 1440), | ||
FORMAT_H265_30_20_15(3840, 2160), | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h265 Uncompressed") { | ||
uvc_host_stream_format_t formats[] = { | ||
FORMAT_UNCOMPRESSED_30_20_15(640, 360), | ||
FORMAT_UNCOMPRESSED_30_20_15(640, 480), | ||
{960, 540, 15, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{960, 540, 10, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{960, 540, 5, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1024, 576, 15, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1024, 576, 10, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1024, 576, 5, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1280, 720, 10, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1280, 720, 5, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1280, 720, 2, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1920, 1080, 5, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
{1920, 1080, 2, UVC_VS_FORMAT_UNCOMPRESSED}, | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_SUPPORTED(cfg, this_format, 1); | ||
} | ||
} | ||
} | ||
|
||
GIVEN("ELP h265 Unsupported") { | ||
uvc_host_stream_format_t formats[] = { | ||
{640, 480, 28, UVC_VS_FORMAT_MJPEG}, // Invalid FPS | ||
{645, 480, 25, UVC_VS_FORMAT_MJPEG}, // Invalid definition | ||
{640, 480, 20, UVC_VS_FORMAT_UNDEFINED}, // Invalid format | ||
}; | ||
|
||
for (uvc_host_stream_format_t this_format : formats) { | ||
SECTION(std::to_string(this_format.h_res) + "x" + std::to_string(this_format.v_res) + "@" + std::to_string(this_format.fps)) { | ||
REQUIRE_FORMAT_NOT_SUPPORTED(cfg, this_format); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.