config.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:44k
源码类别:

Audio

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * config.c: vfw x264 encoder
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 Laurent Aimar
  5.  * $Id: config.c,v 1.1 2004/06/03 19:27:09 fenrir Exp $
  6.  *
  7.  * Authors: Justin Clay
  8.  *          Laurent Aimar <fenrir@via.ecp.fr>
  9.  *          Antony Boucher <proximodo@free.fr>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24.  *****************************************************************************/
  25. /**************************************************************************
  26.  *
  27.  *  History:
  28.  *
  29.  *  2004.05.14  CBR encode mode support
  30.  *
  31.  **************************************************************************/
  32. #include "x264vfw.h"
  33. #include <stdio.h>  /* sprintf */
  34. #include <commctrl.h>
  35. #ifdef _MSC_VER
  36. #define X264_VERSION ""
  37. #else
  38. #include "config.h"
  39. #endif
  40. /* Registry */
  41. #define X264_REG_KEY    HKEY_CURRENT_USER
  42. #define X264_REG_PARENT "Software\GNU"
  43. #define X264_REG_CHILD  "x264"
  44. #define X264_REG_CLASS  "config"
  45. /* window controls */
  46. #define BITRATE_MAX        5000
  47. #define QUANT_MAX        51
  48. /* description */
  49. #define X264_NAME        "x264"
  50. #define X264_DEF_TEXT    "Are you sure you want to load default values?"
  51. /* Registery handling */
  52. typedef struct
  53. {
  54.     char *reg_value;
  55.     int  *config_int;
  56.     int  default_int;
  57. } reg_int_t;
  58. typedef struct
  59. {
  60.     char *reg_value;
  61.     char *config_str;
  62.     char *default_str;
  63.     int max_len;  /* maximum string length, including the terminating NULL char */
  64. } reg_str_t;
  65. CONFIG reg;
  66. HWND hTooltip;
  67. HWND hTabs[8];
  68. static const reg_int_t reg_int_table[] =
  69. {
  70.     /* Main dialog */
  71.     { "bitrate",        &reg.bitrate,         800 },
  72.     { "quantizer",      &reg.i_qp,             26 },
  73.     { "encoding_type",  &reg.i_encoding_type,   1 },
  74.     { "passbitrate",    &reg.i_2passbitrate,  800 },
  75.     { "pass_number",    &reg.i_pass,            1 },
  76.     { "fast1pass",      &reg.b_fast1pass,       1 },
  77.     { "updatestats",    &reg.b_updatestats,     1 },
  78.     /* Rate Control */
  79.     { "key_boost",      &reg.i_key_boost,      40 },
  80.     { "b_red",          &reg.i_b_red,          30 },
  81.     { "curve_comp",     &reg.i_curve_comp,     60 },
  82.     { "qp_min",         &reg.i_qp_min,         10 },
  83.     { "qp_max",         &reg.i_qp_max,         51 },
  84.     { "qp_step",        &reg.i_qp_step,         4 },
  85.     { "scenecut",       &reg.i_scenecut_threshold, 40 },
  86.     { "keyint_min",     &reg.i_keyint_min,     25 },
  87.     { "keyint_max",     &reg.i_keyint_max,    250 },
  88.     /* MBs&Frames */
  89.     { "dct8x8",         &reg.b_dct8x8,          1 },
  90.     { "psub16x16",      &reg.b_psub16x16,       1 },
  91.     { "bsub16x16",      &reg.b_bsub16x16,       1 },
  92.     { "psub8x8",        &reg.b_psub8x8,         0 },
  93.     { "i8x8",           &reg.b_i8x8,            1 },
  94.     { "i4x4",           &reg.b_i4x4,            1 },
  95.     { "bmax",           &reg.i_bframe,          2 },
  96.     { "b_bias",         &reg.i_bframe_bias,     0 },
  97.     { "b_refs",         &reg.b_b_refs,          0 },
  98.     { "b_adapt",        &reg.b_bframe_adaptive, 1 },
  99.     { "b_bidir_me",     &reg.b_bidir_me,        0 },
  100.     { "b_wpred",        &reg.b_b_wpred,         1 },
  101.     { "direct_pred",    &reg.i_direct_mv_pred,  1 },
  102.     /* analysis */
  103.     { "subpel",         &reg.i_subpel_refine,   4 },
  104.     { "me_method",      &reg.i_me_method,       1 },
  105.     { "me_range",       &reg.i_me_range,       16 },
  106.     { "chroma_me",      &reg.b_chroma_me,       1 },
  107.     { "refmax",         &reg.i_refmax,          1 },
  108.     { "mixedref",       &reg.b_mixedref,        0 },
  109.     { "sar_width",      &reg.i_sar_width,       1 },
  110.     { "sar_height",     &reg.i_sar_height,      1 },
  111.     { "threads",        &reg.i_threads,         1 },
  112.     { "cabac",          &reg.b_cabac,           1 },
  113.     { "trellis",        &reg.i_trellis,         1 },
  114.     { "noise_reduction",&reg.i_noise_reduction, 0 },
  115.     { "loop_filter",    &reg.b_filter,          1 },
  116.     { "inloop_a",       &reg.i_inloop_a,        0 },
  117.     { "inloop_b",       &reg.i_inloop_b,        0 },
  118.     { "log_level",      &reg.i_log_level,       1 }
  119. };
  120. static const reg_str_t reg_str_table[] =
  121. {
  122.     { "fourcc",         reg.fcc,         "H264",                5 },
  123.     { "statsfile",      reg.stats,       ".\x264.stats",       MAX_PATH-4 } // -4 because we add pass number
  124. };
  125. static void set_dlgitem_int(HWND hDlg, UINT item, int value)
  126. {
  127.     char buf[8];
  128.     sprintf(buf, "%i", value);
  129.     SetDlgItemText(hDlg, item, buf);
  130. }
  131. /* Registry access */
  132. void config_reg_load( CONFIG *config )
  133. {
  134.     HKEY    hKey;
  135.     DWORD   i_size;
  136.     int     i;
  137.     RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT "\" X264_REG_CHILD,
  138.                   0, KEY_READ, &hKey );
  139.     /* Read all integers */
  140.     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
  141.     {
  142.         i_size = sizeof( int );
  143.         if( RegQueryValueEx( hKey, reg_int_table[i].reg_value, 0, 0,
  144.                              (LPBYTE)reg_int_table[i].config_int,
  145.                              &i_size ) != ERROR_SUCCESS )
  146.             *reg_int_table[i].config_int = reg_int_table[i].default_int;
  147.     }
  148.     /* Read strings */
  149.     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
  150.     {
  151.         i_size = reg_str_table[i].max_len;
  152.         if( RegQueryValueEx( hKey, reg_str_table[i].reg_value, 0, 0,
  153.                              (LPBYTE)reg_str_table[i].config_str,
  154.                              &i_size ) != ERROR_SUCCESS )
  155.             lstrcpy( reg_str_table[i].config_str,
  156.                      reg_str_table[i].default_str );
  157.     }
  158.     RegCloseKey( hKey );
  159.     memcpy( config, &reg, sizeof( CONFIG ) );
  160. }
  161. void config_reg_save( CONFIG *config )
  162. {
  163.     HKEY    hKey;
  164.     DWORD   i_size;
  165.     int     i;
  166.     if( RegCreateKeyEx( X264_REG_KEY,
  167.                         X264_REG_PARENT "\" X264_REG_CHILD,
  168.                         0,
  169.                         X264_REG_CLASS,
  170.                         REG_OPTION_NON_VOLATILE,
  171.                         KEY_WRITE,
  172.                         0, &hKey, &i_size ) != ERROR_SUCCESS )
  173.         return;
  174.     memcpy( &reg, config, sizeof( CONFIG ) );
  175.     /* Save all integers */
  176.     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
  177.     {
  178.         RegSetValueEx( hKey, reg_int_table[i].reg_value, 0, REG_DWORD,
  179.                        (LPBYTE)reg_int_table[i].config_int, sizeof( int ) );
  180.     }
  181.     /* Save strings */
  182.     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
  183.     {
  184.         RegSetValueEx( hKey, reg_str_table[i].reg_value, 0, REG_SZ,
  185.                        (LPBYTE)reg_str_table[i].config_str,
  186.                        lstrlen(reg_str_table[i].config_str)+1 );
  187.     }
  188.     RegCloseKey( hKey );
  189. }
  190. void config_reg_defaults( CONFIG *config )
  191. {
  192.     HKEY hKey;
  193.     if(RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT, 0, KEY_ALL_ACCESS, &hKey )) {
  194.         return;
  195.     }
  196.     if( RegDeleteKey( hKey, X264_REG_CHILD ) ) {
  197.         return;
  198.     }
  199.     RegCloseKey( hKey );
  200.     /* Just in case */
  201.     memset( config, 0, sizeof( CONFIG ) );
  202.     config_reg_load( config );
  203.     config_reg_save( config );
  204. }
  205. /* assigns tooltips */
  206. BOOL CALLBACK enum_tooltips(HWND hWnd, LPARAM lParam)
  207. {
  208.     char help[500];
  209. /* The tooltip for a control is named the same as the control itself */
  210.     if (LoadString(g_hInst, GetDlgCtrlID(hWnd), help, 500))
  211.     {
  212.         TOOLINFO ti;
  213.         ti.cbSize = sizeof(TOOLINFO);
  214.         ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
  215.         ti.hwnd = GetParent(hWnd);
  216.         ti.uId  = (LPARAM)hWnd;
  217.         ti.lpszText = help;
  218.         SendMessage(hTooltip, TTM_ADDTOOL, 0, (LPARAM)&ti);
  219.     }
  220.     return TRUE;
  221. }
  222. /* Main window */
  223. BOOL CALLBACK callback_main( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  224. {
  225.     TCITEM tie;
  226.     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
  227.     switch( uMsg )
  228.     {
  229.     case WM_INITDIALOG :
  230.         {
  231.             RECT rect;
  232.             HWND hTabCtrl = GetDlgItem( hDlg, IDC_TAB1 );
  233.             SetWindowLong( hDlg, GWL_USERDATA, lParam );
  234.             config = (CONFIG*)lParam;
  235.             // insert tabs in tab control
  236.             tie.mask = TCIF_TEXT;
  237.             tie.iImage = -1;
  238.             tie.pszText = "Bitrate";         TabCtrl_InsertItem(hTabCtrl, 0, &tie);
  239.             tie.pszText = "Rate Control";    TabCtrl_InsertItem(hTabCtrl, 1, &tie);
  240.             tie.pszText = "MBs&&Frames";     TabCtrl_InsertItem(hTabCtrl, 2, &tie);
  241.             tie.pszText = "More...";         TabCtrl_InsertItem(hTabCtrl, 3, &tie);
  242.             hTabs[0] = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_TAB_BITRATE),     hDlg, (DLGPROC)callback_tabs, lParam);
  243.             hTabs[1] = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_TAB_RATECONTROL), hDlg, (DLGPROC)callback_tabs, lParam);
  244.             hTabs[2] = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_TAB_IPFRAMES),    hDlg, (DLGPROC)callback_tabs, lParam);
  245.             hTabs[3] = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_TAB_MISC),        hDlg, (DLGPROC)callback_tabs, lParam);
  246.             GetClientRect(hDlg, &rect);
  247.             TabCtrl_AdjustRect(hTabCtrl, FALSE, &rect);
  248.             MoveWindow(hTabs[0], rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top-40, TRUE);
  249.             MoveWindow(hTabs[1], rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top-40, TRUE);
  250.             MoveWindow(hTabs[2], rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top-40, TRUE);
  251.             MoveWindow(hTabs[3], rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top-40, TRUE);
  252.             if ((hTooltip = CreateWindow(TOOLTIPS_CLASS, NULL, TTS_ALWAYSTIP,
  253.                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  254.                 NULL, NULL, g_hInst, NULL)))
  255.             {
  256.                 SetWindowPos(hTooltip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  257.                 SendMessage(hTooltip, TTM_SETMAXTIPWIDTH, 0, 400);
  258.                 EnumChildWindows(hDlg, enum_tooltips, 0);
  259.             }
  260.             tabs_enable_items( hDlg, config );
  261.             tabs_update_items( hDlg, config );
  262.             ShowWindow( hTabs[0], SW_SHOW );
  263.             BringWindowToTop( hTabs[0] );
  264.             UpdateWindow( hDlg );
  265.             break;
  266.         }
  267.     case WM_NOTIFY:
  268.         {
  269.             NMHDR FAR *tem = (NMHDR FAR *)lParam;
  270.             if (tem->code == TCN_SELCHANGING)
  271.             {
  272.                 HWND hTabCtrl = GetDlgItem( hDlg, IDC_TAB1 );
  273.                 int num = TabCtrl_GetCurSel(hTabCtrl);
  274.                 ShowWindow( hTabs[num], SW_HIDE );
  275.                 UpdateWindow( hDlg );
  276.             }
  277.             else if (tem->code == TCN_SELCHANGE)
  278.             {
  279.                 HWND hTabCtrl = GetDlgItem( hDlg, IDC_TAB1 );
  280.                 int num = TabCtrl_GetCurSel(hTabCtrl);
  281.                 ShowWindow( hTabs[num], SW_SHOW );
  282.                 BringWindowToTop( hTabs[num] );
  283.                 UpdateWindow( hDlg );
  284.             }
  285.             break;
  286.         }
  287.     case WM_COMMAND:
  288.         switch ( HIWORD( wParam ) )
  289.         {
  290.         case BN_CLICKED :
  291.             switch( LOWORD( wParam ) )
  292.             {
  293.             case IDOK :
  294.                 config->b_save = TRUE;
  295.                 EndDialog( hDlg, LOWORD(wParam) );
  296.                 break;
  297.             case IDCANCEL :
  298.                 config->b_save = FALSE;
  299.                 EndDialog( hDlg, LOWORD(wParam) );
  300.                 break;
  301.             case IDC_DEFAULTS :
  302.                 if( MessageBox( hDlg, X264_DEF_TEXT, X264_NAME, MB_YESNO ) == IDYES )
  303.                 {
  304.                     config_reg_defaults( config );
  305.                     tabs_enable_items( hDlg, config );
  306.                     tabs_update_items( hDlg, config );
  307.                 }
  308.                 break;
  309.             }
  310.         }
  311.     default :
  312.         return 0;
  313.     }
  314.     return 1;
  315. }
  316. /* Tabs */
  317. void tabs_enable_items( HWND hDlg, CONFIG * config )
  318. {
  319.     char szTmp[1024];
  320.     sprintf( szTmp, "Core %d%s, build %s %s", X264_BUILD, X264_VERSION, __DATE__, __TIME__ );
  321.     SetDlgItemText( hTabs[0], IDC_BUILDREV,  szTmp );
  322.     switch( config->i_encoding_type )
  323.     {
  324.     case 0 : /* 1 Pass, Bitrate Based */
  325.         SetDlgItemText( hTabs[0], IDC_BITRATELABEL, "Average Bitrate" );
  326.         SetDlgItemText( hTabs[0], IDC_BITRATELOW, "0" );
  327.         sprintf(szTmp, "%d", BITRATE_MAX);
  328.         SetDlgItemText( hTabs[0], IDC_BITRATEHIGH, szTmp );
  329.         SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETRANGE, TRUE,
  330.                             (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
  331.         EnableWindow( GetDlgItem( hTabs[0], IDC_UPDATESTATS ), FALSE );
  332.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE ), FALSE );
  333.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE_BROWSE ), FALSE );
  334.         EnableWindow( GetDlgItem( hTabs[1], IDC_CURVECOMP ), TRUE );
  335.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMIN ), TRUE );
  336.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMAX ), TRUE );
  337.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPSTEP ), TRUE );
  338.         break;
  339.     case 1 : /* 1 Pass, Quantizer Based */
  340.         SetDlgItemText( hTabs[0], IDC_BITRATELABEL, "Quantizer" );
  341.         SetDlgItemText( hTabs[0], IDC_BITRATELOW, "0 (High Quality)" );
  342.         sprintf(szTmp, "(Low Quality) %d", QUANT_MAX);
  343.         SetDlgItemText( hTabs[0], IDC_BITRATEHIGH, szTmp );
  344.         SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETRANGE, TRUE,
  345.                             (LPARAM) MAKELONG( 0, QUANT_MAX ) );
  346.         EnableWindow( GetDlgItem( hTabs[0], IDC_UPDATESTATS ), FALSE );
  347.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE ), FALSE );
  348.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE_BROWSE ), FALSE );
  349.         EnableWindow( GetDlgItem( hTabs[1], IDC_CURVECOMP ), FALSE );
  350.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMIN ), FALSE );
  351.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMAX ), FALSE );
  352.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPSTEP ), FALSE );
  353.         break;
  354.     case 2 : /* 2 Pass */
  355.         SetDlgItemText( hTabs[0], IDC_BITRATELABEL, "Target Bitrate" );
  356.         SetDlgItemText( hTabs[0], IDC_BITRATELOW, "0" );
  357.         sprintf(szTmp, "%d", BITRATE_MAX);
  358.         SetDlgItemText( hTabs[0], IDC_BITRATEHIGH, szTmp );
  359.         SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETRANGE, TRUE,
  360.                             (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
  361.         EnableWindow( GetDlgItem( hTabs[0], IDC_UPDATESTATS ), TRUE );
  362.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE ), TRUE );
  363.         EnableWindow( GetDlgItem( hTabs[0], IDC_STATSFILE_BROWSE ), TRUE );
  364.         EnableWindow( GetDlgItem( hTabs[1], IDC_CURVECOMP ), TRUE );
  365.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMIN ), TRUE );
  366.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPMAX ), TRUE );
  367.         EnableWindow( GetDlgItem( hTabs[1], IDC_QPSTEP ), TRUE );
  368.         break;
  369.     }
  370.     EnableWindow( GetDlgItem( hTabs[2], IDC_DIRECTPRED  ), config->i_bframe > 0 );
  371.     EnableWindow( GetDlgItem( hTabs[3], IDC_INLOOP_A    ), config->b_filter );
  372.     EnableWindow( GetDlgItem( hTabs[3], IDC_INLOOP_B    ), config->b_filter );
  373.     EnableWindow( GetDlgItem( hTabs[2], IDC_P4X4        ), config->b_psub16x16 );
  374.     EnableWindow( GetDlgItem( hTabs[2], IDC_I8X8        ), config->b_dct8x8 );
  375.     EnableWindow( GetDlgItem( hTabs[2], IDC_B8X8        ), config->i_bframe > 0 );
  376.     EnableWindow( GetDlgItem( hTabs[2], IDC_BREFS       ), config->i_bframe > 1 );
  377.     EnableWindow( GetDlgItem( hTabs[2], IDC_WBPRED      ), config->i_bframe > 1 );
  378.     EnableWindow( GetDlgItem( hTabs[2], IDC_BADAPT      ), config->i_bframe > 0 );
  379.     EnableWindow( GetDlgItem( hTabs[2], IDC_BIDIR_ME    ), config->i_bframe > 0 );
  380.     EnableWindow( GetDlgItem( hTabs[2], IDC_BBIAS       ), config->i_bframe > 0 && config->b_bframe_adaptive );
  381.     EnableWindow( GetDlgItem( hTabs[2], IDC_BBIASSLIDER ), config->i_bframe > 0 && config->b_bframe_adaptive );
  382.     EnableWindow( GetDlgItem( hTabs[1], IDC_PBRATIO     ), config->i_bframe > 0 );
  383.     EnableWindow( GetDlgItem( hTabs[3], IDC_MERANGE     ), config->i_me_method > 1 );
  384.     EnableWindow( GetDlgItem( hTabs[3], IDC_CHROMAME    ), config->i_subpel_refine >= 4 );
  385.     EnableWindow( GetDlgItem( hTabs[3], IDC_TRELLIS     ), config->b_cabac );
  386.     EnableWindow( GetDlgItem( hTabs[3], IDC_MIXEDREF    ), config->i_refmax > 1 );
  387. }
  388. void tabs_update_items( HWND hDlg, CONFIG * config )
  389. {
  390.     char fourcc[5];
  391.     /* update bitrate tab */
  392.     if (SendMessage( GetDlgItem(hTabs[0],IDC_BITRATEMODE), CB_GETCOUNT, 0, 0 ) == 0)
  393.     {
  394.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_ADDSTRING, 0, (LPARAM)"Single Pass - Bitrate");
  395.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_ADDSTRING, 0, (LPARAM)"Single Pass - Quantizer");
  396.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_ADDSTRING, 0, (LPARAM)"Multipass - First Pass");
  397.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_ADDSTRING, 0, (LPARAM)"Multipass - First Pass (fast)");
  398.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_ADDSTRING, 0, (LPARAM)"Multipass - Nth Pass");
  399.     }
  400.     switch( config->i_encoding_type )
  401.     {
  402.     case 0 : /* 1 Pass, Bitrate Based */
  403.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_SETCURSEL, 0, 0);
  404.         SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->bitrate, FALSE );
  405.         SendDlgItemMessage(hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE,
  406.                            config->bitrate );
  407.         break;
  408.     case 1 : /* 1 Pass, Quantizer Based */
  409.         SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_SETCURSEL, 1, 0);
  410.         SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->i_qp, FALSE );
  411.         SendDlgItemMessage(hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE,
  412.                            config->i_qp );
  413.         break;
  414.     case 2 : /* 2 Pass */
  415.         if (config->i_pass >= 2) {
  416.             SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_SETCURSEL, 4, 0);
  417.         } else if (config->b_fast1pass) {
  418.             SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_SETCURSEL, 3, 0);
  419.         } else {
  420.             SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_SETCURSEL, 2, 0);
  421.         }
  422.         SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->i_2passbitrate, FALSE );
  423.         SendDlgItemMessage(hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE,
  424.                            config->i_2passbitrate );
  425.         break;
  426.     }
  427.     CheckDlgButton( hTabs[0], IDC_UPDATESTATS, config->b_updatestats ? BST_CHECKED : BST_UNCHECKED );
  428.     SetDlgItemText( hTabs[0], IDC_STATSFILE, config->stats );
  429.     /* update rate control tab */
  430.     if (SendMessage( GetDlgItem(hTabs[2],IDC_DIRECTPRED), CB_GETCOUNT, 0, 0 ) == 0)
  431.     {
  432.         SendDlgItemMessage(hTabs[2], IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Spatial");
  433.         SendDlgItemMessage(hTabs[2], IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Temporal");
  434.     }
  435.     SetDlgItemInt( hTabs[1], IDC_QPMIN, config->i_qp_min, FALSE );
  436.     SetDlgItemInt( hTabs[1], IDC_QPMAX, config->i_qp_max, FALSE );
  437.     SetDlgItemInt( hTabs[1], IDC_QPSTEP, config->i_qp_step, FALSE );
  438.     SetDlgItemInt( hTabs[1], IDC_IPRATIO, config->i_key_boost, FALSE );
  439.     SetDlgItemInt( hTabs[1], IDC_PBRATIO, config->i_b_red, FALSE );
  440.     SetDlgItemInt( hTabs[1], IDC_CURVECOMP, config->i_curve_comp, FALSE );
  441.     /* update debug tab */
  442.     if (SendMessage( GetDlgItem(hTabs[3],IDC_LOG), CB_GETCOUNT, 0, 0 ) == 0)
  443.     {
  444.         SendDlgItemMessage(hTabs[3], IDC_LOG, CB_ADDSTRING, 0, (LPARAM)"None");
  445.         SendDlgItemMessage(hTabs[3], IDC_LOG, CB_ADDSTRING, 0, (LPARAM)"Error");
  446.         SendDlgItemMessage(hTabs[3], IDC_LOG, CB_ADDSTRING, 0, (LPARAM)"Warning");
  447.         SendDlgItemMessage(hTabs[3], IDC_LOG, CB_ADDSTRING, 0, (LPARAM)"Info");
  448.         SendDlgItemMessage(hTabs[3], IDC_LOG, CB_ADDSTRING, 0, (LPARAM)"Debug");
  449.     }
  450.     SendDlgItemMessage(hTabs[3], IDC_LOG, CB_SETCURSEL, (config->i_log_level), 0);
  451.     memcpy( fourcc, config->fcc, 4 );
  452.     fourcc[4] = '';
  453.     SetDlgItemText( hTabs[3], IDC_FOURCC, fourcc );
  454.     /* update misc. tab */
  455.     SetDlgItemInt( hTabs[3], IDC_THREADEDIT, config->i_threads, FALSE );
  456.     SetDlgItemInt( hTabs[3], IDC_NR, config->i_noise_reduction, FALSE );
  457.     CheckDlgButton( hTabs[3],IDC_CABAC,
  458.                     config->b_cabac ? BST_CHECKED : BST_UNCHECKED );
  459.     CheckDlgButton( hTabs[3],IDC_TRELLIS,
  460.                     config->i_trellis ? BST_CHECKED: BST_UNCHECKED );
  461.     CheckDlgButton( hTabs[3],IDC_LOOPFILTER,
  462.                     config->b_filter ? BST_CHECKED: BST_UNCHECKED );
  463.     SetDlgItemInt( hTabs[3], IDC_SAR_W, config->i_sar_width,  FALSE );
  464.     SetDlgItemInt( hTabs[3], IDC_SAR_H, config->i_sar_height, FALSE );
  465.     SendDlgItemMessage( hTabs[3], IDC_INLOOP_A, TBM_SETRANGE, TRUE,
  466.                         (LPARAM) MAKELONG( -6, 6 ) );
  467.     SendDlgItemMessage( hTabs[3], IDC_INLOOP_A, TBM_SETPOS, TRUE,
  468.                         config->i_inloop_a );
  469.     set_dlgitem_int( hTabs[3], IDC_LOOPA_TXT, config->i_inloop_a);
  470.     SendDlgItemMessage( hTabs[3], IDC_INLOOP_B, TBM_SETRANGE, TRUE,
  471.                         (LPARAM) MAKELONG( -6, 6 ) );
  472.     SendDlgItemMessage( hTabs[3], IDC_INLOOP_B, TBM_SETPOS, TRUE,
  473.                         config->i_inloop_b );
  474.     set_dlgitem_int( hTabs[3], IDC_LOOPB_TXT, config->i_inloop_b);
  475.     /* update i/p-frames tab */
  476.     CheckDlgButton( hTabs[2],IDC_P8X8,
  477.                     config->b_psub16x16 ? BST_CHECKED: BST_UNCHECKED );
  478.     CheckDlgButton( hTabs[2],IDC_P4X4,
  479.                     config->b_psub8x8 ? BST_CHECKED: BST_UNCHECKED );
  480.     CheckDlgButton( hTabs[2],IDC_I4X4,
  481.                     config->b_i4x4 ? BST_CHECKED: BST_UNCHECKED );
  482.     CheckDlgButton( hTabs[2],IDC_I8X8,
  483.                     config->b_i8x8 ? BST_CHECKED: BST_UNCHECKED );
  484.     CheckDlgButton( hTabs[2],IDC_DCT8X8,
  485.                     config->b_dct8x8 ? BST_CHECKED: BST_UNCHECKED );
  486.     /* update b-frames tab */
  487.     CheckDlgButton( hTabs[2],IDC_WBPRED,
  488.                     config->b_b_wpred ? BST_CHECKED: BST_UNCHECKED );
  489.     CheckDlgButton( hTabs[2],IDC_BADAPT,
  490.                     config->b_bframe_adaptive ? BST_CHECKED: BST_UNCHECKED );
  491.     CheckDlgButton( hTabs[2],IDC_BIDIR_ME,
  492.                     config->b_bidir_me ? BST_CHECKED: BST_UNCHECKED );
  493.     CheckDlgButton( hTabs[2],IDC_BREFS,
  494.                     config->b_b_refs ? BST_CHECKED: BST_UNCHECKED );
  495.     CheckDlgButton( hTabs[2],IDC_B8X8,
  496.                     config->b_bsub16x16 ? BST_CHECKED: BST_UNCHECKED );
  497.     SetDlgItemInt( hTabs[2], IDC_BFRAME, config->i_bframe, FALSE );
  498.     SetDlgItemInt( hTabs[2], IDC_BBIAS, config->i_bframe_bias, TRUE );
  499.     SendDlgItemMessage( hTabs[2], IDC_BBIASSLIDER, TBM_SETRANGE, TRUE,
  500.                         (LPARAM) MAKELONG( -100, 100 ) );
  501.     SendDlgItemMessage( hTabs[2], IDC_BBIASSLIDER, TBM_SETPOS, TRUE,
  502.                         config->i_bframe_bias );
  503.     SendDlgItemMessage(hTabs[2], IDC_DIRECTPRED, CB_SETCURSEL, (config->i_direct_mv_pred), 0);
  504.     /* update scene-cuts tab */
  505.     SetDlgItemInt( hTabs[1], IDC_KEYINTMIN, config->i_keyint_min, FALSE );
  506.     SetDlgItemInt( hTabs[1], IDC_KEYINTMAX, config->i_keyint_max, FALSE );
  507.     SetDlgItemInt( hTabs[1], IDC_SCENECUT, config->i_scenecut_threshold, TRUE );
  508.     /* update motion estimation tab */
  509.     if (SendMessage( GetDlgItem(hTabs[3],IDC_ME_METHOD), CB_GETCOUNT, 0, 0 ) == 0)
  510.     {
  511.         SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_ADDSTRING, 0, (LPARAM)"Diamond Search");
  512.         SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_ADDSTRING, 0, (LPARAM)"Hexagonal Search");
  513.         SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_ADDSTRING, 0, (LPARAM)"Uneven Multi-Hexagon");
  514.         SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_ADDSTRING, 0, (LPARAM)"Exhaustive Search");
  515.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"1 (Fastest)");
  516.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"2");
  517.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"3");
  518.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"4");
  519.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"5 (High Quality)");
  520.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"6 (RDO)");
  521.         SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"6b (RDO on B-frames)");
  522.     }
  523.     SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_SETCURSEL, (config->i_me_method), 0);
  524.     SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_SETCURSEL, (config->i_subpel_refine), 0);
  525.     SetDlgItemInt( hTabs[3], IDC_MERANGE, config->i_me_range, FALSE );
  526.     CheckDlgButton( hTabs[3],IDC_CHROMAME,
  527.                     config->b_chroma_me ? BST_CHECKED: BST_UNCHECKED );
  528.     SetDlgItemInt( hTabs[3], IDC_REFFRAMES, config->i_refmax, FALSE );
  529.     CheckDlgButton( hTabs[3],IDC_MIXEDREF,
  530.                     config->b_mixedref ? BST_CHECKED: BST_UNCHECKED );
  531. }
  532. BOOL CALLBACK callback_tabs( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  533. {
  534.     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
  535.     switch( uMsg )
  536.     {
  537.     case WM_INITDIALOG :
  538.         SetWindowLong( hDlg, GWL_USERDATA, lParam );
  539.         config = (CONFIG*)lParam;
  540.         break;
  541.     case WM_COMMAND:
  542.         switch ( HIWORD( wParam ) )
  543.         {
  544.         case BN_CLICKED :
  545.             switch( LOWORD( wParam ) )
  546.             {
  547.             case IDC_CABAC :
  548.                 config->b_cabac = ( IsDlgButtonChecked( hTabs[3], IDC_CABAC ) == BST_CHECKED );
  549.                 break;
  550.             case IDC_TRELLIS :
  551.                 config->i_trellis = ( IsDlgButtonChecked( hTabs[3], IDC_TRELLIS ) == BST_CHECKED );
  552.                 break;
  553.             case IDC_LOOPFILTER :
  554.                 config->b_filter = ( IsDlgButtonChecked( hTabs[3], IDC_LOOPFILTER ) == BST_CHECKED );
  555.                 break;
  556.             case IDC_BREFS :
  557.                 config->b_b_refs = ( IsDlgButtonChecked( hTabs[2], IDC_BREFS ) == BST_CHECKED );
  558.                 break;
  559.             case IDC_WBPRED :
  560.                 config->b_b_wpred = ( IsDlgButtonChecked( hTabs[2], IDC_WBPRED ) == BST_CHECKED );
  561.                 break;
  562.             case IDC_BADAPT :
  563.                 config->b_bframe_adaptive = ( IsDlgButtonChecked( hTabs[2], IDC_BADAPT ) == BST_CHECKED );
  564.                 break;
  565.             case IDC_BIDIR_ME :
  566.                 config->b_bidir_me = ( IsDlgButtonChecked( hTabs[2], IDC_BIDIR_ME ) == BST_CHECKED );
  567.                 break;
  568.             case IDC_P8X8 :
  569.                 config->b_psub16x16 = ( IsDlgButtonChecked( hTabs[2], IDC_P8X8 ) == BST_CHECKED );
  570.                 break;
  571.             case IDC_P4X4 :
  572.                 config->b_psub8x8 = ( IsDlgButtonChecked( hTabs[2], IDC_P4X4 ) == BST_CHECKED );
  573.                 break;
  574.             case IDC_B8X8 :
  575.                 config->b_bsub16x16 = ( IsDlgButtonChecked( hTabs[2], IDC_B8X8 ) == BST_CHECKED );
  576.                 break;
  577.             case IDC_I4X4 :
  578.                 config->b_i4x4 = ( IsDlgButtonChecked( hTabs[2], IDC_I4X4 ) == BST_CHECKED );
  579.                 break;
  580.             case IDC_I8X8 :
  581.                 config->b_i8x8 = ( IsDlgButtonChecked( hTabs[2], IDC_I8X8 ) == BST_CHECKED );
  582.                 break;
  583.             case IDC_DCT8X8 :
  584.                 config->b_dct8x8 = ( IsDlgButtonChecked( hTabs[2], IDC_DCT8X8 ) == BST_CHECKED );
  585.                 break;
  586.             case IDC_MIXEDREF :
  587.                 config->b_mixedref = ( IsDlgButtonChecked( hTabs[3], IDC_MIXEDREF ) == BST_CHECKED );
  588.                 break;
  589.             case IDC_CHROMAME :
  590.                 config->b_chroma_me = ( IsDlgButtonChecked( hTabs[3], IDC_CHROMAME ) == BST_CHECKED );
  591.                 break;
  592.             case IDC_UPDATESTATS :
  593.                 config->b_updatestats = ( IsDlgButtonChecked( hTabs[0], IDC_UPDATESTATS ) == BST_CHECKED );
  594.                 break;
  595.             case IDC_STATSFILE_BROWSE :
  596.                 {
  597.                 OPENFILENAME ofn;
  598.                 char tmp[MAX_PATH];
  599.                 GetDlgItemText( hTabs[0], IDC_STATSFILE, tmp, MAX_PATH );
  600.                 memset( &ofn, 0, sizeof( OPENFILENAME ) );
  601.                 ofn.lStructSize = sizeof( OPENFILENAME );
  602.                 ofn.hwndOwner = hDlg;
  603.                 ofn.lpstrFilter = "Statsfile (*.stats)*.statsAll files (*.*)*.*";
  604.                 ofn.lpstrFile = tmp;
  605.                 ofn.nMaxFile = MAX_PATH-4;
  606.                 ofn.Flags = OFN_PATHMUSTEXIST;
  607.                 if( config->i_pass == 1 )
  608.                     ofn.Flags |= OFN_OVERWRITEPROMPT;
  609.                 else ofn.Flags |= OFN_FILEMUSTEXIST;
  610.                 if( ( config->i_pass == 1 && GetSaveFileName( &ofn ) ) ||
  611.                     ( config->i_pass > 1 && GetOpenFileName( &ofn ) ) )
  612.                     SetDlgItemText( hTabs[0], IDC_STATSFILE, tmp );
  613.                 }
  614.                 break;
  615.             }
  616.             break;
  617.         case EN_CHANGE :
  618.             switch( LOWORD( wParam ) )
  619.             {
  620.             case IDC_FOURCC :
  621.                 GetDlgItemText( hTabs[3], IDC_FOURCC, config->fcc, 5 );
  622.                 break;
  623.             case IDC_NR :
  624.                 config->i_noise_reduction = GetDlgItemInt( hTabs[3], IDC_NR, FALSE, FALSE );
  625.             case IDC_THREADEDIT :
  626.                 config->i_threads = GetDlgItemInt( hTabs[3], IDC_THREADEDIT, FALSE, FALSE );
  627.                 if (config->i_threads < 1)
  628.                 {
  629.                     config->i_threads = 1;
  630.                     SetDlgItemInt( hTabs[3], IDC_THREADEDIT, config->i_threads, FALSE );
  631.                 }
  632.                 else if (config->i_threads > 4)
  633.                 {
  634.                     config->i_threads = 4;
  635.                     SetDlgItemInt( hTabs[3], IDC_THREADEDIT, config->i_threads, FALSE );
  636.                 }
  637.                 break;
  638.             case IDC_BITRATEEDIT :
  639.                 switch (config->i_encoding_type)
  640.                 {
  641.                 case 0:
  642.                     config->bitrate = GetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, FALSE, FALSE );
  643.                     SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE, config->bitrate );
  644.                     break;
  645.                 case 1:
  646.                     config->i_qp = GetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, FALSE, FALSE );
  647.                     SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE, config->i_qp );
  648.                     break;
  649.                 case 2:
  650.                     config->i_2passbitrate = GetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, FALSE, FALSE );
  651.                     SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_SETPOS, TRUE, config->i_2passbitrate );
  652.                     break;
  653.                 }
  654.                 break;
  655.             case IDC_STATSFILE :
  656.                 if( GetDlgItemText( hTabs[0], IDC_STATSFILE, config->stats, MAX_PATH ) == 0 )
  657.                     lstrcpy( config->stats, ".\x264.stats" );
  658.                 break;
  659.             case IDC_KEYINTMIN :
  660.                 config->i_keyint_min = GetDlgItemInt( hTabs[1], IDC_KEYINTMIN, FALSE, FALSE );
  661.                 break;
  662.             case IDC_KEYINTMAX :
  663.                 config->i_keyint_max = GetDlgItemInt( hTabs[1], IDC_KEYINTMAX, FALSE, FALSE );
  664.                 break;
  665.             case IDC_SCENECUT :
  666.                 config->i_scenecut_threshold = GetDlgItemInt( hTabs[1], IDC_SCENECUT, FALSE, TRUE );
  667.                 if( config->i_scenecut_threshold > 100 )
  668.                 {
  669.                     config->i_scenecut_threshold = 100;
  670.                     SetDlgItemInt( hTabs[1], IDC_SCENECUT, config->i_scenecut_threshold, TRUE );
  671.                 } else if ( config->i_scenecut_threshold < -1 )
  672.                 {
  673.                     config->i_scenecut_threshold = -1;
  674.                     SetDlgItemInt( hTabs[1], IDC_SCENECUT, config->i_scenecut_threshold, TRUE );
  675.                 }
  676.                 break;
  677.             case IDC_QPMIN :
  678.                 config->i_qp_min = GetDlgItemInt( hTabs[1], IDC_QPMIN, FALSE, FALSE );
  679.                 if( config->i_qp_min > 51 )
  680.                 {
  681.                     config->i_qp_min = 51;
  682.                     SetDlgItemInt( hTabs[1], IDC_QPMIN, config->i_qp_min, FALSE );
  683.                 } else if ( config->i_qp_min < 1 )
  684.                 {
  685.                     config->i_qp_min = 1;
  686.                     SetDlgItemInt( hTabs[1], IDC_QPMIN, config->i_qp_min, FALSE );
  687.                 }
  688.                 break;
  689.             case IDC_QPMAX :
  690.                 config->i_qp_max = GetDlgItemInt( hTabs[1], IDC_QPMAX, FALSE, FALSE );
  691.                 if( config->i_qp_max > 51 )
  692.                 {
  693.                     config->i_qp_max = 51;
  694.                     SetDlgItemInt( hTabs[1], IDC_QPMAX, config->i_qp_max, FALSE );
  695.                 } else if ( config->i_qp_max < 1 )
  696.                 {
  697.                     config->i_qp_max = 1;
  698.                     SetDlgItemInt( hTabs[1], IDC_QPMAX, config->i_qp_max, FALSE );
  699.                 }
  700.                 break;
  701.             case IDC_QPSTEP :
  702.                 config->i_qp_step = GetDlgItemInt( hTabs[1], IDC_QPSTEP, FALSE, FALSE );
  703.                 if( config->i_qp_step > 50 )
  704.                 {
  705.                     config->i_qp_step = 50;
  706.                     SetDlgItemInt( hTabs[1], IDC_QPSTEP, config->i_qp_step, FALSE );
  707.                 } else if ( config->i_qp_step < 1 )
  708.                 {
  709.                     config->i_qp_step = 1;
  710.                     SetDlgItemInt( hTabs[1], IDC_QPSTEP, config->i_qp_step, FALSE );
  711.                 }
  712.                 break;
  713.             case IDC_SAR_W :
  714.                 config->i_sar_width = GetDlgItemInt( hTabs[3], IDC_SAR_W, FALSE, FALSE );
  715.                 break;
  716.             case IDC_SAR_H :
  717.                 config->i_sar_height = GetDlgItemInt( hTabs[3], IDC_SAR_H, FALSE, FALSE );
  718.                 break;
  719.             case IDC_REFFRAMES :
  720.                 config->i_refmax = GetDlgItemInt( hTabs[3], IDC_REFFRAMES, FALSE, FALSE );
  721.                 if( config->i_refmax > 16 )
  722.                 {
  723.                     config->i_refmax = 16;
  724.                     SetDlgItemInt( hTabs[3], IDC_REFFRAMES, config->i_refmax, FALSE );
  725.                 }
  726.                 break;
  727.             case IDC_MERANGE :
  728.                 config->i_me_range = GetDlgItemInt( hTabs[3], IDC_MERANGE, FALSE, FALSE );
  729.                 if( config->i_me_range > 64 )
  730.                 {
  731.                     config->i_me_range = 64;
  732.                     SetDlgItemInt( hTabs[3], IDC_MERANGE, config->i_me_range, FALSE );
  733.                 }
  734.                 break;
  735.             case IDC_BFRAME :
  736.                 config->i_bframe = GetDlgItemInt( hTabs[2], IDC_BFRAME, FALSE, FALSE );
  737.                 if( config->i_bframe > 5 )
  738.                 {
  739.                     config->i_bframe = 5;
  740.                     SetDlgItemInt( hTabs[2], IDC_BFRAME, config->i_bframe, FALSE );
  741.                 }
  742.                 break;
  743.             case IDC_BBIAS :
  744.                 config->i_bframe_bias = GetDlgItemInt( hTabs[2], IDC_BBIAS, FALSE, TRUE );
  745.                 SendDlgItemMessage(hTabs[2], IDC_BBIASSLIDER, TBM_SETPOS, 1,
  746.                 config->i_bframe_bias);
  747.                 if( config->i_bframe_bias > 100 )
  748.                 {
  749.                     config->i_bframe_bias = 100;
  750.                     SetDlgItemInt( hTabs[2], IDC_BBIAS, config->i_bframe_bias, TRUE );
  751.                 } else if ( config->i_bframe_bias < -100 )
  752.                 {
  753.                     config->i_bframe_bias = -100;
  754.                     SetDlgItemInt( hTabs[2], IDC_BBIAS, config->i_bframe_bias, TRUE );
  755.                 }
  756.                 break;
  757.             case IDC_IPRATIO :
  758.                 config->i_key_boost = GetDlgItemInt( hTabs[1], IDC_IPRATIO, FALSE, FALSE );
  759.                 if (config->i_key_boost < 0)
  760.                 {
  761.                     config->i_key_boost = 0;
  762.                     SetDlgItemInt( hTabs[1], IDC_IPRATIO, config->i_key_boost, FALSE );
  763.                 }
  764.                 else if (config->i_key_boost > 70)
  765.                 {
  766.                     config->i_key_boost = 70;
  767.                     SetDlgItemInt( hTabs[1], IDC_IPRATIO, config->i_key_boost, FALSE );
  768.                 }
  769.                 break;
  770.             case IDC_PBRATIO :
  771.                 config->i_b_red = GetDlgItemInt( hTabs[1], IDC_PBRATIO, FALSE, FALSE );
  772.                 if (config->i_b_red < 0)
  773.                 {
  774.                     config->i_b_red = 0;
  775.                     SetDlgItemInt( hTabs[1], IDC_PBRATIO, config->i_b_red, FALSE );
  776.                 }
  777.                 else if (config->i_b_red > 60)
  778.                 {
  779.                     config->i_b_red = 60;
  780.                     SetDlgItemInt( hTabs[1], IDC_PBRATIO, config->i_b_red, FALSE );
  781.                 }
  782.                 break;
  783.             case IDC_CURVECOMP:
  784.                 config->i_curve_comp = GetDlgItemInt( hTabs[1], IDC_CURVECOMP, FALSE, FALSE );
  785.                 if( config->i_curve_comp < 0 )
  786.                 {
  787.                     config->i_curve_comp = 0;
  788.                     SetDlgItemInt( hTabs[1], IDC_CURVECOMP, config->i_curve_comp, FALSE );
  789.                 }
  790.                 else if( config->i_curve_comp > 100 )
  791.                 {
  792.                     config->i_curve_comp = 100;
  793.                     SetDlgItemInt( hTabs[1], IDC_CURVECOMP, config->i_curve_comp, FALSE );
  794.                 }
  795.                 break;
  796.             }
  797.             break;
  798.         case LBN_SELCHANGE :
  799.             switch ( LOWORD( wParam ) )
  800.             {
  801.             case IDC_DIRECTPRED:
  802.                 config->i_direct_mv_pred = SendDlgItemMessage(hTabs[2], IDC_DIRECTPRED, CB_GETCURSEL, 0, 0);
  803.                 break;
  804.             case IDC_SUBPEL:
  805.                 config->i_subpel_refine = SendDlgItemMessage(hTabs[3], IDC_SUBPEL, CB_GETCURSEL, 0, 0);
  806.                 break;
  807.             case IDC_ME_METHOD:
  808.                 config->i_me_method = SendDlgItemMessage(hTabs[3], IDC_ME_METHOD, CB_GETCURSEL, 0, 0);
  809.                 break;
  810.             case IDC_LOG:
  811.                 config->i_log_level = SendDlgItemMessage(hTabs[3], IDC_LOG, CB_GETCURSEL, 0, 0);
  812.                 break;
  813.             case IDC_BITRATEMODE:
  814.                 switch(SendDlgItemMessage(hTabs[0], IDC_BITRATEMODE, CB_GETCURSEL, 0, 0))
  815.                 {
  816.                 case 0:
  817.                     config->i_encoding_type = 0;
  818.                     break;
  819.                 case 1:
  820.                     config->i_encoding_type = 1;
  821.                     break;
  822.                 case 2:
  823.                     config->i_encoding_type = 2;
  824.                     config->i_pass = 1;
  825.                     config->b_fast1pass = FALSE;
  826.                     break;
  827.                 case 3:
  828.                     config->i_encoding_type = 2;
  829.                     config->i_pass = 1;
  830.                     config->b_fast1pass = TRUE;
  831.                     break;
  832.                 case 4:
  833.                     config->i_encoding_type = 2;
  834.                     config->i_pass = 2;
  835.                     break;
  836.                 }
  837.                 tabs_update_items( hDlg, config );
  838.                 break;
  839.             }
  840.             break;
  841.         case EN_KILLFOCUS :
  842.             switch( LOWORD( wParam ) )
  843.             {
  844.             case IDC_MERANGE :
  845.                 config->i_me_range = GetDlgItemInt( hTabs[3], IDC_MERANGE, FALSE, FALSE );
  846.                 if( config->i_me_range < 4 )
  847.                 {
  848.                     config->i_me_range = 4;
  849.                     SetDlgItemInt( hTabs[3], IDC_MERANGE, config->i_me_range, FALSE );
  850.                 }
  851.                 break;
  852.             }
  853.             break;
  854.         }
  855.         break;
  856.     case WM_HSCROLL :
  857.         if( (HWND) lParam == GetDlgItem( hTabs[0], IDC_BITRATESLIDER ) )
  858.         {
  859.             switch (config->i_encoding_type)
  860.             {
  861.             case 0:
  862.                 config->bitrate = SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_GETPOS, 0, 0 );
  863.                 SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->bitrate, FALSE );
  864.                 break;
  865.             case 1:
  866.                 config->i_qp = SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_GETPOS, 0, 0 );
  867.                 SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->i_qp, FALSE );
  868.                 break;
  869.             case 2:
  870.                 config->i_2passbitrate = SendDlgItemMessage( hTabs[0], IDC_BITRATESLIDER, TBM_GETPOS, 0, 0 );
  871.                 SetDlgItemInt( hTabs[0], IDC_BITRATEEDIT, config->i_2passbitrate, FALSE );
  872.                 break;
  873.             }
  874.             break;
  875.         }
  876.         else if( (HWND) lParam == GetDlgItem( hTabs[3], IDC_INLOOP_A ) )
  877.         {
  878.             config->i_inloop_a = SendDlgItemMessage( hTabs[3], IDC_INLOOP_A, TBM_GETPOS, 0, 0 );
  879.             set_dlgitem_int( hTabs[3], IDC_LOOPA_TXT, config->i_inloop_a);
  880.         }
  881.         else if( (HWND) lParam == GetDlgItem( hTabs[3], IDC_INLOOP_B ) )
  882.         {
  883.             config->i_inloop_b = SendDlgItemMessage( hTabs[3], IDC_INLOOP_B, TBM_GETPOS, 0, 0 );
  884.             set_dlgitem_int( hTabs[3], IDC_LOOPB_TXT, config->i_inloop_b);
  885.         }
  886.         else if( (HWND) lParam == GetDlgItem( hTabs[2], IDC_BBIASSLIDER ) )
  887.         {
  888.             config->i_bframe_bias = SendDlgItemMessage( hTabs[2], IDC_BBIASSLIDER, TBM_GETPOS, 0, 0 );
  889.             set_dlgitem_int( hTabs[2], IDC_BBIAS, config->i_bframe_bias);
  890.         }
  891.         break;
  892.     default :
  893.         return 0;
  894.     }
  895.     tabs_enable_items( hDlg, config );
  896.     return 1;
  897. }
  898. /* About box */
  899. BOOL CALLBACK callback_about( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  900. {
  901.     switch( uMsg )
  902.     {
  903.     case WM_INITDIALOG :
  904.     {
  905.         char temp[1024];
  906.         sprintf( temp, "Core %d%s, build %s %s", X264_BUILD, X264_VERSION, __DATE__, __TIME__ );
  907.         SetDlgItemText( hDlg, IDC_BUILD,  temp );
  908.         break;
  909.     }
  910.     case WM_COMMAND:
  911.         if (LOWORD(wParam) == IDC_HOMEPAGE && HIWORD(wParam) == STN_CLICKED)
  912.             ShellExecute( hDlg, "open", X264_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
  913.         else if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  914.             EndDialog( hDlg, LOWORD(wParam) );
  915.         break;
  916.     default :
  917.         return 0;
  918.     }
  919.     return 1;
  920. }
  921. /* Error console */
  922. BOOL CALLBACK callback_err_console( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  923. {
  924.     switch( uMsg )
  925.     {
  926.     case WM_INITDIALOG :
  927.         break;
  928.     case WM_DESTROY :
  929.         break;
  930.     case WM_COMMAND :
  931.         if( HIWORD( wParam ) == BN_CLICKED ) {
  932.             switch( LOWORD( wParam ) ) {
  933.             case IDOK :
  934.                 DestroyWindow( hWnd );
  935.                 break;
  936.             case IDC_COPYCLIP :
  937.                 if( OpenClipboard( hWnd ) )
  938.                     {
  939.                         int i;
  940.                         int num_lines = SendDlgItemMessage( hWnd, IDC_CONSOLE,
  941.                                         LB_GETCOUNT, 0, 0 );
  942.                         int text_size;
  943.                         char *buffer;
  944.                         HGLOBAL clipbuffer;
  945.                         if( num_lines <= 0 )
  946.                             break;
  947.                         /* calculate text size */
  948.                         for( i = 0, text_size = 0; i < num_lines; i++ )
  949.                             text_size += SendDlgItemMessage( hWnd, IDC_CONSOLE,
  950.                                    LB_GETTEXTLEN, ( WPARAM )i, 0 );
  951.                         /* CR-LF for each line + terminating NULL */
  952.                         text_size += 2 * num_lines + 1;
  953.                         EmptyClipboard( );
  954.                         clipbuffer = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE,
  955.                                      text_size );
  956.                         buffer = (char *)GlobalLock( clipbuffer );
  957.                         /* concatenate lines of text in the global buffer */
  958.                         for( i = 0; i < num_lines; i++ )
  959.                         {
  960.                             char msg_buf[1024];
  961.                             SendDlgItemMessage( hWnd, IDC_CONSOLE, LB_GETTEXT,
  962.                                               ( WPARAM )i, ( LPARAM )msg_buf );
  963.                             strcat( msg_buf, "rn" );
  964.                             memcpy( buffer, msg_buf, strlen( msg_buf ) );
  965.                             buffer += strlen( msg_buf );
  966.                         }
  967.                         *buffer = 0; /* null-terminate the buffer */
  968.                         GlobalUnlock( clipbuffer );
  969.                         SetClipboardData( CF_TEXT, clipbuffer );
  970.                         CloseClipboard( );
  971.                     }
  972.                 break;
  973.             default :
  974.                 return 0;
  975.             }
  976.             break;
  977.         }
  978.         break;
  979.     default :
  980.         return DefWindowProc( hWnd, uMsg, wParam, lParam );
  981.     }
  982.     return 0;
  983. }