--- branches/dev-api-4/xvidcore/vfw/src/codec.c 2004/01/23 11:17:24 1326 +++ branches/dev-api-4/xvidcore/vfw/src/codec.c 2004/01/31 14:03:26 1346 @@ -72,7 +72,7 @@ or XVID_CSP_NULL if failure */ -int get_colorspace(BITMAPINFOHEADER * hdr) +static int get_colorspace(BITMAPINFOHEADER * hdr) { /* rgb only: negative height specifies top down image */ int rgb_flip = (hdr->biHeight < 0 ? 0 : XVID_CSP_VFLIP); @@ -254,7 +254,7 @@ } -const char type2char(int type) +static char type2char(int type) { if (type==XVID_TYPE_IVOP) return 'I'; @@ -265,7 +265,7 @@ return 'S'; } -int vfw_debug(void *handle, +static int vfw_debug(void *handle, int opt, void *param1, void *param2) @@ -310,7 +310,7 @@ m_hdll = LoadLibrary(XVID_DLL_NAME); if (m_hdll == NULL) { DPRINTF("dll load failed"); - MessageBox(0, XVID_DLL_NAME " not found","Error", 0); + MessageBox(0, XVID_DLL_NAME " not found!","Error!", MB_ICONEXCLAMATION|MB_OK); return XVID_ERR_FAIL; } @@ -346,6 +346,70 @@ return 0; } +/* constant-quant zones for fixed quant encoding */ +static void +prepare_cquant_zones(CONFIG * config) { + + int i = 0; + if (config->num_zones == 0 || config->zones[0].frame != 0) { + /* first zone does not start at frame 0 or doesn't exist */ + + if (config->num_zones >= MAX_ZONES) config->num_zones--; /* we scrifice last zone */ + + config->zones[config->num_zones].frame = 0; + config->zones[config->num_zones].mode = RC_ZONE_QUANT; + config->zones[config->num_zones].weight = 100; + config->zones[config->num_zones].quant = config->desired_quant; + config->zones[config->num_zones].type = XVID_TYPE_AUTO; + config->zones[config->num_zones].greyscale = 0; + config->zones[config->num_zones].chroma_opt = 0; + config->zones[config->num_zones].bvop_threshold = 0; + config->num_zones++; + + sort_zones(config->zones, config->num_zones, &i); + } + + /* step 2: let's change all weight zones into quant zones */ + + for(i = 0; i < config->num_zones; i++) + if (config->zones[i].mode == RC_ZONE_WEIGHT) { + config->zones[i].mode = RC_ZONE_QUANT; + config->zones[i].quant = (100*config->desired_quant) / config->zones[i].weight; + } +} + +/* full first pass zones */ +static void +prepare_full1pass_zones(CONFIG * config) { + + int i = 0; + if (config->num_zones == 0 || config->zones[0].frame != 0) { + /* first zone does not start at frame 0 or doesn't exist */ + + if (config->num_zones >= MAX_ZONES) config->num_zones--; /* we scrifice last zone */ + + config->zones[config->num_zones].frame = 0; + config->zones[config->num_zones].mode = RC_ZONE_QUANT; + config->zones[config->num_zones].weight = 100; + config->zones[config->num_zones].quant = 200; + config->zones[config->num_zones].type = XVID_TYPE_AUTO; + config->zones[config->num_zones].greyscale = 0; + config->zones[config->num_zones].chroma_opt = 0; + config->zones[config->num_zones].bvop_threshold = 0; + config->num_zones++; + + sort_zones(config->zones, config->num_zones, &i); + } + + /* step 2: let's change all weight zones into quant zones */ + + for(i = 0; i < config->num_zones; i++) + if (config->zones[i].mode == RC_ZONE_WEIGHT) { + config->zones[i].mode = RC_ZONE_QUANT; + config->zones[i].quant = 200; + } +} + LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { @@ -356,6 +420,10 @@ xvid_plugin_2pass1_t pass1; xvid_plugin_2pass2_t pass2; int i; + HANDLE hFile; + + CONFIG tmpCfg; /* if we want to alter config to suit our needs, it shouldn't be visible to user later */ + memcpy(&tmpCfg, &codec->config, sizeof(CONFIG)); if (init_dll() != 0) return ICERR_ERROR; /* destroy previously created codec */ @@ -373,21 +441,6 @@ memset(&create, 0, sizeof(create)); create.version = XVID_VERSION; - /* zones */ - create.zones = malloc(sizeof(xvid_enc_zone_t) * codec->config.num_zones); - create.num_zones = codec->config.num_zones; - for (i=0; i < create.num_zones; i++) { - create.zones[i].frame = codec->config.zones[i].frame; - if (codec->config.zones[i].mode == RC_ZONE_QUANT) { - create.zones[i].mode = XVID_ZONE_QUANT; - create.zones[i].increment = codec->config.zones[i].quant; - }else{ - create.zones[i].mode = XVID_ZONE_WEIGHT; - create.zones[i].increment = codec->config.zones[i].weight; - } - create.zones[i].base = 100; - } - /* plugins */ create.plugins = plugins; switch (codec->config.mode) @@ -402,13 +455,16 @@ plugins[create.num_plugins].func = xvid_plugin_single_func; plugins[create.num_plugins].param = &single; create.num_plugins++; + if (!codec->config.use_2pass_bitrate) /* constant-quant mode */ + prepare_cquant_zones(&tmpCfg); break; case RC_MODE_2PASS1 : memset(&pass1, 0, sizeof(pass1)); pass1.version = XVID_VERSION; pass1.filename = codec->config.stats; - + if (codec->config.full1pass) + prepare_full1pass_zones(&tmpCfg); plugins[create.num_plugins].func = xvid_plugin_2pass1_func; plugins[create.num_plugins].param = &pass1; create.num_plugins++; @@ -419,11 +475,21 @@ pass2.version = XVID_VERSION; if (codec->config.use_2pass_bitrate) { pass2.bitrate = codec->config.bitrate * CONFIG_KBPS; - }else{ + } else { pass2.bitrate = -codec->config.desired_size; /* kilobytes */ } pass2.filename = codec->config.stats; + hFile = CreateFile(pass2.filename, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + MessageBox(0, "Statsfile not found!","Error!", MB_ICONEXCLAMATION|MB_OK); + return XVID_ERR_FAIL; + } else + { + CloseHandle(hFile); + } + pass2.keyframe_boost = codec->config.keyframe_boost; /* keyframe boost percentage: [0..100...]; */ pass2.curve_compression_high = codec->config.curve_compression_high; pass2.curve_compression_low = codec->config.curve_compression_low; @@ -446,6 +512,22 @@ break; } + /* zones - copy from tmpCfg in case we automatically altered them above */ + create.zones = malloc(sizeof(xvid_enc_zone_t) * tmpCfg.num_zones); + create.num_zones = tmpCfg.num_zones; + for (i=0; i < create.num_zones; i++) { + create.zones[i].frame = tmpCfg.zones[i].frame; + if (tmpCfg.zones[i].mode == RC_ZONE_QUANT) { + create.zones[i].mode = XVID_ZONE_QUANT; + create.zones[i].increment = tmpCfg.zones[i].quant; + }else{ + create.zones[i].mode = XVID_ZONE_WEIGHT; + create.zones[i].increment = tmpCfg.zones[i].weight; + } + create.zones[i].base = 100; + } + + /* lumimasking plugin */ if ((profiles[codec->config.profile].flags & PROFILE_ADAPTQUANT) && codec->config.lum_masking) { plugins[create.num_plugins].func = xvid_plugin_lumimasking_func; plugins[create.num_plugins].param = NULL; @@ -877,7 +959,7 @@ switch(xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL)) { - case XVID_ERR_FAIL : + case XVID_ERR_FAIL : return ICERR_ERROR; case XVID_ERR_MEMORY :