96 |
double movie_curve; |
double movie_curve; |
97 |
|
|
98 |
/* dynamic */ |
/* dynamic */ |
|
|
|
99 |
int * keyframe_locations; |
int * keyframe_locations; |
100 |
stat_t * stats; |
stat_t * stats; |
101 |
|
|
243 |
} |
} |
244 |
|
|
245 |
/* Compute the target filesize */ |
/* Compute the target filesize */ |
246 |
if (rc->num_frames < create->fbase/create->fincr) { |
if (rc->param.bitrate<0) { |
247 |
|
/* if negative, bitrate equals the target (in kbytes) */ |
248 |
|
rc->target = (-rc->param.bitrate) * 1024; |
249 |
|
} else if (rc->num_frames < create->fbase/create->fincr) { |
250 |
/* Source sequence is less than 1s long, we do as if it was 1s long */ |
/* Source sequence is less than 1s long, we do as if it was 1s long */ |
251 |
rc->target = rc->param.bitrate / 8; |
rc->target = rc->param.bitrate / 8; |
252 |
} else { |
} else { |
359 |
if (data->frame_num >= rc->num_frames) |
if (data->frame_num >= rc->num_frames) |
360 |
return 0; |
return 0; |
361 |
|
|
|
/* |
|
|
* The last case is the one every normal minded developer should fear to |
|
|
* maintain in a project :-) |
|
|
*/ |
|
|
|
|
362 |
/* XXX: why by 8 */ |
/* XXX: why by 8 */ |
363 |
overflow = rc->overflow / 8; |
overflow = rc->overflow / 8; |
364 |
|
|
377 |
dbytes /= rc->movie_curve; |
dbytes /= rc->movie_curve; |
378 |
|
|
379 |
/* |
/* |
|
* 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]; |
|
|
|
|
|
/* |
|
380 |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
381 |
* scaled curve "paying back" past errors in curve previsions. |
* scaled curve "paying back" past errors in curve previsions. |
382 |
*/ |
*/ |
384 |
desired = (int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
desired = (int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
385 |
} else { |
} else { |
386 |
desired = (int)(rc->curve_comp_error * dbytes / |
desired = (int)(rc->curve_comp_error * dbytes / |
387 |
rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay); |
rc->avg_length[s->type-1] / rc->param.bitrate_payback_delay); |
388 |
|
|
389 |
if (labs(desired) > fabs(rc->curve_comp_error)) { |
if (labs(desired) > fabs(rc->curve_comp_error)) |
390 |
desired = (int)rc->curve_comp_error; |
desired = (int)rc->curve_comp_error; |
391 |
} |
} |
|
} |
|
392 |
|
|
393 |
rc->curve_comp_error -= desired; |
rc->curve_comp_error -= desired; |
394 |
|
|
398 |
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) { |
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[s->type-1]) { |
402 |
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); |
403 |
} else { |
} else { |
404 |
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); |
405 |
} |
} |
406 |
|
|
|
/* |
|
|
* 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]; |
|
|
|
|
407 |
desired += (int)curve_temp; |
desired += (int)curve_temp; |
408 |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
409 |
} 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]; |
|
|
|
|
410 |
desired += (int)dbytes; |
desired += (int)dbytes; |
411 |
rc->curve_comp_error += dbytes - (int)dbytes; |
rc->curve_comp_error += dbytes - (int)dbytes; |
412 |
} |
} |
413 |
|
|
|
|
|
414 |
/* |
/* |
415 |
* We can't do bigger frames than first pass, this would be stupid as first |
* We can't do bigger frames than first pass, this would be stupid as first |
416 |
* pass is quant=2 and that reaching quant=1 is not worth it. We would lose |
* pass is quant=2 and that reaching quant=1 is not worth it. We would lose |
430 |
|
|
431 |
s->desired_length = desired; |
s->desired_length = desired; |
432 |
|
|
|
|
|
433 |
/* |
/* |
434 |
* 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 |
435 |
* XXX: why do we do this after setting the desired length ? |
* XXX: why do we do this after setting the desired length ? |
458 |
} |
} |
459 |
} |
} |
460 |
|
|
461 |
|
/* |
462 |
|
* The "sens commun" would force us to use rc->avg_length[s->type-1] but |
463 |
|
* even VFW code uses the pframe average length. Note that this length is |
464 |
|
* used with desired which represents bframes _and_ pframes length. |
465 |
|
* |
466 |
|
* XXX: why are we using the avg pframe length for all frame types ? |
467 |
|
*/ |
468 |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
469 |
|
|
470 |
/* Reign in overflow with huge frames */ |
/* Reign in overflow with huge frames */ |
574 |
if (capped_to_max_framesize == 0) |
if (capped_to_max_framesize == 0) |
575 |
rc->last_quant[s->type-1] = data->quant; |
rc->last_quant[s->type-1] = data->quant; |
576 |
|
|
577 |
|
/* Force frame type */ |
578 |
|
data->type = s->type; |
579 |
|
|
580 |
return 0; |
return 0; |
581 |
} |
} |
582 |
|
|
601 |
rc->overflow += rc->KFoverflow; |
rc->overflow += rc->KFoverflow; |
602 |
rc->KFoverflow = s->desired_length - data->length; |
rc->KFoverflow = s->desired_length - data->length; |
603 |
|
|
604 |
if (kfdiff > 1) { // non-consecutive keyframes |
if (kfdiff > 1) { /* non-consecutive keyframes */ |
605 |
rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1); |
rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1); |
606 |
}else{ // consecutive keyframes |
}else{ /* consecutive keyframes */ |
607 |
rc->overflow += rc->KFoverflow; |
rc->overflow += rc->KFoverflow; |
608 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |
609 |
rc->KFoverflow_partial = 0; |
rc->KFoverflow_partial = 0; |
610 |
} |
} |
611 |
rc->KF_idx++; |
rc->KF_idx++; |
612 |
} else { |
} else { |
613 |
// distribute part of the keyframe overflow |
/* distribute part of the keyframe overflow */ |
614 |
rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial; |
rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial; |
615 |
rc->KFoverflow -= rc->KFoverflow_partial; |
rc->KFoverflow -= rc->KFoverflow_partial; |
616 |
} |
} |
697 |
}else if (type == 'b') { |
}else if (type == 'b') { |
698 |
s->type = XVID_TYPE_BVOP; |
s->type = XVID_TYPE_BVOP; |
699 |
}else{ /* unknown type */ |
}else{ /* unknown type */ |
700 |
DPRINTF(XVID_DEBUG_RC, "unknown stats frame type; assuming pvop\n"); |
DPRINTF(XVID_DEBUG_RC, "WARNING: unknown stats frame type, assuming pvop\n"); |
701 |
s->type = XVID_TYPE_PVOP; |
s->type = XVID_TYPE_PVOP; |
702 |
} |
} |
703 |
|
|
827 |
next -= create->zones[i].frame; |
next -= create->zones[i].frame; |
828 |
rc->avg_weight += (double)(next * create->zones[i].increment) / (double)create->zones[i].base; |
rc->avg_weight += (double)(next * create->zones[i].increment) / (double)create->zones[i].base; |
829 |
n += next; |
n += next; |
830 |
}else{ // XVID_ZONE_QUANT |
}else{ /* XVID_ZONE_QUANT */ |
831 |
for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) { |
for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) { |
832 |
rc->stats[j].zone_mode = XVID_ZONE_QUANT; |
rc->stats[j].zone_mode = XVID_ZONE_QUANT; |
833 |
rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base; |
rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base; |
850 |
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; |
851 |
double scaler; |
double scaler; |
852 |
int i, num_MBs; |
int i, num_MBs; |
|
int min_size[3]; |
|
853 |
|
|
854 |
/* Let's compute a linear scaler in order to perform curve scaling */ |
/* Let's compute a linear scaler in order to perform curve scaling */ |
855 |
scaler = (double)target / (double)pass1_length; |
scaler = (double)target / (double)pass1_length; |
867 |
* Compute min frame lengths (for each frame type) according to the number |
* Compute min frame lengths (for each frame type) according to the number |
868 |
* of MBs. We sum all blocks count from frame 0 (should be an IFrame, so |
* of MBs. We sum all blocks count from frame 0 (should be an IFrame, so |
869 |
* blocks[0] should be enough) to know how many MBs there are. |
* blocks[0] should be enough) to know how many MBs there are. |
870 |
|
* |
871 |
|
* We compare these hardcoded values with observed values in first pass |
872 |
|
* (determined in pre_process0).Then we keep the real minimum. |
873 |
*/ |
*/ |
874 |
num_MBs = rc->stats[0].blks[0] + rc->stats[0].blks[1] + rc->stats[0].blks[2]; |
num_MBs = rc->stats[0].blks[0] + rc->stats[0].blks[1] + rc->stats[0].blks[2]; |
875 |
min_size[0] = ((num_MBs*22) + 240) / 8; |
|
876 |
min_size[1] = ((num_MBs) + 88) / 8; |
if(rc->min_length[0] > ((num_MBs*22) + 240) / 8) |
877 |
min_size[2] = 8; |
rc->min_length[0] = ((num_MBs*22) + 240) / 8; |
878 |
|
|
879 |
|
if(rc->min_length[1] > ((num_MBs) + 88) / 8) |
880 |
|
rc->min_length[1] = ((num_MBs) + 88) / 8; |
881 |
|
|
882 |
|
if(rc->min_length[2] > 8) |
883 |
|
rc->min_length[2] = 8; |
884 |
|
|
885 |
/* |
/* |
886 |
* Perform an initial scale pass. |
* Perform an initial scale pass. |
901 |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
902 |
|
|
903 |
/* Compare with the computed minimum */ |
/* Compare with the computed minimum */ |
904 |
if (len < min_size[s->type-1]) { |
if (len < rc->min_length[s->type-1]) { |
905 |
/* force frame size to our computed minimum */ |
/* force frame size to our computed minimum */ |
906 |
s->scaled_length = min_size[s->type-1]; |
s->scaled_length = rc->min_length[s->type-1]; |
907 |
target -= s->scaled_length; |
target -= s->scaled_length; |
908 |
pass1_length -= s->length; |
pass1_length -= s->length; |
909 |
} else { |
} else { |
983 |
dbytes = s->scaled_length / rc->movie_curve; |
dbytes = s->scaled_length / rc->movie_curve; |
984 |
dbytes2 = 0; /* XXX: warning */ |
dbytes2 = 0; /* XXX: warning */ |
985 |
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]; |
|
986 |
|
|
987 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[s->type-1]) { |
988 |
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); |
989 |
} else { |
} else { |
990 |
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); |
991 |
} |
} |
992 |
|
|
993 |
if (s->type == XVID_TYPE_BVOP) { |
if (dbytes2 < rc->min_length[s->type-1]) |
994 |
dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
dbytes2 = rc->min_length[s->type-1]; |
995 |
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]; |
|
|
} |
|
996 |
total2 += dbytes2; |
total2 += dbytes2; |
997 |
} |
} |
998 |
} |
} |
999 |
|
|
1000 |
rc->curve_comp_scale = total1 / total2; |
rc->curve_comp_scale = total1 / total2; |
1001 |
|
|
1002 |
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", |
1003 |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale)); |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale), |
1004 |
|
(int)(rc->avg_length[XVID_TYPE_BVOP-1] * rc->curve_comp_scale)); |
1005 |
|
|
1006 |
rc->overflow = 0; |
rc->overflow = 0; |
1007 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |