diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 3ec2270250..e506d21549 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -418,6 +418,21 @@ void Camera::onCameraDeviceChange() { } } +int Camera::getMaxFrameSize() { + int framesize = 0; + if (config) { + if (config->type == Camera::ConfigType::CfVideoEx) { + framesize = config->videoExParam.framesize; + } else if (config->type == Camera::ConfigType::CfVideo) { + framesize = config->videoParam.framesize; + } + } + if (framesize <= 0 || framesize > VIDEO_BUFFER_SIZE) { + return VIDEO_BUFFER_SIZE; + } + return framesize; +} + void Camera::pushCameraImage(long long length, unsigned char* image) { std::lock_guard lock(videoBufferMutex); if (!videoBuffer) { diff --git a/Core/HLE/sceUsbCam.h b/Core/HLE/sceUsbCam.h index 4d4e4f0831..d356dbc8a4 100644 --- a/Core/HLE/sceUsbCam.h +++ b/Core/HLE/sceUsbCam.h @@ -121,4 +121,7 @@ namespace Camera { int startCapture(); int stopCapture(); void pushCameraImage(long long length, unsigned char *image); + // The largest JPEG frame the game accepts (framesize in the video setup). The PSP camera compresses + // to fit it, so capture code should too. + int getMaxFrameSize(); } diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index 666cb6542d..c2b2d069a0 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -247,13 +247,23 @@ HRESULT ReaderCallback::OnReadSample( } } - // Compress image to jpeg from RGB24. - jpge::compress_image_to_jpeg_file_in_memory( - device->imageJpeg, imgJpegSize, - dstW, - dstH, - 3, - device->imageRGB); + // Compress image to jpeg from RGB24. Like the PSP camera, lower the quality until the frame + // fits the size the game asked for: Go!Edit stores frames in fixed 15KB slots. + const int maxFrameSize = Camera::getMaxFrameSize(); + jpge::params params; + for (int quality = 85; ; quality -= 10) { + imgJpegSize = device->imgJpegSize; + params.m_quality = quality; + jpge::compress_image_to_jpeg_file_in_memory( + device->imageJpeg, imgJpegSize, + dstW, + dstH, + 3, + device->imageRGB, params); + if (imgJpegSize <= maxFrameSize || quality <= 15) { + break; + } + } } #endif Camera::pushCameraImage(imgJpegSize, device->imageJpeg);