void SettingsAdvanced::ApplySettings() { //precheck for QSV enable/disable in case the checkbox is currently enabled while no hardware support is found bool bHasQSV = CheckQSVHardwareSupport(false); bool bUseQSV = SendMessage(GetDlgItem(hwnd, IDC_USEQSV), BM_GETCHECK, 0, 0) == BST_CHECKED; bool bUseQSV_prev = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; if (!bHasQSV && !bUseQSV && bUseQSV_prev && MessageBox(hwnd, Str("Settings.Advanced.UseQSVDisabledAfterApply"), Str("MessageBoxWarningCaption"), MB_ICONEXCLAMATION | MB_OKCANCEL) != IDOK) { SetAbortApplySettings(true); return; } //precheck for NVENC enable/disable in case the checkbox is currently enabled while no hardware support is found bool bHasNVENC = CheckNVENCHardwareSupport(false); bool bUseNVENC = SendMessage(GetDlgItem(hwnd, IDC_USENVENC), BM_GETCHECK, 0, 0) == BST_CHECKED; bool bUseNVENC_prev = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseNVENC")) != 0; if (!bHasNVENC && !bUseNVENC && bUseNVENC_prev && MessageBox(hwnd, Str("Settings.Advanced.UseNVENCDisabledAfterApply"), Str("MessageBoxWarningCaption"), MB_ICONEXCLAMATION | MB_OKCANCEL) != IDOK) { SetAbortApplySettings(true); return; } //-------------------------------------------------- String strTemp = GetCBText(GetDlgItem(hwnd, IDC_PRESET)); AppConfig->SetString(TEXT("Video Encoding"), TEXT("Preset"), strTemp); //------------------------------------ strTemp = GetCBText(GetDlgItem(hwnd, IDC_X264PROFILE)); AppConfig->SetString(TEXT("Video Encoding"), TEXT("X264Profile"), strTemp); //-------------------------------------------------- bool bUseMTOptimizations = SendMessage(GetDlgItem(hwnd, IDC_USEMULTITHREADEDOPTIMIZATIONS), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), bUseMTOptimizations); int priority = (int)SendMessage(GetDlgItem(hwnd, IDC_PRIORITY), CB_GETCURSEL, 0, 0); switch (priority) { case 0: strTemp = TEXT("High"); break; case 1: strTemp = TEXT("Above Normal"); break; case 2: strTemp = TEXT("Normal"); break; case 3: strTemp = TEXT("Idle"); break; } AppConfig->SetString(TEXT("General"), TEXT("Priority"), strTemp); //-------------------------------------------------- UINT sceneBufferTime = (UINT)SendMessage(GetDlgItem(hwnd, IDC_SCENEBUFFERTIME), UDM_GETPOS32, 0, 0); GlobalConfig->SetInt(TEXT("General"), TEXT("SceneBufferingTime"), sceneBufferTime); //-------------------------------------------------- bool bDisablePreviewEncoding = SendMessage(GetDlgItem(hwnd, IDC_DISABLEPREVIEWENCODING), BM_GETCHECK, 0, 0) == BST_CHECKED; GlobalConfig->SetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), bDisablePreviewEncoding); //-------------------------------------------------- bool bAllowOtherHotkeyModifiers = SendMessage(GetDlgItem(hwnd, IDC_ALLOWOTHERHOTKEYMODIFIERS), BM_GETCHECK, 0, 0) == BST_CHECKED; GlobalConfig->SetInt(TEXT("General"), TEXT("AllowOtherHotkeyModifiers"), bAllowOtherHotkeyModifiers); //-------------------------------------------------- UINT keyframeInt = (UINT)SendMessage(GetDlgItem(hwnd, IDC_KEYFRAMEINTERVAL), UDM_GETPOS32, 0, 0); AppConfig->SetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), keyframeInt); //-------------------------------------------------- bool bUseCFR = SendMessage(GetDlgItem(hwnd, IDC_USECFR), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt (TEXT("Video Encoding"), TEXT("UseCFR"), bUseCFR); //-------------------------------------------------- BOOL bUseCustomX264Settings = SendMessage(GetDlgItem(hwnd, IDC_USEVIDEOENCODERSETTINGS), BM_GETCHECK, 0, 0) == BST_CHECKED; String strCustomX264Settings = GetEditText(GetDlgItem(hwnd, IDC_VIDEOENCODERSETTINGS)); AppConfig->SetInt (TEXT("Video Encoding"), TEXT("UseCustomSettings"), bUseCustomX264Settings); AppConfig->SetString(TEXT("Video Encoding"), TEXT("CustomSettings"), strCustomX264Settings); //-------------------------------------------------- BOOL bUnlockFPS = SendMessage(GetDlgItem(hwnd, IDC_UNLOCKHIGHFPS), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt (TEXT("Video"), TEXT("UnlockFPS"), bUnlockFPS); //------------------------------------ EnableWindow(GetDlgItem(hwnd, IDC_USEQSV), (bHasQSV || bUseQSV) && !bUseNVENC); AppConfig->SetInt(TEXT("Video Encoding"), TEXT("UseQSV"), bUseQSV); BOOL bQSVUseVideoEncoderSettings = SendMessage(GetDlgItem(hwnd, IDC_QSVUSEVIDEOENCODERSETTINGS), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt(TEXT("Video Encoding"), TEXT("QSVUseVideoEncoderSettings"), bQSVUseVideoEncoderSettings); //------------------------------------ EnableWindow(GetDlgItem(hwnd, IDC_USENVENC), (bHasNVENC || bUseNVENC) && !bUseQSV); AppConfig->SetInt(TEXT("Video Encoding"), TEXT("UseNVENC"), bUseNVENC && !bUseQSV); SendMessage(GetDlgItem(hwnd, IDC_USENVENC), BM_SETCHECK, (bUseNVENC && !bUseQSV) ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ BOOL bSyncToVideoTime = SendMessage(GetDlgItem(hwnd, IDC_SYNCTOVIDEOTIME), BM_GETCHECK, 0, 0) == BST_CHECKED; AppConfig->SetInt (TEXT("Audio"), TEXT("SyncToVideoTime"), bSyncToVideoTime); //-------------------------------------------------- BOOL bUseMicQPC = SendMessage(GetDlgItem(hwnd, IDC_USEMICQPC), BM_GETCHECK, 0, 0) == BST_CHECKED; GlobalConfig->SetInt(TEXT("Audio"), TEXT("UseMicQPC"), bUseMicQPC); //-------------------------------------------------- int globalAudioTimeAdjust = (int)SendMessage(GetDlgItem(hwnd, IDC_AUDIOTIMEADJUST), UDM_GETPOS32, 0, 0); GlobalConfig->SetInt(TEXT("Audio"), TEXT("GlobalAudioTimeAdjust"), globalAudioTimeAdjust); //-------------------------------------------------- BOOL bUseMicSyncFixHack = SendMessage(GetDlgItem(hwnd, IDC_MICSYNCFIX), BM_GETCHECK, 0, 0) == BST_CHECKED; GlobalConfig->SetInt(TEXT("Audio"), TEXT("UseMicSyncFixHack"), bUseMicSyncFixHack); //-------------------------------------------------- BOOL bLowLatencyAutoMode = SendMessage(GetDlgItem(hwnd, IDC_LATENCYMETHOD), BM_GETCHECK, 0, 0) == BST_CHECKED; int latencyFactor = GetDlgItemInt(hwnd, IDC_LATENCYTUNE, NULL, TRUE); AppConfig->SetInt (TEXT("Publish"), TEXT("LatencyFactor"), latencyFactor); AppConfig->SetInt (TEXT("Publish"), TEXT("LowLatencyMethod"), bLowLatencyAutoMode); //-------------------------------------------------- strTemp = GetCBText(GetDlgItem(hwnd, IDC_BINDIP)); AppConfig->SetString(TEXT("Publish"), TEXT("BindToIP"), strTemp); }
INT_PTR SettingsEncoding::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { HWND hwndTemp; LocalizeWindow(hwnd); //-------------------------------------------- bool showQSVConfigurationWarning = false; hasQSV = CheckQSVHardwareSupport(false, &showQSVConfigurationWarning); hasNVENC = CheckNVENCHardwareSupport(false); String vcodec = AppConfig->GetString(L"Video Encoding", L"Encoder"); bool useQSV = !!(vcodec == L"QSV"); bool useNVENC = !!(vcodec == L"NVENC"); bool usex264 = !useQSV && !useNVENC; SendMessage(GetDlgItem(hwnd, IDC_ENCODERX264), BM_SETCHECK, usex264, 0); SendMessage(GetDlgItem(hwnd, IDC_ENCODERQSV), BM_SETCHECK, useQSV, 0); SendMessage(GetDlgItem(hwnd, IDC_ENCODERNVENC), BM_SETCHECK, useNVENC, 0); EnableWindow(GetDlgItem(hwnd, IDC_ENCODERQSV), hasQSV || useQSV); EnableWindow(GetDlgItem(hwnd, IDC_ENCODERNVENC), hasNVENC || useNVENC); bool QSVOnUnsupportedWinVer = OSGetVersion() < 7 && IsKnownQSVCPUPlatform() && !hasQSV; ShowWindow(GetDlgItem(hwnd, IDC_QSV_WINVER_WARNING), QSVOnUnsupportedWinVer ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_QSV_CONFIG_WARNING), !QSVOnUnsupportedWinVer && showQSVConfigurationWarning ? SW_SHOW : SW_HIDE); //-------------------------------------------- HWND hwndToolTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, hinstMain, NULL); TOOLINFO ti; zero(&ti, sizeof(ti)); ti.cbSize = sizeof(ti); ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND; ti.hwnd = hwnd; if (LocaleIsRTL()) ti.uFlags |= TTF_RTLREADING; SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 500); SendMessage(hwndToolTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 8000); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_QUALITY); for(int i=0; i<=10; i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)IntString(i).Array()); LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("Quality"), TEXT("8")); ti.lpszText = (LPWSTR)Str("Settings.Encoding.Video.QualityTooltip"); ti.uId = (UINT_PTR)hwndTemp; SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //-------------------------------------------- bool bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0; bool bPadCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("PadCBR"), 1) != 0; SendMessage(GetDlgItem(hwnd, IDC_USECBR), BM_SETCHECK, bUseCBR ? BST_CHECKED : BST_UNCHECKED, 0); SendMessage(GetDlgItem(hwnd, IDC_PADCBR), BM_SETCHECK, bPadCBR ? BST_CHECKED : BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwnd, IDC_QUALITY), !bUseCBR && (usex264 || useNVENC)); EnableWindow(GetDlgItem(hwnd, IDC_PADCBR), bUseCBR && (usex264 || useNVENC)); ti.lpszText = (LPWSTR)Str("Settings.Advanced.PadCBRToolTip"); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_PADCBR); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //-------------------------------------------- int bitrate = LoadSettingEditInt(GetDlgItem(hwnd, IDC_MAXBITRATE), TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int buffersize = LoadSettingEditInt(GetDlgItem(hwnd, IDC_BUFFERSIZE), TEXT("Video Encoding"), TEXT("BufferSize"), 1000); ti.lpszText = (LPWSTR)Str("Settings.Encoding.Video.MaxBitRateTooltip"); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_MAXBITRATE); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); ti.lpszText = (LPWSTR)Str("Settings.Encoding.Video.BufferSizeTooltip"); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_BUFFERSIZE); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //-------------------------------------------- bool bUseBufferSize = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseBufferSize"), 0) != 0; SendMessage(GetDlgItem(hwnd, IDC_CUSTOMBUFFER), BM_SETCHECK, bUseBufferSize ? BST_CHECKED : BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwnd, IDC_BUFFERSIZE), bUseBufferSize); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOCODEC); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("MP3")); #ifdef USE_AAC if(1)//OSGetVersion() >= 7) { SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("AAC")); LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); } else LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Codec"), TEXT("MP3")); #else LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Codec"), TEXT("MP3")); #endif //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOFORMAT); BOOL isAAC = SendMessage(GetDlgItem(hwnd, IDC_AUDIOCODEC), CB_GETCURSEL, 0, 0) == 1; if (isAAC) { SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1kHz")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48kHz")); } else { SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1kHz")); } LoadSettingComboInt(hwndTemp, TEXT("Audio Encoding"), TEXT("Format"), 1, isAAC ? 1 : 0); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOCHANNEL); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("mono")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("stereo")); LoadSettingComboInt(hwndTemp, TEXT("Audio Encoding"), TEXT("isStereo"), 1, 1); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUDIOBITRATE); BOOL isStereo = SendMessage(GetDlgItem(hwnd, IDC_AUDIOCHANNEL), CB_GETCURSEL, 0, 0) == 1; if (isStereo) { SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("64")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("80")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("96"));//default SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("112")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("128")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("160")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("192")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("256")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("320")); } else { SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("32")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("40")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48"));//default SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("56")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("64")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("80")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("96")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("128")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("160")); } LoadSettingComboString(hwndTemp, TEXT("Audio Encoding"), TEXT("Bitrate"), isStereo ? TEXT("96") : TEXT("48")); //-------------------------------------------- ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); SetChangedSettings(false); return TRUE; } case WM_COMMAND: { bool bDataChanged = false; bool useQSV = SendMessage(GetDlgItem(hwnd, IDC_ENCODERQSV), BM_GETCHECK, 0, 0) == BST_CHECKED; bool useNVENC = SendMessage(GetDlgItem(hwnd, IDC_ENCODERNVENC), BM_GETCHECK, 0, 0) == BST_CHECKED; bool usex264 = !useQSV && !useNVENC; bool useCBR = SendMessage(GetDlgItem(hwnd, IDC_USECBR), BM_GETCHECK, 0, 0) == BST_CHECKED; switch(LOWORD(wParam)) { case IDC_QUALITY: case IDC_AUDIOBITRATE: if(HIWORD(wParam) == CBN_SELCHANGE) { bDataChanged = true; } break; case IDC_AUDIOFORMAT: if(HIWORD(wParam) == CBN_SELCHANGE) { bDataChanged = true; } break; case IDC_AUDIOCHANNEL: if(HIWORD(wParam) == CBN_SELCHANGE) { HWND hwndAudioBitrate = GetDlgItem(hwnd, IDC_AUDIOBITRATE); SendMessage(hwndAudioBitrate, CB_RESETCONTENT, 0, 0); BOOL isStereo = SendMessage(GetDlgItem(hwnd, IDC_AUDIOCHANNEL), CB_GETCURSEL, 0, 0) == 1; if (isStereo) { SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("48")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("64")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("80")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("96"));//default SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("112")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("128")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("160")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("192")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("256")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("320")); } else { SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("32")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("40")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("48"));//default SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("56")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("64")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("80")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("96")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("128")); SendMessage(hwndAudioBitrate, CB_ADDSTRING, 0, (LPARAM)TEXT("160")); } SendMessage(hwndAudioBitrate, CB_SETCURSEL, isStereo ? 3 : 2, 0); bDataChanged = true; } break; case IDC_AUDIOCODEC: if(HIWORD(wParam) == CBN_SELCHANGE) { HWND hwndAudioFormat = GetDlgItem(hwnd, IDC_AUDIOFORMAT); SendMessage(hwndAudioFormat, CB_RESETCONTENT, 0, 0); BOOL isAAC = SendMessage(GetDlgItem(hwnd, IDC_AUDIOCODEC), CB_GETCURSEL, 0, 0) == 1; if (isAAC) { SendMessage(hwndAudioFormat, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1kHz")); SendMessage(hwndAudioFormat, CB_ADDSTRING, 0, (LPARAM)TEXT("48kHz")); } else { SendMessage(hwndAudioFormat, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1kHz")); } SendMessage(hwndAudioFormat, CB_SETCURSEL, isAAC ? 1 : 0, 0); bDataChanged = true; } break; case IDC_MAXBITRATE: if(HIWORD(wParam) == EN_CHANGE) { bool bCustomBuffer = SendMessage(GetDlgItem(hwnd, IDC_CUSTOMBUFFER), BM_GETCHECK, 0, 0) == BST_CHECKED; if (!bCustomBuffer) { String strText = GetEditText((HWND)lParam); SetWindowText(GetDlgItem(hwnd, IDC_BUFFERSIZE), strText); } if (App->GetVideoEncoder() && App->GetVideoEncoder()->DynamicBitrateSupported()) SetChangedSettings(true); else bDataChanged = true; } break; case IDC_BUFFERSIZE: if (HIWORD(wParam) == EN_CHANGE) { if (App->GetVideoEncoder() && App->GetVideoEncoder()->DynamicBitrateSupported()) SetChangedSettings(true); else bDataChanged = true; } break; case IDC_ENCODERX264: case IDC_ENCODERQSV: case IDC_ENCODERNVENC: if (HIWORD(wParam) == BN_CLICKED) bDataChanged = true; EnableWindow(GetDlgItem(hwnd, IDC_QUALITY), !useCBR && (usex264 || useNVENC)); EnableWindow(GetDlgItem(hwnd, IDC_PADCBR), useCBR && (usex264 || useNVENC)); break; case IDC_CUSTOMBUFFER: case IDC_USECBR: case IDC_PADCBR: if (HIWORD(wParam) == BN_CLICKED) { bool bChecked = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; if(LOWORD(wParam) == IDC_CUSTOMBUFFER) EnableWindow(GetDlgItem(hwnd, IDC_BUFFERSIZE), bChecked); else if(LOWORD(wParam) == IDC_USECBR) { EnableWindow(GetDlgItem(hwnd, IDC_QUALITY), !bChecked && (usex264 || useNVENC)); EnableWindow(GetDlgItem(hwnd, IDC_PADCBR), bChecked && (usex264 || useNVENC)); } bDataChanged = true; } break; } if(bDataChanged) { if (App->GetVideoEncoder()) ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; } } return FALSE; }
INT_PTR SettingsAdvanced::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //-------------------------------------------- HWND hwndToolTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, hinstMain, NULL); TOOLINFO ti; zero(&ti, sizeof(ti)); ti.cbSize = sizeof(ti); ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND; ti.hwnd = hwnd; SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 500); SendMessage(hwndToolTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 14000); //------------------------------------ UINT sceneBufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 700); SendMessage(GetDlgItem(hwnd, IDC_SCENEBUFFERTIME), UDM_SETRANGE32, 60, 20000); SendMessage(GetDlgItem(hwnd, IDC_SCENEBUFFERTIME), UDM_SETPOS32, 0, sceneBufferingTime); //------------------------------------ bool bUseMTOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0; SendMessage(GetDlgItem(hwnd, IDC_USEMULTITHREADEDOPTIMIZATIONS), BM_SETCHECK, bUseMTOptimizations ? BST_CHECKED : BST_UNCHECKED, 0); HWND hwndTemp = GetDlgItem(hwnd, IDC_PRIORITY); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Advanced.Priority.High")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Advanced.Priority.AboveNormal")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Advanced.Priority.Normal")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Advanced.Priority.Idle")); CTSTR pStr = AppConfig->GetStringPtr(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (scmpi(pStr, TEXT("Idle")) == 0) SendMessage(hwndTemp, CB_SETCURSEL, 3, 0); else if (scmpi(pStr, TEXT("Above Normal")) == 0) SendMessage(hwndTemp, CB_SETCURSEL, 1, 0); else if (scmpi(pStr, TEXT("High")) == 0) SendMessage(hwndTemp, CB_SETCURSEL, 0, 0); else //Normal SendMessage(hwndTemp, CB_SETCURSEL, 2, 0); //------------------------------------ bool bDisablePreviewEncoding = GlobalConfig->GetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), false) != 0; SendMessage(GetDlgItem(hwnd, IDC_DISABLEPREVIEWENCODING), BM_SETCHECK, bDisablePreviewEncoding ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ bool bAllowOtherHotkeyModifiers = GlobalConfig->GetInt(TEXT("General"), TEXT("AllowOtherHotkeyModifiers"), true) != 0; SendMessage(GetDlgItem(hwnd, IDC_ALLOWOTHERHOTKEYMODIFIERS), BM_SETCHECK, bAllowOtherHotkeyModifiers ? BST_CHECKED : BST_UNCHECKED, 0); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_X264PROFILE); static const CTSTR profile_names[3] = {TEXT("main"), TEXT("high")}; for(int i=0; i<2; i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)profile_names[i]); LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("X264Profile"), TEXT("high")); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_PRESET); static const CTSTR preset_names[8] = {TEXT("ultrafast"), TEXT("superfast"), TEXT("veryfast"), TEXT("faster"), TEXT("fast"), TEXT("medium"), TEXT("slow"), TEXT("slower")}; for(int i=0; i<8; i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)preset_names[i]); LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); ti.lpszText = (LPWSTR)Str("Settings.Advanced.VideoEncoderCPUTradeoffTooltip"); ti.uId = (UINT_PTR)hwndTemp; SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //------------------------------------ bool bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 1) != 0; SendMessage(GetDlgItem(hwnd, IDC_USECFR), BM_SETCHECK, bUseCFR ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ bool bUseCustomX264Settings = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings")) != 0; String strX264Settings = AppConfig->GetString(TEXT("Video Encoding"), TEXT("CustomSettings")); SendMessage(GetDlgItem(hwnd, IDC_USEVIDEOENCODERSETTINGS), BM_SETCHECK, bUseCustomX264Settings ? BST_CHECKED : BST_UNCHECKED, 0); SetWindowText(GetDlgItem(hwnd, IDC_VIDEOENCODERSETTINGS), strX264Settings); ti.lpszText = (LPWSTR)Str("Settings.Advanced.VideoEncoderSettingsTooltip"); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_VIDEOENCODERSETTINGS); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_USEVIDEOENCODERSETTINGS); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); EnableWindow(GetDlgItem(hwnd, IDC_VIDEOENCODERSETTINGS), bUseCustomX264Settings); //-------------------------------------------- UINT keyframeInt = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0); SendMessage(GetDlgItem(hwnd, IDC_KEYFRAMEINTERVAL), UDM_SETRANGE32, 0, 20); SendMessage(GetDlgItem(hwnd, IDC_KEYFRAMEINTERVAL), UDM_SETPOS32, 0, keyframeInt); //-------------------------------------------- bool bUnlockFPS = AppConfig->GetInt(TEXT("Video"), TEXT("UnlockFPS")) != 0; SendMessage(GetDlgItem(hwnd, IDC_UNLOCKHIGHFPS), BM_SETCHECK, bUnlockFPS ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ bool bHasQSV = CheckQSVHardwareSupport(false); bool bUseQSV = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; bool bHasNVENC = CheckNVENCHardwareSupport(false); bool bUseNVENC = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseNVENC")) != 0; EnableWindow(GetDlgItem(hwnd, IDC_USEQSV), (bHasQSV || bUseQSV) && !bUseNVENC); SendMessage(GetDlgItem(hwnd, IDC_USEQSV), BM_SETCHECK, bUseQSV ? BST_CHECKED : BST_UNCHECKED, 0); bool bQSVUseVideoEncoderSettings = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("QSVUseVideoEncoderSettings")) != 0; SendMessage(GetDlgItem(hwnd, IDC_QSVUSEVIDEOENCODERSETTINGS), BM_SETCHECK, bQSVUseVideoEncoderSettings ? BST_CHECKED : BST_UNCHECKED, 0); ti.lpszText = (LPWSTR)Str("Settings.Advanced.QSVUseVideoEncoderSettingsTooltip"); ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_QSVUSEVIDEOENCODERSETTINGS); SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); EnableWindow(GetDlgItem(hwnd, IDC_QSVUSEVIDEOENCODERSETTINGS), bUseQSV && !bUseNVENC); EnableWindow(GetDlgItem(hwnd, IDC_USENVENC), (bHasNVENC || bUseNVENC) && !bUseQSV); SendMessage(GetDlgItem(hwnd, IDC_USENVENC), BM_SETCHECK, bUseNVENC ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ bool bSyncToVideoTime = AppConfig->GetInt(TEXT("Audio"), TEXT("SyncToVideoTime")) != 0; SendMessage(GetDlgItem(hwnd, IDC_SYNCTOVIDEOTIME), BM_SETCHECK, bSyncToVideoTime ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ bool bUseMicQPC = GlobalConfig->GetInt(TEXT("Audio"), TEXT("UseMicQPC")) != 0; SendMessage(GetDlgItem(hwnd, IDC_USEMICQPC), BM_SETCHECK, bUseMicQPC ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ BOOL bMicSyncFixHack = GlobalConfig->GetInt(TEXT("Audio"), TEXT("UseMicSyncFixHack")); SendMessage(GetDlgItem(hwnd, IDC_MICSYNCFIX), BM_SETCHECK, bMicSyncFixHack ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ int bufferTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 700); int globalAudioTimeAdjust = GlobalConfig->GetInt(TEXT("Audio"), TEXT("GlobalAudioTimeAdjust")); SendMessage(GetDlgItem(hwnd, IDC_AUDIOTIMEADJUST), UDM_SETRANGE32, -bufferTime, 5000); SendMessage(GetDlgItem(hwnd, IDC_AUDIOTIMEADJUST), UDM_SETPOS32, 0, globalAudioTimeAdjust); //------------------------------------ int lowLatencyFactor = AppConfig->GetInt(TEXT("Publish"), TEXT("LatencyFactor"), 20); SetDlgItemInt(hwnd, IDC_LATENCYTUNE, lowLatencyFactor, TRUE); int bLowLatencyAutoMethod = AppConfig->GetInt(TEXT("Publish"), TEXT("LowLatencyMethod"), 0); SendMessage(GetDlgItem(hwnd, IDC_LATENCYMETHOD), BM_SETCHECK, bLowLatencyAutoMethod ? BST_CHECKED : BST_UNCHECKED, 0); //------------------------------------ MIB_IPADDRTABLE tempTable; DWORD dwSize = 0; if (GetIpAddrTable (&tempTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER) { PMIB_IPADDRTABLE ipTable; ipTable = (PMIB_IPADDRTABLE)Allocate(dwSize); if (GetIpAddrTable (ipTable, &dwSize, TRUE) == NO_ERROR) { DWORD i; hwndTemp = GetDlgItem(hwnd, IDC_BINDIP); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Default")); for (i=0; i < ipTable->dwNumEntries; i++) { String strAddress; DWORD strLength = 32; // don't allow binding to localhost if ((ipTable->table[i].dwAddr & 0xFF) == 127) continue; strAddress.SetLength(strLength); SOCKADDR_IN IP; IP.sin_addr.S_un.S_addr = ipTable->table[i].dwAddr; IP.sin_family = AF_INET; IP.sin_port = 0; zero(&IP.sin_zero, sizeof(IP.sin_zero)); WSAAddressToString ((LPSOCKADDR)&IP, sizeof(IP), NULL, strAddress.Array(), &strLength); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)strAddress.Array()); } LoadSettingComboString(hwndTemp, TEXT("Publish"), TEXT("BindToIP"), TEXT("Default")); } Free(ipTable); } //need this as some of the dialog item sets above trigger the notifications ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); SetChangedSettings(false); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_USEVIDEOENCODERSETTINGS: if(HIWORD(wParam) == BN_CLICKED) { BOOL bUseVideoEncoderSettings = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; EnableWindow(GetDlgItem(hwnd, IDC_VIDEOENCODERSETTINGS), bUseVideoEncoderSettings); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; case IDC_KEYFRAMEINTERVAL_EDIT: case IDC_SCENEBUFFERTIME_EDIT: case IDC_AUDIOTIMEADJUST_EDIT: case IDC_VIDEOENCODERSETTINGS: case IDC_LATENCYTUNE: if(HIWORD(wParam) == EN_CHANGE) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; /*case IDC_TIMER1: case IDC_TIMER2: case IDC_TIMER3: case IDC_DISABLED3DCOMPATIBILITY: if(HIWORD(wParam) == BN_CLICKED) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break;*/ case IDC_USESENDBUFFER: if(HIWORD(wParam) == BN_CLICKED) { BOOL bUseSendBuffer = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; EnableWindow(GetDlgItem(hwnd, IDC_SENDBUFFERSIZE), bUseSendBuffer); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; case IDC_PRESET: if(HIWORD(wParam) == CBN_SELCHANGE) { HWND hwndTemp = (HWND)lParam; String strNewPreset = GetCBText(hwndTemp); if (scmp(strNewPreset.Array(), TEXT("veryfast"))) { static BOOL bHasWarned = FALSE; if (!bHasWarned && MessageBox(hwnd, Str("Settings.Advanced.PresetWarning"), NULL, MB_ICONEXCLAMATION | MB_YESNO) == IDNO) LoadSettingComboString(hwndTemp, TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); else bHasWarned = TRUE; } SetChangedSettings(true); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); } break; case IDC_X264PROFILE: case IDC_SENDBUFFERSIZE: case IDC_PRIORITY: case IDC_BINDIP: if(HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; case IDC_USEQSV: case IDC_USENVENC: if (HIWORD(wParam) == BN_CLICKED) { bool bHasQSV = CheckQSVHardwareSupport(false); bool bHasNVENC = CheckNVENCHardwareSupport(false); bool bUseQSV = SendMessage(GetDlgItem(hwnd, IDC_USEQSV), BM_GETCHECK, 0, 0) == BST_CHECKED; bool bUseNVENC = SendMessage(GetDlgItem(hwnd, IDC_USENVENC), BM_GETCHECK, 0, 0) == BST_CHECKED; bool bUseQSV_prev = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; bool bUseNVENC_prev = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseNVENC")) != 0; EnableWindow(GetDlgItem(hwnd, IDC_QSVUSEVIDEOENCODERSETTINGS), (bHasQSV || bUseQSV) && !bUseNVENC); EnableWindow(GetDlgItem(hwnd, IDC_USEQSV), !bUseNVENC && (bHasQSV || bUseQSV_prev)); EnableWindow(GetDlgItem(hwnd, IDC_USENVENC), !bUseQSV && (bHasNVENC || bUseNVENC_prev)); } case IDC_DISABLEPREVIEWENCODING: case IDC_ALLOWOTHERHOTKEYMODIFIERS: case IDC_MICSYNCFIX: case IDC_USEMICQPC: case IDC_SYNCTOVIDEOTIME: case IDC_USECFR: case IDC_USEMULTITHREADEDOPTIMIZATIONS: case IDC_UNLOCKHIGHFPS: case IDC_LATENCYMETHOD: case IDC_QSVUSEVIDEOENCODERSETTINGS: if(HIWORD(wParam) == BN_CLICKED) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; } } return FALSE; }
void OBS::Start() { if(bRunning) return; bStartingUp = true; OSEnterMutex (hStartupShutdownMutex); scenesConfig.Save(); //------------------------------------------------------------- fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30); frameTime = 1000/fps; //------------------------------------------------------------- if(!bLoggedSystemStats) { LogSystemStats(); bLoggedSystemStats = TRUE; } OSCheckForBuggyDLLs(); //------------------------------------------------------------- retryHookTest: bool alreadyWarnedAboutModules = false; if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (pre-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { OSLeaveMutex (hStartupShutdownMutex); bStartingUp = false; return; } else if (ret == IDRETRY) { goto retryHookTest; } alreadyWarnedAboutModules = true; } String strPatchesError; if (OSIncompatiblePatchesLoaded(strPatchesError)) { OSLeaveMutex (hStartupShutdownMutex); MessageBox(hwndMain, strPatchesError.Array(), NULL, MB_ICONERROR); Log(TEXT("Incompatible patches detected.")); bStartingUp = false; return; } //------------------------------------------------------------- String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (!scmp(processPriority, TEXT("Idle"))) SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("Above Normal"))) SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("High"))) SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); DWORD delayTime = (DWORD)AppConfig->GetInt(TEXT("Publish"), TEXT("Delay")); String strError; bFirstConnect = !bReconnecting; if(bTestStream) network = CreateNullNetwork(); else { switch(networkMode) { case 0: network = (delayTime > 0) ? CreateDelayedPublisher(delayTime) : CreateRTMPPublisher(); break; case 1: network = CreateNullNetwork(); break; } } if(!network) { OSLeaveMutex (hStartupShutdownMutex); if(!bReconnecting) MessageBox(hwndMain, strError, NULL, MB_ICONERROR); else DialogBox(hinstMain, MAKEINTRESOURCE(IDD_RECONNECTING), hwndMain, OBS::ReconnectDialogProc); bStartingUp = false; return; } bReconnecting = false; //------------------------------------------------------------- Log(TEXT("=====Stream Start: %s==============================================="), CurrentDateTimeString().Array()); //------------------------------------------------------------- bEnableProjectorCursor = GlobalConfig->GetInt(L"General", L"EnableProjectorCursor", 1) != 0; bPleaseEnableProjector = bPleaseDisableProjector = false; int monitorID = AppConfig->GetInt(TEXT("Video"), TEXT("Monitor")); if(monitorID >= (int)monitors.Num()) monitorID = 0; RECT &screenRect = monitors[monitorID].rect; int defCX = screenRect.right - screenRect.left; int defCY = screenRect.bottom - screenRect.top; downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0); downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX); baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY); baseCX = MIN(MAX(baseCX, 128), 4096); baseCY = MIN(MAX(baseCY, 128), 4096); scaleCX = UINT(double(baseCX) / double(downscale)); scaleCY = UINT(double(baseCY) / double(downscale)); //align width to 128bit for fast SSE YUV4:2:0 conversion outputCX = scaleCX & 0xFFFFFFFC; outputCY = scaleCY & 0xFFFFFFFE; bUseMultithreadedOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0; Log(TEXT(" Multithreaded optimizations: %s"), (CTSTR)(bUseMultithreadedOptimizations ? TEXT("On") : TEXT("Off"))); encoderSkipThreshold = GlobalConfig->GetInt(TEXT("Video"), TEXT("EncoderSkipThreshold"), fps/4); //------------------------------------------------------------------ Log(TEXT(" Base resolution: %ux%u"), baseCX, baseCY); Log(TEXT(" Output resolution: %ux%u"), outputCX, outputCY); Log(TEXT("------------------------------------------")); //------------------------------------------------------------------ GS = new D3D10System; GS->Init(); //Thanks to ASUS OSD hooking the goddamn user mode driver framework (!!!!), we have to re-check for dangerous //hooks after initializing D3D. retryHookTestV2: if (!alreadyWarnedAboutModules) { if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (post-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { //FIXME: really need a better way to abort startup than this... delete network; delete GS; OSLeaveMutex (hStartupShutdownMutex); bStartingUp = false; return; } else if (ret == IDRETRY) { goto retryHookTestV2; } } } //------------------------------------------------------------- mainVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader")); mainPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawTexture.pShader")); solidVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader")); solidPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader")); if(!mainVertexShader || !mainPixelShader) CrashError(TEXT("Unable to load DrawTexture shaders")); if(!solidVertexShader || !solidPixelShader) CrashError(TEXT("Unable to load DrawSolid shaders")); //------------------------------------------------------------------ CTSTR lpShader; if(CloseFloat(downscale, 1.0)) lpShader = TEXT("shaders/DrawYUVTexture.pShader"); else if(downscale < 2.01) { switch(downscaleType) { case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break; case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break; case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break; } } else if(downscale < 3.01) lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader"); else CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)")); yuvScalePixelShader = CreatePixelShaderFromFile(lpShader); if (!yuvScalePixelShader) CrashError(TEXT("Unable to create shader from file %s"), lpShader); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { mainRenderTextures[i] = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE); yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE); } //------------------------------------------------------------- D3D10_TEXTURE2D_DESC td; zero(&td, sizeof(td)); td.Width = outputCX; td.Height = outputCY; td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; td.MipLevels = 1; td.ArraySize = 1; td.SampleDesc.Count = 1; td.ArraySize = 1; td.Usage = D3D10_USAGE_STAGING; td.CPUAccessFlags = D3D10_CPU_ACCESS_READ; for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { HRESULT err = GetD3D()->CreateTexture2D(&td, NULL, ©Textures[i]); if(FAILED(err)) { CrashError(TEXT("Unable to create copy texture")); //todo - better error handling } } //------------------------------------------------------------------ String strEncoder = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); BOOL isAAC = strEncoder.CompareI(TEXT("AAC")); UINT format = AppConfig->GetInt(L"Audio Encoding", L"Format", 1); if (!isAAC) format = 0; switch (format) { case 0: sampleRateHz = 44100; break; default: case 1: sampleRateHz = 48000; break; } Log(L"------------------------------------------"); Log(L"Audio Format: %uhz", sampleRateHz); //------------------------------------------------------------------ AudioDeviceList playbackDevices; bool useInputDevices = AppConfig->GetInt(L"Audio", L"UseInputDevices", false) != 0; GetAudioDevices(playbackDevices, useInputDevices ? ADT_RECORDING : ADT_PLAYBACK); String strPlaybackDevice = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); if(strPlaybackDevice.IsEmpty() || !playbackDevices.HasID(strPlaybackDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); strPlaybackDevice = TEXT("Default"); } Log(TEXT("Playback device %s"), strPlaybackDevice.Array()); playbackDevices.FreeData(); desktopAudio = CreateAudioSource(false, strPlaybackDevice); if(!desktopAudio) { CrashError(TEXT("Cannot initialize desktop audio sound, more info in the log file.")); } AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING, false, true); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); String strDefaultMic; bool bHasDefault = GetDefaultMicID(strDefaultMic); if(strDevice.CompareI(TEXT("Disable"))) EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); else { bool bUseDefault = strDevice.CompareI(TEXT("Default")) != 0; if(!bUseDefault || bHasDefault) { if(bUseDefault) strDevice = strDefaultMic; micAudio = CreateAudioSource(true, strDevice); if(!micAudio) MessageBox(hwndMain, Str("MicrophoneFailure"), NULL, 0); else micAudio->SetTimeOffset(AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0)); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), micAudio != NULL); } else EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); } //------------------------------------------------------------- bool bDisableEncoding = false; if (bTestStream) bDisableEncoding = GlobalConfig->GetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), false) != 0; //------------------------------------------------------------- UINT bitRate = (UINT)AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96); if (bDisableEncoding) audioEncoder = CreateNullAudioEncoder(); else #ifdef USE_AAC if(isAAC) // && OSGetVersion() >= 7) audioEncoder = CreateAACEncoder(bitRate); else #endif audioEncoder = CreateMP3Encoder(bitRate); //------------------------------------------------------------- desktopVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("DesktopVolume"), 1.0f); micVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("MicVolume"), 1.0f); //------------------------------------------------------------- bRunning = true; if(sceneElement) { scene = CreateScene(sceneElement->GetString(TEXT("class")), sceneElement->GetElement(TEXT("data"))); XElement *sources = sceneElement->GetElement(TEXT("sources")); if(sources) { UINT numSources = sources->NumElements(); for(UINT i=0; i<numSources; i++) { SceneItem *item = scene->AddImageSource(sources->GetElementByID(i)); if(item) { if(ListView_GetItemState(GetDlgItem(hwndMain, ID_SOURCES), i, LVIS_SELECTED) > 0) item->Select(true); } } } scene->BeginScene(); unsigned int numSources = scene->sceneItems.Num(); for(UINT i=0; i<numSources; i++) { XElement *source = scene->sceneItems[i]->GetElement(); String className = source->GetString(TEXT("class")); if(scene->sceneItems[i]->bRender && className == "GlobalSource") { XElement *globalSourceData = source->GetElement(TEXT("data")); String globalSourceName = globalSourceData->GetString(TEXT("name")); if(App->GetGlobalSource(globalSourceName) != NULL) { App->GetGlobalSource(globalSourceName)->GlobalSourceEnterScene(); } } } } if(scene && scene->HasMissingSources()) MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0); //------------------------------------------------------------- int maxBitRate = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int bufferSize = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("BufferSize"), 1000); int quality = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Quality"), 8); String preset = AppConfig->GetString(TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); bUsing444 = false;//AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Use444"), 0) != 0; bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 1) != 0; //------------------------------------------------------------- bufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 700); Log(TEXT("Scene buffering time set to %u"), bufferingTime); //------------------------------------------------------------- bForceMicMono = AppConfig->GetInt(TEXT("Audio"), TEXT("ForceMicMono")) != 0; bRecievedFirstAudioFrame = false; //hRequestAudioEvent = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL); hSoundDataMutex = OSCreateMutex(); hSoundThread = OSCreateThread((XTHREAD)OBS::MainAudioThread, NULL); //------------------------------------------------------------- if (!useInputDevices) StartBlankSoundPlayback(strPlaybackDevice); //------------------------------------------------------------- colorDesc.fullRange = false; colorDesc.primaries = ColorPrimaries_BT709; colorDesc.transfer = ColorTransfer_IEC6196621; colorDesc.matrix = outputCX >= 1280 || outputCY > 576 ? ColorMatrix_BT709 : ColorMatrix_SMPTE170M; videoEncoder = nullptr; if (bDisableEncoding) videoEncoder = CreateNullVideoEncoder(); else if(AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0) videoEncoder = CreateQSVEncoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR); else if(CheckNVENCHardwareSupport(true) && AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseNVENC")) != 0) videoEncoder = CreateNVENCEncoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR); if(!videoEncoder) videoEncoder = CreateX264Encoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR); //------------------------------------------------------------- // Ensure that the render frame is properly sized ResizeRenderFrame(true); //------------------------------------------------------------- StartRecording(); //------------------------------------------------------------- curFramePic = NULL; bShutdownVideoThread = false; bShutdownEncodeThread = false; //ResetEvent(hVideoThread); hEncodeThread = OSCreateThread((XTHREAD)OBS::EncodeThread, NULL); hVideoThread = OSCreateThread((XTHREAD)OBS::MainCaptureThread, NULL); if(bTestStream) { EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.StopTest")); } else { EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StopStream")); } EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), TRUE); //------------------------------------------------------------- ReportStartStreamTrigger(); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0); SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED | ES_DISPLAY_REQUIRED); UpdateRenderViewMessage(); //update notification icon to reflect current status UpdateNotificationAreaIcon(); OSLeaveMutex (hStartupShutdownMutex); bStartingUp = false; }