From 9bcab53c2cb0b52baf8bc0c768887428ac87fbff Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 29 Sep 2021 22:53:26 +0900 Subject: [PATCH] Implement frame rate settings --- examples/device/video_capture/src/main.c | 13 ++++++--- .../video_capture/src/usb_descriptors.h | 2 +- src/class/video/video_device.c | 11 +++++++- src/class/video/video_device.h | 27 ++++++++++++------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 6f47a1841..a38791365 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -110,11 +110,11 @@ static unsigned char const *frames[] = { }; static unsigned current_frame = 0; static unsigned tx_busy = 0; +static unsigned interval_ms = 1000 / FRAME_RATE; void video_task(void) { static unsigned start_ms = 0; - static unsigned interval_ms = 1000 / FRAME_RATE; static unsigned already_sent = 0; if (!tud_video_n_streaming(0, 0)) { @@ -137,7 +137,7 @@ void video_task(void) tud_video_n_frame_xfer(0, 0, (void*)frames[current_frame], FRAME_WIDTH * FRAME_HEIGHT * 12/8); } -int tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { (void)ctl_idx; (void)stm_idx; tx_busy = 0; @@ -145,7 +145,14 @@ int tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) ++current_frame; if (current_frame == sizeof(frames)/sizeof(frames[0])) current_frame = 0; - return 0; +} + +int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const *parameters) +{ + /* convert unit to ms from 100 ns */ + interval_ms = parameters->dwFrameInterval / 10000; + return VIDEO_NO_ERROR; } //--------------------------------------------------------------------+ diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 867e9af42..eff57f1fa 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -99,7 +99,7 @@ enum { TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 12, _width * _height * 12 * _fps, \ _width * _height * 12, \ - (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + (10000000/_fps), (10000000/_fps), 10000000, 100000), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(1, 1, 1, 0), \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index f4ecef446..28ac860e1 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -290,6 +290,9 @@ static inline tusb_desc_cs_video_frm_uncompressed_t const *_find_desc_frame(void _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_UNCOMPRESSED, frmnum); } +/** Set uniquely determined values to variables that have not been set + * + * @param[in,out] param Target */ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm, video_probe_and_commit_control_t *param) { @@ -353,6 +356,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm return true; } +/** Set the minimum or the maximum values to variables which need to negotiate with the host + * + * @param[in] set_max If true, the maximum values is set, otherwise the minimum value is set. + * @param[in,out] param Target + */ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, bool set_max, video_probe_and_commit_control_t *param) { @@ -514,6 +522,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint stm->max_payload_transfer_size = 0; video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t *)&stm->ep_buf; + tu_memclr(param, sizeof(*param)); return _update_streaming_parameters(stm, param); } /* Open endpoints of the new settings. */ @@ -880,7 +889,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu if (!stm || !stm->desc.ep[0] || stm->buffer) return false; - /* find EP address */ + /* Find EP address */ void const *desc = _videod_itf[stm->index_vc].beg; uint_fast8_t ep_addr = 0; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index 8654b63c5..e5012ca7e 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -43,32 +43,39 @@ extern "C" { * stm_idx instance number of streaming interface */ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); - -/* ctl_idx instance number of control interface - * stm_idx instance number of streaming interface */ +/** + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @param[in] buffer Frame buffer. The caller must not use this buffer until the operation is completed. + * @param[in] bufsize Byte size of the frame buffer */ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize); /*------------- Optional callbacks -------------*/ -/* ctl_idx instance number of control interface - * stm_idx instance number of streaming interface */ -TU_ATTR_WEAK int tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); +/** Invoked when compeletion of a frame transfer + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index */ +TU_ATTR_WEAK void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ -/* Invoked when SET POWER_MODE request received to +/** Invoked when SET_POWER_MODE request received + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index * @return video_error_code_t */ TU_ATTR_WEAK int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod); -/** +/** Invoked when VS_COMMIT_CONTROL(SET_CUR) request received * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index * @return video_error_code_t */ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const *parameters); -/* @return video_error_code_t */ -TU_ATTR_WEAK int tud_video_commit_set_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const *settings); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+