VfW: expose option "Nth pass" (i.e. simultaneously read and update the multipass...
[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     { "updatestats",    &reg.b_updatestats,     0 },
77
78     /* Advance dialog */
79     { "cabac",          &reg.b_cabac,           1 },
80     { "loop_filter",    &reg.b_filter,          1 },
81     { "keyint_max",     &reg.i_keyint_min,      25 },
82     { "keyint_min",     &reg.i_keyint_max,      250 },
83     { "refmax",         &reg.i_refmax,          1 },
84     { "bmax",           &reg.i_bframe,          0 },
85     { "direct_pred",    &reg.i_direct_mv_pred,  1 },
86     { "inloop_a",       &reg.i_inloop_a,        0 },
87     { "inloop_b",       &reg.i_inloop_b,        0 },
88     { "key_boost",      &reg.i_key_boost,       40 },
89     { "b_red",          &reg.i_b_red,           30 },
90     { "curve_comp",     &reg.i_curve_comp,      60 },
91
92     /* analysis */
93     { "i4x4",           &reg.b_i4x4,            1 },
94     { "psub16x16",      &reg.b_psub16x16,       1 },
95     { "psub8x8",        &reg.b_psub8x8,         1 },
96     { "bsub16x16",      &reg.b_bsub16x16,       1 },
97     { "subpel",         &reg.i_subpel_refine,   4 }
98
99 };
100
101 static const reg_str_t reg_str_table[] =
102 {
103     { "fourcc",         reg.fcc,                "h264" },
104     { "statsfile",      reg.stats,              ".\\x264.stats" }
105 };
106
107 void config_reg_load( CONFIG *config )
108 {
109     HKEY    hKey;
110     DWORD   i_size;
111     int     i;
112
113     RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT "\\" X264_REG_CHILD,
114                   0, KEY_READ, &hKey );
115
116     /* Read all integers */
117     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
118     {
119         i_size = sizeof( int );
120         if( RegQueryValueEx( hKey, reg_int_table[i].reg_value, 0, 0,
121                              (LPBYTE)reg_int_table[i].config_int,
122                              &i_size ) != ERROR_SUCCESS )
123             *reg_int_table[i].config_int = reg_int_table[i].default_int;
124     }
125
126     /* Read strings */
127     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
128     {
129         i_size = MAX_PATH;
130         if( RegQueryValueEx( hKey, reg_str_table[i].reg_value, 0, 0,
131                              (LPBYTE)reg_str_table[i].config_str,
132                              &i_size ) != ERROR_SUCCESS )
133             lstrcpy( reg_str_table[i].config_str,
134                      reg_str_table[i].default_str );
135     }
136
137     RegCloseKey( hKey );
138
139     memcpy( config, &reg, sizeof( CONFIG ) );
140 }
141
142 void config_reg_save( CONFIG *config )
143 {
144     HKEY    hKey;
145     DWORD   i_size;
146     int     i;
147
148     if( RegCreateKeyEx( X264_REG_KEY,
149                         X264_REG_PARENT "\\" X264_REG_CHILD,
150                         0,
151                         X264_REG_CLASS,
152                         REG_OPTION_NON_VOLATILE,
153                         KEY_WRITE,
154                         0, &hKey, &i_size ) != ERROR_SUCCESS )
155         return;
156
157     memcpy( &reg, config, sizeof( CONFIG ) );
158
159     /* Save all integers */
160     for( i = 0; i < sizeof( reg_int_table )/sizeof( reg_int_t); i++ )
161     {
162         RegSetValueEx( hKey, reg_int_table[i].reg_value, 0, REG_DWORD,
163                        (LPBYTE)reg_int_table[i].config_int, sizeof( int ) );
164     }
165
166     /* Save strings */
167     for( i = 0; i < sizeof( reg_str_table )/sizeof( reg_str_t); i++ )
168     {
169         RegSetValueEx( hKey, reg_str_table[i].reg_value, 0, REG_SZ,
170                        (LPBYTE)reg_str_table[i].config_str,
171                         MAX_PATH );
172     }
173
174     RegCloseKey( hKey );
175 }
176
177 /* config_reg_defaults: */
178 void config_reg_defaults( CONFIG *config )
179 {
180     HKEY hKey;
181
182     if(RegOpenKeyEx( X264_REG_KEY, X264_REG_PARENT, 0, KEY_ALL_ACCESS, &hKey )) {
183         return;
184     }
185     if( RegDeleteKey( hKey, X264_REG_CHILD ) ) {
186         return;
187     }
188     RegCloseKey( hKey );
189
190     /* Just in case */
191     memset( config, 0, sizeof( CONFIG ) );
192
193     config_reg_load( config );
194     config_reg_save( config );
195 }
196
197 /* Enables or Disables Window Elements based on Selection
198  */
199 static void main_enable_item( HWND hDlg, CONFIG * config )
200 {
201     switch( config->i_encoding_type )
202     {
203     case 0 : /* 1 Pass, Bitrate Based */
204         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), TRUE );
205         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), TRUE );
206
207         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), FALSE );
208         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), FALSE );
209
210         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), FALSE );
211         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), FALSE );
212         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), FALSE );
213         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), FALSE );
214         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), FALSE );
215         EnableWindow( GetDlgItem( hDlg, IDC_UPDATESTATS ), FALSE );
216         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE ), FALSE );
217         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE_BROWSE ), FALSE );
218         break;
219
220     case 1 : /* 1 Pass, Quantizer Based */
221         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), FALSE );
222         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), FALSE );
223
224         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), TRUE );
225         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), TRUE );
226
227         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), FALSE );
228         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), FALSE );
229         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), FALSE );
230         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), FALSE );
231         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), FALSE );
232         EnableWindow( GetDlgItem( hDlg, IDC_UPDATESTATS ), FALSE );
233         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE ), FALSE );
234         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE_BROWSE ), FALSE );
235         break;
236     
237     case 2 : /* 2 Pass */
238         EnableWindow( GetDlgItem( hDlg, IDC_BITRATEEDIT ), FALSE );
239         EnableWindow( GetDlgItem( hDlg, IDC_BITRATESLIDER ), FALSE );
240
241         EnableWindow( GetDlgItem( hDlg, IDC_QUANTEDIT ), FALSE );
242         EnableWindow( GetDlgItem( hDlg, IDC_QUANTSLIDER ), FALSE );
243
244         EnableWindow( GetDlgItem( hDlg, IDC_2PASS1 ), TRUE );
245         EnableWindow( GetDlgItem( hDlg, IDC_2PASS2 ), TRUE );
246         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), config->i_pass > 1 );
247         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), config->i_pass > 1 );
248         EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), config->i_pass == 1);
249         EnableWindow( GetDlgItem( hDlg, IDC_UPDATESTATS ), config->i_pass > 1 );
250         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE ), TRUE );
251         EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE_BROWSE ), TRUE );
252         break;
253     }
254
255     SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETRANGE, TRUE,
256                         (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
257     SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETRANGE, TRUE,
258                         (LPARAM) MAKELONG( 0, QUANT_MAX ) );
259     SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETRANGE, TRUE,
260                         (LPARAM) MAKELONG( 0, BITRATE_MAX ) );
261
262 }
263
264 /* Updates the window from config */
265 static void main_update_dlg( HWND hDlg, CONFIG * config )
266 {
267     SetDlgItemInt( hDlg, IDC_BITRATEEDIT, config->bitrate, FALSE );
268     SetDlgItemInt( hDlg, IDC_QUANTEDIT, config->i_qp, FALSE );
269     SetDlgItemInt( hDlg, IDC_2PASSBITRATE, config->i_2passbitrate, FALSE );
270     SetDlgItemText( hDlg, IDC_STATSFILE, config->stats );
271
272     switch( config->i_encoding_type )
273     {
274     case 0 : /* 1 Pass, Bitrate Based */
275         CheckRadioButton( hDlg,
276                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOBITRATE);
277         break;
278     case 1 : /* 1 Pass, Quantizer Based */
279         CheckRadioButton( hDlg,
280                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOQUANT);
281             break;
282     case 2 : /* 2 Pass */
283         CheckRadioButton( hDlg,
284                           IDC_RADIOBITRATE, IDC_RADIOTWOPASS, IDC_RADIOTWOPASS);
285
286         if (config->i_pass == 1)
287             CheckRadioButton(hDlg,
288                              IDC_2PASS1, IDC_2PASS2, IDC_2PASS1);
289         else 
290             CheckRadioButton(hDlg,
291                              IDC_2PASS1, IDC_2PASS2, IDC_2PASS2);
292         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE ), config->i_pass > 1 );
293         EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), config->i_pass > 1 );
294
295         break;
296     }
297
298     SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETPOS, TRUE,
299                         config->bitrate );
300     SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETPOS, TRUE,
301                         config->i_qp );
302     SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETPOS, TRUE,
303                         config->i_2passbitrate );
304     CheckDlgButton( hDlg, IDC_FAST1PASS, config->b_fast1pass ? BST_CHECKED : BST_UNCHECKED );
305     CheckDlgButton( hDlg, IDC_UPDATESTATS, config->b_updatestats ? BST_CHECKED : BST_UNCHECKED );
306
307 }
308
309
310 /* Main config dialog */
311 BOOL CALLBACK callback_main( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
312 {
313     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
314
315     switch( uMsg )
316     {
317     case WM_INITDIALOG :
318         SetWindowLong( hDlg, GWL_USERDATA, lParam );
319         config = (CONFIG*)lParam;
320
321         main_enable_item( hDlg, config );
322         main_update_dlg( hDlg, config );
323
324         break;
325
326     case WM_COMMAND:
327         switch ( HIWORD( wParam ) )
328         {
329         case BN_CLICKED :
330             switch( LOWORD( wParam ) )
331             {
332             case IDOK :
333                 config->b_save = TRUE;
334                             EndDialog( hDlg, LOWORD(wParam) );
335                 break;
336             case IDCANCEL :
337                 config->b_save = FALSE;
338                 EndDialog( hDlg, LOWORD(wParam) );
339                 break;
340             case IDC_ADVANCED :
341                 DialogBoxParam( g_hInst, MAKEINTRESOURCE(IDD_ADVANCED),
342                                 (HWND)lParam, callback_advanced,
343                                 (LPARAM)config );
344                 break;
345             case IDC_DEFAULTS :
346                 if( MessageBox( hDlg, X264_DEF_TEXT, X264_NAME, MB_YESNO ) == IDYES )
347                 {
348                     config_reg_defaults( config );
349                     main_enable_item( hDlg, config );
350                     main_update_dlg( hDlg, config );
351                 }
352                 break;
353             case IDC_RADIOBITRATE :
354                 config->i_encoding_type = 0; /* 1 Pass, Bitrate Mode=0 */
355                 main_enable_item( hDlg, config );
356                 main_update_dlg( hDlg, config );
357                 break;
358             case IDC_RADIOQUANT :
359                 config->i_encoding_type = 1; /* 1 Pass, Quantizer Mode=1 */
360                 main_enable_item( hDlg, config );
361                 main_update_dlg( hDlg, config );
362                 break;
363             case IDC_RADIOTWOPASS :
364                 config->i_encoding_type = 2; /* 2 Pass Mode=2 */
365                 main_enable_item( hDlg,  config );
366                 main_update_dlg( hDlg, config );
367                 break;
368             case IDC_2PASS1 :
369                 config->i_pass = 1; /* 1st pass */
370                 main_enable_item( hDlg,  config );
371                 main_update_dlg( hDlg, config );
372                 break;
373             case IDC_2PASS2 :
374                 config->i_pass = 2; /* 2nd pass */
375                 main_enable_item( hDlg,  config );
376                 main_update_dlg( hDlg, config );
377                 break;
378             case IDC_FAST1PASS :
379                 config->b_fast1pass = ( IsDlgButtonChecked( hDlg, IDC_FAST1PASS ) == BST_CHECKED );
380                 break;
381             case IDC_UPDATESTATS :
382                 config->b_updatestats = ( IsDlgButtonChecked( hDlg, IDC_UPDATESTATS ) == BST_CHECKED );
383                 break;
384             case IDC_STATSFILE_BROWSE :
385                 {
386                 OPENFILENAME ofn;
387                 char tmp[MAX_PATH];
388
389                 GetDlgItemText( hDlg, IDC_STATSFILE, tmp, MAX_PATH );
390
391                 memset( &ofn, 0, sizeof( OPENFILENAME ) );
392                 ofn.lStructSize = sizeof( OPENFILENAME );
393
394                 ofn.hwndOwner = hDlg;
395                 ofn.lpstrFilter = "Statsfile (*.stats)\0*.stats\0All files (*.*)\0*.*\0\0";
396                 ofn.lpstrFile = tmp;
397                 ofn.nMaxFile = MAX_PATH;
398                 ofn.Flags = OFN_PATHMUSTEXIST;
399
400                 if( config->i_pass == 1 )
401                     ofn.Flags |= OFN_OVERWRITEPROMPT;
402                 else ofn.Flags |= OFN_FILEMUSTEXIST;
403
404                 if( ( config->i_pass == 1 && GetSaveFileName( &ofn ) ) || 
405                     ( config->i_pass > 1 && GetOpenFileName( &ofn ) ) )
406                     SetDlgItemText( hDlg, IDC_STATSFILE, tmp );
407                 }
408                 break;
409             }
410             break;
411         case EN_CHANGE :
412             switch( LOWORD( wParam ) )
413             {
414             case IDC_BITRATEEDIT :
415                 config->bitrate = GetDlgItemInt( hDlg, IDC_BITRATEEDIT, FALSE, FALSE );
416                 SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_SETPOS, TRUE, config->bitrate );
417                 break;
418             case IDC_QUANTEDIT :
419                 config->i_qp = GetDlgItemInt( hDlg, IDC_QUANTEDIT, FALSE, FALSE );
420                 SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_SETPOS, TRUE, config->i_qp );
421                 break;
422             case IDC_2PASSBITRATE :
423                 config->i_2passbitrate = GetDlgItemInt( hDlg, IDC_2PASSBITRATE, FALSE, FALSE );
424                 SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_SETPOS, TRUE, config->i_2passbitrate );
425                 break;
426             case IDC_STATSFILE :
427                 if( GetDlgItemText( hDlg, IDC_STATSFILE, config->stats, MAX_PATH ) == 0 )
428                     lstrcpy( config->stats, ".\\x264.stats" );
429                 break;
430             }
431             break;
432         default:
433             break;
434         }
435         break;
436
437         case WM_HSCROLL :
438             if( (HWND) lParam == GetDlgItem( hDlg, IDC_BITRATESLIDER ) )
439             {
440                 config->bitrate = SendDlgItemMessage( hDlg, IDC_BITRATESLIDER, TBM_GETPOS, 0, 0 );
441                 SetDlgItemInt( hDlg, IDC_BITRATEEDIT, config->bitrate, FALSE );
442
443             }
444             else if( (HWND) lParam == GetDlgItem( hDlg, IDC_QUANTSLIDER ) )
445             {
446                 config->i_qp = SendDlgItemMessage( hDlg, IDC_QUANTSLIDER, TBM_GETPOS, 0, 0 );
447                 SetDlgItemInt( hDlg, IDC_QUANTEDIT, config->i_qp, FALSE );
448             }
449             else if( (HWND) lParam == GetDlgItem( hDlg, IDC_2PASSBITRATE_S ) )
450             {
451                 config->i_2passbitrate = SendDlgItemMessage( hDlg, IDC_2PASSBITRATE_S, TBM_GETPOS, 0, 0 );
452                 SetDlgItemInt( hDlg, IDC_2PASSBITRATE, config->i_2passbitrate, FALSE );
453             }
454             break;
455
456     default :
457         return 0;
458     }
459
460     return 1;
461 }
462
463 /* About dialog */
464 BOOL CALLBACK callback_about( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
465 {
466     switch( uMsg )
467     {
468     case WM_INITDIALOG :
469     {
470         char temp[1024];
471         sprintf( temp, "Core %d, build %s %s", X264_BUILD, __DATE__, __TIME__ );
472         SetDlgItemText( hDlg, IDC_BUILD,  temp );
473         break;
474     }
475
476     case WM_COMMAND:
477         if (LOWORD(wParam) == IDC_HOMEPAGE && HIWORD(wParam) == STN_CLICKED)
478             ShellExecute( hDlg, "open", X264_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
479         else if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
480             EndDialog( hDlg, LOWORD(wParam) );
481         break;
482
483     default :
484         return 0;
485     }
486
487     return 1;
488 }
489
490 static void set_dlgitem_int(HWND hDlg, UINT item, int value)
491 {
492     char buf[8];
493     sprintf(buf, "%i", value);
494     SetDlgItemText(hDlg, item, buf);
495 }
496
497 static void adv_update_dlg( HWND hDlg, CONFIG * config )
498 {
499     char fourcc[5];
500
501     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Spatial");
502     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_ADDSTRING, 0, (LPARAM)"Temporal");
503
504     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"1 (Fastest)");
505     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"2");
506     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"3");
507     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"4");
508     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_ADDSTRING, 0, (LPARAM)"5 (Max Quality)");
509
510     CheckDlgButton( hDlg,IDC_CABAC,
511                     config->b_cabac ? BST_CHECKED : BST_UNCHECKED );
512     CheckDlgButton( hDlg,IDC_LOOPFILTER,
513                     config->b_filter ? BST_CHECKED: BST_UNCHECKED );
514     CheckDlgButton( hDlg,IDC_P16X16,
515                     config->b_psub16x16 ? BST_CHECKED: BST_UNCHECKED );
516     CheckDlgButton( hDlg,IDC_P8X8,
517                     config->b_psub8x8 ? BST_CHECKED: BST_UNCHECKED );
518     CheckDlgButton( hDlg,IDC_B16X16,
519                     config->b_bsub16x16 ? BST_CHECKED: BST_UNCHECKED );
520     CheckDlgButton( hDlg,IDC_I4X4,
521                     config->b_i4x4 ? BST_CHECKED: BST_UNCHECKED );
522
523     SetDlgItemInt( hDlg, IDC_KEYINTMIN, config->i_keyint_min, FALSE );
524     SetDlgItemInt( hDlg, IDC_KEYINTMAX, config->i_keyint_max, FALSE );
525     SetDlgItemInt( hDlg, IDC_REFFRAMES, config->i_refmax, FALSE );
526     SetDlgItemInt( hDlg, IDC_BFRAME, config->i_bframe, FALSE );
527     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
528     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
529     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
530
531     SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_SETCURSEL, (config->i_direct_mv_pred), 0);
532     SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_SETCURSEL, (config->i_subpel_refine), 0);
533
534     SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_SETRANGE, TRUE,
535                         (LPARAM) MAKELONG( -6, 6 ) );
536     SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_SETRANGE, TRUE,
537                         (LPARAM) MAKELONG( -6, 6 ) );
538
539     SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_SETPOS, TRUE,
540                         config->i_inloop_a );
541     SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_SETPOS, TRUE,
542                         config->i_inloop_b );
543     set_dlgitem_int( hDlg, IDC_LOOPA_TXT, config->i_inloop_a);
544     set_dlgitem_int( hDlg, IDC_LOOPB_TXT, config->i_inloop_b);
545
546     EnableWindow( GetDlgItem( hDlg, IDC_P8X8 ), config->b_psub16x16 );
547
548     memcpy( fourcc, config->fcc, 4 );
549     fourcc[4] = '\0';
550     SetDlgItemText( hDlg, IDC_FOURCC, fourcc );
551 }
552
553 /* advanced configuration dialog process */
554 BOOL CALLBACK callback_advanced( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
555 {
556     CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA);
557
558     switch( uMsg )
559     {
560     case WM_INITDIALOG :
561         SetWindowLong( hDlg, GWL_USERDATA, lParam );
562         config = (CONFIG*)lParam;
563
564         adv_update_dlg( hDlg, config );
565         break;
566
567     case WM_COMMAND:
568         switch ( HIWORD( wParam ) )
569         {
570         case BN_CLICKED :
571             switch( LOWORD( wParam ) )
572             {
573             case IDOK :
574                 EndDialog( hDlg, LOWORD( wParam ) );
575                 break;
576             case IDC_CABAC :
577                 config->b_cabac = ( IsDlgButtonChecked( hDlg, IDC_CABAC ) == BST_CHECKED );
578                 break;
579             case IDC_LOOPFILTER :
580                 config->b_filter = ( IsDlgButtonChecked( hDlg, IDC_LOOPFILTER ) == BST_CHECKED );
581                 break;
582             case IDC_P16X16 :
583                 config->b_psub16x16 = ( IsDlgButtonChecked( hDlg, IDC_P16X16 ) == BST_CHECKED );
584                 EnableWindow( GetDlgItem( hDlg, IDC_P8X8 ), config->b_psub16x16 );
585                 break;
586             case IDC_P8X8 :
587                 config->b_psub8x8 = ( IsDlgButtonChecked( hDlg, IDC_P8X8 ) == BST_CHECKED );
588                 break;
589             case IDC_B16X16 :
590                 config->b_bsub16x16 = ( IsDlgButtonChecked( hDlg, IDC_B16X16 ) == BST_CHECKED );
591                 break;
592             case IDC_I4X4 :
593                 config->b_i4x4 = ( IsDlgButtonChecked( hDlg, IDC_I4X4 ) == BST_CHECKED );
594                 break;
595             }
596             break;
597         case EN_CHANGE :
598             switch( LOWORD( wParam ) )
599             {
600             case IDC_KEYINTMIN :
601                 config->i_keyint_min = GetDlgItemInt( hDlg, IDC_KEYINTMIN, FALSE, FALSE );
602                 break;
603             case IDC_KEYINTMAX :
604                 config->i_keyint_max = GetDlgItemInt( hDlg, IDC_KEYINTMAX, FALSE, FALSE );
605                 break;
606             case IDC_REFFRAMES :
607                 config->i_refmax = GetDlgItemInt( hDlg, IDC_REFFRAMES, FALSE, FALSE );
608                 break;
609             case IDC_FOURCC :
610                 GetDlgItemText( hDlg, IDC_FOURCC, config->fcc, 5 );
611                 break;
612             case IDC_BFRAME :
613                 config->i_bframe = GetDlgItemInt( hDlg, IDC_BFRAME, FALSE, FALSE );
614                 break;
615             case IDC_IPRATIO :
616                 config->i_key_boost = GetDlgItemInt( hDlg, IDC_IPRATIO, FALSE, FALSE );
617                 if (config->i_key_boost < 0)
618                 {
619                     config->i_key_boost = 0;
620                     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
621                 }
622                 else if (config->i_key_boost > 60)
623                 {
624                     config->i_key_boost = 60;
625                     SetDlgItemInt( hDlg, IDC_IPRATIO, config->i_key_boost, FALSE );
626                 }                        
627                 break;
628             case IDC_PBRATIO :
629                 config->i_b_red = GetDlgItemInt( hDlg, IDC_PBRATIO, FALSE, FALSE );
630                 if (config->i_b_red < 0)
631                 {
632                     config->i_b_red = 0;
633                     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
634                 }
635                 else if (config->i_b_red > 50)
636                 {
637                     config->i_b_red = 50;
638                     SetDlgItemInt( hDlg, IDC_PBRATIO, config->i_b_red, FALSE );
639                 }                        
640                 break;
641             case IDC_CURVECOMP:
642                 config->i_curve_comp = GetDlgItemInt( hDlg, IDC_CURVECOMP, FALSE, FALSE );
643                 if( config->i_curve_comp < 0 )
644                 {
645                     config->i_curve_comp = 0;
646                     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
647                 }
648                 else if( config->i_curve_comp > 100 )
649                 {
650                     config->i_curve_comp = 100;
651                     SetDlgItemInt( hDlg, IDC_CURVECOMP, config->i_curve_comp, FALSE );
652                 }                        
653                 break;
654             }
655             break;
656             case LBN_SELCHANGE :
657                 switch ( LOWORD( wParam ) ) {
658                 case IDC_DIRECTPRED:
659                     config->i_direct_mv_pred = SendDlgItemMessage(hDlg, IDC_DIRECTPRED, CB_GETCURSEL, 0, 0);
660                     break;
661                 case IDC_SUBPEL:
662                     config->i_subpel_refine = SendDlgItemMessage(hDlg, IDC_SUBPEL, CB_GETCURSEL, 0, 0);
663                     break;
664                 }
665             break;
666         }
667         break;
668         case WM_HSCROLL : 
669         if( (HWND) lParam == GetDlgItem( hDlg, IDC_INLOOP_A ) ) {
670                 config->i_inloop_a = SendDlgItemMessage( hDlg, IDC_INLOOP_A, TBM_GETPOS, 0, 0 );
671                 set_dlgitem_int( hDlg, IDC_LOOPA_TXT, config->i_inloop_a);
672
673         } else if ( (HWND) lParam == GetDlgItem( hDlg, IDC_INLOOP_B ) ) {
674                 config->i_inloop_b = SendDlgItemMessage( hDlg, IDC_INLOOP_B, TBM_GETPOS, 0, 0 );
675                 set_dlgitem_int( hDlg, IDC_LOOPB_TXT, config->i_inloop_b);
676         }
677         break;
678         case WM_CLOSE:
679             EndDialog( hDlg, LOWORD( wParam ) );
680             break;
681     default :
682         return 0;
683     }
684     return 1;
685 }
686