Skip to content

Commit

Permalink
Merge pull request #60 from cuevavirus/master
Browse files Browse the repository at this point in the history
 Add frame descriptor for 1280x720 and improve memory management
  • Loading branch information
xerpi authored Jun 8, 2020
2 parents 6803d26 + d34ef1e commit 38beb91
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 20 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ controller directly performs a DMA transfer from the physical address of the res
* 896x504 @ 30 FPS and (almost) 60 FPS
* 864x488 @ 30 FPS and 60 FPS
* 480x272 @ 30 FPS and 60 FPS
* 1280x720 @ 30 FPS

## Download and installation

Expand All @@ -41,7 +42,7 @@ ur0:tai/udcd_uvc.skprx

## Troubleshooting

If the video looks glitched, try to change the video player configuration to use the *NV12* format or switch to another player (like PotPlayer or OBS).
If the video looks glitched, try to change the video player configuration to use the *NV12* format or switch to another player (like PotPlayer or OBS). If the colors look wrong, set color range to full and color space to BT.601 (Rec. 601).

If you use Windows 10 you might have to change the Camera access permissions on the Privacy Settings.

Expand Down
2 changes: 1 addition & 1 deletion debug/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

static int console_x = 16;
static int console_y = 16;
static SceKernelLwMutexWork mutex;
static int64_t mutex[8];

int console_init()
{
Expand Down
19 changes: 17 additions & 2 deletions include/usb_descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ DECLARE_UVC_FRAME_UNCOMPRESSED(2);
static struct __attribute__((packed)) {
struct UVC_INPUT_HEADER_DESCRIPTOR(1, 1) input_header_descriptor;
struct uvc_format_uncompressed format_uncompressed_nv12;
struct UVC_FRAME_UNCOMPRESSED(2) frames_uncompressed_nv12[4];
struct UVC_FRAME_UNCOMPRESSED(2) frames_uncompressed_nv12[5];
struct uvc_color_matching_descriptor format_uncompressed_nv12_color_matching;
} video_streaming_descriptors = {
.input_header_descriptor = {
Expand All @@ -112,7 +112,7 @@ static struct __attribute__((packed)) {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED,
.bFormatIndex = FORMAT_INDEX_UNCOMPRESSED_NV12,
.bNumFrameDescriptors = 4,
.bNumFrameDescriptors = 5,
.guidFormat = UVC_GUID_FORMAT_NV12,
.bBitsPerPixel = 12,
.bDefaultFrameIndex = 1,
Expand Down Expand Up @@ -182,6 +182,21 @@ static struct __attribute__((packed)) {
.bFrameIntervalType = 2,
.dwFrameInterval = {FPS_TO_INTERVAL(60), FPS_TO_INTERVAL(30)},
},
(struct UVC_FRAME_UNCOMPRESSED(2)){
.bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(2),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
.bFrameIndex = 5,
.bmCapabilities = 0,
.wWidth = 1280,
.wHeight = 720,
.dwMinBitRate = FRAME_BITRATE(1280, 720, 12, FPS_TO_INTERVAL(20)),
.dwMaxBitRate = FRAME_BITRATE(1280, 720, 12, FPS_TO_INTERVAL(30)),
.dwMaxVideoFrameBufferSize = VIDEO_FRAME_SIZE_NV12(1280, 720),
.dwDefaultFrameInterval = FPS_TO_INTERVAL(30),
.bFrameIntervalType = 2,
.dwFrameInterval = {FPS_TO_INTERVAL(30), FPS_TO_INTERVAL(20)},
},
},
.format_uncompressed_nv12_color_matching = {
.bLength = sizeof(video_streaming_descriptors.format_uncompressed_nv12_color_matching),
Expand Down
43 changes: 27 additions & 16 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#define UVC_DRIVER_NAME "VITAUVC00"
#define UVC_USB_PID 0x1337

#define MAX_UVC_VIDEO_FRAME_SIZE VIDEO_FRAME_SIZE_NV12(960, 544)
#define MAX_UVC_VIDEO_FRAME_SIZE VIDEO_FRAME_SIZE_NV12(1280, 720)

#define UVC_PAYLOAD_HEADER_SIZE 16
#define UVC_PAYLOAD_SIZE(frame_size) (UVC_PAYLOAD_HEADER_SIZE + (frame_size))
Expand Down Expand Up @@ -85,10 +85,13 @@ static SceUID uvc_event_flag_id;
static int uvc_thread_run;
static int stream;

static SceUID uvc_frame_buffer_uid;
static SceUID uvc_frame_buffer_uid = -1;
static struct uvc_frame *uvc_frame_buffer_addr;
SceUID uvc_frame_req_evflag;

static int uvc_frame_init(unsigned int size);
static int uvc_frame_term();

#if defined(DISPLAY_OFF_OLED) || defined(DISPLAY_OFF_LCD)
static int prev_brightness;
#endif
Expand Down Expand Up @@ -667,8 +670,21 @@ static int send_frame(void)
case FORMAT_INDEX_UNCOMPRESSED_NV12: {
const struct UVC_FRAME_UNCOMPRESSED(2) *frames =
video_streaming_descriptors.frames_uncompressed_nv12;
int dst_width = frames[uvc_probe_control_setting.bFrameIndex - 1].wWidth;
int dst_height = frames[uvc_probe_control_setting.bFrameIndex - 1].wHeight;
int cur_frame_index = uvc_probe_control_setting.bFrameIndex;
int dst_width = frames[cur_frame_index - 1].wWidth;
int dst_height = frames[cur_frame_index - 1].wHeight;

static int last_frame_index = 0;
if (uvc_frame_buffer_uid < 0 || cur_frame_index != last_frame_index) {
uvc_frame_term();
ret = uvc_frame_init(VIDEO_FRAME_SIZE_NV12(dst_width, dst_height));
if (ret < 0) {
LOG("Error allocating the UVC frame (0x%08X)\n", ret);
return ret;
} else {
last_frame_index = cur_frame_index;
}
}

ret = convert_and_send_frame_nv12(fid, &fb_info, dst_width, dst_height);
if (ret < 0) {
Expand Down Expand Up @@ -740,12 +756,14 @@ static int uvc_thread(SceSize args, void *argp)
while (uvc_thread_run) {
unsigned int out_bits;

ksceKernelWaitEventFlagCB(uvc_event_flag_id, 1,
SCE_EVENT_WAITOR | SCE_EVENT_WAITCLEAR_PAT,
&out_bits, NULL);
int ret = ksceKernelWaitEventFlagCB(uvc_event_flag_id, 1,
SCE_EVENT_WAITOR | SCE_EVENT_WAITCLEAR_PAT,
&out_bits, (SceUInt32[]){1000000});

if (stream)
if (ret == 0 && stream)
send_frame();
else if (ret == 0x80028005) /* SCE_KERNEL_ERROR_WAIT_TIMEOUT */
uvc_frame_term();
}

ksceDisplayUnregisterVblankStartCallback(display_vblank_cb_uid);
Expand Down Expand Up @@ -790,6 +808,7 @@ static int uvc_frame_init(unsigned int size)
if (ret < 0) {
LOG("Error getting CSC desr memory addr: 0x%08X\n", ret);
ksceKernelFreeMemBlock(uvc_frame_buffer_uid);
uvc_frame_buffer_uid = -1;
return ret;
}

Expand Down Expand Up @@ -851,12 +870,6 @@ int uvc_start(void)
goto err_activate;
}

ret = uvc_frame_init(MAX_UVC_PAYLOAD_TRANSFER_SIZE);
if (ret < 0) {
LOG("Error allocating the UVC frame (0x%08X)\n", ret);
goto err_uvc_frame_init;
}

ret = uvc_frame_req_init();
if (ret < 0) {
LOG("Error allocating USB request (0x%08X)\n", ret);
Expand All @@ -872,8 +885,6 @@ int uvc_start(void)
return 0;

err_alloc_uvc_frame_req:
uvc_frame_term();
err_uvc_frame_init:
ksceUdcdDeactivate();
err_activate:
ksceUdcdStop(UVC_DRIVER_NAME, 0, NULL);
Expand Down

0 comments on commit 38beb91

Please sign in to comment.