Atlas - SDL_camera_vita.c

Home / ext / SDL / src / camera / vita Lines: 1 | Size: 8017 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef SDL_CAMERA_DRIVER_VITA 24 25#include "../SDL_syscamera.h" 26#include <psp2/camera.h> 27#include <psp2/kernel/sysmem.h> 28 29static struct { 30 Sint32 w; 31 Sint32 h; 32 Sint32 res; 33} resolutions[] = { 34 {640, 480, SCE_CAMERA_RESOLUTION_640_480}, 35 {320, 240, SCE_CAMERA_RESOLUTION_320_240}, 36 {160, 120, SCE_CAMERA_RESOLUTION_160_120}, 37 {352, 288, SCE_CAMERA_RESOLUTION_352_288}, 38 {176, 144, SCE_CAMERA_RESOLUTION_176_144}, 39 {480, 272, SCE_CAMERA_RESOLUTION_480_272}, 40 {640, 360, SCE_CAMERA_RESOLUTION_640_360}, 41 {0, 0, 0} 42}; 43 44static Sint32 fps[] = {5, 10, 15, 20, 24, 25, 30, 60, 0}; 45 46static void GatherCameraSpecs(Sint32 devid, CameraFormatAddData *add_data, char **fullname, SDL_CameraPosition *position) 47{ 48 SDL_zerop(add_data); 49 50 if (devid == SCE_CAMERA_DEVICE_FRONT) { 51 *position = SDL_CAMERA_POSITION_FRONT_FACING; 52 *fullname = SDL_strdup("Front-facing camera"); 53 } else if (devid == SCE_CAMERA_DEVICE_BACK) { 54 *position = SDL_CAMERA_POSITION_BACK_FACING; 55 *fullname = SDL_strdup("Back-facing camera"); 56 } 57 58 if (!*fullname) { 59 *fullname = SDL_strdup("Generic camera"); 60 } 61 62 // Note: there are actually more fps and pixelformats. Planar YUV is fastest. Support only YUV and integer fps for now 63 Sint32 idx = 0; 64 while (resolutions[idx].res > 0) { 65 Sint32 fps_idx = 0; 66 while (fps[fps_idx] > 0) { 67 SDL_AddCameraFormat(add_data, SDL_PIXELFORMAT_IYUV, SDL_COLORSPACE_BT601_LIMITED, resolutions[idx].w, resolutions[idx].h, fps[fps_idx], 1); /* SCE_CAMERA_FORMAT_ARGB */ 68 fps_idx++; 69 } 70 idx++; 71 } 72} 73 74static bool FindVitaCameraByID(SDL_Camera *device, void *userdata) 75{ 76 Sint32 devid = (Sint32) userdata; 77 return (devid == (Sint32)device->handle); 78} 79 80static void MaybeAddDevice(Sint32 devid) 81{ 82 #if DEBUG_CAMERA 83 SDL_Log("CAMERA: MaybeAddDevice('%d')", devid); 84 #endif 85 86 if (SDL_FindPhysicalCameraByCallback(FindVitaCameraByID, (void *) devid)) { 87 return; // already have this one. 88 } 89 90 SDL_CameraPosition position = SDL_CAMERA_POSITION_UNKNOWN; 91 char *fullname = NULL; 92 CameraFormatAddData add_data; 93 GatherCameraSpecs(devid, &add_data, &fullname, &position); 94 95 if (add_data.num_specs > 0) { 96 SDL_AddCamera(fullname, position, add_data.num_specs, add_data.specs, (void *)devid); 97 } 98 99 SDL_free(fullname); 100 SDL_free(add_data.specs); 101} 102 103static SceUID imbUid = -1; 104 105static void freeBuffers(SceCameraInfo *info) 106{ 107 if (imbUid != -1) { 108 sceKernelFreeMemBlock(imbUid); 109 info->pIBase = NULL; 110 imbUid = -1; 111 } 112} 113 114static bool VITACAMERA_OpenDevice(SDL_Camera *device, const SDL_CameraSpec *spec) 115{ 116 // we can't open more than one camera, so error-out early 117 if (imbUid != -1) { 118 return SDL_SetError("Only one camera can be active"); 119 } 120 121 SceCameraInfo *info = (SceCameraInfo *)SDL_calloc(1, sizeof(SceCameraInfo)); 122 123 info->size = sizeof(SceCameraInfo); 124 info->priority = SCE_CAMERA_PRIORITY_SHARE; 125 info->buffer = 0; // target buffer set by sceCameraOpen 126 127 info->framerate = spec->framerate_numerator / spec->framerate_denominator; 128 129 Sint32 idx = 0; 130 while (resolutions[idx].res > 0) { 131 if (spec->width == resolutions[idx].w && spec->height == resolutions[idx].h) { 132 info->resolution = resolutions[idx].res; 133 break; 134 } 135 idx++; 136 } 137 138 info->range = 1; 139 info->format = SCE_CAMERA_FORMAT_YUV420_PLANE; 140 info->pitch = 0; // same size surface 141 142 info->sizeIBase = spec->width * spec->height; 143 info->sizeUBase = ((spec->width+1)/2) * ((spec->height+1) / 2); 144 info->sizeVBase = ((spec->width+1)/2) * ((spec->height+1) / 2); 145 146 // PHYCONT memory size *must* be a multiple of 1MB, we can just always spend 2MB, since we don't use PHYCONT anywhere else 147 imbUid = sceKernelAllocMemBlock("CameraI", SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW, 2 * 1024 * 1024 , NULL); 148 if (imbUid < 0) 149 { 150 return SDL_SetError("sceKernelAllocMemBlock error: 0x%08X", imbUid); 151 } 152 sceKernelGetMemBlockBase(imbUid, &(info->pIBase)); 153 154 info->pUBase = info->pIBase + info->sizeIBase; 155 info->pVBase = info->pIBase + (info->sizeIBase + info->sizeUBase); 156 157 device->hidden = (struct SDL_PrivateCameraData *)info; 158 159 int ret = sceCameraOpen((int)device->handle, info); 160 if (ret == 0) { 161 ret = sceCameraStart((int)device->handle); 162 if (ret == 0) { 163 SDL_CameraPermissionOutcome(device, true); 164 return true; 165 } else { 166 SDL_SetError("sceCameraStart error: 0x%08X", imbUid); 167 } 168 } else { 169 SDL_SetError("sceCameraOpen error: 0x%08X", imbUid); 170 } 171 172 freeBuffers(info); 173 174 return false; 175} 176 177static void VITACAMERA_CloseDevice(SDL_Camera *device) 178{ 179 if (device->hidden) { 180 sceCameraStop((int)device->handle); 181 sceCameraClose((int)device->handle); 182 freeBuffers((SceCameraInfo *)device->hidden); 183 SDL_free(device->hidden); 184 } 185} 186 187static bool VITACAMERA_WaitDevice(SDL_Camera *device) 188{ 189 while(!sceCameraIsActive((int)device->handle)) {} 190 return true; 191} 192 193static SDL_CameraFrameResult VITACAMERA_AcquireFrame(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS, float *rotation) 194{ 195 SceCameraRead read = {0}; 196 read.size = sizeof(SceCameraRead); 197 read.mode = 1; // don't wait next frame 198 199 int ret = sceCameraRead((int)device->handle, &read); 200 201 if (ret < 0) { 202 SDL_SetError("sceCameraRead error: 0x%08X", ret); 203 return SDL_CAMERA_FRAME_ERROR; 204 } 205 206 *timestampNS = read.timestamp; 207 208 SceCameraInfo *info = (SceCameraInfo *)(device->hidden); 209 210 frame->pitch = info->width; 211 frame->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), info->sizeIBase + info->sizeUBase + info->sizeVBase); 212 213 if (frame->pixels) { 214 SDL_memcpy(frame->pixels, info->pIBase, info->sizeIBase + info->sizeUBase + info->sizeVBase); 215 return SDL_CAMERA_FRAME_READY; 216 } 217 218 return SDL_CAMERA_FRAME_ERROR; 219} 220 221static void VITACAMERA_ReleaseFrame(SDL_Camera *device, SDL_Surface *frame) 222{ 223 SDL_aligned_free(frame->pixels); 224} 225 226static void VITACAMERA_DetectDevices(void) 227{ 228 MaybeAddDevice(SCE_CAMERA_DEVICE_FRONT); 229 MaybeAddDevice(SCE_CAMERA_DEVICE_BACK); 230} 231 232static void VITACAMERA_FreeDeviceHandle(SDL_Camera *device) 233{ 234} 235 236static void VITACAMERA_Deinitialize(void) 237{ 238} 239 240static bool VITACAMERA_Init(SDL_CameraDriverImpl *impl) 241{ 242 impl->DetectDevices = VITACAMERA_DetectDevices; 243 impl->OpenDevice = VITACAMERA_OpenDevice; 244 impl->CloseDevice = VITACAMERA_CloseDevice; 245 impl->WaitDevice = VITACAMERA_WaitDevice; 246 impl->AcquireFrame = VITACAMERA_AcquireFrame; 247 impl->ReleaseFrame = VITACAMERA_ReleaseFrame; 248 impl->FreeDeviceHandle = VITACAMERA_FreeDeviceHandle; 249 impl->Deinitialize = VITACAMERA_Deinitialize; 250 251 return true; 252} 253 254CameraBootStrap VITACAMERA_bootstrap = { 255 "vita", "SDL PSVita camera driver", VITACAMERA_Init, false 256}; 257 258#endif // SDL_CAMERA_DRIVER_VITA 259
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.