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.17 2003-05-29 13:53:17 edgomez Exp $ |
* $Id: plugin_2pass2.c,v 1.1.2.18 2003-05-29 14:18:18 edgomez Exp $ |
29 |
* |
* |
30 |
*****************************************************************************/ |
*****************************************************************************/ |
31 |
|
|
357 |
if (data->frame_num >= rc->num_frames) |
if (data->frame_num >= rc->num_frames) |
358 |
return 0; |
return 0; |
359 |
|
|
|
/* |
|
|
* The last case is the one every normal minded developer should fear to |
|
|
* maintain in a project :-) |
|
|
*/ |
|
|
|
|
360 |
/* XXX: why by 8 */ |
/* XXX: why by 8 */ |
361 |
overflow = rc->overflow / 8; |
overflow = rc->overflow / 8; |
362 |
|
|
375 |
dbytes /= rc->movie_curve; |
dbytes /= rc->movie_curve; |
376 |
|
|
377 |
/* |
/* |
|
* We are now entering in the hard part of the algo, it was first designed |
|
|
* to work with i/pframes only streams, so the way it computes things is |
|
|
* adapted to pframes only. However we can use it if we just take care to |
|
|
* scale the bframes sizes to pframes sizes using the ratio avg_p/avg_p and |
|
|
* then before really using values depending on frame sizes, scaling the |
|
|
* value again with the inverse ratio |
|
|
*/ |
|
|
if (s->type == XVID_TYPE_BVOP) |
|
|
dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1]; |
|
|
|
|
|
/* |
|
378 |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
379 |
* scaled curve "paying back" past errors in curve previsions. |
* scaled curve "paying back" past errors in curve previsions. |
380 |
*/ |
*/ |
382 |
desired = (int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
desired = (int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
383 |
} else { |
} else { |
384 |
desired = (int)(rc->curve_comp_error * dbytes / |
desired = (int)(rc->curve_comp_error * dbytes / |
385 |
rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay); |
rc->avg_length[s->type-1] / rc->param.bitrate_payback_delay); |
386 |
|
|
387 |
if (labs(desired) > fabs(rc->curve_comp_error)) { |
if (labs(desired) > fabs(rc->curve_comp_error)) |
388 |
desired = (int)rc->curve_comp_error; |
desired = (int)rc->curve_comp_error; |
389 |
} |
} |
|
} |
|
390 |
|
|
391 |
rc->curve_comp_error -= desired; |
rc->curve_comp_error -= desired; |
392 |
|
|
396 |
if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) { |
if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) { |
397 |
|
|
398 |
curve_temp = rc->curve_comp_scale; |
curve_temp = rc->curve_comp_scale; |
399 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[s->type-1]) { |
400 |
curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
curve_temp *= ((double)dbytes + (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
401 |
} else { |
} else { |
402 |
curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
curve_temp *= ((double)dbytes + (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
403 |
} |
} |
404 |
|
|
|
/* |
|
|
* 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]; |
|
|
|
|
405 |
desired += (int)curve_temp; |
desired += (int)curve_temp; |
406 |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
407 |
} else { |
} 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]; |
|
|
|
|
408 |
desired += (int)dbytes; |
desired += (int)dbytes; |
409 |
rc->curve_comp_error += dbytes - (int)dbytes; |
rc->curve_comp_error += dbytes - (int)dbytes; |
410 |
} |
} |
429 |
|
|
430 |
s->desired_length = desired; |
s->desired_length = desired; |
431 |
|
|
|
|
|
432 |
/* |
/* |
433 |
* if this keyframe is too close to the next, reduce it's byte allotment |
* if this keyframe is too close to the next, reduce it's byte allotment |
434 |
* XXX: why do we do this after setting the desired length ? |
* XXX: why do we do this after setting the desired length ? |
457 |
} |
} |
458 |
} |
} |
459 |
|
|
460 |
|
/* |
461 |
|
* The "sens commun" would force us to use rc->avg_length[s->type-1] but |
462 |
|
* even VFW code uses the pframe average length. Note that this length is |
463 |
|
* used with desired which represents bframes _and_ pframes length. |
464 |
|
* |
465 |
|
* XXX: why are we using the avg pframe length for all frame types ? |
466 |
|
*/ |
467 |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
468 |
|
|
469 |
/* Reign in overflow with huge frames */ |
/* Reign in overflow with huge frames */ |
696 |
}else if (type == 'b') { |
}else if (type == 'b') { |
697 |
s->type = XVID_TYPE_BVOP; |
s->type = XVID_TYPE_BVOP; |
698 |
}else{ /* unknown type */ |
}else{ /* unknown type */ |
699 |
DPRINTF(XVID_DEBUG_RC, "unknown stats frame type; assuming pvop\n"); |
DPRINTF(XVID_DEBUG_RC, "WARNING: unknown stats frame type, assuming pvop\n"); |
700 |
s->type = XVID_TYPE_PVOP; |
s->type = XVID_TYPE_PVOP; |
701 |
} |
} |
702 |
|
|
982 |
dbytes = s->scaled_length / rc->movie_curve; |
dbytes = s->scaled_length / rc->movie_curve; |
983 |
dbytes2 = 0; /* XXX: warning */ |
dbytes2 = 0; /* XXX: warning */ |
984 |
total1 += dbytes; |
total1 += dbytes; |
|
if (s->type == XVID_TYPE_BVOP) |
|
|
dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1]; |
|
985 |
|
|
986 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[s->type-1]) { |
987 |
dbytes2=((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
dbytes2=((double)dbytes + (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_high / 100.0); |
988 |
} else { |
} else { |
989 |
dbytes2 = ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
dbytes2 = ((double)dbytes + (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_low / 100.0); |
990 |
} |
} |
991 |
|
|
992 |
if (s->type == XVID_TYPE_BVOP) { |
if (dbytes2 < rc->min_length[s->type-1]) |
993 |
dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
dbytes2 = rc->min_length[s->type-1]; |
994 |
if (dbytes2 < rc->min_length[XVID_TYPE_BVOP-1]) |
|
|
dbytes2 = rc->min_length[XVID_TYPE_BVOP-1]; |
|
|
}else{ |
|
|
if (dbytes2 < rc->min_length[XVID_TYPE_PVOP-1]) |
|
|
dbytes2 = rc->min_length[XVID_TYPE_PVOP-1]; |
|
|
} |
|
995 |
total2 += dbytes2; |
total2 += dbytes2; |
996 |
} |
} |
997 |
} |
} |
998 |
|
|
999 |
rc->curve_comp_scale = total1 / total2; |
rc->curve_comp_scale = total1 / total2; |
1000 |
|
|
1001 |
DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: %i\n", |
DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: pframe%d bframe:%d\n", |
1002 |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale)); |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale), |
1003 |
|
(int)(rc->avg_length[XVID_TYPE_BVOP-1] * rc->curve_comp_scale)); |
1004 |
|
|
1005 |
rc->overflow = 0; |
rc->overflow = 0; |
1006 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |