267ae9170e6b97298f6b0ff0669a5d5f91317a8e
[x262.git] / vfw / config.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  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /**************************************************************************
26  *
27  *  History:
28  *
29  *  2004.05.14  CBR encode mode support
30  *
31  **************************************************************************/
32
33 #include "x264vfw.h"
34 #include <stdio.h>  /* sprintf */
35 #include <commctrl.h>
36
37 /* Registry */
38 #define X264_REG_KEY    HKEY_CURRENT_USER
39 #define X264_REG_PARENT "Software\\GNU"
40 #define X264_REG_CHILD  "x264"
41 #define X264_REG_CLASS  "config"
42
43 /* window controls */
44 #define BITRATE_MAX        5000
45 #define QUANT_MAX        51
46
47 /* description */
48 #define X264_NAME        "x264"
49 #define X264_DEF_TEXT    "Are you sure you want to load default values"
50
51 /* Registery handling */
52 typedef struct
53 {
54     char *reg_value;
55     int  *config_int;
56     int  default_int;
57 } reg_int_t;
58
59 typedef struct
60 {
61     char *reg_value;
62     char *config_str;
63     char *default_str;
64 } reg_str_t;
65
66 CONFIG reg;
67 static const reg_int_t reg_int_table[] =
68 {
69     /* Main dialog */
70     { "bitrate",        &reg.bitrate,           800 },
71     { "quantizer",      &reg.i_qp,              26 },
72     { "encoding_type",  &reg.i_encoding_type,   1 },
73     { "passbitrate",    &reg.i_2passbitrate,    800 },
74     { "pass_number",    &reg.i_pass,            1 },
75     { "fast1pass",      &reg.b_fast1pass,       1 },
76
77     /* Advance dialog */
78     { "cabac",          &reg.b_cabac,           1 },
79     { "loop_filter",    &reg.b_filter,          1 },
80     { "keyint_max",     &reg.i_keyint_min,      25 },
81     { "keyint_min",     &reg.i_keyint_max,      250 },
82     { "refmax",         &reg.i_refmax,          1 },
83     { "bmax",           &reg.i_bframe,          0 },
84     { "direct_pred",    &reg.i_direct_mv_pred,  1 },
85     { "inloop_a",       &reg.i_inloop_a,        0 },
86     { "inloop_b",       &reg.i_inloop_b,        0 },
87     { "key_boost",      &reg.i_key_boost,       40 },
88     { "b_red",          &reg.i_b_red,           30 },
89     { "curve_comp",     &reg.i_curve_comp,      60 },
90
91     /* analysis */
92     { "i4x4",           &reg.b_i4x4,            1 },
93     { "psub16x16",      &reg.b_psub16x16,       1 },
94     { "psub8x8",        &reg.b_psub8x8,         1 },
95     { "bsub16x16",      &reg.b_bsub16x16,       1 },
96     { "subpel",         &reg.i_subpel_refine,   4 }
97
98 };
99
100 static const reg_str_t reg_str_table[] =
101 {
102     { "fourcc",         reg.fcc,                "h264" }
103 };
104
105 void config_reg_load( CONFIG *config )
106 {
107     HKEY    hKey;
108     DWORD   i_size;
109     int     i;
110
111     RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT "\\" X264_REG_CHILD,
112                   0, KEY_READ, &hKey );
113
114     /* Read all integers */
115     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
116     {
117         i_size = sizeof( int );
118         if( RegQueryValueEx( hKey, reg_int_table[i].reg_value, 0, 0,
119                              (LPBYTE)reg_int_table[i].config_int,
120                              &i_size ) != ERROR_SUCCESS )
121             *reg_int_table[i].config_int = reg_int_table[i].default_int;
122     }
123
124     /* Read strings */
125     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
126     {
127         i_size = 5;   /* fourcc + 1 FIXME ugly */
128         if( RegQueryValueEx( hKey, reg_str_table[i].reg_value, 0, 0,
129                              (LPBYTE)reg_str_table[i].config_str,
130                              &i_size ) != ERROR_SUCCESS )
131             memcpy( reg_str_table[i].config_str,
132                     reg_str_table[i].default_str, 5 );
133     }
134
135     RegCloseKey( hKey );
136
137     memcpy( config, &reg, sizeof( CONFIG ) );
138 }
139
140 void config_reg_save( CONFIG *config )
141 {
142     HKEY    hKey;
143     DWORD   i_size;
144     int     i;
145
146     if( RegCreateKeyEx( X264_REG_KEY,
147                         X264_REG_PARENT "\\" X264_REG_CHILD,
148                         0,
149                         X264_REG_CLASS,
150                         REG_OPTION_NON_VOLATILE,
151                         KEY_WRITE,
152                         0, &hKey, &i_size ) != ERROR_SUCCESS )
153         return;
154
155     memcpy( &reg, config, sizeof( CONFIG ) );
156
157     /* Save all integers */
158     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
159     {
160         RegSetValueEx( hKey, reg_int_table[i].reg_value, 0, REG_DWORD,
161                        (LPBYTE)reg_int_table[i].config_int, sizeof( int ) );
162     }
163
164     /* Save strings */
165     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
166     {
167         RegSetValueEx( hKey, reg_str_table[i].reg_value, 0, REG_SZ,
168                        (LPBYTE)reg_str_table[i].config_str,
169                         5 );    /* FIXME */
170     }
171
172     RegCloseKey( hKey );
173 }
174
175 /* config_reg_defaults: */
176 void config_reg_defaults( CONFIG *config )
177 {
178     HKEY hKey;
179
180     if(RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT, 0, KEY_ALL_ACCESS, &hKey )) {
181         return;
182     }
183     if( RegDeleteKey( hKey, X264_REG_CHILD ) ) {
184         return;
185     }
186     RegCloseKey( hKey );
187
188     /* Just in case */
189     memset( config, 0, sizeof( CONFIG ) );
190
191     config_reg_load( config );
192     config_reg_save( config );
193 }
194
195 /* Enables or Disables Window Elements based on Selection
196  */
197 static void main_enable_item( HWND hDlg, CONFIG * config )
198 {
199     switch( config->i_encoding_type )
200     {
201     case 0 : /* 1 Pass, Bitrate Based */
202         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), TRUE );
203         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), TRUE );
204
205         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), FALSE );
206         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), FALSE );
207
208         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), FALSE );
209         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), FALSE );
210         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), FALSE );
211         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), FALSE );
212         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), FALSE );
213         break;
214
215     case 1 : /* 1 Pass, Quantizer Based */
216         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), FALSE );
217         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), FALSE );
218
219         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), TRUE );
220         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), TRUE );
221
222         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), FALSE );
223         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), FALSE );
224         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), FALSE );
225         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), FALSE );
226         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), FALSE );
227         break;
228     
229     case 2 : /* 2 Pass */
230         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), FALSE );
231         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), FALSE );
232
233         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), FALSE );
234         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), FALSE );
235
236         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), TRUE );
237         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), TRUE );
238         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), config->i_pass > 1 );
239         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), config->i_pass > 1 );
240         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), config->i_pass == 1);
241         break;
242     }
243
244     SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETRANGE, TRUE,
245                         (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
246     SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETRANGE, TRUE,
247                         (LPARAM) MAKELONG( 0, QUANT_MAX ) );
248     SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETRANGE, TRUE,
249                         (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
250
251 }
252
253 /* Updates the window from config */
254 static void main_update_dlg( HWND hDlg, CONFIG * config )
255 {
256     SetDlgItemInt( hDlg, IDC_BITRATEEDIT, config->bitrate, FALSE );
257     SetDlgItemInt( hDlg, IDC_QUANTEDIT, config->i_qp, FALSE );
258     SetDlgItemInt( hDlg, IDC_2PASSBITRATE, config->i_2passbitrate, FALSE );
259
260     switch( config->i_encoding_type )
261     {
262     case 0 : /* 1 Pass, Bitrate Based */
263         CheckRadioButton( hDlg,
264                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOBITRATE);
265         break;
266     case 1 : /* 1 Pass, Quantizer Based */
267         CheckRadioButton( hDlg,
268                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOQUANT);
269             break;
270     case 2 : /* 2 Pass */
271         CheckRadioButton( hDlg,
272                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOTWOPASS);
273
274         if (config->i_pass == 1)
275             CheckRadioButton(hDlg,
276                              IDC_2PASS1, IDC_2PASS2, IDC_2PASS1);
277         else 
278             CheckRadioButton(hDlg,
279                              IDC_2PASS1, IDC_2PASS2, IDC_2PASS2);
280         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), config->i_pass > 1 );
281         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), config->i_pass > 1 );
282
283         break;
284     }
285
286     SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETPOS, TRUE,
287                         config->bitrate );
288     SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETPOS, TRUE,
289                         config->i_qp );
290     SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETPOS, TRUE,
291                         config->i_2passbitrate );
292     CheckDlgButton( hDlg, IDC_FAST1PASS, config->b_fast1pass ? BST_CHECKED : BST_UNCHECKED );
293
294 }
295
296
297 /* Main config dialog */
298 BOOL CALLBACK callback_main( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
299 {
300     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
301
302     switch( uMsg )
303     {
304     case WM_INITDIALOG :
305         SetWindowLong( hDlg, GWL_USERDATA, lParam );
306         config = (CONFIG*)lParam;
307
308         main_enable_item( hDlg, config );
309         main_update_dlg( hDlg, config );
310
311         break;
312
313     case WM_COMMAND:
314         switch ( HIWORD( wParam ) )
315         {
316         case BN_CLICKED :
317             switch( LOWORD( wParam ) )
318             {
319             case IDOK :
320                 config->b_save = TRUE;
321                 EndDialog( hDlg, LOWORD(wParam) );
322                 break;
323             case IDCANCEL :
324                 config->b_save = FALSE;
325                 EndDialog( hDlg, LOWORD(wParam) );
326                 break;
327             case IDC_ADVANCED :
328                 DialogBoxParam( g_hInst, MAKEINTRESOURCE(IDD_ADVANCED),
329                                 (HWND)lParam, callback_advanced,
330                                 (LPARAM)config );
331                 break;
332             case IDC_DEFAULTS :
333                 if( MessageBox( hDlg, X264_DEF_TEXT, X264_NAME, MB_YESNO ) == IDYES )
334                 {
335                     config_reg_defaults( config );
336                     main_enable_item( hDlg, config );
337                     main_update_dlg( hDlg, config );
338                 }
339                 break;
340             case IDC_RADIOBITRATE :
341                 config->i_encoding_type = 0; /* 1 Pass, Bitrate Mode=0 */
342                 main_enable_item( hDlg, config );
343                 main_update_dlg( hDlg, config );
344                 break;
345             case IDC_RADIOQUANT :
346                 config->i_encoding_type = 1; /* 1 Pass, Quantizer Mode=1 */
347                 main_enable_item( hDlg, config );
348                 main_update_dlg( hDlg, config );
349                 break;
350             case IDC_RADIOTWOPASS :
351                 config->i_encoding_type = 2; /* 2 Pass Mode=2 */
352                 main_enable_item( hDlg,  config );
353                 main_update_dlg( hDlg, config );
354                 break;
355             case IDC_2PASS1 :
356                 config->i_pass = 1; /* 1st pass */
357                 main_enable_item( hDlg,  config );
358                 main_update_dlg( hDlg, config );
359                 break;
360             case IDC_2PASS2 :
361                 config->i_pass = 2; /* 2nd pass */
362                 main_enable_item( hDlg,  config );
363                 main_update_dlg( hDlg, config );
364                 break;
365             case IDC_FAST1PASS :
366                 config->b_fast1pass = ( IsDlgButtonChecked( hDlg, IDC_FAST1PASS ) == BST_CHECKED );
367                 break;
368             }
369             break;
370         case EN_CHANGE :
371             switch( LOWORD( wParam ) )
372             {
373             case IDC_BITRATEEDIT :
374                 config->bitrate = GetDlgItemInt( hDlg, IDC_BITRATEEDIT, FALSE, FALSE );
375                 SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETPOS, TRUE, config->bitrate );
376                 break;
377             case IDC_QUANTEDIT :
378                 config->i_qp = GetDlgItemInt( hDlg, IDC_QUANTEDIT, FALSE, FALSE );
379                 SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETPOS, TRUE, config->i_qp );
380                 break;
381             case IDC_2PASSBITRATE :
382                 config->i_2passbitrate = GetDlgItemInt( hDlg, IDC_2PASSBITRATE, FALSE, FALSE );
383                 SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETPOS, TRUE, config->i_2passbitrate );
384                 break;
385             }
386             break;
387         default:
388             break;
389         }
390         break;
391
392         case WM_HSCROLL :
393             if( (HWND) lParam == GetDlgItem( hDlg, IDC_BITRATESLIDER ) )
394             {
395                 config->bitrate = SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_GETPOS, 0, 0 );
396                 SetDlgItemInt( hDlg, IDC_BITRATEEDIT, config->bitrate, FALSE );
397
398             }
399             else if( (HWND) lParam == GetDlgItem( hDlg, IDC_QUANTSLIDER ) )
400             {
401                 config->i_qp = SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_GETPOS, 0, 0 );
402                 SetDlgItemInt( hDlg, IDC_QUANTEDIT, config->i_qp, FALSE );
403             }
404             else if( (HWND) lParam == GetDlgItem( hDlg, IDC_2PASSBITRATE_S ) )
405             {
406                 config->i_2passbitrate = SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_GETPOS, 0, 0 );
407                 SetDlgItemInt( hDlg, IDC_2PASSBITRATE, config->i_2passbitrate, FALSE );
408             }
409             break;
410
411     default :
412         return 0;
413     }
414
415     return 1;
416 }
417
418 /* About dialog */
419 BOOL CALLBACK callback_about( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
420 {
421     switch( uMsg )
422     {
423     case WM_INITDIALOG :
424     {
425         char temp[1024];
426         sprintf( temp, "Core %d, build %s %s", X264_BUILD, __DATE__, __TIME__ );
427         SetDlgItemText( hDlg, IDC_BUILD,  temp );
428         break;
429     }
430
431     case WM_COMMAND:
432         if (LOWORD(wParam) == IDC_HOMEPAGE && HIWORD(wParam) == STN_CLICKED)
433             ShellExecute( hDlg, "open", X264_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
434         else if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
435             EndDialog( hDlg, LOWORD(wParam) );
436         break;
437
438     default :
439         return 0;
440     }
441
442     return 1;
443 }
444
445 static void set_dlgitem_int(HWND hDlg, UINT item, int value)
446 {
447     char buf[8];
448     sprintf(buf, "%i", value);
449     SetDlgItemText(hDlg, item, buf);
450 }
451
452 static void adv_update_dlg( HWND hDlg, CONFIG * config )
453 {
454     char fourcc[5];
455
456     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Spatial");
457     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Temporal");
458
459     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"1 (Fastest)");
460     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"2");
461     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"3");
462     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"4");
463     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"5 (Max Quality)");
464
465     CheckDlgButton( hDlg,IDC_CABAC,
466                     config->b_cabac ? BST_CHECKED : BST_UNCHECKED );
467     CheckDlgButton( hDlg,IDC_LOOPFILTER,
468                     config->b_filter ? BST_CHECKED: BST_UNCHECKED );
469     CheckDlgButton( hDlg,IDC_P16X16,
470                     config->b_psub16x16 ? BST_CHECKED: BST_UNCHECKED );
471     CheckDlgButton( hDlg,IDC_P8X8,
472                     config->b_psub8x8 ? BST_CHECKED: BST_UNCHECKED );
473     CheckDlgButton( hDlg,IDC_B16X16,
474                     config->b_bsub16x16 ? BST_CHECKED: BST_UNCHECKED );
475     CheckDlgButton( hDlg,IDC_I4X4,
476                     config->b_i4x4 ? BST_CHECKED: BST_UNCHECKED );
477
478     SetDlgItemInt( hDlg, IDC_KEYINTMIN, config->i_keyint_min, FALSE );
479     SetDlgItemInt( hDlg, IDC_KEYINTMAX, config->i_keyint_max, FALSE );
480     SetDlgItemInt( hDlg, IDC_REFFRAMES, config->i_refmax, FALSE );
481     SetDlgItemInt( hDlg, IDC_BFRAME, config->i_bframe, FALSE );
482     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
483     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
484     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
485
486     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_SETCURSEL, (config->i_direct_mv_pred), 0);
487     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_SETCURSEL, (config->i_subpel_refine), 0);
488
489     SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_SETRANGE, TRUE,
490                         (LPARAM) MAKELONG( -6, 6 ) );
491     SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_SETRANGE, TRUE,
492                         (LPARAM) MAKELONG( -6, 6 ) );
493
494     SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_SETPOS, TRUE,
495                         config->i_inloop_a );
496     SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_SETPOS, TRUE,
497                         config->i_inloop_b );
498     set_dlgitem_int( hDlg, IDC_LOOPA_TXT, config->i_inloop_a);
499     set_dlgitem_int( hDlg, IDC_LOOPB_TXT, config->i_inloop_b);
500
501     EnableWindow( GetDlgItem( hDlg, IDC_P8X8 ), config->b_psub16x16 );
502
503
504     memcpy( fourcc, config->fcc, 4 );
505     fourcc[4] = '\0';
506
507     SetDlgItemText( hDlg, IDC_FOURCC, fourcc );
508 }
509
510 /* advanced configuration dialog process */
511 BOOL CALLBACK callback_advanced( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
512 {
513     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
514
515     switch( uMsg )
516     {
517     case WM_INITDIALOG :
518         SetWindowLong( hDlg, GWL_USERDATA, lParam );
519         config = (CONFIG*)lParam;
520
521         adv_update_dlg( hDlg, config );
522         break;
523
524     case WM_COMMAND:
525         switch ( HIWORD( wParam ) )
526         {
527         case BN_CLICKED :
528             switch( LOWORD( wParam ) )
529             {
530             case IDOK :
531                 EndDialog( hDlg, LOWORD( wParam ) );
532                 break;
533             case IDC_CABAC :
534                 config->b_cabac = ( IsDlgButtonChecked( hDlg, IDC_CABAC ) == BST_CHECKED );
535                 break;
536             case IDC_LOOPFILTER :
537                 config->b_filter = ( IsDlgButtonChecked( hDlg, IDC_LOOPFILTER ) == BST_CHECKED );
538                 break;
539             case IDC_P16X16 :
540                 config->b_psub16x16 = ( IsDlgButtonChecked( hDlg, IDC_P16X16 ) == BST_CHECKED );
541                 EnableWindow( GetDlgItem( hDlg, IDC_P8X8 ), config->b_psub16x16 );
542                 break;
543             case IDC_P8X8 :
544                 config->b_psub8x8 = ( IsDlgButtonChecked( hDlg, IDC_P8X8 ) == BST_CHECKED );
545                 break;
546             case IDC_B16X16 :
547                 config->b_bsub16x16 = ( IsDlgButtonChecked( hDlg, IDC_B16X16 ) == BST_CHECKED );
548                 break;
549             case IDC_I4X4 :
550                 config->b_i4x4 = ( IsDlgButtonChecked( hDlg, IDC_I4X4 ) == BST_CHECKED );
551                 break;
552             }
553             break;
554         case EN_CHANGE :
555             switch( LOWORD( wParam ) )
556             {
557             case IDC_KEYINTMIN :
558                 config->i_keyint_min = GetDlgItemInt( hDlg, IDC_KEYINTMIN, FALSE, FALSE );
559                 break;
560             case IDC_KEYINTMAX :
561                 config->i_keyint_max = GetDlgItemInt( hDlg, IDC_KEYINTMAX, FALSE, FALSE );
562                 break;
563             case IDC_REFFRAMES :
564                 config->i_refmax = GetDlgItemInt( hDlg, IDC_REFFRAMES, FALSE, FALSE );
565                 break;
566             case IDC_FOURCC :
567                 GetDlgItemText( hDlg, IDC_FOURCC, config->fcc, 5 );
568                 break;
569             case IDC_BFRAME :
570                 config->i_bframe = GetDlgItemInt( hDlg, IDC_BFRAME, FALSE, FALSE );
571                 break;
572             case IDC_IPRATIO :
573                 config->i_key_boost = GetDlgItemInt( hDlg, IDC_IPRATIO, FALSE, FALSE );
574                 if (config->i_key_boost < 0)
575                 {
576                     config->i_key_boost = 0;
577                     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
578                 }
579                 else if (config->i_key_boost > 60)
580                 {
581                     config->i_key_boost = 60;
582                     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
583                 }                        
584                 break;
585             case IDC_PBRATIO :
586                 config->i_b_red = GetDlgItemInt( hDlg, IDC_PBRATIO, FALSE, FALSE );
587                 if (config->i_b_red < 0)
588                 {
589                     config->i_b_red = 0;
590                     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
591                 }
592                 else if (config->i_b_red > 50)
593                 {
594                     config->i_b_red = 50;
595                     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
596                 }                        
597                 break;
598             case IDC_CURVECOMP:
599                 config->i_curve_comp = GetDlgItemInt( hDlg, IDC_CURVECOMP, FALSE, FALSE );
600                 if( config->i_curve_comp < 0 )
601                 {
602                     config->i_curve_comp = 0;
603                     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
604                 }
605                 else if( config->i_curve_comp > 100 )
606                 {
607                     config->i_curve_comp = 100;
608                     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
609                 }                        
610                 break;
611             }
612             break;
613             case LBN_SELCHANGE :
614                 switch ( LOWORD( wParam ) ) {
615                 case IDC_DIRECTPRED:
616                     config->i_direct_mv_pred = SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_GETCURSEL, 0, 0);
617                     break;
618                 case IDC_SUBPEL:
619                     config->i_subpel_refine = SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_GETCURSEL, 0, 0);
620                     break;
621                 }
622             break;
623         }
624         break;
625         case WM_HSCROLL : 
626         if( (HWND) lParam == GetDlgItem( hDlg, IDC_INLOOP_A ) ) {
627                 config->i_inloop_a = SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_GETPOS, 0, 0 );
628                 set_dlgitem_int( hDlg, IDC_LOOPA_TXT, config->i_inloop_a);
629
630         } else if ( (HWND) lParam == GetDlgItem( hDlg, IDC_INLOOP_B ) ) {
631                 config->i_inloop_b = SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_GETPOS, 0, 0 );
632                 set_dlgitem_int( hDlg, IDC_LOOPB_TXT, config->i_inloop_b);
633         }
634         break;
635         case WM_CLOSE:
636             EndDialog( hDlg, LOWORD( wParam ) );
637             break;
638     default :
639         return 0;
640     }
641     return 1;
642 }
643