Skip to content

Commit

Permalink
Remove unused INT endpoint, more bandwidth for video streaming
Browse files Browse the repository at this point in the history
Sending a 960x544 NV12 frame took ~16ms, now it takes ~13ms.
  • Loading branch information
xerpi committed May 2, 2020
1 parent 08cc289 commit 6803d26
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 91 deletions.
131 changes: 50 additions & 81 deletions include/usb_descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@
#define FRAME_BITRATE(w, h, bpp, interval) (((w) * (h) * (bpp)) / ((interval) * 100 * 1E-9))
#define FPS_TO_INTERVAL(fps) ((1E9 / 100) / (fps))

/* Interface Association Descriptor */
static
unsigned char interface_association_descriptor[] = {
/* Interface Association Descriptor */
0x08, /* Descriptor Size */
0x0B, /* Interface Association Descr Type: 11 */
0x00, /* I/f number of first VideoControl i/f */
0x02, /* Number of Video i/f */
USB_CLASS_VIDEO, /* CC_VIDEO : Video i/f class code */
UVC_SC_VIDEO_INTERFACE_COLLECTION, /* SC_VIDEO_INTERFACE_COLLECTION : Subclass code */
UVC_PC_PROTOCOL_UNDEFINED, /* Protocol : Not used */
0x00, /* String desc index for interface */
UVC_INTERFACE_ASSOCIATION_DESC_SIZE, /* Descriptor Size: 8 */
UVC_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* Interface Association Descr Type: 11 */
0x00, /* I/f number of first VideoControl i/f */
0x02, /* Number of Video i/f */
USB_CLASS_VIDEO, /* CC_VIDEO : Video i/f class code */
UVC_SC_VIDEO_INTERFACE_COLLECTION, /* SC_VIDEO_INTERFACE_COLLECTION : Subclass code */
UVC_PC_PROTOCOL_UNDEFINED, /* Protocol : Not used */
0x00, /* String desc index for interface */
};

DECLARE_UVC_HEADER_DESCRIPTOR(1);
Expand Down Expand Up @@ -83,14 +83,6 @@ static struct __attribute__((packed)) {
},
};

static
struct uvc_control_endpoint_descriptor video_control_specific_interrupt_endpoint_descriptor = {
.bLength = sizeof(video_control_specific_interrupt_endpoint_descriptor),
.bDescriptorType = 0x25,
.bDescriptorSubType = UVC_EP_INTERRUPT,
.wMaxTransferSize = 0x40,
};

DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 1);
DECLARE_UVC_FRAME_UNCOMPRESSED(2);

Expand All @@ -106,7 +98,7 @@ static struct __attribute__((packed)) {
.bDescriptorSubType = UVC_VS_INPUT_HEADER,
.bNumFormats = 1,
.wTotalLength = sizeof(video_streaming_descriptors),
.bEndpointAddress = 0x83,
.bEndpointAddress = USB_ENDPOINT_IN | 0x01,
.bmInfo = 0,
.bTerminalLink = OUTPUT_TERMINAL_ID,
.bStillCaptureMethod = 0,
Expand Down Expand Up @@ -203,10 +195,9 @@ static struct __attribute__((packed)) {

/* Endpoint blocks */
static
struct SceUdcdEndpoint endpoints[3] = {
struct SceUdcdEndpoint endpoints[2] = {
{USB_ENDPOINT_OUT, 0, 0, 0},
{USB_ENDPOINT_IN, 1, 0, 0},
{USB_ENDPOINT_IN, 2, 0, 0}
};

/* Interface */
Expand Down Expand Up @@ -237,39 +228,28 @@ static
struct SceUdcdDeviceDescriptor devdesc_hi = {
USB_DT_DEVICE_SIZE,
USB_DT_DEVICE,
0x200, /* bcdUSB */
0xEF, /* bDeviceClass (Miscellaneous Device Class)*/
0x02, /* bDeviceSubClass (Common Class) */
0x01, /* bDeviceProtocol (Interface Association Descriptor) */
64, /* bMaxPacketSize0 */
0, /* idProduct */
0, /* idVendor */
0x100, /* bcdDevice */
0, /* iManufacturer */
2, /* iProduct */
3, /* iSerialNumber */
1 /* bNumConfigurations */
0x200, /* bcdUSB */
USB_DEVICE_CLASS_MISCELLANEOUS, /* bDeviceClass (Miscellaneous Device Class)*/
0x02, /* bDeviceSubClass (Common Class) */
0x01, /* bDeviceProtocol (Interface Association Descriptor) */
64, /* bMaxPacketSize0 */
0, /* idProduct */
0, /* idVendor */
0x100, /* bcdDevice */
0, /* iManufacturer */
2, /* iProduct */
3, /* iSerialNumber */
1 /* bNumConfigurations */
};

/* Hi-Speed endpoint descriptors */
static
struct SceUdcdEndpointDescriptor endpdesc_hi[3] = {
/* Video Control endpoints */
{
USB_DT_ENDPOINT_SIZE,
USB_DT_ENDPOINT,
USB_ENDPOINT_IN | 0x01, /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
0x40, /* wMaxPacketSize */
0x01, /* bInterval */
(void *)&video_control_specific_interrupt_endpoint_descriptor,
sizeof(video_control_specific_interrupt_endpoint_descriptor)
},
struct SceUdcdEndpointDescriptor endpdesc_hi[2] = {
/* Video Streaming endpoints */
{
USB_DT_ENDPOINT_SIZE,
USB_DT_ENDPOINT,
USB_ENDPOINT_IN | 0x02, /* bEndpointAddress */
USB_ENDPOINT_IN | 0x01, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
0x200, /* wMaxPacketSize */
0x00 /* bInterval */
Expand All @@ -287,16 +267,17 @@ struct SceUdcdInterfaceDescriptor interdesc_hi[3] = {
USB_DT_INTERFACE,
CONTROL_INTERFACE, /* bInterfaceNumber */
0, /* bAlternateSetting */
1, /* bNumEndpoints */
0, /* bNumEndpoints */
USB_CLASS_VIDEO, /* bInterfaceClass */
UVC_SC_VIDEOCONTROL, /* bInterfaceSubClass */
UVC_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0, /* iInterface */
&endpdesc_hi[0], /* endpoints */
NULL, /* endpoints */
(void *)&video_control_descriptors,
sizeof(video_control_descriptors)
},
{ /* Standard Video Streaming Interface Descriptor */
/* Alternate setting 0 = Operational Setting */
USB_DT_INTERFACE_SIZE,
USB_DT_INTERFACE,
STREAM_INTERFACE, /* bInterfaceNumber */
Expand All @@ -306,7 +287,7 @@ struct SceUdcdInterfaceDescriptor interdesc_hi[3] = {
UVC_SC_VIDEOSTREAMING, /* bInterfaceSubClass */
UVC_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0, /* iInterface */
&endpdesc_hi[1], /* endpoints */
&endpdesc_hi[0], /* endpoints */
(void *)&video_streaming_descriptors,
sizeof(video_streaming_descriptors)
},
Expand All @@ -319,18 +300,17 @@ struct SceUdcdInterfaceDescriptor interdesc_hi[3] = {
static
struct SceUdcdInterfaceSettings settings_hi[2] = {
{&interdesc_hi[0], 0, 1},
{&interdesc_hi[1], 0, 1}
{&interdesc_hi[1], 0, 1},
};

/* Hi-Speed configuration descriptor */
static
struct SceUdcdConfigDescriptor confdesc_hi = {
USB_DT_CONFIG_SIZE,
USB_DT_CONFIG,
(USB_DT_CONFIG_SIZE + 2 * USB_DT_INTERFACE_SIZE + 2 * USB_DT_ENDPOINT_SIZE +
(USB_DT_CONFIG_SIZE + 2 * USB_DT_INTERFACE_SIZE + 1 * USB_DT_ENDPOINT_SIZE +
/* sizeof(interface_association_descriptor) + */
sizeof(video_control_descriptors) +
sizeof(video_control_specific_interrupt_endpoint_descriptor) +
sizeof(video_streaming_descriptors)), /* wTotalLength */
2, /* bNumInterfaces */
1, /* bConfigurationValue */
Expand All @@ -356,39 +336,28 @@ static
struct SceUdcdDeviceDescriptor devdesc_full = {
USB_DT_DEVICE_SIZE,
USB_DT_DEVICE,
0x200, /* bcdUSB (should be 0x110 but the PSVita freezes otherwise) */
0xEF, /* bDeviceClass (Miscellaneous Device Class)*/
0x02, /* bDeviceSubClass (Common Class) */
0x01, /* bDeviceProtocol (Interface Association Descriptor) */
0x40, /* bMaxPacketSize0 */
0, /* idProduct */
0, /* idVendor */
0x100, /* bcdDevice */
0, /* iManufacturer */
2, /* iProduct */
3, /* iSerialNumber */
1 /* bNumConfigurations */
0x200, /* bcdUSB (should be 0x110 but the PSVita freezes otherwise) */
USB_DEVICE_CLASS_MISCELLANEOUS, /* bDeviceClass (Miscellaneous Device Class)*/
0x02, /* bDeviceSubClass (Common Class) */
0x01, /* bDeviceProtocol (Interface Association Descriptor) */
0x40, /* bMaxPacketSize0 */
0, /* idProduct */
0, /* idVendor */
0x100, /* bcdDevice */
0, /* iManufacturer */
2, /* iProduct */
3, /* iSerialNumber */
1 /* bNumConfigurations */
};

/* Full-Speed endpoint descriptors */
static
struct SceUdcdEndpointDescriptor endpdesc_full[3] = {
/* Video Control endpoints */
{
USB_DT_ENDPOINT_SIZE,
USB_DT_ENDPOINT,
USB_ENDPOINT_IN | 0x01, /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
0x40, /* wMaxPacketSize */
0x01, /* bInterval */
(void *)&video_control_specific_interrupt_endpoint_descriptor,
sizeof(video_control_specific_interrupt_endpoint_descriptor)
},
struct SceUdcdEndpointDescriptor endpdesc_full[2] = {
/* Video Streaming endpoints */
{
USB_DT_ENDPOINT_SIZE,
USB_DT_ENDPOINT,
USB_ENDPOINT_IN | 0x02, /* bEndpointAddress */
USB_ENDPOINT_IN | 0x01, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
0x40, /* wMaxPacketSize */
0x00 /* bInterval */
Expand All @@ -406,16 +375,17 @@ struct SceUdcdInterfaceDescriptor interdesc_full[3] = {
USB_DT_INTERFACE,
CONTROL_INTERFACE, /* bInterfaceNumber */
0, /* bAlternateSetting */
1, /* bNumEndpoints */
0, /* bNumEndpoints */
USB_CLASS_VIDEO, /* bInterfaceClass */
UVC_SC_VIDEOCONTROL, /* bInterfaceSubClass */
UVC_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0, /* iInterface */
&endpdesc_full[0], /* endpoints */
NULL, /* endpoints */
(void *)&video_control_descriptors,
sizeof(video_control_descriptors)
},
{ /* Standard Video Streaming Interface Descriptor */
/* Alternate setting 0 = Operational Setting */
USB_DT_INTERFACE_SIZE,
USB_DT_INTERFACE,
STREAM_INTERFACE, /* bInterfaceNumber */
Expand All @@ -425,7 +395,7 @@ struct SceUdcdInterfaceDescriptor interdesc_full[3] = {
UVC_SC_VIDEOSTREAMING, /* bInterfaceSubClass */
UVC_PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0, /* iInterface */
&endpdesc_full[1], /* endpoints */
&endpdesc_full[0], /* endpoints */
(void *)&video_streaming_descriptors,
sizeof(video_streaming_descriptors)
},
Expand All @@ -446,10 +416,9 @@ static
struct SceUdcdConfigDescriptor confdesc_full = {
USB_DT_CONFIG_SIZE,
USB_DT_CONFIG,
(USB_DT_CONFIG_SIZE + 2 * USB_DT_INTERFACE_SIZE + 2 * USB_DT_ENDPOINT_SIZE +
(USB_DT_CONFIG_SIZE + 2 * USB_DT_INTERFACE_SIZE + 1 * USB_DT_ENDPOINT_SIZE +
/* sizeof(interface_association_descriptor) + */
sizeof(video_control_descriptors) +
sizeof(video_control_specific_interrupt_endpoint_descriptor) +
sizeof(video_streaming_descriptors)), /* wTotalLength */
2, /* bNumInterfaces */
1, /* bConfigurationValue */
Expand Down
9 changes: 7 additions & 2 deletions include/uvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

#include <stdint.h>

#define __packed__ packed

typedef uint8_t __u8;
typedef uint16_t __u16;
typedef uint32_t __u32;
Expand Down Expand Up @@ -168,6 +166,13 @@ typedef uint32_t __u32;
#define UVC_STREAM_EOF (1 << 1)
#define UVC_STREAM_FID (1 << 0)

/* 3.2 Device Descriptor */
#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF

/* 3.6 Interface Association Descriptor */
#define UVC_INTERFACE_ASSOCIATION_DESC_SIZE 8
#define UVC_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 0x0B

/* 4.1.2. Control Capabilities */
#define UVC_CONTROL_CAP_GET (1 << 0)
#define UVC_CONTROL_CAP_SET (1 << 1)
Expand Down
16 changes: 8 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static int uvc_frame_req_submit_phycont(const void *data, unsigned int size)
int ret;

req = (SceUdcdDeviceRequest){
.endpoint = &endpoints[2],
.endpoint = &endpoints[1],
.data = (void *)data,
.attributes = SCE_UDCD_DEVICE_REQUEST_ATTR_PHYCONT,
.size = size,
Expand Down Expand Up @@ -316,14 +316,14 @@ static void uvc_handle_video_abort(void)
if (stream) {
stream = 0;

ksceUdcdClearFIFO(&endpoints[2]);
ksceUdcdReqCancelAll(&endpoints[2]);
ksceUdcdClearFIFO(&endpoints[1]);
ksceUdcdReqCancelAll(&endpoints[1]);
}
}

static void uvc_handle_set_interface(const SceUdcdEP0DeviceRequest *req)
{
LOG("uvc_handle_set_interface\n");
LOG("uvc_handle_set_interface %x %x\n", req->wIndex, req->wValue);

/* MAC OS sends Set Interface Alternate Setting 0 command after
* stopping to stream. This application needs to stop streaming. */
Expand All @@ -342,7 +342,7 @@ static void uvc_handle_clear_feature(const SceUdcdEP0DeviceRequest *req)
switch (req->wValue) {
case USB_FEATURE_ENDPOINT_HALT:
if ((req->wIndex & USB_ENDPOINT_ADDRESS_MASK) ==
endpoints[2].endpointNumber) {
endpoints[1].endpointNumber) {
uvc_handle_video_abort();
}
break;
Expand Down Expand Up @@ -428,7 +428,7 @@ static int uvc_udcd_attach(int usb_version, void *user_data)
{
LOG("uvc_udcd_attach %d\n", usb_version);

ksceUdcdClearFIFO(&endpoints[2]);
ksceUdcdClearFIFO(&endpoints[1]);

#if defined(DISPLAY_OFF_OLED)
prev_brightness = ksceOledGetBrightness();
Expand Down Expand Up @@ -477,8 +477,8 @@ static int uvc_driver_stop(int size, void *p, void *user_data)

static SceUdcdDriver uvc_udcd_driver = {
.driverName = UVC_DRIVER_NAME,
.numEndpoints = 3,
.endpoints = &endpoints[0],
.numEndpoints = 2,
.endpoints = endpoints,
.interface = &interface,
.descriptor_hi = &devdesc_hi,
.configuration_hi = &config_hi,
Expand Down

0 comments on commit 6803d26

Please sign in to comment.