summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkkitayam <[email protected]>2021-10-16 15:52:46 +0900
committerkkitayam <[email protected]>2021-10-18 21:53:38 +0900
commit4fd0ee4eef149237aa58b24e843649b16d5ca1dc (patch)
tree8e56239fc9777b882701a4a7167674f477cf3e9b
parent7325dd633536d086491ef057a544760886190cc7 (diff)
Implement GET_DEF and GET_LEN handling on Probe/Commit entities of streaming interface
-rw-r--r--src/class/video/video_device.c86
1 files changed, 68 insertions, 18 deletions
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index 91d3b2b72..cd6459a18 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -354,21 +354,25 @@ 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
+/** Set the minimum, maximum or default 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] request GET_MAX, GET_MIN or GET_DEF
* @param[in,out] param Target
*/
-static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, bool set_max,
+static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, uint_fast8_t request,
video_probe_and_commit_control_t *param)
{
uint_fast8_t const fmtnum = param->bFormatIndex;
if (!fmtnum) {
- if (set_max) {
- tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
- param->bFormatIndex = vs->stm.bNumFormats;
- } else {
- param->bFormatIndex = 1;
+ switch (request) {
+ case VIDEO_REQUEST_GET_MAX:
+ param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats;
+ break;
+ case VIDEO_REQUEST_GET_MIN:
+ case VIDEO_REQUEST_GET_DEF:
+ param->bFormatIndex = 1;
+ break;
+ default: return false;
}
/* Set the parameters determined by the format */
param->wKeyFrameRate = 1;
@@ -391,7 +395,18 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
void const *end = _end_of_streaming_descriptor(vs);
tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum);
- frmnum = set_max ? fmt->bNumFrameDescriptors: 1;
+ switch (request) {
+ case VIDEO_REQUEST_GET_MAX:
+ frmnum = fmt->bNumFrameDescriptors;
+ break;
+ case VIDEO_REQUEST_GET_MIN:
+ frmnum = 1;
+ break;
+ case VIDEO_REQUEST_GET_DEF:
+ frmnum = fmt->bDefaultFrameIndex;
+ break;
+ default: return false;
+ }
param->bFrameIndex = frmnum;
/* Set the parameters determined by the frame */
tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum);
@@ -406,11 +421,20 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum);
uint_fast32_t interval;
- uint_fast8_t num_intervals = frm->bFrameIntervalType;
- if (!num_intervals) {
- interval = set_max ? frm->dwFrameInterval[1]: frm->dwFrameInterval[0];
- } else {
- interval = set_max ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[0];
+ switch (request) {
+ case VIDEO_REQUEST_GET_MAX:
+ {
+ uint_fast8_t num_intervals = frm->bFrameIntervalType;
+ interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1];
+ }
+ break;
+ case VIDEO_REQUEST_GET_MIN:
+ interval = frm->dwFrameInterval[0];
+ break;
+ case VIDEO_REQUEST_GET_DEF:
+ interval = frm->dwDefaultFrameInterval;
+ break;
+ default: return false;
}
param->dwFrameInterval = interval;
uint_fast32_t interval_ms = interval / 10000;
@@ -784,7 +808,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
video_probe_and_commit_control_t tmp;
tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
- TU_VERIFY(_negotiate_streaming_parameters(self, false, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
+ TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MIN, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
@@ -795,14 +819,31 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
video_probe_and_commit_control_t tmp;
tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
- TU_VERIFY(_negotiate_streaming_parameters(self, true, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
+ TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_MAX, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_RES: return VIDEO_ERROR_UNKNOWN;
- case VIDEO_REQUEST_GET_DEF: return VIDEO_ERROR_UNKNOWN;
- case VIDEO_REQUEST_GET_LEN: return VIDEO_ERROR_UNKNOWN;
+ case VIDEO_REQUEST_GET_DEF:
+ if (stage == CONTROL_STAGE_SETUP)
+ {
+ TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
+ video_probe_and_commit_control_t tmp;
+ tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
+ TU_VERIFY(_negotiate_streaming_parameters(self, VIDEO_REQUEST_GET_DEF, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
+ TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
+ }
+ return VIDEO_ERROR_UNKNOWN;
+
+ case VIDEO_REQUEST_GET_LEN:
+ if (stage == CONTROL_STAGE_SETUP)
+ {
+ TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN);
+ uint16_t len = sizeof(video_probe_and_commit_control_t);
+ TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN);
+ }
+ return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_INFO:
if (stage == CONTROL_STAGE_SETUP)
@@ -838,6 +879,15 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
}
return VIDEO_ERROR_NONE;
+ case VIDEO_REQUEST_GET_LEN:
+ if (stage == CONTROL_STAGE_SETUP)
+ {
+ TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN);
+ uint16_t len = sizeof(video_probe_and_commit_control_t);
+ TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN);
+ }
+ return VIDEO_ERROR_NONE;
+
case VIDEO_REQUEST_GET_INFO:
if (stage == CONTROL_STAGE_SETUP)
{