diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index 790bcb0bb64d..f532233203fd 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -23,6 +23,7 @@ #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceJpeg.h" #include "Core/HLE/sceMpeg.h" +#include "GPU/GPUCommon.h" #include "Core/MemMap.h" #include "Core/Reporting.h" @@ -112,7 +113,10 @@ static void __JpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferW static int sceJpegMJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth) { __JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth); - DEBUG_LOG(ME, "sceJpegMJpegCsc(%i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth); + int width = (widthHeight >> 16) & 0xFFF; + int height = widthHeight & 0xFFF; + DEBUG_LOG(ME, "sceJpegMJpegCsc(%08x, %08x, (%dx%d), %i)", imageAddr, yCbCrAddr, width, height, bufferWidth); + gpu->NotifyVideoUpload(imageAddr, width * height * 4, width, GE_FORMAT_8888); return 0; } @@ -165,7 +169,7 @@ static int sceJpegDecodeMJpeg(u32 jpegAddr, int jpegSize, u32 imageAddr, int dht return 0; } - DEBUG_LOG(ME, "sceJpegDecodeMJpeg(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); + DEBUG_LOG(ME, "sceJpegDecodeMJpeg(%08x, %i, %08x, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); return __DecodeJpeg(jpegAddr, jpegSize, imageAddr); } @@ -180,19 +184,19 @@ static int sceJpegDecodeMJpegSuccessively(u32 jpegAddr, int jpegSize, u32 imageA return 0; } - DEBUG_LOG(ME, "sceJpegDecodeMJpegSuccessively(%i, %i, %i, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); + DEBUG_LOG(ME, "sceJpegDecodeMJpegSuccessively(%08x, %i, %08x, %i)", jpegAddr, jpegSize, imageAddr, dhtMode); return __DecodeJpeg(jpegAddr, jpegSize, imageAddr); } static int sceJpegCsc(u32 imageAddr, u32 yCbCrAddr, int widthHeight, int bufferWidth, int colourInfo) { if (bufferWidth < 0 || widthHeight < 0){ - WARN_LOG(ME, "sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo); + WARN_LOG(ME, "sceJpegCsc(%08x, %08x, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo); return ERROR_JPEG_INVALID_VALUE; } __JpegCsc(imageAddr, yCbCrAddr, widthHeight, bufferWidth); - DEBUG_LOG(ME, "sceJpegCsc(%i, %i, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo); + DEBUG_LOG(ME, "sceJpegCsc(%08x, %08x, %i, %i, %i)", imageAddr, yCbCrAddr, widthHeight, bufferWidth, colourInfo); return 0; } @@ -257,7 +261,7 @@ static int sceJpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr, return getYCbCrBufferSize(0, 0); } - DEBUG_LOG(ME, "sceJpegGetOutputInfo(%i, %i, %i, %i)", jpegAddr, jpegSize, colourInfoAddr, dhtMode); + DEBUG_LOG(ME, "sceJpegGetOutputInfo(%08x, %i, %08x, %i)", jpegAddr, jpegSize, colourInfoAddr, dhtMode); return __JpegGetOutputInfo(jpegAddr, jpegSize, colourInfoAddr); } @@ -345,7 +349,7 @@ static int sceJpegDecodeMJpegYCbCr(u32 jpegAddr, int jpegSize, u32 yCbCrAddr, in return getWidthHeight(0, 0); } - DEBUG_LOG(ME, "sceJpegDecodeMJpegYCbCr(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); + DEBUG_LOG(ME, "sceJpegDecodeMJpegYCbCr(%08x, %i, %08x, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr); } @@ -355,7 +359,7 @@ static int sceJpegDecodeMJpegYCbCrSuccessively(u32 jpegAddr, int jpegSize, u32 y return getWidthHeight(0, 0); } - DEBUG_LOG(ME, "sceJpegDecodeMJpegYCbCrSuccessively(%i, %i, %i, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); + DEBUG_LOG(ME, "sceJpegDecodeMJpegYCbCrSuccessively(%08x, %i, %08x, %i, %i)", jpegAddr, jpegSize, yCbCrAddr, yCbCrSize, dhtMode); // Do as same way as sceJpegDecodeMJpegYCbCr() but with smaller block size return __JpegDecodeMJpegYCbCr(jpegAddr, jpegSize, yCbCrAddr); } diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index bf409a247c5d..c375c59a049a 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -81,6 +81,7 @@ #include "sceHeap.h" #include "sceDmac.h" #include "sceMp4.h" +#include "sceUsbCam.h" #include "../Util/PPGeDraw.h" @@ -143,6 +144,7 @@ void __KernelInit() __AudioCodecInit(); __VideoPmpInit(); __UsbGpsInit(); + __UsbCamInit(); SaveState::Init(); // Must be after IO, as it may create a directory Reporting::Init(); @@ -166,6 +168,8 @@ void __KernelShutdown() hleCurrentThreadName = NULL; kernelObjects.Clear(); + __UsbCamShutdown(); + __AudioCodecShutdown(); __VideoPmpShutdown(); __AACShutdown(); diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp index 7ddf16ec618d..361f55f26bb6 100644 --- a/Core/HLE/sceUsb.cpp +++ b/Core/HLE/sceUsb.cpp @@ -63,13 +63,13 @@ void __UsbDoState(PointerWrap &p) } static int sceUsbStart(const char* driverName, u32 argsSize, u32 argsPtr) { - ERROR_LOG(HLE, "UNIMPL sceUsbStart(%s, %i, %08x)", driverName, argsSize, argsPtr); + INFO_LOG(HLE, "sceUsbStart(%s, %i, %08x)", driverName, argsSize, argsPtr); usbStarted = true; return 0; } static int sceUsbStop(const char* driverName, u32 argsSize, u32 argsPtr) { - ERROR_LOG(HLE, "UNIMPL sceUsbStop(%s, %i, %08x)", driverName, argsSize, argsPtr); + INFO_LOG(HLE, "sceUsbStop(%s, %i, %08x)", driverName, argsSize, argsPtr); usbStarted = false; return 0; } @@ -83,18 +83,18 @@ static int sceUsbGetState() { | (usbConnected ? USB_STATUS_CONNECTED : USB_STATUS_DISCONNECTED) | (usbActivated ? USB_STATUS_ACTIVATED : USB_STATUS_DEACTIVATED); } - ERROR_LOG(HLE, "UNIMPL sceUsbGetState: 0x%x", state); + INFO_LOG(HLE, "sceUsbGetState: 0x%x", state); return state; } static int sceUsbActivate(u32 pid) { - ERROR_LOG(HLE, "UNIMPL sceUsbActivate(%i)", pid); + INFO_LOG(HLE, "sceUsbActivate(%i)", pid); usbActivated = true; return 0; } static int sceUsbDeactivate(u32 pid) { - ERROR_LOG(HLE, "UNIMPL sceUsbDeactivate(%i)", pid); + INFO_LOG(HLE, "sceUsbDeactivate(%i)", pid); usbActivated = false; return 0; } diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index ae0599c97df1..b2be0192458b 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include #include "base/NativeApp.h" @@ -29,9 +30,25 @@ PspUsbCamSetupVideoParam videoParam; unsigned int videoBufferLength = 0; unsigned int nextVideoFrame = 0; -unsigned char videoBuffer[40 * 1000]; +uint8_t *videoBuffer; std::mutex videoBufferMutex; +enum { + VIDEO_BUFFER_SIZE = 40 * 1000, +}; + +void __UsbCamInit() { + videoBuffer = new uint8_t[VIDEO_BUFFER_SIZE]; +} + +void __UsbCamShutdown() { + delete[] videoBuffer; + videoBuffer = nullptr; +} + +// TODO: Technically, we should store the videoBuffer into the savestate, if this +// module has been initialized. + static int sceUsbCamSetupMic(u32 paramAddr, u32 workareaAddr, int wasize) { INFO_LOG(HLE, "UNIMPL sceUsbCamSetupMic"); if (Memory::IsValidRange(paramAddr, sizeof(micParam))) { @@ -67,13 +84,14 @@ static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) { Memory::ReadStruct(paramAddr, &videoParam); } + INFO_LOG(HLE, "UNIMPL sceUsbCamSetupVideo - size: %d", videoParam.size); + INFO_LOG(HLE, "UNIMPL sceUsbCamSetupVideo - resolution: %d", videoParam.resolution); + INFO_LOG(HLE, "UNIMPL sceUsbCamSetupVideo - framesize: %d", videoParam.framesize); + std::lock_guard lock(videoBufferMutex); videoBufferLength = sizeof(sceUsbCamDummyImage); memset(videoBuffer, 0, sizeof(videoBuffer)); memcpy(videoBuffer, sceUsbCamDummyImage, sizeof(sceUsbCamDummyImage)); - - INFO_LOG(HLE, "UNIMPL sceUsbCamSetupVideo - size: %d", videoParam.size); - INFO_LOG(HLE, "UNIMPL sceUsbCamSetupVideo - resolution: %d", videoParam.resolution); return 0; } @@ -96,20 +114,19 @@ static int sceUsbCamAutoImageReverseSW(int rev) { static int sceUsbCamReadVideoFrameBlocking(u32 bufAddr, u32 size) { std::lock_guard lock(videoBufferMutex); - for (unsigned int i = 0; i < videoBufferLength && i < size; i++) { - if (Memory::IsValidAddress(bufAddr + i)) { - Memory::Write_U8(videoBuffer[i], bufAddr + i); - } + + u32 transferSize = std::min(videoBufferLength, size); + if (Memory::IsValidRange(bufAddr, size)) { + Memory::Memcpy(bufAddr, videoBuffer, transferSize); } return videoBufferLength; } static int sceUsbCamReadVideoFrame(u32 bufAddr, u32 size) { std::lock_guard lock(videoBufferMutex); - for (unsigned int i = 0; i < videoBufferLength && i < size; i++) { - if (Memory::IsValidAddress(bufAddr + i)) { - Memory::Write_U8(videoBuffer[i], bufAddr + i); - } + u32 transferSize = std::min(videoBufferLength, size); + if (Memory::IsValidRange(bufAddr, size)) { + Memory::Memcpy(bufAddr, videoBuffer, transferSize); } nextVideoFrame = videoBufferLength; return 0; diff --git a/Core/HLE/sceUsbCam.h b/Core/HLE/sceUsbCam.h index ef088fe91da4..ebb5388db656 100644 --- a/Core/HLE/sceUsbCam.h +++ b/Core/HLE/sceUsbCam.h @@ -19,6 +19,9 @@ void Register_sceUsbCam(); +void __UsbCamInit(); +void __UsbCamShutdown(); + namespace Camera { void pushCameraImage(long long length, unsigned char *image); }