diff --git a/Common/CommonTypes.h b/Common/CommonTypes.h index 84e7d2dcd9..f2066dc000 100644 --- a/Common/CommonTypes.h +++ b/Common/CommonTypes.h @@ -48,8 +48,6 @@ typedef signed __int64 s64; #define ThreadContext _ThreadContext #include // Cleanup -#undef KeyInputFlags::UP -#undef KeyInputFlags::DOWN #undef Event #undef Framebuffer #undef Waitable diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 7ff3bdcccf..5a72f3c467 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -354,11 +354,10 @@ int Camera::startCapture() { if (winCamera) { if (winCamera->isShutDown()) { delete winCamera; - winCamera = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::VIDEO); - winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr }); + winCamera = new WindowsCaptureDevice(CAPTUREDEVICE_TYPE::VIDEO); } void* resolution = static_cast(new std::vector({ width, height })); - winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::START, resolution }); + winCamera->sendMessage({ CAPTUREDEVICE_COMMAND::START, resolution }); } #elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) || defined(USING_QT_UI) char command[40] = {0}; @@ -378,7 +377,7 @@ int Camera::stopCapture() { INFO_LOG(Log::HLE, "%s", __FUNCTION__); #ifdef HAVE_WIN32_CAMERA if (winCamera) { - winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr }); + winCamera->sendMessage({ CAPTUREDEVICE_COMMAND::STOP, nullptr }); } #elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) || defined(USING_QT_UI) System_CameraCommand("stopVideo"); diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 07075d1e43..afcacd0bea 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -307,7 +307,7 @@ static int sceUsbMicWaitInputEnd() { int Microphone::startMic(void *param) { #ifdef HAVE_WIN32_MICROPHONE if (winMic) - winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::START, param }); + winMic->sendMessage({ CAPTUREDEVICE_COMMAND::START, param }); #elif PPSSPP_PLATFORM(ANDROID) std::vector *micParam = static_cast*>(param); int sampleRate = micParam->at(0); @@ -322,7 +322,7 @@ int Microphone::startMic(void *param) { int Microphone::stopMic() { #ifdef HAVE_WIN32_MICROPHONE if (winMic) - winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr }); + winMic->sendMessage({ CAPTUREDEVICE_COMMAND::STOP, nullptr }); #elif PPSSPP_PLATFORM(ANDROID) System_MicrophoneCommand("stopRecording"); #endif diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 53b838e165..4a26924960 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -832,10 +832,8 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) if (IsWin7OrHigher()) { - winCamera = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::VIDEO); - winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr }); - winMic = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::Audio); - winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr }); + winCamera = new WindowsCaptureDevice(CAPTUREDEVICE_TYPE::VIDEO); + winMic = new WindowsCaptureDevice(CAPTUREDEVICE_TYPE::AUDIO); } #endif diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index 59a831158f..666cb6542d 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -18,6 +18,8 @@ #include #include +#include "mfapi.h" + #include "Common/Thread/ThreadUtil.h" #include "CaptureDevice.h" #include "BufferLock.h" @@ -33,64 +35,87 @@ namespace MFAPI { HINSTANCE Mfplatlib; HINSTANCE Mfreadwritelib; + // NOTE: MFGetAttributeSize is an inline function, so we don't need to load it dynamically. + typedef HRESULT(WINAPI *MFEnumDeviceSourcesFunc)(IMFAttributes *, IMFActivate ***, UINT32 *); + typedef HRESULT(WINAPI *MFStartupFunc)(ULONG, DWORD); + typedef HRESULT(WINAPI *MFShutdownFunc)(); + typedef HRESULT(WINAPI *MFCreateAttributesFunc)(IMFAttributes **, 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; + MFStartupFunc Startup; + MFShutdownFunc ShutdownFn; + MFCreateAttributesFunc CreateAttributes; 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; +bool RegisterCMPTMFApis() { + // We dynamically load these, as they are not always available (de-bloated Windows, Windows Vista, etc). - 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) + MFAPI::Mflib = LoadLibrary(L"Mf.dll"); + if (!MFAPI::Mflib) { + ERROR_LOG(Log::System, "Failed to load Mflib."); return false; + } + MFAPI::Mfplatlib = LoadLibrary(L"Mfplat.dll"); + if (!MFAPI::Mfplatlib) { + ERROR_LOG(Log::System, "Failed to load Mfplat."); + return false; + } + MFAPI::Mfreadwritelib = LoadLibrary(L"Mfreadwrite.dll"); + if (!MFAPI::Mfreadwritelib) { + ERROR_LOG(Log::System, "Failed to load Mfreadwrite."); + return false; + } + + MFAPI::EnumDeviceSources = (MFAPI::MFEnumDeviceSourcesFunc)GetProcAddress(MFAPI::Mflib, "MFEnumDeviceSources"); + MFAPI::Startup = (MFAPI::MFStartupFunc)GetProcAddress(MFAPI::Mfplatlib, "MFStartup"); + MFAPI::ShutdownFn = (MFAPI::MFShutdownFunc)GetProcAddress(MFAPI::Mfplatlib, "MFShutdown"); + MFAPI::CreateAttributes = (MFAPI::MFCreateAttributesFunc)GetProcAddress(MFAPI::Mfplatlib, "MFCreateAttributes"); + MFAPI::GetStrideForBitmapInfoHeader = (MFAPI::MFGetStrideForBitmapInfoHeaderFunc)GetProcAddress(MFAPI::Mfplatlib, "MFGetStrideForBitmapInfoHeader"); + MFAPI::CopyImage = (MFAPI::MFCopyImageFunc)GetProcAddress(MFAPI::Mfplatlib, "MFCopyImage"); + MFAPI::CreateSourceReaderFromMediaSource = (MFAPI::MFCreateSourceReaderFromMediaSourceFunc)GetProcAddress(MFAPI::Mfreadwritelib, "MFCreateSourceReaderFromMediaSource"); + if (!MFAPI::EnumDeviceSources || !MFAPI::Startup || !MFAPI::ShutdownFn || !MFAPI::CreateAttributes || !MFAPI::GetStrideForBitmapInfoHeader || !MFAPI::CreateSourceReaderFromMediaSource || !MFAPI::CopyImage) { + return false; + } return true; } -bool unRegisterCMPTMFApis() { - if (Mflib) { - FreeLibrary(Mflib); - Mflib = nullptr; +bool UnRegisterCMPTMFApis() { + if (MFAPI::Mflib) { + FreeLibrary(MFAPI::Mflib); + MFAPI::Mflib = nullptr; } - if (Mfplatlib) { - FreeLibrary(Mfplatlib); - Mfplatlib = nullptr; + if (MFAPI::Mfplatlib) { + FreeLibrary(MFAPI::Mfplatlib); + MFAPI::Mfplatlib = nullptr; } - if (Mfreadwritelib) { - FreeLibrary(Mfreadwritelib); - Mfreadwritelib = nullptr; + if (MFAPI::Mfreadwritelib) { + FreeLibrary(MFAPI::Mfreadwritelib); + MFAPI::Mfreadwritelib = nullptr; } - EnumDeviceSources = nullptr; - GetStrideForBitmapInfoHeader = nullptr; - CreateSourceReaderFromMediaSource = nullptr; + MFAPI::EnumDeviceSources = nullptr; + MFAPI::Startup = nullptr; + MFAPI::ShutdownFn = nullptr; + MFAPI::CreateAttributes = nullptr; + MFAPI::GetStrideForBitmapInfoHeader = nullptr; + MFAPI::CreateSourceReaderFromMediaSource = nullptr; MFAPI::CopyImage = nullptr; - return true; } WindowsCaptureDevice *winCamera; WindowsCaptureDevice *winMic; - // TODO: Add more formats, but need some tests. VideoFormatTransform g_VideoFormats[] = { @@ -160,7 +185,7 @@ HRESULT ReaderCallback::OnReadSample( } if (SUCCEEDED(hr)) { switch (device->type) { - case CAPTUREDEVIDE_TYPE::VIDEO: { + case CAPTUREDEVICE_TYPE::VIDEO: { BYTE *pbScanline0 = nullptr; VideoBufferLock *videoBuffer = nullptr; int imgJpegSize = device->imgJpegSize; @@ -247,7 +272,7 @@ HRESULT ReaderCallback::OnReadSample( delete videoBuffer; break; } - case CAPTUREDEVIDE_TYPE::Audio: { + case CAPTUREDEVICE_TYPE::AUDIO: { BYTE *sampleBuf = nullptr; DWORD length = 0; u32 sizeAfterResample = 0; @@ -464,34 +489,33 @@ u32 ReaderCallback::doResample(u8 **dst, u32 &dstSampleRate, u32 &dstChannels, u #endif } -WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVIDE_TYPE _type) : +WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVICE_TYPE _type) : type(_type), error(CAPTUREDEVIDE_ERROR_NO_ERROR), - state(CAPTUREDEVIDE_STATE::UNINITIALIZED) { + state(CAPTUREDEVICE_STATE::UNINITIALIZED) { param = { 0 }; deviceParam = { { 0 } }; switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: + case CAPTUREDEVICE_TYPE::VIDEO: targetMediaParam = defaultVideoParam; break; - case CAPTUREDEVIDE_TYPE::Audio: + case CAPTUREDEVICE_TYPE::AUDIO: targetMediaParam = defaultAudioParam; break; } - std::thread t(&WindowsCaptureDevice::messageHandler, this); - t.detach(); + thread_ = std::thread(&WindowsCaptureDevice::messageHandler, this); } WindowsCaptureDevice::~WindowsCaptureDevice() { #ifdef USE_FFMPEG switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: + case CAPTUREDEVICE_TYPE::VIDEO: av_freep(&imageRGB); av_freep(&imageJpeg); break; - case CAPTUREDEVIDE_TYPE::Audio: + case CAPTUREDEVICE_TYPE::AUDIO: av_freep(&resampleBuf); break; } @@ -502,26 +526,6 @@ void WindowsCaptureDevice::CheckDevices() { isDeviceChanged = true; } -bool WindowsCaptureDevice::init() { - HRESULT hr = S_OK; - - if (!RegisterCMPTMFApis()) { - setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot register devices"); - return false; - } - std::unique_lock lock(paramMutex); - hr = enumDevices(); - lock.unlock(); - - if (FAILED(hr)) { - setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot enumerate devices"); - return false; - } - - updateState(CAPTUREDEVIDE_STATE::STOPPED); - return true; -} - bool WindowsCaptureDevice::start(void *startParam) { HRESULT hr = S_OK; ComPtr pAttributes; @@ -543,10 +547,10 @@ bool WindowsCaptureDevice::start(void *startParam) { m_pCallback = new ReaderCallback(this); - std::string selectedDeviceName = type == CAPTUREDEVIDE_TYPE::VIDEO ? g_Config.sCameraDevice : g_Config.sMicDevice; + std::string selectedDeviceName = type == CAPTUREDEVICE_TYPE::VIDEO ? g_Config.sCameraDevice : g_Config.sMicDevice; switch (state) { - case CAPTUREDEVIDE_STATE::STOPPED: + case CAPTUREDEVICE_STATE::STOPPED: for (auto &name : deviceList) { if (name == selectedDeviceName) { selection = count; @@ -559,7 +563,7 @@ bool WindowsCaptureDevice::start(void *startParam) { IID_PPV_ARGS(&m_pSource)); if (SUCCEEDED(hr)) - hr = MFCreateAttributes(&pAttributes, 2); + hr = MFAPI::CreateAttributes(&pAttributes, 2); // Use async mode if (SUCCEEDED(hr)) @@ -569,7 +573,7 @@ bool WindowsCaptureDevice::start(void *startParam) { hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE); if (SUCCEEDED(hr)) { - hr = CreateSourceReaderFromMediaSource( + hr = MFAPI::CreateSourceReaderFromMediaSource( m_pSource.Get(), pAttributes.Get(), &m_pReader @@ -581,7 +585,7 @@ bool WindowsCaptureDevice::start(void *startParam) { if (SUCCEEDED(hr)) { switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: { + case CAPTUREDEVICE_TYPE::VIDEO: { if (startParam) { std::vector *resolution = static_cast*>(startParam); targetMediaParam.width = resolution->at(0); @@ -635,7 +639,7 @@ bool WindowsCaptureDevice::start(void *startParam) { break; } - case CAPTUREDEVIDE_TYPE::Audio: { + case CAPTUREDEVICE_TYPE::AUDIO: { if (startParam) { std::vector *micParam = static_cast*>(startParam); targetMediaParam.sampleRate = micParam->at(0); @@ -682,15 +686,15 @@ bool WindowsCaptureDevice::start(void *startParam) { return false; } - updateState(CAPTUREDEVIDE_STATE::STARTED); + updateState(CAPTUREDEVICE_STATE::STARTED); break; - case CAPTUREDEVIDE_STATE::LOST: + case CAPTUREDEVICE_STATE::LOST: setError(CAPTUREDEVIDE_ERROR_START_FAILED, "Device has lost"); return false; - case CAPTUREDEVIDE_STATE::STARTED: + case CAPTUREDEVICE_STATE::STARTED: setError(CAPTUREDEVIDE_ERROR_START_FAILED, "Device has started"); return false; - case CAPTUREDEVIDE_STATE::UNINITIALIZED: + case CAPTUREDEVICE_STATE::UNINITIALIZED: setError(CAPTUREDEVIDE_ERROR_START_FAILED, "Device doesn't initialize"); return false; default: @@ -700,12 +704,12 @@ bool WindowsCaptureDevice::start(void *startParam) { } bool WindowsCaptureDevice::stop() { - if (state == CAPTUREDEVIDE_STATE::STOPPED) + if (state == CAPTUREDEVICE_STATE::STOPPED) return true; if (m_pSource) m_pSource->Stop(); - updateState(CAPTUREDEVIDE_STATE::STOPPED); + updateState(CAPTUREDEVICE_STATE::STOPPED); return true; }; @@ -778,7 +782,7 @@ HRESULT WindowsCaptureDevice::setDeviceParam(IMFMediaType *pType) { bool getFormat = false; switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: + case CAPTUREDEVICE_TYPE::VIDEO: hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype); if (FAILED(hr)) break; @@ -817,12 +821,12 @@ HRESULT WindowsCaptureDevice::setDeviceParam(IMFMediaType *pType) { hr = GetDefaultStride(pType, &deviceParam.default_stride); break; - case CAPTUREDEVIDE_TYPE::Audio: + case CAPTUREDEVICE_TYPE::AUDIO: hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype); if (FAILED(hr)) break; - for (int i = 0; i < g_cVideoFormats; i++) { + for (int i = 0; i < g_cAudioFormats; i++) { if (subtype == g_AudioFormats[i].MFAudioFormat) { deviceParam.audioFormat = subtype; getFormat = true; @@ -864,17 +868,17 @@ HRESULT WindowsCaptureDevice::setDeviceParam(IMFMediaType *pType) { return hr; } -void WindowsCaptureDevice::sendMessage(CAPTUREDEVIDE_MESSAGE message) { +void WindowsCaptureDevice::sendMessage(CAPTUREDEVICE_MESSAGE message) { // Must be unique lock std::unique_lock lock(mutex); messageQueue.push(message); cond.notify_one(); } -CAPTUREDEVIDE_MESSAGE WindowsCaptureDevice::getMessage() { +CAPTUREDEVICE_MESSAGE WindowsCaptureDevice::getMessage() { // Must be unique lock std::unique_lock lock(mutex); - CAPTUREDEVIDE_MESSAGE message; + CAPTUREDEVICE_MESSAGE message; cond.wait(lock, [this]() { return !messageQueue.empty(); }); message = messageQueue.front(); messageQueue.pop(); @@ -882,7 +886,7 @@ CAPTUREDEVIDE_MESSAGE WindowsCaptureDevice::getMessage() { return message; } -void WindowsCaptureDevice::updateState(const CAPTUREDEVIDE_STATE &newState) { +void WindowsCaptureDevice::updateState(const CAPTUREDEVICE_STATE &newState) { state = newState; if (isShutDown()) { std::unique_lock guard(stateMutex_); @@ -891,52 +895,67 @@ void WindowsCaptureDevice::updateState(const CAPTUREDEVIDE_STATE &newState) { } void WindowsCaptureDevice::waitShutDown() { - sendMessage({ CAPTUREDEVIDE_COMMAND::SHUTDOWN, nullptr }); - - std::unique_lock guard(stateMutex_); - while (!isShutDown()) { - stateCond_.wait(guard); + _dbg_assert_(thread_.joinable()); + if (!thread_.joinable()) { + ERROR_LOG(Log::System, "Tried to wait for capture device thread, but not joinable."); + return; } + + sendMessage({ CAPTUREDEVICE_COMMAND::SHUTDOWN, nullptr }); + thread_.join(); } +// This is the main thread for the capture device. void WindowsCaptureDevice::messageHandler() { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - MFStartup(MF_VERSION); - CAPTUREDEVIDE_MESSAGE message; + SetCurrentThreadName(type == CAPTUREDEVICE_TYPE::AUDIO ? "AudioCapture" : "VideoCapture"); - if (type == CAPTUREDEVIDE_TYPE::VIDEO) { + if (!MFAPI::Startup) { + setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot register devices"); + return; + } + + HRESULT hr = ERROR_SUCCESS; + { + std::lock_guard lock(paramMutex); + hr = enumDevices(); + } + if (FAILED(hr)) { + setError(CAPTUREDEVIDE_ERROR_INIT_FAILED, "Cannot enumerate devices"); + return; + } + + updateState(CAPTUREDEVICE_STATE::STOPPED); + CAPTUREDEVICE_MESSAGE message; + + if (type == CAPTUREDEVICE_TYPE::VIDEO) { SetCurrentThreadName("Camera"); - } else if (type == CAPTUREDEVIDE_TYPE::Audio) { + } else if (type == CAPTUREDEVICE_TYPE::AUDIO) { SetCurrentThreadName("Microphone"); } - while ((message = getMessage()).command != CAPTUREDEVIDE_COMMAND::SHUTDOWN) { + while ((message = getMessage()).command != CAPTUREDEVICE_COMMAND::SHUTDOWN) { switch (message.command) { - case CAPTUREDEVIDE_COMMAND::INITIALIZE: - init(); - break; - case CAPTUREDEVIDE_COMMAND::START: + case CAPTUREDEVICE_COMMAND::START: start(message.opacity); break; - case CAPTUREDEVIDE_COMMAND::STOP: + case CAPTUREDEVICE_COMMAND::STOP: stop(); break; - case CAPTUREDEVIDE_COMMAND::UPDATE_STATE: - updateState((*(CAPTUREDEVIDE_STATE *)message.opacity)); + case CAPTUREDEVICE_COMMAND::UPDATE_STATE: + updateState((*(CAPTUREDEVICE_STATE *)message.opacity)); break; - case CAPTUREDEVIDE_COMMAND::SHUTDOWN: + case CAPTUREDEVICE_COMMAND::SHUTDOWN: break; } } - if (state != CAPTUREDEVIDE_STATE::STOPPED) + if (state != CAPTUREDEVICE_STATE::STOPPED) stop(); std::lock_guard lock(sdMutex); m_pSource = nullptr; m_pReader = nullptr; m_pCallback = nullptr; - unRegisterCMPTMFApis(); std::unique_lock lock2(paramMutex); for (DWORD i = 0; i < param.count; i++) { @@ -945,27 +964,24 @@ void WindowsCaptureDevice::messageHandler() { CoTaskMemFree(param.ppDevices); // Null pointer is okay. lock2.unlock(); - MFShutdown(); - CoUninitialize(); - - updateState(CAPTUREDEVIDE_STATE::SHUTDOWN); + updateState(CAPTUREDEVICE_STATE::SHUTDOWN); } HRESULT WindowsCaptureDevice::enumDevices() { HRESULT hr = S_OK; ComPtr pAttributes; - hr = MFCreateAttributes(&pAttributes, 1); + hr = MFAPI::CreateAttributes(&pAttributes, 1); if (SUCCEEDED(hr)) { switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: + case CAPTUREDEVICE_TYPE::VIDEO: hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ); break; - case CAPTUREDEVIDE_TYPE::Audio: + case CAPTUREDEVICE_TYPE::AUDIO: hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID @@ -978,7 +994,7 @@ HRESULT WindowsCaptureDevice::enumDevices() { } } if (SUCCEEDED(hr)) { - hr = EnumDeviceSources(pAttributes.Get(), ¶m.ppDevices, ¶m.count); + hr = MFAPI::EnumDeviceSources(pAttributes.Get(), ¶m.ppDevices, ¶m.count); } return hr; @@ -1020,7 +1036,7 @@ HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride) } if (SUCCEEDED(hr)) { - hr = GetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride); + hr = MFAPI::GetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride); } // Set the attribute for later reference. diff --git a/Windows/CaptureDevice.h b/Windows/CaptureDevice.h index c1575d92b4..81acd712ce 100644 --- a/Windows/CaptureDevice.h +++ b/Windows/CaptureDevice.h @@ -49,12 +49,12 @@ struct AudioFormatTransform { AVSampleFormat AVAudioFormat; }; -enum class CAPTUREDEVIDE_TYPE { +enum class CAPTUREDEVICE_TYPE { VIDEO, - Audio + AUDIO, }; -enum class CAPTUREDEVIDE_STATE { +enum class CAPTUREDEVICE_STATE { UNINITIALIZED, LOST, STOPPED, @@ -62,15 +62,14 @@ enum class CAPTUREDEVIDE_STATE { SHUTDOWN }; -enum class CAPTUREDEVIDE_COMMAND { - INITIALIZE, +enum class CAPTUREDEVICE_COMMAND { START, STOP, SHUTDOWN, UPDATE_STATE }; -enum CAPTUREDEVIDE_ERROR { +enum CAPTUREDEVICE_ERROR { CAPTUREDEVIDE_ERROR_NO_ERROR, CAPTUREDEVIDE_ERROR_UNKNOWN_TYPE = 0x80000001, CAPTUREDEVIDE_ERROR_INIT_FAILED, @@ -79,8 +78,8 @@ enum CAPTUREDEVIDE_ERROR { CAPTUREDEVIDE_ERROR_GETNAMES_FAILED }; -struct CAPTUREDEVIDE_MESSAGE{ - CAPTUREDEVIDE_COMMAND command; +struct CAPTUREDEVICE_MESSAGE { + CAPTUREDEVICE_COMMAND command; void *opacity; }; @@ -178,31 +177,30 @@ protected: class WindowsCaptureDevice { public: - WindowsCaptureDevice(CAPTUREDEVIDE_TYPE type); + WindowsCaptureDevice(CAPTUREDEVICE_TYPE type); ~WindowsCaptureDevice(); void CheckDevices(); - bool init(); bool start(void *startParam); bool stop(); - CAPTUREDEVIDE_ERROR getError() const { return error; } + CAPTUREDEVICE_ERROR getError() const { return error; } std::string getErrorMessage() const { return errorMessage; } int getDeviceCounts() const { return param.count; } // Get a list contained friendly device name. std::vector getDeviceList(bool forceEnum = false, int *pActuallCount = nullptr); - void setError(const CAPTUREDEVIDE_ERROR &newError, const std::string &newErrorMessage) { error = newError; errorMessage = newErrorMessage; } + void setError(const CAPTUREDEVICE_ERROR &newError, const std::string &newErrorMessage) { error = newError; errorMessage = newErrorMessage; } void setSelection(const UINT32 &selection) { param.selection = selection; } HRESULT setDeviceParam(IMFMediaType *pType); - bool isShutDown() const { return state == CAPTUREDEVIDE_STATE::SHUTDOWN; } - bool isStarted() const { return state == CAPTUREDEVIDE_STATE::STARTED; } + bool isShutDown() const { return state == CAPTUREDEVICE_STATE::SHUTDOWN; } + bool isStarted() const { return state == CAPTUREDEVICE_STATE::STARTED; } void waitShutDown(); - void sendMessage(CAPTUREDEVIDE_MESSAGE message); - CAPTUREDEVIDE_MESSAGE getMessage(); + void sendMessage(CAPTUREDEVICE_MESSAGE message); + CAPTUREDEVICE_MESSAGE getMessage(); HRESULT enumDevices(); @@ -211,49 +209,54 @@ public: friend class ReaderCallback; protected: - void updateState(const CAPTUREDEVIDE_STATE &newState); + void updateState(const CAPTUREDEVICE_STATE &newState); // Handle message here. void messageHandler(); - CAPTUREDEVIDE_TYPE type; + CAPTUREDEVICE_TYPE type; MediaParam deviceParam; MediaParam targetMediaParam; - CAPTUREDEVIDE_STATE state; + CAPTUREDEVICE_STATE state; ChooseDeviceParam param; - CAPTUREDEVIDE_ERROR error; + CAPTUREDEVICE_ERROR error; std::string errorMessage; bool isDeviceChanged = false; -// MF interface. + // MF interface. Microsoft::WRL::ComPtr m_pCallback; Microsoft::WRL::ComPtr m_pReader; Microsoft::WRL::ComPtr m_pSource; -// Message loop. + // Message loop. std::mutex mutex; std::condition_variable cond; - std::queue messageQueue; + std::queue messageQueue; -// For the shutdown event safety. + // For the shutdown event safety. std::mutex sdMutex; -// Param updating synchronously. + // Param updating synchronously. std::mutex paramMutex; std::mutex stateMutex_; std::condition_variable stateCond_; -// Camera only + // Camera only unsigned char *imageRGB = nullptr; int imgRGBLineSizes[4]{}; unsigned char *imageJpeg = nullptr; int imgJpegSize = 0; -//Microphone only + //Microphone only u8 *resampleBuf = nullptr; u32 resampleBufSize = 0; + + std::thread thread_; }; extern WindowsCaptureDevice *winCamera; extern WindowsCaptureDevice *winMic; + +bool RegisterCMPTMFApis(); +bool UnRegisterCMPTMFApis(); diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index dc415e0c67..ed8a0029ef 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -194,7 +194,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib true Windows @@ -233,7 +233,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib true $(OutDir)$(ProjectName).pdb @@ -267,7 +267,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib true $(OutDir)$(ProjectName).pdb @@ -303,7 +303,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories) $(OutDir)$(TargetName)$(TargetExt) true @@ -351,7 +351,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories) true Windows @@ -393,7 +393,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) true Windows @@ -1466,4 +1466,4 @@ - \ No newline at end of file + diff --git a/Windows/main.cpp b/Windows/main.cpp index c7ad0989c3..9d042ba757 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -68,6 +68,7 @@ #include "Windows/resource.h" #include "Windows/InputDevice.h" #include "Windows/MainWindow.h" +#include "Windows/CaptureDevice.h" #include "Windows/Debugger/Debugger_Disasm.h" #include "Windows/Debugger/Debugger_MemoryDlg.h" #include "Windows/Debugger/Debugger_VFPUDlg.h" @@ -1171,6 +1172,13 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin g_logManager.SetAllLogLevels(LogLevel::LDEBUG); } + // Media foundation + if (!RegisterCMPTMFApis()) { + ERROR_LOG(Log::System, "Failed to load Media Foundation functions"); + // Let's unregister again. + UnRegisterCMPTMFApis(); + } + ContextMenuInit(_hInstance); MainWindow::Init(_hInstance); MainWindow::Show(_hInstance); @@ -1252,6 +1260,8 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin DialogManager::DestroyAll(); timeEndPeriod(1); + UnRegisterCMPTMFApis(); + g_logManager.Shutdown(); WinMainCleanup(); diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 1ff3a1f3ea..52a171dc42 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -150,7 +150,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -183,7 +183,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -215,7 +215,7 @@ Console true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -248,7 +248,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -286,7 +286,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -323,7 +323,7 @@ true true true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) @@ -409,4 +409,4 @@ - \ No newline at end of file + diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 3b2320af93..13ac7577c7 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -142,7 +142,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -165,7 +165,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -188,7 +188,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -216,7 +216,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -245,7 +245,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -274,7 +274,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -342,4 +342,4 @@ - \ No newline at end of file +