25 |
* along with this program; if not, write to the Free Software |
* along with this program; if not, write to the Free Software |
26 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
27 |
* |
* |
28 |
* $Id: plugin_2pass2.c,v 1.1.2.12 2003-05-24 22:03:50 edgomez Exp $ |
* $Id: plugin_2pass2.c,v 1.1.2.14 2003-05-29 10:36:41 edgomez Exp $ |
29 |
* |
* |
30 |
*****************************************************************************/ |
*****************************************************************************/ |
31 |
|
|
40 |
* Some constants |
* Some constants |
41 |
****************************************************************************/ |
****************************************************************************/ |
42 |
|
|
|
#define RAD2DEG 57.295779513082320876798154814105 |
|
|
#define DEG2RAD 0.017453292519943295769236907684886 |
|
|
|
|
43 |
#define DEFAULT_KEYFRAME_BOOST 0 |
#define DEFAULT_KEYFRAME_BOOST 0 |
44 |
#define DEFAULT_PAYBACK_METHOD XVID_PAYBACK_PROP |
#define DEFAULT_PAYBACK_METHOD XVID_PAYBACK_PROP |
45 |
#define DEFAULT_BITRATE_PAYBACK_DELAY 250 |
#define DEFAULT_BITRATE_PAYBACK_DELAY 250 |
106 |
double curve_comp_scale; |
double curve_comp_scale; |
107 |
double movie_curve; |
double movie_curve; |
108 |
|
|
|
double alt_curve_low; |
|
|
double alt_curve_high; |
|
|
double alt_curve_low_diff; |
|
|
double alt_curve_high_diff; |
|
|
double alt_curve_curve_bias_bonus; |
|
|
double alt_curve_mid_qual; |
|
|
double alt_curve_qual_dev; |
|
|
|
|
109 |
/* dynamic */ |
/* dynamic */ |
110 |
|
|
111 |
int * keyframe_locations; |
int * keyframe_locations; |
200 |
_INIT(rc->param.max_overflow_improvement, DEFAULT_MAX_OVERFLOW_IMPROVEMENT); |
_INIT(rc->param.max_overflow_improvement, DEFAULT_MAX_OVERFLOW_IMPROVEMENT); |
201 |
_INIT(rc->param.max_overflow_degradation, DEFAULT_MAX_OVERFLOW_DEGRADATION); |
_INIT(rc->param.max_overflow_degradation, DEFAULT_MAX_OVERFLOW_DEGRADATION); |
202 |
|
|
|
/* Alt curve settings */ |
|
|
_INIT(rc->param.use_alt_curve, DEFAULT_USE_ALT_CURVE); |
|
|
_INIT(rc->param.alt_curve_high_dist, DEFAULT_ALT_CURVE_HIGH_DIST); |
|
|
_INIT(rc->param.alt_curve_low_dist, DEFAULT_ALT_CURVE_LOW_DIST); |
|
|
_INIT(rc->param.alt_curve_use_auto, DEFAULT_ALT_CURVE_USE_AUTO); |
|
|
_INIT(rc->param.alt_curve_auto_str, DEFAULT_ALT_CURVE_AUTO_STR); |
|
|
_INIT(rc->param.alt_curve_type, DEFAULT_ALT_CURVE_TYPE); |
|
|
_INIT(rc->param.alt_curve_min_rel_qual, DEFAULT_ALT_CURVE_MIN_REL_QUAL); |
|
|
_INIT(rc->param.alt_curve_use_auto_bonus_bias, DEFAULT_ALT_CURVE_USE_AUTO_BONUS_BIAS); |
|
|
_INIT(rc->param.alt_curve_bonus_bias, DEFAULT_ALT_CURVE_BONUS_BIAS); |
|
|
|
|
203 |
/* Keyframe settings */ |
/* Keyframe settings */ |
204 |
_INIT(rc->param.kftreshold, DEFAULT_KFTRESHOLD); |
_INIT(rc->param.kftreshold, DEFAULT_KFTRESHOLD); |
205 |
_INIT(rc->param.kfreduction, DEFAULT_KFREDUCTION); |
_INIT(rc->param.kfreduction, DEFAULT_KFREDUCTION); |
348 |
* The rc->overflow field represents the overflow in current scene (between two |
* The rc->overflow field represents the overflow in current scene (between two |
349 |
* IFrames) so we must not forget to reset it if we are entering a new scene |
* IFrames) so we must not forget to reset it if we are entering a new scene |
350 |
*/ |
*/ |
351 |
if (s->type == XVID_TYPE_IVOP) { |
if (s->type == XVID_TYPE_IVOP) |
352 |
overflow = 0; |
overflow = 0; |
|
} |
|
353 |
|
|
354 |
desired = s->scaled_length; |
desired = s->scaled_length; |
355 |
|
|
356 |
dbytes = desired; |
dbytes = desired; |
357 |
if (s->type == XVID_TYPE_IVOP) { |
if (s->type == XVID_TYPE_IVOP) |
358 |
dbytes += desired * rc->param.keyframe_boost / 100; |
dbytes += desired * rc->param.keyframe_boost / 100; |
|
} |
|
359 |
dbytes /= rc->movie_curve; |
dbytes /= rc->movie_curve; |
360 |
|
|
361 |
/* |
/* |
395 |
/* XXX: warning */ |
/* XXX: warning */ |
396 |
curve_temp = 0; |
curve_temp = 0; |
397 |
|
|
398 |
if (rc->param.use_alt_curve) { |
if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) { |
|
if (s->type != XVID_TYPE_IVOP) { |
|
|
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
|
|
if (dbytes >= rc->alt_curve_high) { |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev); |
|
|
} else { |
|
|
switch(rc->param.alt_curve_type) { |
|
|
case XVID_CURVE_SINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)))); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
if (dbytes <= rc->alt_curve_low){ |
|
|
curve_temp = dbytes; |
|
|
} else { |
|
|
switch(rc->param.alt_curve_type) { |
|
|
case XVID_CURVE_SINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)))); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* |
|
|
* End of code path for curve_temp, as told earlier, we are now |
|
|
* obliged to scale the value to a bframe one using the inverse |
|
|
* ratio applied earlier |
|
|
*/ |
|
|
if (s->type == XVID_TYPE_BVOP) |
|
|
curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
|
|
|
|
|
curve_temp = curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus; |
|
|
|
|
|
desired += ((int)curve_temp); |
|
|
rc->curve_comp_error += curve_temp - (int)curve_temp; |
|
|
} else { |
|
|
/* |
|
|
* End of code path for dbytes, as told earlier, we are now |
|
|
* obliged to scale the value to a bframe one using the inverse |
|
|
* ratio applied earlier |
|
|
*/ |
|
|
if (s->type == XVID_TYPE_BVOP) |
|
|
dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
|
|
|
|
|
desired += ((int)dbytes); |
|
|
rc->curve_comp_error += dbytes - (int)dbytes; |
|
|
} |
|
|
|
|
|
} else if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) { |
|
399 |
|
|
400 |
curve_temp = rc->curve_comp_scale; |
curve_temp = rc->curve_comp_scale; |
401 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
477 |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
478 |
|
|
479 |
/* Reign in overflow with huge frames */ |
/* Reign in overflow with huge frames */ |
480 |
if (labs(overflow) > labs(rc->overflow)) { |
if (labs(overflow) > labs(rc->overflow)) |
481 |
overflow = rc->overflow; |
overflow = rc->overflow; |
|
} |
|
482 |
|
|
483 |
/* Make sure overflow doesn't run away */ |
/* Make sure overflow doesn't run away */ |
484 |
if (overflow > desired * rc->param.max_overflow_improvement / 100) { |
if (overflow > desired * rc->param.max_overflow_improvement / 100) { |
581 |
* We don't want to pollute the RC history results when our computed quant |
* We don't want to pollute the RC history results when our computed quant |
582 |
* has been computed from a capped frame size |
* has been computed from a capped frame size |
583 |
*/ |
*/ |
584 |
if (capped_to_max_framesize == 0) { |
if (capped_to_max_framesize == 0) |
585 |
rc->last_quant[s->type-1] = data->quant; |
rc->last_quant[s->type-1] = data->quant; |
|
} |
|
586 |
|
|
587 |
return 0; |
return 0; |
588 |
} |
} |
847 |
int64_t target = rc->target - rc->tot_quant; |
int64_t target = rc->target - rc->tot_quant; |
848 |
int64_t pass1_length = rc->tot_length[0] + rc->tot_length[1] + rc->tot_length[2] - rc->tot_quant; |
int64_t pass1_length = rc->tot_length[0] + rc->tot_length[1] + rc->tot_length[2] - rc->tot_quant; |
849 |
double scaler; |
double scaler; |
850 |
int i; |
int i, num_MBs; |
851 |
|
int min_size[3]; |
852 |
|
|
853 |
/* Let's compute a linear scaler in order to perform curve scaling */ |
/* Let's compute a linear scaler in order to perform curve scaling */ |
854 |
scaler = (double)target / (double)pass1_length; |
scaler = (double)target / (double)pass1_length; |
863 |
(int)target, (int)pass1_length, scaler); |
(int)target, (int)pass1_length, scaler); |
864 |
|
|
865 |
/* |
/* |
866 |
|
* Compute min frame lengths (for each frame type) according to the number |
867 |
|
* of MBs. We sum all blocks count from frame 0 (should be an IFrame, so |
868 |
|
* blocks[0] should be enough) to know how many MBs there are. |
869 |
|
*/ |
870 |
|
num_MBs = rc->stats[0].blks[0] + rc->stats[0].blks[1] + rc->stats[0].blks[2]; |
871 |
|
min_size[0] = ((num_MBs*22) + 240) / 8; |
872 |
|
min_size[1] = ((num_MBs) + 88) / 8; |
873 |
|
min_size[2] = 8; |
874 |
|
|
875 |
|
/* |
876 |
* Perform an initial scale pass. |
* Perform an initial scale pass. |
877 |
* If a frame size is scaled underneath our hardcoded minimums, then we |
* If a frame size is scaled underneath our hardcoded minimums, then we |
878 |
* force the frame size to the minimum, and deduct the original & scaled |
* force the frame size to the minimum, and deduct the original & scaled |
879 |
* frame length from the original and target total lengths |
* frame length from the original and target total lengths |
880 |
*/ |
*/ |
|
|
|
881 |
for (i=0; i<rc->num_frames; i++) { |
for (i=0; i<rc->num_frames; i++) { |
882 |
stat_t * s = &rc->stats[i]; |
stat_t * s = &rc->stats[i]; |
|
int min_size[3]; |
|
883 |
int len; |
int len; |
884 |
|
|
|
/* Compute min frame lengths (oe for each frame type) */ |
|
|
min_size[0] = ((s->blks[0]*22) + 240) / 8; |
|
|
min_size[1] = (s->blks[0] + 88) / 8; |
|
|
min_size[2] = 8; |
|
|
|
|
885 |
if (s->zone_mode == XVID_ZONE_QUANT) { |
if (s->zone_mode == XVID_ZONE_QUANT) { |
886 |
s->scaled_length = s->length; |
s->scaled_length = s->length; |
887 |
continue; |
continue; |
900 |
/* Do nothing for now, we'll scale this later */ |
/* Do nothing for now, we'll scale this later */ |
901 |
s->scaled_length = 0; |
s->scaled_length = 0; |
902 |
} |
} |
|
|
|
903 |
} |
} |
904 |
|
|
905 |
/* Correct the scaler for all non forced frames */ |
/* Correct the scaler for all non forced frames */ |
961 |
} |
} |
962 |
} |
} |
963 |
|
|
|
/* alt curve stuff here */ |
|
|
|
|
|
if (rc->param.use_alt_curve) { |
|
|
const double avg_pvop = rc->avg_length[XVID_TYPE_PVOP-1]; |
|
|
const uint64_t tot_pvop = rc->tot_length[XVID_TYPE_PVOP-1]; |
|
|
const uint64_t tot_bvop = rc->tot_length[XVID_TYPE_BVOP-1]; |
|
|
const uint64_t tot_scaled_pvop = rc->tot_scaled_length[XVID_TYPE_PVOP-1]; |
|
|
const uint64_t tot_scaled_bvop = rc->tot_scaled_length[XVID_TYPE_BVOP-1]; |
|
|
|
|
|
rc->alt_curve_low = avg_pvop - avg_pvop * (double)rc->param.alt_curve_low_dist / 100.0; |
|
|
rc->alt_curve_low_diff = avg_pvop - rc->alt_curve_low; |
|
|
rc->alt_curve_high = avg_pvop + avg_pvop * (double)rc->param.alt_curve_high_dist / 100.0; |
|
|
rc->alt_curve_high_diff = rc->alt_curve_high - avg_pvop; |
|
|
|
|
|
if (rc->param.alt_curve_use_auto) { |
|
|
if (tot_bvop + tot_pvop > tot_scaled_bvop + tot_scaled_pvop) { |
|
|
rc->param.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / |
|
|
((double)(tot_pvop + tot_bvop) / (double)(tot_scaled_pvop + tot_scaled_bvop))) * (double)rc->param.alt_curve_auto_str / 100.0); |
|
|
|
|
|
if (rc->param.alt_curve_min_rel_qual < 20) |
|
|
rc->param.alt_curve_min_rel_qual = 20; |
|
|
}else{ |
|
|
rc->param.alt_curve_min_rel_qual = 100; |
|
|
} |
|
|
} |
|
|
rc->alt_curve_mid_qual = (1.0 + (double)rc->param.alt_curve_min_rel_qual / 100.0) / 2.0; |
|
|
rc->alt_curve_qual_dev = 1.0 - rc->alt_curve_mid_qual; |
|
|
|
|
|
if (rc->param.alt_curve_low_dist > 100) { |
|
|
switch(rc->param.alt_curve_type) { |
|
|
case XVID_CURVE_SINE: // Sine Curve (high aggressiveness) |
|
|
rc->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff))); |
|
|
rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR: // Linear (medium aggressiveness) |
|
|
rc->alt_curve_qual_dev *= 2.0 / (1.0 + avg_pvop / rc->alt_curve_low_diff); |
|
|
rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * avg_pvop / rc->alt_curve_low_diff; |
|
|
break; |
|
|
case XVID_CURVE_COSINE: // Cosine Curve (low aggressiveness) |
|
|
rc->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)))); |
|
|
rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff))); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
964 |
/* --- */ |
/* --- */ |
965 |
|
|
966 |
total1=total2=0; |
total1=total2=0; |
977 |
if (s->type == XVID_TYPE_BVOP) |
if (s->type == XVID_TYPE_BVOP) |
978 |
dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1]; |
dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1]; |
979 |
|
|
|
if (rc->param.use_alt_curve) { |
|
|
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
|
|
|
|
|
if (dbytes >= rc->alt_curve_high) { |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev); |
|
|
}else{ |
|
|
switch(rc->param.alt_curve_type) { |
|
|
case XVID_CURVE_SINE : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)))); |
|
|
} |
|
|
} |
|
|
}else{ |
|
|
if (dbytes <= rc->alt_curve_low) { |
|
|
dbytes2 = dbytes; |
|
|
}else{ |
|
|
switch(rc->param.alt_curve_type) { |
|
|
case XVID_CURVE_SINE : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
dbytes2 = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)))); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
}else{ |
|
980 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
981 |
dbytes2=((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
dbytes2=((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
982 |
}else{ |
}else{ |
983 |
dbytes2 = ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
dbytes2 = ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
984 |
} |
} |
|
} |
|
985 |
|
|
986 |
if (s->type == XVID_TYPE_BVOP) { |
if (s->type == XVID_TYPE_BVOP) { |
987 |
dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
997 |
|
|
998 |
rc->curve_comp_scale = total1 / total2; |
rc->curve_comp_scale = total1 / total2; |
999 |
|
|
|
if (!rc->param.use_alt_curve) { |
|
1000 |
DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: %i\n", |
DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: %i\n", |
1001 |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale)); |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale)); |
|
} |
|
|
|
|
|
if (rc->param.use_alt_curve) { |
|
|
int bonus_bias = rc->param.alt_curve_bonus_bias; |
|
|
int oldquant = 1; |
|
|
|
|
|
if (rc->param.alt_curve_use_auto_bonus_bias) |
|
|
bonus_bias = rc->param.alt_curve_min_rel_qual; |
|
|
|
|
|
rc->alt_curve_curve_bias_bonus = (total1 - total2) * (double)bonus_bias / 100.0 / (double)(rc->num_frames /* - credits_frames */ - rc->num_keyframes); |
|
|
rc->curve_comp_scale = ((total1 - total2) * (1.0 - (double)bonus_bias / 100.0) + total2) / total2; |
|
|
|
|
|
|
|
|
/* special info for alt curve: bias bonus and quantizer thresholds */ |
|
|
|
|
|
DPRINTF(XVID_DEBUG_RC, "avg scaled framesize:%i\n", (int)rc->avg_length[XVID_TYPE_PVOP-1]); |
|
|
DPRINTF(XVID_DEBUG_RC, "bias bonus:%i bytes\n", (int)rc->alt_curve_curve_bias_bonus); |
|
|
|
|
|
for (i=1; i <= (int)(rc->alt_curve_high*2)+1; i++) { |
|
|
double curve_temp, dbytes; |
|
|
int newquant; |
|
|
|
|
|
dbytes = i; |
|
|
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
|
|
if (dbytes >= rc->alt_curve_high) { |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev); |
|
|
}else{ |
|
|
switch(rc->param.alt_curve_type) |
|
|
{ |
|
|
case XVID_CURVE_SINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)))); |
|
|
} |
|
|
} |
|
|
}else{ |
|
|
if (dbytes <= rc->alt_curve_low) { |
|
|
curve_temp = dbytes; |
|
|
}else{ |
|
|
switch(rc->param.alt_curve_type) |
|
|
{ |
|
|
case XVID_CURVE_SINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))); |
|
|
break; |
|
|
case XVID_CURVE_LINEAR : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff); |
|
|
break; |
|
|
case XVID_CURVE_COSINE : |
|
|
curve_temp = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)))); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
if (rc->movie_curve > 1.0) |
|
|
dbytes *= rc->movie_curve; |
|
|
|
|
|
newquant = (int)(dbytes * 2.0 / (curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus)); |
|
|
if (newquant > 1) { |
|
|
if (newquant != oldquant) { |
|
|
int percent = (int)((i - rc->avg_length[XVID_TYPE_PVOP-1]) * 100.0 / rc->avg_length[XVID_TYPE_PVOP-1]); |
|
|
oldquant = newquant; |
|
|
DPRINTF(XVID_DEBUG_RC, "quant:%i threshold at %i : %i percent\n", newquant, i, percent); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
1002 |
|
|
1003 |
rc->overflow = 0; |
rc->overflow = 0; |
1004 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |