mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-21 21:41:09 +00:00
Implement GET_DEF and GET_LEN handling on Probe/Commit entities of streaming interface
This commit is contained in:
parent
7325dd6335
commit
4fd0ee4eef
@ -354,21 +354,25 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
|
|||||||
return true;
|
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
|
* @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)
|
video_probe_and_commit_control_t *param)
|
||||||
{
|
{
|
||||||
uint_fast8_t const fmtnum = param->bFormatIndex;
|
uint_fast8_t const fmtnum = param->bFormatIndex;
|
||||||
if (!fmtnum) {
|
if (!fmtnum) {
|
||||||
if (set_max) {
|
switch (request) {
|
||||||
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
|
case VIDEO_REQUEST_GET_MAX:
|
||||||
param->bFormatIndex = vs->stm.bNumFormats;
|
param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats;
|
||||||
} else {
|
break;
|
||||||
param->bFormatIndex = 1;
|
case VIDEO_REQUEST_GET_MIN:
|
||||||
|
case VIDEO_REQUEST_GET_DEF:
|
||||||
|
param->bFormatIndex = 1;
|
||||||
|
break;
|
||||||
|
default: return false;
|
||||||
}
|
}
|
||||||
/* Set the parameters determined by the format */
|
/* Set the parameters determined by the format */
|
||||||
param->wKeyFrameRate = 1;
|
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);
|
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
|
||||||
void const *end = _end_of_streaming_descriptor(vs);
|
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);
|
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;
|
param->bFrameIndex = frmnum;
|
||||||
/* Set the parameters determined by the frame */
|
/* 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);
|
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);
|
tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum);
|
||||||
|
|
||||||
uint_fast32_t interval;
|
uint_fast32_t interval;
|
||||||
uint_fast8_t num_intervals = frm->bFrameIntervalType;
|
switch (request) {
|
||||||
if (!num_intervals) {
|
case VIDEO_REQUEST_GET_MAX:
|
||||||
interval = set_max ? frm->dwFrameInterval[1]: frm->dwFrameInterval[0];
|
{
|
||||||
} else {
|
uint_fast8_t num_intervals = frm->bFrameIntervalType;
|
||||||
interval = set_max ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[0];
|
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;
|
param->dwFrameInterval = interval;
|
||||||
uint_fast32_t interval_ms = interval / 10000;
|
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;
|
video_probe_and_commit_control_t tmp;
|
||||||
tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
|
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);
|
TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
|
||||||
}
|
}
|
||||||
return VIDEO_ERROR_NONE;
|
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);
|
TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
|
||||||
video_probe_and_commit_control_t tmp;
|
video_probe_and_commit_control_t tmp;
|
||||||
tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
|
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);
|
TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
|
||||||
}
|
}
|
||||||
return VIDEO_ERROR_NONE;
|
return VIDEO_ERROR_NONE;
|
||||||
|
|
||||||
case VIDEO_REQUEST_GET_RES: return VIDEO_ERROR_UNKNOWN;
|
case VIDEO_REQUEST_GET_RES: return VIDEO_ERROR_UNKNOWN;
|
||||||
case VIDEO_REQUEST_GET_DEF: return VIDEO_ERROR_UNKNOWN;
|
case VIDEO_REQUEST_GET_DEF:
|
||||||
case VIDEO_REQUEST_GET_LEN: return VIDEO_ERROR_UNKNOWN;
|
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:
|
case VIDEO_REQUEST_GET_INFO:
|
||||||
if (stage == CONTROL_STAGE_SETUP)
|
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;
|
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:
|
case VIDEO_REQUEST_GET_INFO:
|
||||||
if (stage == CONTROL_STAGE_SETUP)
|
if (stage == CONTROL_STAGE_SETUP)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user