#include "x264vfw.h"
#include <stdio.h> /* debug only */
+#include <io.h>
+#include <unistd.h>
+
+#define X264_MAX(a,b) ( (a)>(b) ? (a) : (b) )
/* get_csp:
* return a valid x264 CSP or X264_CSP_NULL if unsuported */
return ICERR_OK;
}
+static void statsfilename_renumber( char *dest, char *src, int i_pass )
+{
+ char *last_dot = strrchr( src, '.' );
+ char *last_slash = X264_MAX( strrchr( src, '/' ), strrchr( src, '\\' ) );
+ char pass_str[5];
+
+ sprintf( pass_str, "-%i", i_pass );
+ strcpy( dest, src );
+ if( last_slash < last_dot ) {
+ dest[ last_dot - src ] = 0;
+ strcat( dest, pass_str );
+ strcat( dest, last_dot );
+ }
+ else
+ {
+ strcat( dest, pass_str );
+ }
+}
+
/* */
LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput )
{
CONFIG *config = &codec->config;
x264_param_t param;
+ int pass_number;
/* Destroy previous handle */
if( codec->h != NULL )
/* Get default param */
x264_param_default( ¶m );
+ param.rc.psz_stat_out = malloc (MAX_PATH);
+ param.rc.psz_stat_in = malloc (MAX_PATH);
+
param.i_log_level = X264_LOG_NONE;
param.analyse.b_psnr = 0;
param.analyse.inter = 0;
if( config->b_bsub16x16 )
param.analyse.inter |= X264_ANALYSE_BSUB16x16;
-
if( config->b_psub16x16 )
+ {
param.analyse.inter |= X264_ANALYSE_PSUB16x16;
- if( config->b_psub8x8 )
- param.analyse.inter |= X264_ANALYSE_PSUB8x8;
+ if( config->b_psub8x8 )
+ param.analyse.inter |= X264_ANALYSE_PSUB8x8;
+ }
if( config->b_i4x4 )
param.analyse.inter |= X264_ANALYSE_I4x4;
break;
default:
case 2: /* 2 PASS */
- param.rc.psz_stat_out = param.rc.psz_stat_in = config->stats;
- if (config->i_pass == 1)
+ {
+ for( pass_number = 1; pass_number < 99; pass_number++ )
+ {
+ FILE *f;
+ statsfilename_renumber( param.rc.psz_stat_out, config->stats, pass_number );
+ if( ( f = fopen( param.rc.psz_stat_out, "r" ) ) != NULL )
+ {
+ fclose( f );
+ if( config->i_pass == 1 )
+ unlink( param.rc.psz_stat_out );
+ }
+ else break;
+ }
+
+ if( config->i_pass > pass_number )
{
+ /* missing 1st pass statsfile */
+ free( param.rc.psz_stat_out );
+ free( param.rc.psz_stat_in );
+ return ICERR_ERROR;
+ }
+
+ if( config->i_pass == 1 )
+ {
+ statsfilename_renumber( param.rc.psz_stat_out, config->stats, 1 );
param.rc.b_stat_write = 1;
- if (config->b_fast1pass)
+ if( config->b_fast1pass )
{
/* adjust or turn off some flags to gain speed, if needed */
- if (param.analyse.i_subpel_refine > 1)
- param.analyse.i_subpel_refine --;
- if (param.analyse.i_subpel_refine > 3)
- param.analyse.i_subpel_refine = 3;
- param.i_frame_reference = (param.i_frame_reference + 1) >> 1;
- param.analyse.inter &= (~X264_ANALYSE_PSUB8x8);
- param.analyse.inter &= (~X264_ANALYSE_BSUB16x16);
+ param.analyse.i_subpel_refine = X264_MAX( 3, param.analyse.i_subpel_refine - 1 );
+ param.i_frame_reference = ( param.i_frame_reference + 1 ) >> 1;
+ param.analyse.inter &= ( ~X264_ANALYSE_PSUB8x8 );
+ param.analyse.inter &= ( ~X264_ANALYSE_BSUB16x16 );
}
- }
+ }
else
- {
+ {
+ statsfilename_renumber( param.rc.psz_stat_in, config->stats, pass_number - 1 );
param.rc.i_bitrate = config->i_2passbitrate;
- param.rc.b_stat_read = 1;
param.rc.b_cbr = 1;
+ param.rc.b_stat_read = 1;
if( config->b_updatestats )
param.rc.b_stat_write = 1;
}
+
break;
+ }
}
/* Open the encoder */
codec->h = x264_encoder_open( ¶m );
+
+ free( param.rc.psz_stat_out );
+ free( param.rc.psz_stat_in );
+
if( codec->h == NULL )
return ICERR_ERROR;
/* create bitstream, unless we're dropping it in 1st pass */
i_out = 0;
- if (codec->config.i_encoding_type != 2 || codec->config.i_pass > 1) {
+ if( codec->config.i_encoding_type != 2 || codec->config.i_pass > 1 ) {
for( i = 0; i < i_nal; i++ ) {
int i_size = outhdr->biSizeImage - i_out;
x264_nal_encode( (uint8_t*)icc->lpOutput + i_out, &i_size, 1, &nal[i] );
static const reg_str_t reg_str_table[] =
{
{ "fourcc", reg.fcc, "H264", 5 },
- { "statsfile", reg.stats, ".\\x264.stats", MAX_PATH }
+ { "statsfile", reg.stats, ".\\x264.stats", MAX_PATH-4 } // -4 because we add pass number
};
void config_reg_load( CONFIG *config )
EnableWindow( GetDlgItem( hDlg, IDC_2PASSBITRATE_S ), config->i_pass > 1 );
EnableWindow( GetDlgItem( hDlg, IDC_FAST1PASS ), config->i_pass == 1);
EnableWindow( GetDlgItem( hDlg, IDC_UPDATESTATS ), config->i_pass > 1 );
- EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE_BROWSE ), TRUE );
+ EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE ), config->i_pass == 1 );
+ EnableWindow( GetDlgItem( hDlg, IDC_STATSFILE_BROWSE ), config->i_pass == 1 );
break;
}
ofn.hwndOwner = hDlg;
ofn.lpstrFilter = "Statsfile (*.stats)\0*.stats\0All files (*.*)\0*.*\0\0";
ofn.lpstrFile = tmp;
- ofn.nMaxFile = MAX_PATH;
+ ofn.nMaxFile = MAX_PATH-4;
ofn.Flags = OFN_PATHMUSTEXIST;
if( config->i_pass == 1 )