--- codec.c 2004/01/24 13:36:00 1.1.2.32 +++ codec.c 2004/03/31 19:35:31 1.2.2.1 @@ -58,6 +58,7 @@ #include "status.h" + static const int pmvfast_presets[7] = { 0, 0, 0, 0, 0 | XVID_ME_HALFPELREFINE16 | 0, @@ -72,7 +73,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 +255,7 @@ } -const char type2char(int type) +static char type2char(int type) { if (type==XVID_TYPE_IVOP) return 'I'; @@ -265,7 +266,7 @@ return 'S'; } -int vfw_debug(void *handle, +static int vfw_debug(void *handle, int opt, void *param1, void *param2) @@ -302,53 +303,70 @@ #define XVID_DLL_NAME "xvidcore.dll" -static int init_dll() +static int init_dll(CODEC* codec) { - if (m_hdll != NULL) return 0; + if (codec->m_hdll != NULL) + return 0; DPRINTF("init_dll"); - m_hdll = LoadLibrary(XVID_DLL_NAME); - if (m_hdll == NULL) { + codec->m_hdll = LoadLibrary(XVID_DLL_NAME); + if (codec->m_hdll == NULL) { DPRINTF("dll load failed"); MessageBox(0, XVID_DLL_NAME " not found!","Error!", MB_ICONEXCLAMATION|MB_OK); return XVID_ERR_FAIL; } - xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global"); - if (xvid_global_func == NULL) { + codec->xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(codec->m_hdll, "xvid_global"); + if (codec->xvid_global_func == NULL) { MessageBox(0, "xvid_global() not found", "Error", 0); return XVID_ERR_FAIL; } - xvid_encore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_encore"); - if (xvid_encore_func == NULL) { + codec->xvid_encore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(codec->m_hdll, "xvid_encore"); + if (codec->xvid_encore_func == NULL) { MessageBox(0, "xvid_encore() not found", "Error", 0); return XVID_ERR_FAIL; } - xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore"); - if (xvid_decore_func == NULL) { + codec->xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(codec->m_hdll, "xvid_decore"); + if (codec->xvid_decore_func == NULL) { MessageBox(0, "xvid_decore() not found", "Error", 0); return XVID_ERR_FAIL; } - xvid_plugin_single_func = - (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_single")); - xvid_plugin_2pass1_func = - (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass1")); - xvid_plugin_2pass2_func = - (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass2")); - xvid_plugin_lumimasking_func = - (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_lumimasking")); - xvid_plugin_psnr_func = - (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_psnr")); + codec->xvid_plugin_single_func = + (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(codec->m_hdll, "xvid_plugin_single")); + codec->xvid_plugin_2pass1_func = + (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(codec->m_hdll, "xvid_plugin_2pass1")); + codec->xvid_plugin_2pass2_func = + (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(codec->m_hdll, "xvid_plugin_2pass2")); + codec->xvid_plugin_lumimasking_func = + (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(codec->m_hdll, "xvid_plugin_lumimasking")); + codec->xvid_plugin_psnr_func = + (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(codec->m_hdll, "xvid_plugin_psnr")); return 0; } -void -sort_zones(zone_t * zones, int zone_num, int * sel); +static int exit_dll(CODEC* codec) +{ + if(codec->m_hdll) + { + FreeLibrary(codec->m_hdll); + codec->m_hdll = NULL; + codec->xvid_global_func = NULL; + codec->xvid_encore_func = NULL; + codec->xvid_decore_func = NULL; + codec->xvid_plugin_single_func = NULL; + codec->xvid_plugin_2pass1_func = NULL; + codec->xvid_plugin_2pass2_func = NULL; + codec->xvid_plugin_lumimasking_func = NULL; + codec->xvid_plugin_psnr_func = NULL; + } + return 0; +} +/* constant-quant zones for fixed quant encoding */ static void prepare_cquant_zones(CONFIG * config) { @@ -380,6 +398,38 @@ } } +/* 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) { @@ -395,10 +445,10 @@ 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; + if (init_dll(codec) != 0) return ICERR_ERROR; /* destroy previously created codec */ if(codec->ehandle) { - xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); + codec->xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); codec->ehandle = NULL; } @@ -406,7 +456,7 @@ init.version = XVID_VERSION; init.cpu_flags = codec->config.cpu; init.debug = codec->config.debug; - xvid_global_func(0, XVID_GBL_INIT, &init, NULL); + codec->xvid_global_func(0, XVID_GBL_INIT, &init, NULL); memset(&create, 0, sizeof(create)); create.version = XVID_VERSION; @@ -422,7 +472,7 @@ single.reaction_delay_factor = codec->config.rc_reaction_delay_factor; single.averaging_period = codec->config.rc_averaging_period; single.buffer = codec->config.rc_buffer; - plugins[create.num_plugins].func = xvid_plugin_single_func; + plugins[create.num_plugins].func = codec->xvid_plugin_single_func; plugins[create.num_plugins].param = &single; create.num_plugins++; if (!codec->config.use_2pass_bitrate) /* constant-quant mode */ @@ -433,8 +483,9 @@ memset(&pass1, 0, sizeof(pass1)); pass1.version = XVID_VERSION; pass1.filename = codec->config.stats; - - plugins[create.num_plugins].func = xvid_plugin_2pass1_func; + if (codec->config.full1pass) + prepare_full1pass_zones(&tmpCfg); + plugins[create.num_plugins].func = codec->xvid_plugin_2pass1_func; plugins[create.num_plugins].param = &pass1; create.num_plugins++; break; @@ -469,7 +520,7 @@ pass2.kfthreshold = codec->config.kfthreshold; pass2.container_frame_overhead = 24; /* AVI */ - plugins[create.num_plugins].func = xvid_plugin_2pass2_func; + plugins[create.num_plugins].func = codec->xvid_plugin_2pass2_func; plugins[create.num_plugins].param = &pass2; create.num_plugins++; break; @@ -498,7 +549,7 @@ /* 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].func = codec->xvid_plugin_lumimasking_func; plugins[create.num_plugins].param = NULL; create.num_plugins++; } @@ -540,7 +591,7 @@ create.num_threads = codec->config.num_threads; - switch(xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL)) + switch(codec->xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR; @@ -570,13 +621,12 @@ LRESULT compress_end(CODEC * codec) { - if (m_hdll != NULL) { + if (codec->m_hdll != NULL) { if (codec->ehandle != NULL) { - xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); + codec->xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); codec->ehandle = NULL; } - FreeLibrary(m_hdll); - m_hdll = NULL; + exit_dll(codec); } if (codec->config.display_status) @@ -745,8 +795,10 @@ if ((frame.input.csp = get_colorspace(inhdr)) == XVID_CSP_NULL) return ICERR_BADFORMAT; - if (frame.input.csp == XVID_CSP_I420 || frame.input.csp == XVID_CSP_YV12) - frame.input.stride[0] = (frame.input.stride[0]*2)/3; + if (frame.input.csp == XVID_CSP_I420 || frame.input.csp == XVID_CSP_YV12) { + frame.input.stride[0] = (4 * icc->lpbiInput->biWidth + 3) / 4; + frame.input.stride[1] = frame.input.stride[2] = frame.input.stride[0] / 2 ; + } frame.bitstream = icc->lpOutput; frame.length = icc->lpbiOutput->biSizeImage; @@ -771,7 +823,7 @@ memset(&stats, 0, sizeof(stats)); stats.version = XVID_VERSION; - length = xvid_encore_func(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats); + length = codec->xvid_encore_func(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats); switch (length) { case XVID_ERR_FAIL : @@ -914,19 +966,19 @@ xvid_dec_create_t create; HKEY hKey; - if (init_dll() != 0) return ICERR_ERROR; + if (init_dll(codec) != 0) return ICERR_ERROR; memset(&init, 0, sizeof(init)); init.version = XVID_VERSION; init.cpu_flags = codec->config.cpu; - xvid_global_func(0, XVID_GBL_INIT, &init, NULL); + codec->xvid_global_func(0, XVID_GBL_INIT, &init, NULL); memset(&create, 0, sizeof(create)); create.version = XVID_VERSION; create.width = lpbiInput->bmiHeader.biWidth; create.height = lpbiInput->bmiHeader.biHeight; - switch(xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL)) + switch(codec->xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR; @@ -958,13 +1010,12 @@ LRESULT decompress_end(CODEC * codec) { - if (m_hdll != NULL) { + if (codec->m_hdll != NULL) { if (codec->dhandle != NULL) { - xvid_decore_func(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL); + codec->xvid_decore_func(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL); codec->dhandle = NULL; } - FreeLibrary(m_hdll); - m_hdll = NULL; + exit_dll(codec); } return ICERR_OK; @@ -1012,7 +1063,7 @@ convert.interlacing = 0; if (convert.input.csp == XVID_CSP_NULL || convert.output.csp == XVID_CSP_NULL || - xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0) + codec->xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0) { return ICERR_BADFORMAT; } @@ -1047,7 +1098,7 @@ /* if (pp_dr) frame.general |= XVID_DERING; */ if (pp_fe) frame.general |= XVID_FILMEFFECT; - switch (xvid_decore_func(codec->dhandle, XVID_DEC_DECODE, &frame, NULL)) + switch (codec->xvid_decore_func(codec->dhandle, XVID_DEC_DECODE, &frame, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR;