void do_unregister( XAudio2_Output * p_instance ) { if ( InterlockedDecrement( ®istered ) == 0 ) { if (pEnumerator) { pEnumerator->UnregisterEndpointNotificationCallback( this ); pEnumerator->Release(); pEnumerator = NULL; } } EnterCriticalSection( &lock ); for ( std::vector<XAudio2_Output*>::iterator it = instances.begin(); it < instances.end(); ++it ) { if ( *it == p_instance ) { instances.erase( it ); break; } } LeaveCriticalSection( &lock ); }
HRESULT unregister_notification_callback(IMMNotificationClient *pClient) { HRESULT hr = S_OK; IMMDeviceEnumerator *pMMDeviceEnumerator; // activate a device enumerator hr = CoCreateInstance( __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator ); if (FAILED(hr)) { printf("CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\n", hr); return hr; } // get the default render endpoint hr = pMMDeviceEnumerator->UnregisterEndpointNotificationCallback(pClient); pMMDeviceEnumerator->Release(); if (FAILED(hr)) { printf("IMMDeviceEnumerator::UnregisterEndpointNotificationCallback failed: hr = 0x%08x\n", hr); return hr; } return S_OK; }
//----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT ) { // set up some xbmc specific relationships XBMC::Context context; //this can't be set from CAdvancedSettings::Initialize() because it will overwrite //the loglevel set with the --debug flag #ifdef _DEBUG g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG; g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG; #else g_advancedSettings.m_logLevel = LOG_LEVEL_NORMAL; g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL; #endif CLog::SetLogLevel(g_advancedSettings.m_logLevel); // Initializes CreateMiniDump to handle exceptions. win32_exception::set_version(g_infoManager.GetVersion()); SetUnhandledExceptionFilter( CreateMiniDump ); // check if Kodi is already running std::string appName = CSysInfo::GetAppName(); CreateMutex(NULL, FALSE, (appName + " Media Center").c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) { HWND m_hwnd = FindWindow(appName.c_str(), appName.c_str()); if(m_hwnd != NULL) { // switch to the running instance ShowWindow(m_hwnd,SW_RESTORE); SetForegroundWindow(m_hwnd); } return 0; } #ifndef HAS_DX if(CWIN32Util::GetDesktopColorDepth() < 32) { //FIXME: replace it by a SDL window for all ports MessageBox(NULL, "Desktop Color Depth isn't 32Bit", (appName + ": Fatal Error").c_str(), MB_OK|MB_ICONERROR); return 0; } #endif if((g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE2) == 0) { MessageBox(NULL, "No SSE2 support detected", (appName + ": Fatal Error").c_str(), MB_OK|MB_ICONERROR); return 0; } //Initialize COM CoInitializeEx(NULL, COINIT_MULTITHREADED); // Handle numeric values using the default/POSIX standard setlocale(LC_NUMERIC, "C"); // If the command line passed to WinMain, commandLine, is not "" we need // to process the command line arguments. // Note that commandLine does not include the program name and can be // equal to "" if no arguments were supplied. By contrast GetCommandLineW() // does include the program name and is never equal to "". g_advancedSettings.Initialize(); if (strlen(commandLine) != 0) { int argc; LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc); std::vector<std::string> strargvA; strargvA.resize(argc); const char** argv = (const char**) LocalAlloc(LMEM_FIXED, argc*sizeof(char*)); if (!argv) return 20; for (int i = 0; i < argc; i++) { g_charsetConverter.wToUTF8(argvW[i], strargvA[i]); argv[i] = strargvA[i].c_str(); } // Parse the arguments CAppParamParser appParamParser; appParamParser.Parse(argv, argc); // Clean up the storage we've used LocalFree(argvW); LocalFree(argv); } // Initialise Winsock WSADATA wd; WSAStartup(MAKEWORD(2,2), &wd); // use 1 ms timer precision - like SDL initialization used to do timeBeginPeriod(1); #ifdef XBMC_TRACK_EXCEPTIONS try { #endif // Create and run the app if(!g_application.Create()) { MessageBox(NULL, "ERROR: Unable to create application. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #ifdef XBMC_TRACK_EXCEPTIONS } catch (const XbmcCommons::UncheckedException &e) { e.LogThrowMessage("CApplication::Create()"); MessageBox(NULL, "ERROR: Unable to create application. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::Create()"); MessageBox(NULL, "ERROR: Unable to create application. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #endif #ifndef _DEBUG // we don't want to see the "no disc in drive" windows message box SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); #endif #ifdef XBMC_TRACK_EXCEPTIONS try { #endif if (!g_application.CreateGUI()) { MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #ifdef XBMC_TRACK_EXCEPTIONS } catch (const XbmcCommons::UncheckedException &e) { e.LogThrowMessage("CApplication::CreateGUI()"); MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::CreateGUI()"); MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #endif #ifdef XBMC_TRACK_EXCEPTIONS try { #endif if (!g_application.Initialize()) { MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #ifdef XBMC_TRACK_EXCEPTIONS } catch (const XbmcCommons::UncheckedException &e) { e.LogThrowMessage("CApplication::Initialize()"); MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::Initialize()"); MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", (appName + ": Error").c_str(), MB_OK|MB_ICONERROR); return 1; } #endif IMMDeviceEnumerator *pEnumerator = NULL; CMMNotificationClient cMMNC; HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); if(SUCCEEDED(hr)) { pEnumerator->RegisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } g_application.Run(); // clear previously set timer resolution timeEndPeriod(1); // the end hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); if(SUCCEEDED(hr)) { pEnumerator->UnregisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } WSACleanup(); CoUninitialize(); return 0; }
extern "C" int XBMC_Run(bool renderGUI) { int status = -1; if (!g_advancedSettings.Initialized()) { #ifdef _DEBUG g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG; g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG; #else g_advancedSettings.m_logLevel = LOG_LEVEL_NORMAL; g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL; #endif g_advancedSettings.Initialize(); } if (!g_application.Create()) { CMessagePrinter::DisplayError("ERROR: Unable to create application. Exiting"); return status; } #if defined(HAVE_BREAKPAD) // Must have our TEMP dir fixed first std::string tempPath = CSpecialProtocol::TranslatePath("special://temp/"); google_breakpad::MinidumpDescriptor descriptor(tempPath.c_str()); google_breakpad::ExceptionHandler eh(descriptor, NULL, NULL, NULL, true, -1); #endif #ifdef TARGET_RASPBERRY_PI if(!g_RBP.Initialize()) return false; g_RBP.LogFirmwareVerison(); #endif if (renderGUI && !g_application.CreateGUI()) { CMessagePrinter::DisplayError("ERROR: Unable to create GUI. Exiting"); return status; } if (!g_application.Initialize()) { CMessagePrinter::DisplayError("ERROR: Unable to Initialize. Exiting"); return status; } #ifdef TARGET_WINDOWS IMMDeviceEnumerator *pEnumerator = nullptr; CMMNotificationClient cMMNC; HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, reinterpret_cast<void**>(&pEnumerator)); if (SUCCEEDED(hr)) { pEnumerator->RegisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } #endif try { status = g_application.Run(); } #ifdef TARGET_WINDOWS catch (const XbmcCommons::UncheckedException &e) { e.LogThrowMessage("CApplication::Create()"); CMessagePrinter::DisplayError("ERROR: Exception caught on main loop. Exiting"); status = -1; } #endif catch(...) { CMessagePrinter::DisplayError("ERROR: Exception caught on main loop. Exiting"); status = -1; } #ifdef TARGET_WINDOWS // the end hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, reinterpret_cast<void**>(&pEnumerator)); if (SUCCEEDED(hr)) { pEnumerator->UnregisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } #endif #ifdef TARGET_RASPBERRY_PI g_RBP.Deinitialize(); #endif return status; }
extern "C" int XBMC_Run(bool renderGUI) { int status = -1; if (!g_advancedSettings.Initialized()) { #ifdef _DEBUG g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG; g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG; #else g_advancedSettings.m_logLevel = LOG_LEVEL_NORMAL; g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL; #endif g_advancedSettings.Initialize(); } if (!g_application.Create()) { CMessagePrinter::DisplayError("ERROR: Unable to create application. Exiting"); return status; } #ifdef TARGET_RASPBERRY_PI if(!g_RBP.Initialize()) return false; g_RBP.LogFirmwareVerison(); #endif if (renderGUI && !g_application.CreateGUI()) { CMessagePrinter::DisplayError("ERROR: Unable to create GUI. Exiting"); return status; } if (!g_application.Initialize()) { CMessagePrinter::DisplayError("ERROR: Unable to Initialize. Exiting"); return status; } #ifdef TARGET_WINDOWS IMMDeviceEnumerator *pEnumerator = nullptr; CMMNotificationClient cMMNC; HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, reinterpret_cast<void**>(&pEnumerator)); if (SUCCEEDED(hr)) { pEnumerator->RegisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } #endif try { status = g_application.Run(); } #ifdef TARGET_WINDOWS catch (const XbmcCommons::UncheckedException &e) { e.LogThrowMessage("CApplication::Create()"); CMessagePrinter::DisplayError("ERROR: Exception caught on main loop. Exiting"); status = -1; } #endif catch(...) { CMessagePrinter::DisplayError("ERROR: Exception caught on main loop. Exiting"); status = -1; } #ifdef TARGET_WINDOWS // the end hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, reinterpret_cast<void**>(&pEnumerator)); if (SUCCEEDED(hr)) { pEnumerator->UnregisterEndpointNotificationCallback(&cMMNC); SAFE_RELEASE(pEnumerator); } #endif #ifdef TARGET_RASPBERRY_PI g_RBP.Deinitialize(); #endif return status; }