Exemple #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;
}
Exemple #2
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;
}