77#include " core/libraries/camera/camera.h"
88#include " core/libraries/camera/camera_error.h"
99#include " core/libraries/error_codes.h"
10+ #include " core/libraries/kernel/memory.h"
1011#include " core/libraries/kernel/process.h"
1112#include " core/libraries/libs.h"
13+ #include " core/memory.h"
1214
1315#include < utility>
1416
@@ -22,6 +24,9 @@ static s32 g_firmware_version = 0;
2224static s32 g_handles = 0 ;
2325static constexpr s32 c_width = 1280 , c_height = 800 ;
2426
27+ static u16 *raw16_buffer1{}, *raw16_buffer2{};
28+ static u8 *raw8_buffer1{}, *raw8_buffer2{};
29+
2530SDL_Camera* sdl_camera = nullptr ;
2631OrbisCameraConfigExtention output_config0, output_config1;
2732
@@ -180,9 +185,37 @@ s32 PS4_SYSV_ABI sceCameraGetAutoWhiteBalance(s32 handle, OrbisCameraChannel cha
180185 return ORBIS_OK ;
181186}
182187
183- s32 PS4_SYSV_ABI sceCameraGetCalibData () {
184- LOG_ERROR (Lib_Camera, " (STUBBED) called" );
185- return ORBIS_CAMERA_ERROR_NOT_CONNECTED ;
188+ s32 PS4_SYSV_ABI sceCameraGetCalibData (s32 id, void * calib_data, void * maybe_reserved) {
189+ LOG_WARNING (Lib_Camera, " (DUMMY) called, id: {}" , id);
190+ if (calib_data == nullptr ) {
191+ return ORBIS_CAMERA_ERROR_PARAM ;
192+ }
193+ if (id != 1 && id != 2 ) {
194+ return ORBIS_OK ;
195+ }
196+ static constexpr u64 dumped_calib_data1[32 ]{
197+ 0x000000000b0b0200 , 0x00000000bc128639 , 0x000000003de79766 , 0x00000000be6e2869 ,
198+ 0x3ca0ce1f3e30521c , 0x4452d55e3d0160b6 , 0x3cf7fdaa4453abf1 , 0x000000003ce3f40f ,
199+ 0x000000003cdbcaa6 , 0x000000003d635f4e , 0x00000000be299439 , 0xbb98ddc23e1159b4 ,
200+ 0x44523b6c3c87d83c , 0x3c8d1c46445308a2 , 0xbbb83fe03c9bcc40 , 0xbab0ed65b8fe93b0 ,
201+ 0xba677004bb598091 , 0x3c0eb61e3b49d173 , 0xba1bac9f3c67af0b , 0x00000000b9d0e64d ,
202+ 0x0000000000000000 , 0x0000000000000000 , 0xb97653e400000000 , 0x00000000ba95460e ,
203+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
204+ 0x0000000000000000 , 0x0000000000000000 , 0xbab5330000000000 , 0x000001013b07a47f ,
205+ };
206+ static constexpr u64 dumped_calib_data2[32 ]{
207+ 0x002d000000ff0009 , 0x002d0ff70ffd0f14 , 0x002d0efe00010008 , 0x002f0ffe0f020008 ,
208+ 0x002f000800060105 , 0x002e00fc0001000a , 0x0000000000000000 , 0x0000000000000000 ,
209+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
210+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
211+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
212+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
213+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
214+ 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 , 0x0000000000000000 ,
215+ };
216+ std::memcpy (calib_data, id == 1 ? dumped_calib_data1 : dumped_calib_data2,
217+ sizeof (dumped_calib_data1));
218+ return ORBIS_OK ;
186219}
187220
188221s32 PS4_SYSV_ABI sceCameraGetCalibDataFromDevice () {
@@ -335,9 +368,6 @@ s32 PS4_SYSV_ABI sceCameraGetExposureGain(s32 handle, OrbisCameraChannel channel
335368 return ORBIS_OK ;
336369}
337370
338- static std::vector<u16 > raw16_buffer1, raw16_buffer2;
339- static std::vector<u8 > raw8_buffer1, raw8_buffer2;
340-
341371static void ConvertRGBA8888ToRAW16 (const u8 * src, u16 * dst, int width, int height) {
342372 for (int y = 0 ; y < height; ++y) {
343373 const u8 * row = src + y * width * 4 ;
@@ -446,30 +476,32 @@ s32 PS4_SYSV_ABI sceCameraGetFrameData(s32 handle, OrbisCameraFrameData* frame_d
446476
447477 switch (output_config0.format .formatLevel0 ) {
448478 case ORBIS_CAMERA_FORMAT_YUV422 :
449- frame_data->pFramePointerList [0 ][0 ] = frame->pixels ;
479+ std::memcpy (raw16_buffer1, frame->pixels , c_width * c_height * sizeof (u16 ));
480+ frame_data->pFramePointerList [0 ][0 ] = raw16_buffer1;
450481 break ;
451482 case ORBIS_CAMERA_FORMAT_RAW16 :
452- ConvertRGBA8888ToRAW16 ((u8 *)frame->pixels , raw16_buffer1. data () , c_width, c_height);
453- frame_data->pFramePointerList [0 ][0 ] = raw16_buffer1. data () ;
483+ ConvertRGBA8888ToRAW16 ((u8 *)frame->pixels , raw16_buffer1, c_width, c_height);
484+ frame_data->pFramePointerList [0 ][0 ] = raw16_buffer1;
454485 break ;
455486 case ORBIS_CAMERA_FORMAT_RAW8 :
456- ConvertRGBA8888ToRAW8 ((u8 *)frame->pixels , raw8_buffer1. data () , c_width, c_height);
457- frame_data->pFramePointerList [0 ][0 ] = raw8_buffer1. data () ;
487+ ConvertRGBA8888ToRAW8 ((u8 *)frame->pixels , raw8_buffer1, c_width, c_height);
488+ frame_data->pFramePointerList [0 ][0 ] = raw8_buffer1;
458489 break ;
459490 default :
460491 UNREACHABLE ();
461492 }
462493 switch (output_config1.format .formatLevel0 ) {
463494 case ORBIS_CAMERA_FORMAT_YUV422 :
464- frame_data->pFramePointerList [1 ][0 ] = frame->pixels ;
495+ std::memcpy (raw16_buffer2, frame->pixels , c_width * c_height * sizeof (u16 ));
496+ frame_data->pFramePointerList [1 ][0 ] = raw16_buffer2;
465497 break ;
466498 case ORBIS_CAMERA_FORMAT_RAW16 :
467- ConvertRGBA8888ToRAW16 ((u8 *)frame->pixels , raw16_buffer2. data () , c_width, c_height);
468- frame_data->pFramePointerList [1 ][0 ] = raw16_buffer2. data () ;
499+ ConvertRGBA8888ToRAW16 ((u8 *)frame->pixels , raw16_buffer2, c_width, c_height);
500+ frame_data->pFramePointerList [1 ][0 ] = raw16_buffer2;
469501 break ;
470502 case ORBIS_CAMERA_FORMAT_RAW8 :
471- ConvertRGBA8888ToRAW8 ((u8 *)frame->pixels , raw8_buffer2. data () , c_width, c_height);
472- frame_data->pFramePointerList [1 ][0 ] = raw8_buffer2. data () ;
503+ ConvertRGBA8888ToRAW8 ((u8 *)frame->pixels , raw8_buffer2, c_width, c_height);
504+ frame_data->pFramePointerList [1 ][0 ] = raw8_buffer2;
473505 break ;
474506 default :
475507 UNREACHABLE ();
@@ -688,6 +720,30 @@ s32 PS4_SYSV_ABI sceCameraOpen(Libraries::UserService::OrbisUserServiceUserId us
688720 return ORBIS_CAMERA_ERROR_PARAM ;
689721 }
690722
723+ constexpr s32 camera_system_mem_size = 0xfd0000 ;
724+ void * camera_garlic_pool = (void *)0xfd0000000 ;
725+
726+ s32 ret = Libraries::Kernel::sceKernelMapNamedSystemFlexibleMemory (
727+ &camera_garlic_pool, camera_system_mem_size,
728+ (s32)(Core::MemoryProt::CpuReadWrite | Core::MemoryProt::GpuRead), 0 ,
729+ " SceCameraGpuGarlicPool" );
730+ ASSERT (ret == ORBIS_OK );
731+
732+ constexpr s32 raw8_buffer_size = c_width * c_height * sizeof (u8 );
733+ constexpr s32 raw16_buffer_size = c_width * c_height * sizeof (u16 );
734+
735+ u8 * remaining_camera_buf = (u8 *)camera_garlic_pool;
736+
737+ raw8_buffer1 = remaining_camera_buf += raw8_buffer_size;
738+ raw8_buffer2 = remaining_camera_buf += raw8_buffer_size;
739+ raw16_buffer1 = (u16 *)(remaining_camera_buf += raw16_buffer_size);
740+ raw16_buffer2 = (u16 *)(remaining_camera_buf += raw16_buffer_size);
741+
742+ ASSERT (remaining_camera_buf <= (u8 *)camera_garlic_pool + camera_system_mem_size);
743+
744+ ASSERT (Core::Memory::Instance ()->IsValidGpuMapping ((VAddr)camera_garlic_pool,
745+ camera_system_mem_size));
746+
691747 g_library_opened = true ;
692748 return ++g_handles;
693749}
@@ -1075,10 +1131,6 @@ s32 PS4_SYSV_ABI sceCameraStart(s32 handle, OrbisCameraStartParameter* param) {
10751131 LOG_INFO (Lib_Camera, " No camera devices connected" );
10761132 return ORBIS_CAMERA_ERROR_NOT_CONNECTED ;
10771133 }
1078- raw8_buffer1.resize (c_width * c_height);
1079- raw16_buffer1.resize (c_width * c_height);
1080- raw8_buffer2.resize (c_width * c_height);
1081- raw16_buffer2.resize (c_width * c_height);
10821134 SDL_CameraSpec cam_spec{};
10831135 switch (output_config0.format .formatLevel0 ) {
10841136 case ORBIS_CAMERA_FORMAT_YUV422 :
0 commit comments