Skip to content

Commit ee832e4

Browse files
committed
Fix descriptor searching
1 parent 1debf62 commit ee832e4

File tree

1 file changed

+28
-93
lines changed

1 file changed

+28
-93
lines changed

src/class/video/video_device.c

Lines changed: 28 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030
#if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING)
3131

32-
#include <stdarg.h>
33-
3432
#include "device/usbd.h"
3533
#include "device/usbd_pvt.h"
3634

@@ -194,72 +192,6 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des
194192
return cur;
195193
}
196194

197-
/** Find the first descriptor of a given types
198-
*
199-
* @param[in] beg The head of descriptor byte array.
200-
* @param[in] end The tail of descriptor byte array.
201-
* @param[in] ... The target descriptor types. The last type must be 0.
202-
*
203-
* @return The pointer for interface descriptor.
204-
* @retval end did not found interface descriptor */
205-
static void const* _find_desc_n(void const *beg, void const *end, ...)
206-
{
207-
uint_fast8_t target = 0;
208-
void const *cur;
209-
for (cur = beg; cur < end && !target; cur = tu_desc_next(cur)) {
210-
uint_fast8_t actual = tu_desc_type(cur);
211-
va_list ap;
212-
va_start(ap, end);
213-
do {
214-
target = va_arg(ap, unsigned);
215-
} while (target && target != actual);
216-
va_end(ap);
217-
}
218-
return cur;
219-
}
220-
221-
/** Find the first descriptor specified by the arguments
222-
*
223-
* @param[in] beg The head of descriptor byte array.
224-
* @param[in] end The tail of descriptor byte array.
225-
* @param[in] sub_types The target bDescriptorSubtype list. The last elemnt must be 0.
226-
*
227-
* @return The pointer for interface descriptor.
228-
* @retval end did not found interface descriptor */
229-
static void const* _find_desc_cs(void const *beg, void const *end, uint8_t const *sub_types)
230-
{
231-
uint_fast8_t target = 0;
232-
void const *cur;
233-
for (cur = beg; cur < end && !target; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) {
234-
uint_fast8_t actual = ((uint8_t const *)cur)[2];
235-
uint8_t const *p = sub_types;
236-
do {
237-
target = *p++;
238-
} while (target && target != actual);
239-
}
240-
return cur;
241-
}
242-
243-
/** Find the first descriptor specified by the arguments
244-
*
245-
* @param[in] beg The head of descriptor byte array.
246-
* @param[in] end The tail of descriptor byte array.
247-
* @param[in] desc_type The target descriptor type
248-
* @param[in] element_0 The target element following the desc_type
249-
*
250-
* @return The pointer for interface descriptor.
251-
* @retval end did not found interface descriptor */
252-
static void const* _find_desc_2(void const *beg, void const *end,
253-
uint_fast8_t desc_type, uint_fast8_t element_0)
254-
{
255-
for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) {
256-
uint8_t const *p = (uint8_t const *)cur;
257-
if (p[2] == element_0) return cur;
258-
cur = tu_desc_next(cur);
259-
}
260-
return end;
261-
}
262-
263195
/** Find the first descriptor specified by the arguments
264196
*
265197
* @param[in] beg The head of descriptor byte array.
@@ -328,9 +260,11 @@ static inline void const* _find_desc_itf(void const *beg, void const *end, uint_
328260
* @retval end did not found endpoint descriptor */
329261
static void const* _find_desc_ep(void const *beg, void const *end)
330262
{
331-
void const *cur = _find_desc_n(beg, end, TUSB_DESC_ENDPOINT, TUSB_DESC_INTERFACE, 0);
332-
if ((cur < end) && (TUSB_DESC_ENDPOINT == tu_desc_type(cur)))
333-
return cur;
263+
for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) {
264+
uint_fast8_t desc_type = tu_desc_type(cur);
265+
if (TUSB_DESC_ENDPOINT == desc_type) return cur;
266+
if (TUSB_DESC_INTERFACE == desc_type) break;
267+
}
334268
return end;
335269
}
336270

@@ -374,36 +308,36 @@ static inline void const* _end_of_streaming_descriptor(void const *desc)
374308
/** Find the first format descriptor with the specified format number. */
375309
static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum)
376310
{
377-
static uint8_t const sub_types[] = {
378-
VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
379-
VIDEO_CS_ITF_VS_FORMAT_MJPEG,
380-
VIDEO_CS_ITF_VS_FORMAT_DV,
381-
VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED,
382-
0
383-
};
384-
while (true) {
385-
uint8_t const *cur = _find_desc_cs(beg, end, sub_types);
386-
if ((end == cur) || (fmtnum == cur[3]))
311+
for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) {
312+
uint8_t const *p = (uint8_t const *)cur;
313+
uint_fast8_t fmt = p[2];
314+
if ((fmt == VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED ||
315+
fmt == VIDEO_CS_ITF_VS_FORMAT_MJPEG ||
316+
fmt == VIDEO_CS_ITF_VS_FORMAT_DV ||
317+
fmt == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) &&
318+
fmtnum == p[3]) {
387319
return cur;
320+
}
388321
cur = tu_desc_next(cur);
389322
}
323+
return end;
390324
}
391325

392326
/** Find the first frame descriptor with the specified format number. */
393327
static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum)
394328
{
395-
static uint8_t const sub_types[] = {
396-
VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
397-
VIDEO_CS_ITF_VS_FRAME_MJPEG,
398-
VIDEO_CS_ITF_VS_FRAME_FRAME_BASED,
399-
0
400-
};
401-
while (true) {
402-
uint8_t const *cur = _find_desc_cs(beg, end, sub_types);
403-
if ((end == cur) || (frmnum == ((uint8_t const *)cur)[3]))
329+
for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) {
330+
uint8_t const *p = (uint8_t const *)cur;
331+
uint_fast8_t frm = p[2];
332+
if ((frm == VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED ||
333+
frm == VIDEO_CS_ITF_VS_FRAME_MJPEG ||
334+
frm == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) &&
335+
frmnum == p[3]) {
404336
return cur;
337+
}
405338
cur = tu_desc_next(cur);
406339
}
340+
return end;
407341
}
408342

409343
/** Set uniquely determined values to variables that have not been set
@@ -501,7 +435,8 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
501435
if (!fmtnum) {
502436
switch (request) {
503437
case VIDEO_REQUEST_GET_MAX:
504-
param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats;
438+
if (_get_desc_vs(stm))
439+
param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats;
505440
break;
506441
case VIDEO_REQUEST_GET_MIN:
507442
case VIDEO_REQUEST_GET_DEF:
@@ -982,7 +917,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
982917
video_probe_and_commit_control_t tmp;
983918
tmp = *(video_probe_and_commit_control_t*)&self->ep_buf;
984919
TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
985-
TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN);
920+
TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN);
986921
}
987922
return VIDEO_ERROR_NONE;
988923

@@ -999,7 +934,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
999934
if (stage == CONTROL_STAGE_SETUP)
1000935
{
1001936
TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN);
1002-
TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN);
937+
TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN);
1003938
}
1004939
return VIDEO_ERROR_NONE;
1005940

0 commit comments

Comments
 (0)