summaryrefslogtreecommitdiff
path: root/src/class/video
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2026-06-22 21:30:58 +0200
committerHiFiPhile <[email protected]>2026-06-22 21:30:58 +0200
commit693cdce08e14833f26f4e8a1f26e4fd546be4c35 (patch)
tree7667d2223dc32d9f21b5b60ab200e64ed46e3e20 /src/class/video
parent41e9eaa65a935136085d78ec4b99c81ff991b560 (diff)
parentcd3561bf158afd5a5718904b8139a338d1e3b67c (diff)
Merge remote-tracking branch 'tinyusb/master' into pr-osal-spin-deinit
Signed-off-by: HiFiPhile <[email protected]>
Diffstat (limited to 'src/class/video')
-rw-r--r--src/class/video/video.h10
-rw-r--r--src/class/video/video_device.c219
-rw-r--r--src/class/video/video_device.h19
3 files changed, 174 insertions, 74 deletions
diff --git a/src/class/video/video.h b/src/class/video/video.h
index f348e187b..5bdf4b840 100644
--- a/src/class/video/video.h
+++ b/src/class/video/video.h
@@ -219,11 +219,11 @@ typedef enum {
uint8_t baInterfaceNr[_nitf]; \
}
-typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t;
-typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t;
-typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t;
-typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t;
-typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t;
+typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; //-V2586 incorrectly detected as flexible array
+typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; //-V2586 incorrectly detected as flexible array
+typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; //-V2586 incorrectly detected as flexible array
+typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; //-V2586 incorrectly detected as flexible array
+typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; //-V2586 incorrectly detected as flexible array
typedef struct TU_ATTR_PACKED {
uint8_t bLength;
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index 5c00cc358..e31ab4194 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -70,6 +70,13 @@ typedef struct TU_ATTR_PACKED {
uint8_t bEntityId;
} tusb_desc_cs_video_entity_itf_t;
+typedef struct TU_ATTR_PACKED {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubtype;
+ uint16_t wMaxTransferSize;
+} tusb_desc_cs_video_vc_ep_t;
+
typedef union {
struct TU_ATTR_PACKED {
uint8_t bLength;
@@ -103,7 +110,7 @@ typedef struct TU_ATTR_PACKED {
uint8_t index_vc; /* index of bound video control interface */
uint8_t index_vs; /* index from the video control interface */
struct {
- uint16_t beg; /* Offset of the begging of video streaming interface descriptor */
+ uint16_t beg; /* Offset of the beginning of video streaming interface descriptor */
uint16_t end; /* Offset of the end of video streaming interface descriptor */
uint16_t cur; /* Offset of the current settings */
uint16_t ep[2]; /* Offset of endpoint descriptors. 0: streaming, 1: still capture */
@@ -214,6 +221,12 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
return VIDEO_ERROR_NONE;
}
+TU_ATTR_WEAK void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request) {
+ (void) ctl_idx;
+ (void) stm_idx;
+ (void) request;
+}
+
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
@@ -244,9 +257,13 @@ static inline uint8_t _desc_ep_addr(void const *desc) {
* @return instance */
static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
videod_interface_t *ctl = &_videod_itf[ctl_idx];
- if (!ctl->beg) return NULL;
+ if (!ctl->beg) {
+ return NULL;
+ }
videod_streaming_interface_t *stm = &_videod_streaming_itf[ctl->stm[stm_idx]];
- if (!stm->desc.beg) return NULL;
+ if (!stm->desc.beg) {
+ return NULL;
+ }
return stm;
}
@@ -255,7 +272,9 @@ static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) {
}
static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) {
- if (!self->desc.cur) return NULL;
+ if (!self->desc.cur) {
+ return NULL;
+ }
uint8_t const *desc = _videod_itf[self->index_vc].beg;
return (tusb_desc_vs_itf_t const*)(desc + self->desc.cur);
}
@@ -366,8 +385,12 @@ static void const* _find_desc_ep(void const *beg, void const *end)
{
for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) {
uint_fast8_t desc_type = tu_desc_type(cur);
- if (TUSB_DESC_ENDPOINT == desc_type) return cur;
- if (TUSB_DESC_INTERFACE == desc_type) break;
+ if (TUSB_DESC_ENDPOINT == desc_type) {
+ return cur;
+ }
+ if (TUSB_DESC_INTERFACE == desc_type) {
+ break;
+ }
}
return end;
}
@@ -453,8 +476,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
uint_fast8_t fmtnum = param->bFormatIndex;
TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats);
- if (!fmtnum) {
- if (1 < vs->stm.bNumFormats) return true; /* Need to negotiate all variables. */
+ if (0 == fmtnum) {
+ if (1 < vs->stm.bNumFormats) {
+ return true; /* Need to negotiate all variables. */
+ }
fmtnum = 1;
param->bFormatIndex = 1;
}
@@ -492,8 +517,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
uint_fast8_t frmnum = param->bFrameIndex;
TU_ASSERT(frmnum <= fmt->bNumFrameDescriptors);
- if (!frmnum) {
- if (1 < fmt->bNumFrameDescriptors) return true;
+ if (0 == frmnum) {
+ if (1 < fmt->bNumFrameDescriptors) {
+ return true;
+ }
frmnum = 1;
param->bFrameIndex = 1;
}
@@ -502,7 +529,7 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
/* Set the parameters determined by the frame */
uint_fast32_t frame_size = param->dwMaxVideoFrameSize;
- if (!frame_size) {
+ if (0 == frame_size) {
switch (fmt->bDescriptorSubType) {
case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED:
frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8;
@@ -522,7 +549,7 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
}
uint_fast32_t interval = param->dwFrameInterval;
- if (!interval) {
+ if (0 == interval) {
if ((1 < frm->uncompressed.bFrameIntervalType) ||
((0 == frm->uncompressed.bFrameIntervalType) &&
(frm->uncompressed.dwFrameInterval[1] != frm->uncompressed.dwFrameInterval[0]))) {
@@ -532,7 +559,7 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
param->dwFrameInterval = interval;
}
uint_fast32_t interval_ms = interval / 10000;
- TU_ASSERT(interval_ms);
+ TU_ASSERT(interval_ms != 0);
uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) {
payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
@@ -550,7 +577,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
video_probe_and_commit_control_t *param)
{
uint_fast8_t const fmtnum = param->bFormatIndex;
- if (!fmtnum) {
+ if (0 == fmtnum) {
switch (request) {
case VIDEO_REQUEST_GET_MAX:
if (_get_desc_vs(stm))
@@ -581,7 +608,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
}
uint_fast8_t frmnum = param->bFrameIndex;
- if (!frmnum) {
+ if (0 == frmnum) {
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
TU_ASSERT(vs);
void const *end = _end_of_streaming_descriptor(vs);
@@ -637,7 +664,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
return true;
}
- if (!param->dwFrameInterval) {
+ if (0 == param->dwFrameInterval) {
tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm);
TU_ASSERT(vs);
void const *end = _end_of_streaming_descriptor(vs);
@@ -686,12 +713,12 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
default: return false;
}
param->dwFrameInterval = interval;
- if (!interval) {
+ if (0 == interval) {
param->dwMaxPayloadTransferSize = 0;
} else {
uint_fast32_t frame_size = param->dwMaxVideoFrameSize;
uint_fast32_t payload_size;
- if (!interval_ms) {
+ if (0 == interval_ms) {
payload_size = frame_size + 2;
} else {
payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
@@ -719,7 +746,10 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self)
/* The end of the video control interface descriptor. */
void const *end = _end_of_control_descriptor(vc);
- if (vc->std.bNumEndpoints) {
+ if (vc->std.bNumEndpoints != 0) {
+ /* Extend end to cover the standard endpoint and class-specific endpoint descriptors
+ * that follow wTotalLength */
+ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t);
/* Find the notification endpoint descriptor. */
cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT);
TU_ASSERT(cur < end);
@@ -757,9 +787,12 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t
cur += vc->std.bLength + vc->ctl.bLength;
TU_LOG_DRV(" bNumEndpoints %d\r\n", vc->std.bNumEndpoints);
/* Open the notification endpoint if it exist. */
- if (vc->std.bNumEndpoints) {
+ if (vc->std.bNumEndpoints != 0) {
/* Support for 1 endpoint only. */
TU_VERIFY(1 == vc->std.bNumEndpoints);
+ /* Extend end to cover the standard endpoint and class-specific endpoint descriptors
+ * that follow wTotalLength */
+ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t);
/* Find the notification endpoint descriptor. */
cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT);
TU_VERIFY(cur < end);
@@ -832,7 +865,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
/* FS must be less than or equal to max packet size */
TU_VERIFY (tu_edpt_packet_size(ep) >= max_size);
#ifdef TUP_DCD_EDPT_ISO_ALLOC
- usbd_edpt_iso_activate(rhport, ep);
+ TU_ASSERT(usbd_edpt_iso_activate(rhport, ep));
#else
TU_ASSERT(usbd_edpt_open(rhport, ep));
#endif
@@ -843,7 +876,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
stm->desc.ep[i] = (uint16_t) (cur - desc);
TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur));
}
- if (altnum) {
+ if (altnum != 0) {
stm->state = VS_STATE_STREAMING;
}
TU_LOG_DRV(" done\r\n");
@@ -860,7 +893,16 @@ static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm, uint
}
TU_ASSERT(pkt_len >= hdr_len);
uint_fast16_t data_len = pkt_len - hdr_len;
- memcpy(&ep_buf[hdr_len], stm->buffer + stm->offset, data_len);
+ if (stm->buffer) {
+ memcpy(&ep_buf[hdr_len], stm->buffer + stm->offset, data_len);
+ } else {
+ tud_video_payload_request_t rqst = {
+ .buf = &ep_buf[hdr_len],
+ .length = data_len,
+ .offset = stm->offset
+ };
+ tud_video_prepare_payload_cb(stm->index_vc, stm->index_vs, &rqst);
+ }
stm->offset += data_len;
remaining -= data_len;
if (!remaining) {
@@ -929,16 +971,14 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage,
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_CUR:
- if (stage == CONTROL_STAGE_SETUP)
- {
+ if (stage == CONTROL_STAGE_SETUP) {
TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN);
TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_INFO:
- if (stage == CONTROL_STAGE_SETUP)
- {
+ if (stage == CONTROL_STAGE_SETUP) {
TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN);
TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN);
}
@@ -951,15 +991,13 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage,
case VIDEO_VC_CTL_REQUEST_ERROR_CODE:
switch (request->bRequest) {
case VIDEO_REQUEST_GET_CUR:
- if (stage == CONTROL_STAGE_SETUP)
- {
+ if (stage == CONTROL_STAGE_SETUP) {
TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_INFO:
- if (stage == CONTROL_STAGE_SETUP)
- {
+ if (stage == CONTROL_STAGE_SETUP) {
TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
@@ -986,7 +1024,7 @@ static int handle_video_ctl_req(uint8_t rhport, uint8_t stage,
case TUSB_REQ_TYPE_CLASS: {
uint_fast8_t entity_id = TU_U16_HIGH(request->wIndex);
- if (!entity_id) {
+ if (0 == entity_id) {
return handle_video_ctl_cs_req(rhport, stage, request, ctl_idx);
} else {
TU_VERIFY(_find_desc_entity(_get_desc_vc(&_videod_itf[ctl_idx]), entity_id), VIDEO_ERROR_INVALID_REQUEST);
@@ -1001,14 +1039,12 @@ static int handle_video_ctl_req(uint8_t rhport, uint8_t stage,
static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage,
tusb_control_request_t const *request,
- uint_fast8_t stm_idx)
-{
+ uint_fast8_t stm_idx) {
TU_LOG_DRV("\r\n");
videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx];
switch (request->bRequest) {
case TUSB_REQ_GET_INTERFACE:
- if (stage == CONTROL_STAGE_SETUP)
- {
+ if (stage == CONTROL_STAGE_SETUP) {
TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN);
tusb_desc_vs_itf_t const *vs = _get_desc_vs(self);
TU_VERIFY(vs, VIDEO_ERROR_UNKNOWN);
@@ -1075,12 +1111,14 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
} else if (stage == CONTROL_STAGE_DATA) {
TU_VERIFY(_update_streaming_parameters(stm, &stm->probe_commit_payload),
VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
+ } else {
+ // nothing to do
}
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_CUR:
if (stage == CONTROL_STAGE_SETUP) {
- TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
+ TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN);
TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
@@ -1090,7 +1128,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
case VIDEO_REQUEST_GET_RES:
case VIDEO_REQUEST_GET_DEF:
if (stage == CONTROL_STAGE_SETUP) {
- TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
+ TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN);
video_probe_and_commit_control_t tmp = stm->probe_commit_payload;
TU_VERIFY(_negotiate_streaming_parameters(stm, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN);
@@ -1137,12 +1175,14 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
hdr->bHeaderLength = sizeof(*hdr);
hdr->bmHeaderInfo = 0;
}
+ } else {
+ // nothing to do
}
return VIDEO_ERROR_NONE;
case VIDEO_REQUEST_GET_CUR:
if (stage == CONTROL_STAGE_SETUP) {
- TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN);
+ TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN);
TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
}
return VIDEO_ERROR_NONE;
@@ -1185,14 +1225,15 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
static int handle_video_stm_req(uint8_t rhport, uint8_t stage,
tusb_control_request_t const *request,
- uint_fast8_t stm_idx)
-{
+ uint_fast8_t stm_idx) {
switch (request->bmRequestType_bit.type) {
case TUSB_REQ_TYPE_STANDARD:
return handle_video_stm_std_req(rhport, stage, request, stm_idx);
case TUSB_REQ_TYPE_CLASS:
- if (TU_U16_HIGH(request->wIndex)) return VIDEO_ERROR_INVALID_REQUEST;
+ if (0 != TU_U16_HIGH(request->wIndex)) {
+ return VIDEO_ERROR_INVALID_REQUEST;
+ }
return handle_video_stm_cs_req(rhport, stage, request, stm_idx);
default: return VIDEO_ERROR_INVALID_REQUEST;
@@ -1203,11 +1244,12 @@ static int handle_video_stm_req(uint8_t rhport, uint8_t stage,
// APPLICATION API
//--------------------------------------------------------------------+
-bool tud_video_n_connected(uint_fast8_t ctl_idx)
-{
+bool tud_video_n_connected(uint_fast8_t ctl_idx) {
TU_ASSERT(ctl_idx < CFG_TUD_VIDEO);
videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, 0);
- if (stm) return true;
+ if (stm != NULL) {
+ return true;
+ }
return false;
}
@@ -1216,15 +1258,21 @@ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx)
TU_ASSERT(ctl_idx < CFG_TUD_VIDEO);
TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING);
videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx);
- if (!stm || !stm->desc.ep[0]) return false;
- if (stm->state == VS_STATE_PROBING) return false;
+ if (NULL == stm || 0 == stm->desc.ep[0]) {
+ return false;
+ }
+ if (stm->state == VS_STATE_PROBING) {
+ return false;
+ }
-#ifdef TUP_DCD_EDPT_ISO_ALLOC
+ #ifdef TUP_DCD_EDPT_ISO_ALLOC
uint8_t const *desc = _videod_itf[stm->index_vc].beg;
uint_fast16_t ofs_ep = stm->desc.ep[0];
tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep);
if (ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) {
- if (stm->state == VS_STATE_COMMITTED) return false;
+ if (stm->state == VS_STATE_COMMITTED) {
+ return false;
+ }
}
#endif
@@ -1235,25 +1283,36 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu
TU_ASSERT(ctl_idx < CFG_TUD_VIDEO);
TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING);
- if (!buffer || !bufsize) return false;
+ if (0 == bufsize) {
+ return false;
+ }
+
videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx);
videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[ctl_idx];
- if (!stm || !stm->desc.ep[0] || stm->buffer) return false;
- if (stm->state == VS_STATE_PROBING) return false;
+ if (NULL == stm || 0 == stm->desc.ep[0] || stm->bufsize) {
+ return false;
+ }
+ if (stm->state == VS_STATE_PROBING) {
+ return false;
+ }
/* Find EP address */
uint8_t const *desc = _videod_itf[stm->index_vc].beg;
uint8_t ep_addr = 0;
for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) {
uint_fast16_t ofs_ep = stm->desc.ep[i];
- if (!ofs_ep) continue;
+ if (0 == ofs_ep) {
+ continue;
+ }
ep_addr = _desc_ep_addr(desc + ofs_ep);
break;
}
- if (!ep_addr) return false;
+ if (0 == ep_addr) {
+ return false;
+ }
- TU_VERIFY( usbd_edpt_claim(0, ep_addr) );
+ TU_VERIFY(usbd_edpt_claim(0, ep_addr));
/* update the packet header */
tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm_epbuf->buf;
hdr->FrameID ^= 1;
@@ -1262,7 +1321,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu
stm->buffer = (uint8_t*)buffer;
stm->bufsize = bufsize;
uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf);
- TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len), 0);
+ TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0);
return true;
}
@@ -1305,7 +1364,9 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
videod_interface_t *self = NULL;
uint8_t ctl_idx;
for (ctl_idx = 0; ctl_idx < CFG_TUD_VIDEO; ++ctl_idx) {
- if (_videod_itf[ctl_idx].beg) continue;
+ if (NULL != _videod_itf[ctl_idx].beg) {
+ continue;
+ }
self = &_videod_itf[ctl_idx];
break;
}
@@ -1326,7 +1387,9 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
videod_streaming_interface_t *stm = NULL;
/* find free streaming interface handle */
for (uint8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) {
- if (_videod_streaming_itf[i].desc.beg) continue;
+ if (0 != _videod_streaming_itf[i].desc.beg) {
+ continue;
+ }
stm = &_videod_streaming_itf[i];
self->stm[stm_idx] = i;
break;
@@ -1354,7 +1417,9 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
}
p_desc = tu_desc_next(p_desc);
}
- if(ep_addr > 0 && ep_size > 0) usbd_edpt_iso_alloc(rhport, ep_addr, ep_size);
+ if(ep_addr > 0 && ep_size > 0) {
+ usbd_edpt_iso_alloc(rhport, ep_addr, ep_size);
+ }
#endif
if (0 == stm_idx && 1 == bInCollection) {
/* If there is only one streaming interface and no alternate settings,
@@ -1381,31 +1446,43 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_
uint_fast8_t itf;
for (itf = 0; itf < CFG_TUD_VIDEO; ++itf) {
void const *desc = _videod_itf[itf].beg;
- if (!desc) continue;
- if (itfnum == _desc_itfnum(desc)) break;
+ if (!desc) {
+ continue;
+ }
+ if (itfnum == _desc_itfnum(desc)) {
+ break;
+ }
}
if (itf < CFG_TUD_VIDEO) {
TU_LOG_DRV(" VC[%d]: ", itf);
err = handle_video_ctl_req(rhport, stage, request, itf);
_videod_itf[itf].error_code = (uint8_t)err;
- if (err) return false;
+ if (0 != err) {
+ return false;
+ }
return true;
}
/* Identify which streaming interface to use */
for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) {
videod_streaming_interface_t *stm = &_videod_streaming_itf[itf];
- if (!stm->desc.beg) continue;
+ if (0 == stm->desc.beg) {
+ continue;
+ }
uint8_t const *desc = _videod_itf[stm->index_vc].beg;
- if (itfnum == _desc_itfnum(desc + stm->desc.beg)) break;
+ if (itfnum == _desc_itfnum(desc + stm->desc.beg)) {
+ break;
+ }
}
if (itf < CFG_TUD_VIDEO_STREAMING) {
TU_LOG_DRV(" VS[%d]: ", itf);
err = handle_video_stm_req(rhport, stage, request, itf);
_videod_streaming_itf[itf].error_code = (uint8_t)err;
- if (err) return false;
+ if (err != 0) {
+ return false;
+ }
return true;
}
return false;
@@ -1421,19 +1498,23 @@ bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) {
stm = &_videod_streaming_itf[itf];
uint_fast16_t const ep_ofs = stm->desc.ep[0];
- if (!ep_ofs) continue;
+ if (0 == ep_ofs) {
+ continue;
+ }
ctl = &_videod_itf[stm->index_vc];
uint8_t const *desc = ctl->beg;
- if (ep_addr == _desc_ep_addr(desc + ep_ofs)) break;
+ if (ep_addr == _desc_ep_addr(desc + ep_ofs)) {
+ break;
+ }
}
TU_ASSERT(itf < CFG_TUD_VIDEO_STREAMING);
videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[itf];
if (stm->offset < stm->bufsize) {
/* Claim the endpoint */
- TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0);
+ TU_VERIFY(usbd_edpt_claim(rhport, ep_addr), 0);
uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf);
- TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len), 0);
+ TU_ASSERT(usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0);
} else {
stm->buffer = NULL;
stm->bufsize = 0;
diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h
index 2b41c3bfe..2750bb2fb 100644
--- a/src/class/video/video_device.h
+++ b/src/class/video/video_device.h
@@ -35,6 +35,16 @@
extern "C" {
#endif
+
+//--------------------------------------------------------------------+
+// Payload request
+//--------------------------------------------------------------------+
+typedef struct TU_ATTR_PACKED {
+ void* buf; /* Payload buffer to be filled */
+ size_t length; /* Length of the requested data in bytes */
+ size_t offset; /* Offset within the frame (in bytes) */
+} tud_video_payload_request_t;
+
//--------------------------------------------------------------------+
// Application API (Multiple Ports)
// CFG_TUD_VIDEO > 1
@@ -83,6 +93,15 @@ int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod);
int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
video_probe_and_commit_control_t const *parameters);
+/** Invoked if buffer is set to NULL (allows bufferless on the fly data generation)
+ *
+ * @param[in] ctl_idx Destination control interface index
+ * @param[in] stm_idx Destination streaming interface index
+ * @param[out] payload_buf Payload storage buffer (target buffer for requested data)
+ * @param[in] payload_size Size of payload_buf (requested data size)
+ * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize) */
+void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request);
+
//--------------------------------------------------------------------+
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+