Improve compatibility.

Don't implemente on vista and UWP,they don't have a full support for this.
This commit is contained in:
shenweip 2020-01-14 17:15:11 +08:00
parent 5c4a1e00fc
commit d1e354ce04
7 changed files with 120 additions and 17 deletions

View File

@ -95,6 +95,25 @@ bool IsVistaOrHigher() {
#endif
}
bool IsWin7OrHigher() {
#if PPSSPP_PLATFORM(UWP)
return true;
#else
OSVERSIONINFOEX osvi;
DWORDLONG dwlConditionMask = 0;
int op = VER_GREATER_EQUAL;
ZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
osvi.dwMajorVersion = 6; // Win7 is 6.1
osvi.dwMinorVersion = 1;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE;
#endif
}
std::string GetWindowsVersion() {
const bool IsWindowsXPSP2 = DoesVersionMatchWindows(5, 1, 2, 0, false);
const bool IsWindowsXPSP3 = DoesVersionMatchWindows(5, 1, 3, 0, false);

View File

@ -5,6 +5,7 @@
#ifdef _WIN32
bool IsVistaOrHigher();
bool IsWin7OrHigher();
bool DoesVersionMatchWindows(uint32_t major, uint32_t minor, uint32_t spMajor, uint32_t spMinor, bool acceptGreater);
std::string GetWindowsVersion();
std::string GetWindowsSystemArchitecture();

View File

@ -706,6 +706,8 @@ static ConfigSetting graphicsSettings[] = {
ConfigSetting("VulkanDevice", &g_Config.sVulkanDevice, "", true, false),
#ifdef _WIN32
ConfigSetting("D3D11Device", &g_Config.sD3D11Device, "", true, false),
#endif
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
ConfigSetting("WinCameraDevice", &g_Config.sWinCameraDevice, "", true, false),
#endif
ConfigSetting("VendorBugChecksEnabled", &g_Config.bVendorBugChecksEnabled, true, false, false),

View File

@ -25,7 +25,7 @@
#include "Core/HLE/sceUsbCam.h"
#include "Core/MemMapHelpers.h"
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
#include "Windows/CaptureDevice.h"
#undef min
#endif
@ -50,7 +50,7 @@ void __UsbCamInit() {
}
void __UsbCamShutdown() {
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (winCamera) {
winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::SHUTDOWN, nullptr });
}
@ -112,7 +112,7 @@ static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) {
static int sceUsbCamStartVideo() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStartVideo");
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (winCamera) {
if (winCamera->isShutDown()) {
delete winCamera;
@ -131,7 +131,7 @@ static int sceUsbCamStartVideo() {
static int sceUsbCamStopVideo() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStopVideo");
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (winCamera)
winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr });
#else
@ -155,6 +155,7 @@ static int sceUsbCamReadVideoFrameBlocking(u32 bufAddr, u32 size) {
}
static int sceUsbCamReadVideoFrame(u32 bufAddr, u32 size) {
ERROR_LOG(HLE, "%s", winCamera->getErrorMessage().c_str());
std::lock_guard<std::mutex> lock(videoBufferMutex);
u32 transferSize = std::min(videoBufferLength, size);
if (Memory::IsValidRange(bufAddr, size)) {

View File

@ -68,13 +68,9 @@
#include "Windows/MainWindow.h"
#include <shlobj.h>
#include "Windows/W32Util/ShellUtil.h"
#endif
#ifdef _WIN32
#include "Windows/CaptureDevice.h"
#endif
GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore)
: UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), enableReports_(false), editThenRestore_(editThenRestore) {
lastVertical_ = UseVerticalLayout();
@ -267,7 +263,7 @@ void GameSettingsScreen::CreateViews() {
softwareGPU->SetEnabled(false);
}
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (winCamera && winCamera->getDeviceList().size() >= 1) {
graphicsSettings->Add(new ItemHeader(gr->T("Camera")));
PopupMultiChoiceDynamic *cameraChoice = graphicsSettings->Add(new PopupMultiChoiceDynamic(&g_Config.sWinCameraDevice, gr->T("Camera Device"), winCamera->getDeviceList(), nullptr, screenManager()));

View File

@ -37,6 +37,9 @@
#if defined(_WIN32)
#include "Windows/WindowsAudio.h"
#include "Windows/MainWindow.h"
#endif
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
#include "Windows/CaptureDevice.h"
#endif
@ -857,8 +860,8 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
#endif
#endif
#ifdef _WIN32
if (IsVistaOrHigher()) {
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (IsWin7OrHigher()) {
winCamera = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::VIDEO);
winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr });
}
@ -888,7 +891,7 @@ void NativeShutdownGraphics() {
winAudioBackend = nullptr;
#endif
#ifdef _WIN32
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
if (winCamera) {
delete winCamera;
winCamera = nullptr;

View File

@ -24,6 +24,66 @@
#include "Core/HLE/sceUsbCam.h"
#include "Core/Config.h"
namespace MFAPI {
HINSTANCE Mflib;
HINSTANCE Mfplatlib;
HINSTANCE Mfreadwritelib;
typedef HRESULT(WINAPI *MFEnumDeviceSourcesFunc)(IMFAttributes *, IMFActivate ***, UINT32 *);
typedef HRESULT(WINAPI *MFGetStrideForBitmapInfoHeaderFunc)(DWORD, DWORD, LONG *);
typedef HRESULT(WINAPI *MFCreateSourceReaderFromMediaSourceFunc)(IMFMediaSource *, IMFAttributes *, IMFSourceReader **);
typedef HRESULT(WINAPI *MFCopyImageFunc)(BYTE *, LONG, const BYTE *, LONG, DWORD, DWORD);
MFEnumDeviceSourcesFunc EnumDeviceSources;
MFGetStrideForBitmapInfoHeaderFunc GetStrideForBitmapInfoHeader;
MFCreateSourceReaderFromMediaSourceFunc CreateSourceReaderFromMediaSource;
MFCopyImageFunc CopyImage;
}
using namespace MFAPI;
bool RegisterCMPTMFApis(){
//For the compatibility,these funcs don't be supported on vista.
Mflib = LoadLibrary(L"Mf.dll");
Mfplatlib = LoadLibrary(L"Mfplat.dll");
Mfreadwritelib = LoadLibrary(L"Mfreadwrite.dll");
if (!Mflib || !Mfplatlib || !Mfreadwritelib)
return false;
EnumDeviceSources = (MFEnumDeviceSourcesFunc)GetProcAddress(Mflib, "MFEnumDeviceSources");
GetStrideForBitmapInfoHeader = (MFGetStrideForBitmapInfoHeaderFunc)GetProcAddress(Mfplatlib, "MFGetStrideForBitmapInfoHeader");
MFAPI::CopyImage = (MFCopyImageFunc)GetProcAddress(Mfplatlib, "MFCopyImage");
CreateSourceReaderFromMediaSource = (MFCreateSourceReaderFromMediaSourceFunc)GetProcAddress(Mfreadwritelib, "MFCreateSourceReaderFromMediaSource");
if (!EnumDeviceSources || !GetStrideForBitmapInfoHeader || !CreateSourceReaderFromMediaSource || !MFAPI::CopyImage)
return false;
return true;
}
bool unRegisterCMPTMFApis() {
if (Mflib) {
FreeLibrary(Mflib);
Mflib = nullptr;
}
if (Mfplatlib) {
FreeLibrary(Mfplatlib);
Mfplatlib = nullptr;
}
if (Mfreadwritelib) {
FreeLibrary(Mfreadwritelib);
Mfreadwritelib = nullptr;
}
EnumDeviceSources = nullptr;
GetStrideForBitmapInfoHeader = nullptr;
CreateSourceReaderFromMediaSource = nullptr;
MFAPI::CopyImage = nullptr;
return true;
}
WindowsCaptureDevice *winCamera;
// TODO: Add more formats, but need some tests.
@ -237,7 +297,7 @@ void ReaderCallback::imgInvert(unsigned char *dst, unsigned char *src, const int
}
void ReaderCallback::imgInvertRGBA(unsigned char *dst, int &dstStride, unsigned char *src, const int &srcStride, const int &h) {
MFCopyImage(dst, dstStride, src, srcStride, dstStride, h);
MFAPI::CopyImage(dst, dstStride, src, srcStride, dstStride, h);
}
void ReaderCallback::imgInvertRGB(unsigned char *dst, int &dstStride, unsigned char *src, const int &srcStride, const int &h) {
@ -333,6 +393,11 @@ bool WindowsCaptureDevice::init() {
param = { 0 };
IMFAttributes *pAttributes = nullptr;
if (!RegisterCMPTMFApis()) {
setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot register devices");
return false;
}
hr = MFCreateAttributes(&pAttributes, 1);
if (SUCCEEDED(hr)) {
switch (type) {
@ -357,7 +422,7 @@ bool WindowsCaptureDevice::init() {
}
if (SUCCEEDED(hr))
hr = MFEnumDeviceSources(pAttributes, &param.ppDevices, &param.count);
hr = EnumDeviceSources(pAttributes, &param.ppDevices, &param.count);
if (FAILED(hr)) {
setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot enumerate devices");
@ -410,7 +475,7 @@ bool WindowsCaptureDevice::start() {
hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE);
if (SUCCEEDED(hr)) {
hr = MFCreateSourceReaderFromMediaSource(
hr = CreateSourceReaderFromMediaSource(
m_pSource,
pAttributes,
&m_pReader
@ -423,13 +488,28 @@ bool WindowsCaptureDevice::start() {
if (SUCCEEDED(hr)) {
switch (type) {
case CAPTUREDEVIDE_TYPE::VIDEO:
for (DWORD i = 0; ; i++) {
hr = m_pReader->GetNativeMediaType(
(DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM,
i,
&pType
);
if (FAILED(hr)) { break; }
hr = setDeviceParam(pType);
if (SUCCEEDED(hr))
break;
}
/*
hr = m_pReader->GetNativeMediaType(
(DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM,
(DWORD)0xFFFFFFFF,//MF_SOURCE_READER_CURRENT_TYPE_INDEX
&pType
);
if (SUCCEEDED(hr))
hr = setDeviceParam(pType);
hr = setDeviceParam(pType);*/ // Don't support on Win7
// Request the first frame, in asnyc mode, OnReadSample will be called when ReadSample completed.
if (SUCCEEDED(hr)) {
@ -644,6 +724,7 @@ void WindowsCaptureDevice::messageHandler() {
SafeRelease(&m_pReader);
CoTaskMemFree(param.ppDevices);
delete m_pCallback;
unRegisterCMPTMFApis();
MFShutdown();
CoUninitialize();
@ -680,7 +761,7 @@ HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride)
}
if (SUCCEEDED(hr))
{
hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride);
hr = GetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride);
}
// Set the attribute for later reference.