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.13 2003-05-29 10:19:35 edgomez Exp $ |
* $Id: plugin_2pass2.c,v 1.1.2.21 2003-06-10 10:12:24 suxen_drol Exp $ |
29 |
* |
* |
30 |
*****************************************************************************/ |
*****************************************************************************/ |
31 |
|
|
48 |
#define DEFAULT_MAX_OVERFLOW_IMPROVEMENT 60 |
#define DEFAULT_MAX_OVERFLOW_IMPROVEMENT 60 |
49 |
#define DEFAULT_MAX_OVERFLOW_DEGRADATION 60 |
#define DEFAULT_MAX_OVERFLOW_DEGRADATION 60 |
50 |
|
|
|
/* Alt curve settings */ |
|
|
#define DEFAULT_USE_ALT_CURVE 0 |
|
|
#define DEFAULT_ALT_CURVE_HIGH_DIST 500 |
|
|
#define DEFAULT_ALT_CURVE_LOW_DIST 90 |
|
|
#define DEFAULT_ALT_CURVE_USE_AUTO 1 |
|
|
#define DEFAULT_ALT_CURVE_AUTO_STR 30 |
|
|
#define DEFAULT_ALT_CURVE_TYPE XVID_CURVE_LINEAR |
|
|
#define DEFAULT_ALT_CURVE_MIN_REL_QUAL 50 |
|
|
#define DEFAULT_ALT_CURVE_USE_AUTO_BONUS_BIAS 1 |
|
|
#define DEFAULT_ALT_CURVE_BONUS_BIAS 50 |
|
|
|
|
51 |
/* Keyframe settings */ |
/* Keyframe settings */ |
52 |
#define DEFAULT_KFTRESHOLD 10 |
#define DEFAULT_KFTRESHOLD 10 |
53 |
#define DEFAULT_KFREDUCTION 20 |
#define DEFAULT_KFREDUCTION 20 |
100 |
int * keyframe_locations; |
int * keyframe_locations; |
101 |
stat_t * stats; |
stat_t * stats; |
102 |
|
|
103 |
double pquant_error[32]; |
double quant_error[3][32]; |
|
double bquant_error[32]; |
|
104 |
int quant_count[32]; |
int quant_count[32]; |
105 |
int last_quant[3]; |
int last_quant[3]; |
106 |
|
|
178 |
|
|
179 |
rc->param = *param; |
rc->param = *param; |
180 |
|
|
181 |
|
/* |
182 |
|
* Initialize all defaults |
183 |
|
*/ |
184 |
#define _INIT(a, b) if((a) <= 0) (a) = (b) |
#define _INIT(a, b) if((a) <= 0) (a) = (b) |
185 |
/* Let's set our defaults if needed */ |
/* Let's set our defaults if needed */ |
186 |
_INIT(rc->param.keyframe_boost, DEFAULT_KEYFRAME_BOOST); |
_INIT(rc->param.keyframe_boost, DEFAULT_KEYFRAME_BOOST); |
197 |
_INIT(rc->param.min_key_interval, DEFAULT_MIN_KEY_INTERVAL); |
_INIT(rc->param.min_key_interval, DEFAULT_MIN_KEY_INTERVAL); |
198 |
#undef _INIT |
#undef _INIT |
199 |
|
|
200 |
|
/* Initialize some stuff to zero */ |
201 |
|
for(i=0; i<32; i++) rc->quant_count[i] = 0; |
202 |
|
|
203 |
|
for(i=0; i<3; i++) { |
204 |
|
int j; |
205 |
|
for (j=0; j<32; j++) |
206 |
|
rc->quant_error[i][j] = 0; |
207 |
|
} |
208 |
|
|
209 |
|
for (i=0; i<3; i++) |
210 |
|
rc->last_quant[i] = 0; |
211 |
|
|
212 |
|
rc->fq_error = 0; |
213 |
|
|
214 |
/* Count frames in the stats file */ |
/* Count frames in the stats file */ |
215 |
if (!det_stats_length(rc, param->filename)) { |
if (!det_stats_length(rc, param->filename)) { |
216 |
DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename); |
DPRINTF(XVID_DEBUG_RC,"ERROR: fopen %s failed\n", param->filename); |
217 |
free(rc); |
free(rc); |
218 |
return XVID_ERR_FAIL; |
return XVID_ERR_FAIL; |
219 |
} |
} |
228 |
* Allocate keyframes location's memory |
* Allocate keyframes location's memory |
229 |
* PS: see comment in pre_process0 for the +1 location requirement |
* PS: see comment in pre_process0 for the +1 location requirement |
230 |
*/ |
*/ |
231 |
if ((rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int))) == NULL) { |
rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int)); |
232 |
|
if (rc->keyframe_locations == NULL) { |
233 |
free(rc->stats); |
free(rc->stats); |
234 |
free(rc); |
free(rc); |
235 |
return XVID_ERR_MEMORY; |
return XVID_ERR_MEMORY; |
236 |
} |
} |
237 |
|
|
238 |
if (!load_stats(rc, param->filename)) { |
if (!load_stats(rc, param->filename)) { |
239 |
DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename); |
DPRINTF(XVID_DEBUG_RC,"ERROR: fopen %s failed\n", param->filename); |
240 |
free(rc->keyframe_locations); |
free(rc->keyframe_locations); |
241 |
free(rc->stats); |
free(rc->stats); |
242 |
free(rc); |
free(rc); |
243 |
return XVID_ERR_FAIL; |
return XVID_ERR_FAIL; |
244 |
} |
} |
245 |
|
|
246 |
/* pre-process our stats */ |
/* Compute the target filesize */ |
247 |
|
if (rc->param.bitrate<0) { |
248 |
if (rc->num_frames < create->fbase/create->fincr) { |
/* if negative, bitrate equals the target (int kbytes) */ |
249 |
rc->target = rc->param.bitrate / 8; /* one second */ |
rc->target = (-rc->param.bitrate) * 1024; |
250 |
|
|
251 |
|
}else if (rc->num_frames < create->fbase/create->fincr) { |
252 |
|
/* Source sequence is less than 1s long, we do as if it was 1s long */ |
253 |
|
rc->target = rc->param.bitrate / 8; |
254 |
} else { |
} else { |
255 |
|
/* Target filesize = bitrate/8 * numframes / framerate */ |
256 |
rc->target = |
rc->target = |
257 |
((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * (uint64_t)create->fincr) / \ |
((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * \ |
258 |
|
(uint64_t)create->fincr) / \ |
259 |
((uint64_t)create->fbase * 8); |
((uint64_t)create->fbase * 8); |
260 |
} |
} |
261 |
|
|
262 |
|
DPRINTF(XVID_DEBUG_RC, "Frame rate: %d/%d (%ffps)\n", |
263 |
|
create->fbase, create->fincr, |
264 |
|
(double)create->fbase/(double)create->fincr); |
265 |
DPRINTF(XVID_DEBUG_RC, "Number of frames: %d\n", rc->num_frames); |
DPRINTF(XVID_DEBUG_RC, "Number of frames: %d\n", rc->num_frames); |
|
DPRINTF(XVID_DEBUG_RC, "Frame rate: %d/%d\n", create->fbase, create->fincr); |
|
266 |
DPRINTF(XVID_DEBUG_RC, "Target bitrate: %ld\n", rc->param.bitrate); |
DPRINTF(XVID_DEBUG_RC, "Target bitrate: %ld\n", rc->param.bitrate); |
267 |
DPRINTF(XVID_DEBUG_RC, "Target filesize: %lld\n", rc->target); |
DPRINTF(XVID_DEBUG_RC, "Target filesize: %lld\n", rc->target); |
268 |
|
|
269 |
/* Compensate the mean frame overhead caused by the container */ |
/* Compensate the average frame overhead caused by the container */ |
270 |
rc->target -= rc->num_frames*rc->param.container_frame_overhead; |
rc->target -= rc->num_frames*rc->param.container_frame_overhead; |
271 |
DPRINTF(XVID_DEBUG_RC, "Container Frame overhead: %d\n", rc->param.container_frame_overhead); |
DPRINTF(XVID_DEBUG_RC, "Container Frame overhead: %d\n", rc->param.container_frame_overhead); |
272 |
DPRINTF(XVID_DEBUG_RC, "Target filesize (after container compensation): %lld\n", rc->target); |
DPRINTF(XVID_DEBUG_RC, "Target filesize (after container compensation): %lld\n", rc->target); |
273 |
|
|
274 |
|
/* |
275 |
|
* First data pre processing: |
276 |
|
* - finds the minimum frame length for each frame type during 1st pass. |
277 |
|
* rc->min_size[] |
278 |
|
* - determines the maximum frame length observed (no frame type distinction). |
279 |
|
* rc->max_size |
280 |
|
* - count how many times each frame type has been used. |
281 |
|
* rc->count[] |
282 |
|
* - total bytes used per frame type |
283 |
|
* rc->total[] |
284 |
|
* - store keyframe location |
285 |
|
* rc->keyframe_locations[] |
286 |
|
*/ |
287 |
pre_process0(rc); |
pre_process0(rc); |
288 |
|
|
289 |
|
/* |
290 |
|
* When bitrate is not given it means it has been scaled by an external |
291 |
|
* application |
292 |
|
*/ |
293 |
if (rc->param.bitrate) { |
if (rc->param.bitrate) { |
294 |
|
/* Apply zone settings */ |
295 |
zone_process(rc, create); |
zone_process(rc, create); |
296 |
|
/* Perform curve scaling */ |
297 |
internal_scale(rc); |
internal_scale(rc); |
298 |
}else{ |
}else{ |
299 |
/* external scaler: ignore zone */ |
/* External scaling -- zones are ignored */ |
300 |
for (i=0;i<rc->num_frames;i++) { |
for (i=0;i<rc->num_frames;i++) { |
301 |
rc->stats[i].zone_mode = XVID_ZONE_WEIGHT; |
rc->stats[i].zone_mode = XVID_ZONE_WEIGHT; |
302 |
rc->stats[i].weight = 1.0; |
rc->stats[i].weight = 1.0; |
304 |
rc->avg_weight = 1.0; |
rc->avg_weight = 1.0; |
305 |
rc->tot_quant = 0; |
rc->tot_quant = 0; |
306 |
} |
} |
|
pre_process1(rc); |
|
|
|
|
|
for (i=0; i<32;i++) { |
|
|
rc->pquant_error[i] = 0; |
|
|
rc->bquant_error[i] = 0; |
|
|
rc->quant_count[i] = 0; |
|
|
} |
|
307 |
|
|
308 |
rc->fq_error = 0; |
pre_process1(rc); |
309 |
|
|
310 |
*handle = rc; |
*handle = rc; |
311 |
return(0); |
return(0); |
334 |
int desired; |
int desired; |
335 |
double dbytes; |
double dbytes; |
336 |
double curve_temp; |
double curve_temp; |
337 |
|
double scaled_quant; |
338 |
int capped_to_max_framesize = 0; |
int capped_to_max_framesize = 0; |
339 |
|
|
340 |
/* |
/* |
348 |
|
|
349 |
/* Second case: We are in a Quant zone */ |
/* Second case: We are in a Quant zone */ |
350 |
if (s->zone_mode == XVID_ZONE_QUANT) { |
if (s->zone_mode == XVID_ZONE_QUANT) { |
|
|
|
351 |
rc->fq_error += s->weight; |
rc->fq_error += s->weight; |
352 |
data->quant = (int)rc->fq_error; |
data->quant = (int)rc->fq_error; |
353 |
rc->fq_error -= data->quant; |
rc->fq_error -= data->quant; |
355 |
s->desired_length = s->length; |
s->desired_length = s->length; |
356 |
|
|
357 |
return(0); |
return(0); |
|
|
|
358 |
} |
} |
359 |
|
|
360 |
/* Third case: insufficent stats data */ |
/* Third case: insufficent stats data */ |
361 |
if (data->frame_num >= rc->num_frames) |
if (data->frame_num >= rc->num_frames) |
362 |
return 0; |
return 0; |
363 |
|
|
|
/* |
|
|
* The last case is the one every normal minded developer should fear to |
|
|
* maintain in a project :-) |
|
|
*/ |
|
|
|
|
364 |
/* XXX: why by 8 */ |
/* XXX: why by 8 */ |
365 |
overflow = rc->overflow / 8; |
overflow = rc->overflow / 8; |
366 |
|
|
379 |
dbytes /= rc->movie_curve; |
dbytes /= rc->movie_curve; |
380 |
|
|
381 |
/* |
/* |
|
* 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]; |
|
|
|
|
|
/* |
|
382 |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
* Apply user's choosen Payback method. Payback helps bitrate to follow the |
383 |
* scaled curve "paying back" past errors in curve previsions. |
* scaled curve "paying back" past errors in curve previsions. |
384 |
*/ |
*/ |
386 |
desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay); |
387 |
} else { |
} else { |
388 |
desired = (int)(rc->curve_comp_error * dbytes / |
desired = (int)(rc->curve_comp_error * dbytes / |
389 |
rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay); |
rc->avg_length[s->type-1] / rc->param.bitrate_payback_delay); |
390 |
|
|
391 |
if (labs(desired) > fabs(rc->curve_comp_error)) { |
if (labs(desired) > fabs(rc->curve_comp_error)) |
392 |
desired = (int)rc->curve_comp_error; |
desired = (int)rc->curve_comp_error; |
393 |
} |
} |
|
} |
|
394 |
|
|
395 |
rc->curve_comp_error -= desired; |
rc->curve_comp_error -= desired; |
396 |
|
|
|
/* |
|
|
* Alt curve treatment is not that hard to understand though the formulas |
|
|
* seem to be huge. Alt treatment is basically a way to soft/harden the |
|
|
* curve flux applying sine/linear/cosine ratios |
|
|
*/ |
|
|
|
|
397 |
/* XXX: warning */ |
/* XXX: warning */ |
398 |
curve_temp = 0; |
curve_temp = 0; |
399 |
|
|
400 |
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) { |
401 |
|
|
402 |
curve_temp = rc->curve_comp_scale; |
curve_temp = rc->curve_comp_scale; |
403 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[s->type-1]) { |
404 |
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); |
405 |
} else { |
} else { |
406 |
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); |
407 |
} |
} |
408 |
|
|
|
/* |
|
|
* 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]; |
|
|
|
|
409 |
desired += (int)curve_temp; |
desired += (int)curve_temp; |
410 |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
rc->curve_comp_error += curve_temp - (int)curve_temp; |
411 |
} 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]; |
|
|
|
|
412 |
desired += (int)dbytes; |
desired += (int)dbytes; |
413 |
rc->curve_comp_error += dbytes - (int)dbytes; |
rc->curve_comp_error += dbytes - (int)dbytes; |
414 |
} |
} |
433 |
|
|
434 |
s->desired_length = desired; |
s->desired_length = desired; |
435 |
|
|
436 |
|
/* |
437 |
/* 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 |
438 |
XXX: why do we do this after setting the desired length */ |
* XXX: why do we do this after setting the desired length ? |
439 |
|
*/ |
440 |
|
|
441 |
if (s->type == XVID_TYPE_IVOP) { |
if (s->type == XVID_TYPE_IVOP) { |
442 |
int KFdistance = rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1]; |
int KFdistance = rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1]; |
461 |
} |
} |
462 |
} |
} |
463 |
|
|
464 |
|
/* |
465 |
|
* The "sens commun" would force us to use rc->avg_length[s->type-1] but |
466 |
|
* even VFW code uses the pframe average length. Note that this length is |
467 |
|
* used with desired which represents bframes _and_ pframes length. |
468 |
|
* |
469 |
|
* XXX: why are we using the avg pframe length for all frame types ? |
470 |
|
*/ |
471 |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]); |
472 |
|
|
473 |
/* Reign in overflow with huge frames */ |
/* Reign in overflow with huge frames */ |
503 |
* Don't laugh at this very 'simple' quant<->filesize relationship, it |
* Don't laugh at this very 'simple' quant<->filesize relationship, it |
504 |
* proves to be acurate enough for our algorithm |
* proves to be acurate enough for our algorithm |
505 |
*/ |
*/ |
506 |
data->quant = s->quant*s->length/desired; |
scaled_quant = (double)s->quant*(double)s->length/(double)desired; |
507 |
|
|
508 |
|
/* |
509 |
|
* Quantizer has been scaled using floating point operations/results, we |
510 |
|
* must cast it to integer |
511 |
|
*/ |
512 |
|
data->quant = (int)scaled_quant; |
513 |
|
|
514 |
/* Let's clip the computed quantizer, if needed */ |
/* Let's clip the computed quantizer, if needed */ |
515 |
if (data->quant < 1) { |
if (data->quant < 1) { |
519 |
} else if (s->type != XVID_TYPE_IVOP) { |
} else if (s->type != XVID_TYPE_IVOP) { |
520 |
|
|
521 |
/* |
/* |
522 |
* The frame quantizer has not been clipped, this appear to be a good |
* The frame quantizer has not been clipped, this appears to be a good |
523 |
* computed quantizer, however past frames give us some info about how |
* computed quantizer, do not loose quantizer decimal part that we |
524 |
* this quantizer performs against the algo prevision. Let's use this |
* accumulate for later reuse when its sum represents a complete unit. |
|
* prevision to increase the quantizer when we observe a too big |
|
|
* accumulated error |
|
525 |
*/ |
*/ |
526 |
if (s->type == XVID_TYPE_BVOP) { |
rc->quant_error[s->type-1][data->quant] += scaled_quant - (double)data->quant; |
|
rc->bquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant; |
|
527 |
|
|
528 |
if (rc->bquant_error[data->quant] >= 1.0) { |
if (rc->quant_error[s->type-1][data->quant] >= 1.0) { |
529 |
rc->bquant_error[data->quant] -= 1.0; |
rc->quant_error[s->type-1][data->quant] -= 1.0; |
530 |
data->quant++; |
data->quant++; |
531 |
|
} else if (rc->quant_error[s->type-1][data->quant] <= -1.0) { |
532 |
|
rc->quant_error[s->type-1][data->quant] += 1.0; |
533 |
|
data->quant--; |
534 |
} |
} |
|
} else { |
|
|
rc->pquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant; |
|
535 |
|
|
|
if (rc->pquant_error[data->quant] >= 1.0) { |
|
|
rc->pquant_error[data->quant] -= 1.0; |
|
|
data->quant++; |
|
|
} |
|
|
} |
|
536 |
} |
} |
537 |
|
|
538 |
/* |
/* |
577 |
if (capped_to_max_framesize == 0) |
if (capped_to_max_framesize == 0) |
578 |
rc->last_quant[s->type-1] = data->quant; |
rc->last_quant[s->type-1] = data->quant; |
579 |
|
|
580 |
|
/* Force frame type */ |
581 |
|
data->type = s->type; |
582 |
|
|
583 |
return 0; |
return 0; |
584 |
} |
} |
585 |
|
|
604 |
rc->overflow += rc->KFoverflow; |
rc->overflow += rc->KFoverflow; |
605 |
rc->KFoverflow = s->desired_length - data->length; |
rc->KFoverflow = s->desired_length - data->length; |
606 |
|
|
607 |
if (kfdiff > 1) { // non-consecutive keyframes |
if (kfdiff > 1) { /* non-consecutive keyframes */ |
608 |
rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1); |
rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1); |
609 |
}else{ // consecutive keyframes |
}else{ /* consecutive keyframes */ |
610 |
rc->overflow += rc->KFoverflow; |
rc->overflow += rc->KFoverflow; |
611 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |
612 |
rc->KFoverflow_partial = 0; |
rc->KFoverflow_partial = 0; |
613 |
} |
} |
614 |
rc->KF_idx++; |
rc->KF_idx++; |
615 |
} else { |
} else { |
616 |
// distribute part of the keyframe overflow |
/* distribute part of the keyframe overflow */ |
617 |
rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial; |
rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial; |
618 |
rc->KFoverflow -= rc->KFoverflow_partial; |
rc->KFoverflow -= rc->KFoverflow_partial; |
619 |
} |
} |
620 |
|
|
621 |
DPRINTF(XVID_DEBUG_RC, "[%i] type:%c quant:%i stats1:%i scaled:%i actual:%i overflow:%i\n", |
DPRINTF(XVID_DEBUG_RC, "[%i] type:%c quant:%i stats1:%i scaled:%i actual:%i desired:%d overflow:%i\n", |
622 |
data->frame_num, |
data->frame_num, |
623 |
frame_type[data->type-1], |
frame_type[data->type-1], |
624 |
data->quant, |
data->quant, |
625 |
s->length, |
s->length, |
626 |
s->scaled_length, |
s->scaled_length, |
627 |
data->length, |
data->length, |
628 |
|
s->desired_length, |
629 |
rc->overflow); |
rc->overflow); |
630 |
|
|
631 |
return(0); |
return(0); |
700 |
}else if (type == 'b') { |
}else if (type == 'b') { |
701 |
s->type = XVID_TYPE_BVOP; |
s->type = XVID_TYPE_BVOP; |
702 |
}else{ /* unknown type */ |
}else{ /* unknown type */ |
703 |
DPRINTF(XVID_DEBUG_RC, "unknown stats frame type; assuming pvop\n"); |
DPRINTF(XVID_DEBUG_RC, "WARNING: unknown stats frame type, assuming pvop\n"); |
704 |
s->type = XVID_TYPE_PVOP; |
s->type = XVID_TYPE_PVOP; |
705 |
} |
} |
706 |
|
|
736 |
{ |
{ |
737 |
int i,j; |
int i,j; |
738 |
|
|
739 |
|
/* |
740 |
|
* *rc fields initialization |
741 |
|
* NB: INT_MAX and INT_MIN are used in order to be immediately replaced |
742 |
|
* with real values of the 1pass |
743 |
|
*/ |
744 |
for (i=0; i<3; i++) { |
for (i=0; i<3; i++) { |
745 |
rc->count[i]=0; |
rc->count[i]=0; |
746 |
rc->tot_length[i] = 0; |
rc->tot_length[i] = 0; |
|
rc->last_quant[i] = 0; |
|
747 |
rc->min_length[i] = INT_MAX; |
rc->min_length[i] = INT_MAX; |
748 |
} |
} |
749 |
|
|
750 |
rc->max_length = INT_MIN; |
rc->max_length = INT_MIN; |
751 |
|
|
752 |
|
/* |
753 |
|
* Loop through all frames and find/compute all the stuff this function |
754 |
|
* is supposed to do |
755 |
|
*/ |
756 |
for (i=j=0; i<rc->num_frames; i++) { |
for (i=j=0; i<rc->num_frames; i++) { |
757 |
stat_t * s = &rc->stats[i]; |
stat_t * s = &rc->stats[i]; |
758 |
|
|
830 |
next -= create->zones[i].frame; |
next -= create->zones[i].frame; |
831 |
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; |
832 |
n += next; |
n += next; |
833 |
}else{ // XVID_ZONE_QUANT |
}else{ /* XVID_ZONE_QUANT */ |
834 |
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++ ) { |
835 |
rc->stats[j].zone_mode = XVID_ZONE_QUANT; |
rc->stats[j].zone_mode = XVID_ZONE_QUANT; |
836 |
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; |
852 |
int64_t target = rc->target - rc->tot_quant; |
int64_t target = rc->target - rc->tot_quant; |
853 |
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; |
854 |
double scaler; |
double scaler; |
855 |
int i; |
int i, num_MBs; |
|
|
|
856 |
|
|
857 |
/* Let's compute a linear scaler in order to perform curve scaling */ |
/* Let's compute a linear scaler in order to perform curve scaling */ |
858 |
scaler = (double)target / (double)pass1_length; |
scaler = (double)target / (double)pass1_length; |
867 |
(int)target, (int)pass1_length, scaler); |
(int)target, (int)pass1_length, scaler); |
868 |
|
|
869 |
/* |
/* |
870 |
|
* Compute min frame lengths (for each frame type) according to the number |
871 |
|
* of MBs. We sum all blocks count from frame 0 (should be an IFrame, so |
872 |
|
* blocks[0] should be enough) to know how many MBs there are. |
873 |
|
* |
874 |
|
* We compare these hardcoded values with observed values in first pass |
875 |
|
* (determined in pre_process0).Then we keep the real minimum. |
876 |
|
*/ |
877 |
|
num_MBs = rc->stats[0].blks[0] + rc->stats[0].blks[1] + rc->stats[0].blks[2]; |
878 |
|
|
879 |
|
if(rc->min_length[0] > ((num_MBs*22) + 240) / 8) |
880 |
|
rc->min_length[0] = ((num_MBs*22) + 240) / 8; |
881 |
|
|
882 |
|
if(rc->min_length[1] > ((num_MBs) + 88) / 8) |
883 |
|
rc->min_length[1] = ((num_MBs) + 88) / 8; |
884 |
|
|
885 |
|
if(rc->min_length[2] > 8) |
886 |
|
rc->min_length[2] = 8; |
887 |
|
|
888 |
|
/* |
889 |
* Perform an initial scale pass. |
* Perform an initial scale pass. |
890 |
* If a frame size is scaled underneath our hardcoded minimums, then we |
* If a frame size is scaled underneath our hardcoded minimums, then we |
891 |
* force the frame size to the minimum, and deduct the original & scaled |
* force the frame size to the minimum, and deduct the original & scaled |
892 |
* frame length from the original and target total lengths |
* frame length from the original and target total lengths |
893 |
*/ |
*/ |
|
|
|
894 |
for (i=0; i<rc->num_frames; i++) { |
for (i=0; i<rc->num_frames; i++) { |
895 |
stat_t * s = &rc->stats[i]; |
stat_t * s = &rc->stats[i]; |
|
int min_size[3]; |
|
896 |
int len; |
int len; |
897 |
|
|
|
/* 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; |
|
|
|
|
898 |
if (s->zone_mode == XVID_ZONE_QUANT) { |
if (s->zone_mode == XVID_ZONE_QUANT) { |
899 |
s->scaled_length = s->length; |
s->scaled_length = s->length; |
900 |
continue; |
continue; |
901 |
} |
} |
902 |
|
|
903 |
/* Compute teh scaled length */ |
/* Compute the scaled length */ |
904 |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
905 |
|
|
906 |
/* Compare with the computed minimum */ |
/* Compare with the computed minimum */ |
907 |
if (len < min_size[s->type-1]) { |
if (len < rc->min_length[s->type-1]) { |
908 |
/* force frame size to our computed minimum */ |
/* force frame size to our computed minimum */ |
909 |
s->scaled_length = min_size[s->type-1]; |
s->scaled_length = rc->min_length[s->type-1]; |
910 |
target -= s->scaled_length; |
target -= s->scaled_length; |
911 |
pass1_length -= s->length; |
pass1_length -= s->length; |
912 |
} else { |
} else { |
913 |
/* Do nothing for now, we'll scale this later */ |
/* Do nothing for now, we'll scale this later */ |
914 |
s->scaled_length = 0; |
s->scaled_length = 0; |
915 |
} |
} |
|
|
|
916 |
} |
} |
917 |
|
|
918 |
/* Correct the scaler for all non forced frames */ |
/* Correct the scaler for all non forced frames */ |
936 |
if (s->scaled_length == 0) |
if (s->scaled_length == 0) |
937 |
s->scaled_length = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
s->scaled_length = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
938 |
} |
} |
|
|
|
939 |
} |
} |
940 |
|
|
941 |
static void |
static void |
986 |
dbytes = s->scaled_length / rc->movie_curve; |
dbytes = s->scaled_length / rc->movie_curve; |
987 |
dbytes2 = 0; /* XXX: warning */ |
dbytes2 = 0; /* XXX: warning */ |
988 |
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]; |
|
989 |
|
|
990 |
if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) { |
if (dbytes > rc->avg_length[s->type-1]) { |
991 |
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); |
992 |
} else { |
} else { |
993 |
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); |
994 |
} |
} |
995 |
|
|
996 |
if (s->type == XVID_TYPE_BVOP) { |
if (dbytes2 < rc->min_length[s->type-1]) |
997 |
dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1]; |
dbytes2 = rc->min_length[s->type-1]; |
998 |
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]; |
|
|
} |
|
999 |
total2 += dbytes2; |
total2 += dbytes2; |
1000 |
} |
} |
1001 |
} |
} |
1002 |
|
|
1003 |
rc->curve_comp_scale = total1 / total2; |
rc->curve_comp_scale = total1 / total2; |
1004 |
|
|
1005 |
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", |
1006 |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale)); |
(int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale), |
1007 |
|
(int)(rc->avg_length[XVID_TYPE_BVOP-1] * rc->curve_comp_scale)); |
1008 |
|
|
1009 |
rc->overflow = 0; |
rc->overflow = 0; |
1010 |
rc->KFoverflow = 0; |
rc->KFoverflow = 0; |