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