Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}