Esempio n. 1
0
LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
{
	xvid_gbl_init_t init;
	xvid_enc_create_t create;
	xvid_enc_plugin_t plugins[3];
	xvid_plugin_single_t single;
	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(codec) != 0) return ICERR_ERROR;
	/* destroy previously created codec */
	if(codec->ehandle) {
		codec->xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
		codec->ehandle = NULL;
	}

	memset(&init, 0, sizeof(init));
	init.version = XVID_VERSION;
	init.cpu_flags = codec->config.cpu;
	init.debug = codec->config.debug;
	codec->xvid_global_func(0, XVID_GBL_INIT, &init, NULL);

	memset(&create, 0, sizeof(create));
	create.version = XVID_VERSION;

	/* plugins */
	create.plugins = plugins;
	switch (codec->config.mode) 
	{
	case RC_MODE_1PASS :
		memset(&single, 0, sizeof(single));
		single.version = XVID_VERSION;
		single.bitrate = codec->config.bitrate * CONFIG_KBPS;
		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 = codec->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 = codec->xvid_plugin_2pass1_func;
		plugins[create.num_plugins].param = &pass1;
		create.num_plugins++;
		break;

	case RC_MODE_2PASS2 :
		memset(&pass2, 0, sizeof(pass2));
		pass2.version = XVID_VERSION;
		if (codec->config.use_2pass_bitrate) {
			pass2.bitrate = codec->config.bitrate * CONFIG_KBPS;
		} 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;
		pass2.overflow_control_strength = codec->config.overflow_control_strength;
		pass2.max_overflow_improvement = codec->config.twopass_max_overflow_improvement;
		pass2.max_overflow_degradation = codec->config.twopass_max_overflow_degradation;
		pass2.kfreduction = codec->config.kfreduction;
		pass2.kfthreshold = codec->config.kfthreshold;
		pass2.container_frame_overhead = 24;	/* AVI */

		plugins[create.num_plugins].func = codec->xvid_plugin_2pass2_func;
		plugins[create.num_plugins].param = &pass2;
		create.num_plugins++;
		break;

	case RC_MODE_NULL :
		return ICERR_OK;

	default :
		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 = codec->xvid_plugin_lumimasking_func;
		plugins[create.num_plugins].param = NULL;
		create.num_plugins++; 
	}

	plugins[create.num_plugins].func = vfw_debug;
	plugins[create.num_plugins].param = NULL;
	create.num_plugins++; 

	create.profile = profiles[codec->config.profile].id;

	create.width = lpbiInput->bmiHeader.biWidth;
	create.height = lpbiInput->bmiHeader.biHeight;
	create.fincr = codec->fincr;
	create.fbase = codec->fbase;

	create.max_key_interval = codec->config.max_key_interval;

	create.min_quant[0] = codec->config.min_iquant;
	create.max_quant[0] = codec->config.max_iquant;
	create.min_quant[1] = codec->config.min_pquant;
	create.max_quant[1] = codec->config.max_pquant;
	create.min_quant[2] = codec->config.min_bquant;
	create.max_quant[2] = codec->config.max_bquant;

	if ((profiles[codec->config.profile].flags & PROFILE_BVOP) && codec->config.use_bvop) {
		create.max_bframes = codec->config.max_bframes;
		create.bquant_ratio = codec->config.bquant_ratio;
		create.bquant_offset = codec->config.bquant_offset;

		if (codec->config.packed) 
			create.global |= XVID_GLOBAL_PACKED;

		if (codec->config.closed_gov) 
			create.global |= XVID_GLOBAL_CLOSED_GOP;

	}

	create.frame_drop_ratio = codec->config.frame_drop_ratio;

	create.num_threads = codec->config.num_threads;

	switch(codec->xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL))
	{
	case XVID_ERR_FAIL :	
		return ICERR_ERROR;

	case XVID_ERR_MEMORY :
		return ICERR_MEMORY;

	case XVID_ERR_FORMAT :
		return ICERR_BADFORMAT;

	case XVID_ERR_VERSION :
		return ICERR_UNSUPPORTED;
	}

	free(create.zones);
	codec->ehandle = create.handle;
	codec->framenum = 0;
	codec->keyspacing = 0;

	if (codec->config.display_status) {
		status_destroy_always(&codec->status);
		status_create(&codec->status, codec->fincr, codec->fbase);
	}

	return ICERR_OK;
}
Esempio n. 2
0
/* __declspec(dllexport) */ LRESULT WINAPI DriverProc(
	DWORD_PTR dwDriverId, 
	HDRVR hDriver, 
	UINT uMsg, 
	LPARAM lParam1, 
	LPARAM lParam2) 
{
	CODEC * codec = (CODEC *)dwDriverId;

	switch(uMsg)
	{

	/* driver primitives */

	case DRV_LOAD :
	case DRV_FREE :
		return DRVCNF_OK;

	case DRV_OPEN :
		DPRINTF("DRV_OPEN");

		{
			ICOPEN * icopen = (ICOPEN *)lParam2;
			
			if (icopen != NULL && icopen->fccType != ICTYPE_VIDEO)
			{
				return DRVCNF_CANCEL;
			}

			codec = malloc(sizeof(CODEC));

			if (codec == NULL)
			{
				if (icopen != NULL)
				{
					icopen->dwError = ICERR_MEMORY;
				}
				return 0;
			}
            
			memset(codec, 0, sizeof(CODEC));
            
            codec->status.hDlg = NULL;
            codec->config.ci_valid = 0;
            codec->ehandle = codec->dhandle = NULL;
            codec->fbase = 25;
			codec->fincr = 1;
			config_reg_get(&codec->config);

#if 0
			/* bad things happen if this piece of code is activated */
			if (lstrcmp(XVID_BUILD, codec->config.build))
			{
				config_reg_default(&codec->config);
			}
#endif			

			if (icopen != NULL)
			{
				icopen->dwError = ICERR_OK;
			}
			return (LRESULT)codec;
		}

	case DRV_CLOSE :
		DPRINTF("DRV_CLOSE");
		/* compress_end/decompress_end don't always get called */
		compress_end(codec);
		decompress_end(codec);
		clean_dll_bindings(codec);
        status_destroy_always(&codec->status);
		free(codec);
		return DRVCNF_OK;

	case DRV_DISABLE :
	case DRV_ENABLE :
		return DRVCNF_OK;

	case DRV_INSTALL :
	case DRV_REMOVE :
		return DRVCNF_OK;

	case DRV_QUERYCONFIGURE :
	case DRV_CONFIGURE :
		return DRVCNF_CANCEL;


	/* info */

	case ICM_GETINFO :
		DPRINTF("ICM_GETINFO");
		
		if (lParam1 && lParam2 >= sizeof(ICINFO)) {
			ICINFO *icinfo = (ICINFO *)lParam1;

			icinfo->fccType = ICTYPE_VIDEO;
			icinfo->fccHandler = FOURCC_XVID;
			icinfo->dwFlags =
				VIDCF_FASTTEMPORALC |
				VIDCF_FASTTEMPORALD |
				VIDCF_COMPRESSFRAMES;

			icinfo->dwVersion = 0;
#if !defined(ICVERSION)
#define ICVERSION       0x0104
#endif
			icinfo->dwVersionICM = ICVERSION;
			
			wcscpy(icinfo->szName, XVID_NAME_L); 
			wcscpy(icinfo->szDescription, XVID_DESC_L);
						
			return lParam2; /* size of struct */
		}

		return 0;	/* error */
		
		/* state control */

	case ICM_ABOUT :
		DPRINTF("ICM_ABOUT");
		DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), (HWND)lParam1, about_proc, 0);
		return ICERR_OK;

	case ICM_CONFIGURE :
		DPRINTF("ICM_CONFIGURE");
		if (lParam1 != -1)
		{
			CONFIG temp;

			codec->config.save = FALSE;
			memcpy(&temp, &codec->config, sizeof(CONFIG));

			DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_MAIN), (HWND)lParam1, main_proc, (LPARAM)&temp);

			if (temp.save)
			{
				memcpy(&codec->config, &temp, sizeof(CONFIG));
				config_reg_set(&codec->config);
			}
		}
		return ICERR_OK;
			
	case ICM_GETSTATE :
		DPRINTF("ICM_GETSTATE");
		if ((void*)lParam1 == NULL)
		{
			return sizeof(CONFIG);
		}
		memcpy((void*)lParam1, &codec->config, sizeof(CONFIG));
		return ICERR_OK;

	case ICM_SETSTATE :
		DPRINTF("ICM_SETSTATE");
		if ((void*)lParam1 == NULL)
		{
			DPRINTF("ICM_SETSTATE : DEFAULT");
			config_reg_get(&codec->config);
			return 0;
		}
		memcpy(&codec->config,(void*)lParam1, sizeof(CONFIG));
		return 0; /* sizeof(CONFIG); */

	/* not sure the difference, private/public data? */

	case ICM_GET :
	case ICM_SET :
		return ICERR_OK;


	/* older-stype config */

	case ICM_GETDEFAULTQUALITY :
	case ICM_GETQUALITY :
	case ICM_SETQUALITY :
	case ICM_GETBUFFERSWANTED :
	case ICM_GETDEFAULTKEYFRAMERATE :
		return ICERR_UNSUPPORTED;


	/* compressor */

	case ICM_COMPRESS_QUERY :
		DPRINTF("ICM_COMPRESS_QUERY");
		return compress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_COMPRESS_GET_FORMAT :
		DPRINTF("ICM_COMPRESS_GET_FORMAT");
		return compress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_COMPRESS_GET_SIZE :
		DPRINTF("ICM_COMPRESS_GET_SIZE");
		return compress_get_size(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_COMPRESS_FRAMES_INFO :
		DPRINTF("ICM_COMPRESS_FRAMES_INFO");
		return compress_frames_info(codec, (ICCOMPRESSFRAMES *)lParam1);

	case ICM_COMPRESS_BEGIN :
		DPRINTF("ICM_COMPRESS_BEGIN");
		return compress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_COMPRESS_END :
		DPRINTF("ICM_COMPRESS_END");
		return compress_end(codec);

	case ICM_COMPRESS :
		DPRINTF("ICM_COMPRESS");
		return compress(codec, (ICCOMPRESS *)lParam1);

	/* decompressor */
	
	case ICM_DECOMPRESS_QUERY :
		DPRINTF("ICM_DECOMPRESS_QUERY");
		return decompress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_DECOMPRESS_GET_FORMAT :
		DPRINTF("ICM_DECOMPRESS_GET_FORMAT");
		return decompress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);
	
	case ICM_DECOMPRESS_BEGIN :
		DPRINTF("ICM_DECOMPRESS_BEGIN");
		return decompress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2);

	case ICM_DECOMPRESS_END :
		DPRINTF("ICM_DECOMPRESS_END");
		return decompress_end(codec);

	case ICM_DECOMPRESS :
		DPRINTF("ICM_DECOMPRESS");
		return decompress(codec, (ICDECOMPRESS *)lParam1);

	case ICM_DECOMPRESS_GET_PALETTE :
	case ICM_DECOMPRESS_SET_PALETTE :
	case ICM_DECOMPRESSEX_QUERY:
	case ICM_DECOMPRESSEX_BEGIN:
	case ICM_DECOMPRESSEX_END:
	case ICM_DECOMPRESSEX:
		return ICERR_UNSUPPORTED;

    /* VFWEXT entry point */
    case ICM_USER+0x0fff :
        if (lParam1 == VFWEXT_CONFIGURE_INFO) {
            VFWEXT_CONFIGURE_INFO_T * info = (VFWEXT_CONFIGURE_INFO_T*)lParam2;
            DPRINTF("%i %i %i %i %i %i",
                info->ciWidth, info->ciHeight,
                info->ciRate, info->ciScale,
                info->ciActiveFrame, info->ciFrameCount);

            codec->config.ci_valid = 1;
            memcpy(&codec->config.ci, (void*)lParam2, sizeof(VFWEXT_CONFIGURE_INFO_T));
            return ICERR_OK;
        }
        return ICERR_UNSUPPORTED;

	default:
		if (uMsg < DRV_USER)
			return DefDriverProc(dwDriverId, hDriver, uMsg, lParam1, lParam2);
		else 
			return ICERR_UNSUPPORTED;
	}
}
Esempio n. 3
0
LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
{
	xvid_gbl_init_t init;
	xvid_enc_create_t create;
	xvid_enc_plugin_t plugins[3];
	xvid_plugin_single_t single;
	xvid_plugin_2pass1_t pass1;
	xvid_plugin_2pass2_t pass2;
	xvid_plugin_lumimasking_t masking;
    xvid_gbl_info_t info;
	int i;
	HANDLE hFile;
	const quality_t* quality_preset = (codec->config.quality==quality_table_num) ?
    &codec->config.quality_user : &quality_table[codec->config.quality];

	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(codec) != 0) return ICERR_ERROR;
	/* destroy previously created codec */
	if(codec->ehandle) {
		codec->xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
		codec->ehandle = NULL;
	}

	memset(&init, 0, sizeof(init));
	init.version = XVID_VERSION;
	init.cpu_flags = codec->config.cpu;
	init.debug = codec->config.debug;
	codec->xvid_global_func(0, XVID_GBL_INIT, &init, NULL);

	memset(&info, 0, sizeof(info));
	info.version = XVID_VERSION;
	codec->xvid_global_func(0, XVID_GBL_INFO, &info, NULL);

	memset(&create, 0, sizeof(create));
	create.version = XVID_VERSION;

    /* Encoder threads */
    if (codec->config.cpu & XVID_CPU_FORCE)
		create.num_threads = codec->config.num_threads;
	else 
        create.num_threads = info.num_threads; /* Autodetect */

	/* Encoder slices */
	if ((profiles[codec->config.profile].flags & PROFILE_RESYNCMARKER) && codec->config.num_slices != 1) {
		
		if (codec->config.num_slices == 0) { /* auto */
			int mb_width = (lpbiInput->bmiHeader.biWidth + 15) / 16;
			int mb_height = (lpbiInput->bmiHeader.biHeight + 15) / 16;

			int slices = (int)((mb_width*mb_height) / 811); /* use multiple slices only above SD resolutions for now */

			if (slices > 1) {
				if (create.num_threads <= 1)
					slices &= ~1; /* make even */
				else if (create.num_threads <= slices)
					slices = (slices / create.num_threads) * create.num_threads; /* multiple of threads */
				else if (create.num_threads % slices)
					slices = (!(create.num_threads%2)) ? (create.num_threads/2) : (create.num_threads/3);
			}

			create.num_slices = slices;
		}
		else {
			create.num_slices = codec->config.num_slices; /* force manual value - by registry edit */
		}

	}

	/* plugins */
	create.plugins = plugins;
	switch (codec->config.mode) 
	{
	case RC_MODE_1PASS :
		memset(&single, 0, sizeof(single));
		single.version = XVID_VERSION;
		single.bitrate = codec->config.bitrate * CONFIG_KBPS;
		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 = codec->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 = codec->xvid_plugin_2pass1_func;
		plugins[create.num_plugins].param = &pass1;
		create.num_plugins++;
		break;

	case RC_MODE_2PASS2 :
		memset(&pass2, 0, sizeof(pass2));
		pass2.version = XVID_VERSION;
		if (codec->config.use_2pass_bitrate) {
			pass2.bitrate = codec->config.bitrate * CONFIG_KBPS;
		} 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;
		pass2.overflow_control_strength = codec->config.overflow_control_strength;
		pass2.max_overflow_improvement = codec->config.twopass_max_overflow_improvement;
		pass2.max_overflow_degradation = codec->config.twopass_max_overflow_degradation;
		pass2.kfreduction = codec->config.kfreduction;
		pass2.kfthreshold = codec->config.kfthreshold;
		pass2.container_frame_overhead = 24;	/* AVI */

		/* VBV */
		pass2.vbv_size = profiles[codec->config.profile].max_vbv_size;
		pass2.vbv_initial = (profiles[codec->config.profile].max_vbv_size*3)/4; /* 75% */
		pass2.vbv_maxrate = profiles[codec->config.profile].max_bitrate;
		pass2.vbv_peakrate = profiles[codec->config.profile].vbv_peakrate;

		plugins[create.num_plugins].func = codec->xvid_plugin_2pass2_func;
		plugins[create.num_plugins].param = &pass2;
		create.num_plugins++;
		break;

	case RC_MODE_NULL :
		return ICERR_OK;

	default :
		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>0)) {
		memset(&masking, 0, sizeof(masking));
		masking.method = (codec->config.lum_masking==2);
		plugins[create.num_plugins].func = codec->xvid_plugin_lumimasking_func;
		plugins[create.num_plugins].param = &masking;
		create.num_plugins++; 
	}

	plugins[create.num_plugins].func = vfw_debug;
	plugins[create.num_plugins].param = NULL;
	create.num_plugins++; 

	create.profile = profiles[codec->config.profile].id;

	create.width = lpbiInput->bmiHeader.biWidth;
	create.height = lpbiInput->bmiHeader.biHeight;
	create.fincr = codec->fincr;
	create.fbase = codec->fbase;

	create.max_key_interval = quality_preset->max_key_interval;

	create.min_quant[0] = quality_preset->min_iquant;
	create.max_quant[0] = quality_preset->max_iquant;
	create.min_quant[1] = quality_preset->min_pquant;
	create.max_quant[1] = quality_preset->max_pquant;
	create.min_quant[2] = quality_preset->min_bquant;
	create.max_quant[2] = quality_preset->max_bquant;

	if ((profiles[codec->config.profile].flags & PROFILE_BVOP) && codec->config.use_bvop) {

    /* dxn: prevent bframes usage if interlacing is selected */
    if (!((profiles[codec->config.profile].flags & PROFILE_EXTRA) && codec->config.interlacing)) {
      create.max_bframes = codec->config.max_bframes;
		  create.bquant_ratio = codec->config.bquant_ratio;
		  create.bquant_offset = codec->config.bquant_offset;

		  if (codec->config.packed) 
			  create.global |= XVID_GLOBAL_PACKED;

		  create.global |= XVID_GLOBAL_CLOSED_GOP;

      /* restrict max bframes */
      if ((create.max_bframes > profiles[codec->config.profile].xvid_max_bframes) && (profiles[codec->config.profile].xvid_max_bframes >= 0))
        create.max_bframes = profiles[codec->config.profile].xvid_max_bframes;

      /* DXN: enable packed bframes */
      if ((profiles[codec->config.profile].flags & PROFILE_PACKED)) {
        create.global |= XVID_GLOBAL_PACKED;
      }
    }
	}

    /* dxn: always write divx5 userdata */
    if ((profiles[codec->config.profile].flags & PROFILE_EXTRA))
      create.global |= XVID_GLOBAL_DIVX5_USERDATA;

	if ((profiles[codec->config.profile].flags & PROFILE_EXTRA) || 
		(profiles[codec->config.profile].flags & PROFILE_XVID)) {
  	  create.frame_drop_ratio = 0;
	} else {
  	  create.frame_drop_ratio = quality_preset->frame_drop_ratio;
	}

	switch(codec->xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL))
	{
	case XVID_ERR_FAIL :	
		return ICERR_ERROR;

	case XVID_ERR_MEMORY :
		return ICERR_MEMORY;

	case XVID_ERR_FORMAT :
		return ICERR_BADFORMAT;

	case XVID_ERR_VERSION :
		return ICERR_UNSUPPORTED;
	}

	free(create.zones);
	codec->ehandle = create.handle;
	codec->framenum = 0;
	codec->keyspacing = 0;

	if (codec->config.display_status) {
		status_destroy_always(&codec->status);
		status_create(&codec->status, codec->fincr, codec->fbase);
	}

	return ICERR_OK;
}