270 |
static void first_pass_stats_prepare_data(rc_2pass2_t * rc); |
static void first_pass_stats_prepare_data(rc_2pass2_t * rc); |
271 |
static void first_pass_scale_curve_internal(rc_2pass2_t *rc); |
static void first_pass_scale_curve_internal(rc_2pass2_t *rc); |
272 |
static void scaled_curve_apply_advanced_parameters(rc_2pass2_t * rc); |
static void scaled_curve_apply_advanced_parameters(rc_2pass2_t * rc); |
|
#ifdef VBV |
|
273 |
static int check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps); |
static int check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps); |
274 |
static int scale_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps); |
static int scale_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps); |
|
#endif |
|
|
|
|
275 |
#if 0 |
#if 0 |
276 |
static void stats_print(rc_2pass2_t * rc); |
static void stats_print(rc_2pass2_t * rc); |
277 |
#endif |
#endif |
428 |
* shape the curve in the BEFORE/AFTER pair of functions */ |
* shape the curve in the BEFORE/AFTER pair of functions */ |
429 |
scaled_curve_apply_advanced_parameters(rc); |
scaled_curve_apply_advanced_parameters(rc); |
430 |
|
|
|
|
|
|
#ifdef VBV |
|
431 |
/* Check curve for VBV compliancy and rescale if necessary */ |
/* Check curve for VBV compliancy and rescale if necessary */ |
432 |
|
|
|
|
|
433 |
#ifdef VBV_FORCE |
#ifdef VBV_FORCE |
434 |
if (rc->param.vbvsize==0) |
if (rc->param.vbv_size==0) |
435 |
{ |
{ |
436 |
rc->param.vbvsize = 3145728; |
rc->param.vbv_size = 3145728; |
437 |
rc->param.vbvinitial = 2359296; |
rc->param.vbv_initial = 2359296; |
438 |
rc->param.vbv_maxrate = 4000000; |
rc->param.vbv_maxrate = 4000000; |
439 |
rc->param.vbv_peakrate = 10000000; |
rc->param.vbv_peakrate = 10000000; |
440 |
} |
} |
441 |
#endif |
#endif |
442 |
|
|
443 |
if (rc->param.vbvsize>0) /* vbvsize==0 switches VBV check off */ |
if (rc->param.vbv_size>0) /* vbv_size==0 switches VBV check off */ |
444 |
{ |
{ |
445 |
const double fps = (double)create->fbase/(double)create->fincr; |
const double fps = (double)create->fbase/(double)create->fincr; |
446 |
int status = check_curve_for_vbv_compliancy(rc, fps); |
int status = check_curve_for_vbv_compliancy(rc, fps); |
458 |
fprintf(stderr,"impossible.\n"); |
fprintf(stderr,"impossible.\n"); |
459 |
#endif |
#endif |
460 |
} |
} |
|
#endif |
|
|
|
|
461 |
*handle = rc; |
*handle = rc; |
462 |
return(0); |
return(0); |
463 |
} |
} |
1412 |
return; |
return; |
1413 |
} |
} |
1414 |
|
|
|
|
|
|
#ifdef VBV |
|
|
|
|
1415 |
/***************************************************************************** |
/***************************************************************************** |
1416 |
* VBV compliancy check and scale |
* VBV compliancy check and scale |
1417 |
* MPEG-4 standard specifies certain restrictions for bitrate/framesize in VBR |
* MPEG-4 standard specifies certain restrictions for bitrate/framesize in VBR |
1433 |
|
|
1434 |
static int check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps) |
static int check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps) |
1435 |
{ |
{ |
1436 |
/* We do all calculations in float, for higher accuracy, and bytes for convenience |
/* We do all calculations in float, for higher accuracy, |
1437 |
|
and in bytes for convenience |
1438 |
|
|
1439 |
typical values from DivX Home Theater profile: |
typical values from DivX Home Theater profile: |
1440 |
vbvsize= 384*1024 (384kB), vbvinitial= 288*1024 (75% fill) |
vbv_size= 384*1024 (384kB), vbv_initial= 288*1024 (75% fill) |
1441 |
maxrate= 4000000 (4MBps), peakrate= 10000000 (10MBps) |
maxrate= 4000000 (4MBps), peakrate= 10000000 (10MBps) |
1442 |
|
|
1443 |
PAL: offset3s = 75 (3 seconds of 25fps) |
PAL: offset3s = 75 (3 seconds of 25fps) |
1444 |
NTSC: offset3s = 90 (3 seconds of 29.97fps) or 72 (3 seconds of 23.976fps) |
NTSC: offset3s = 90 (3 seconds of 29.97fps) or 72 (3 seconds of 23.976fps) |
1445 |
*/ |
*/ |
1446 |
|
|
1447 |
const float vbvsize = (float)rc->param.vbvsize/8.f; |
const float vbv_size = (float)rc->param.vbv_size/8.f; |
1448 |
float vbvfill = (float)rc->param.vbvinitial/8.f; |
float vbvfill = (float)rc->param.vbv_initial/8.f; |
1449 |
|
|
1450 |
const float maxrate = (float)rc->param.vbv_maxrate; |
const float maxrate = (float)rc->param.vbv_maxrate; |
1451 |
const float peakrate = (float)rc->param.vbv_peakrate; |
const float peakrate = (float)rc->param.vbv_peakrate; |
1470 |
vbvfill += r0 - rc->stats[i].scaled_length; |
vbvfill += r0 - rc->stats[i].scaled_length; |
1471 |
|
|
1472 |
/* this check is _NOT_ an "overflow"! only reading from disk stops then */ |
/* this check is _NOT_ an "overflow"! only reading from disk stops then */ |
1473 |
if (vbvfill > vbvsize) |
if (vbvfill > vbv_size) |
1474 |
vbvfill = vbvsize; |
vbvfill = vbv_size; |
1475 |
|
|
1476 |
/* but THIS would be an underflow. report it! */ |
/* but THIS would be an underflow. report it! */ |
1477 |
if (vbvfill < 0) |
if (vbvfill < 0) |
1480 |
|
|
1481 |
return VBV_COMPLIANT; |
return VBV_COMPLIANT; |
1482 |
} |
} |
1483 |
/* idea: min(vbvfill) could be stored to print "minimum buffer fill" */ |
/* TODO: store min(vbvfill) and print "minimum buffer fill" */ |
|
|
|
1484 |
|
|
1485 |
|
|
1486 |
static int scale_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps) |
static int scale_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps) |
1500 |
For each scene of len N, we have to check up to N^2 possible buffer fills. |
For each scene of len N, we have to check up to N^2 possible buffer fills. |
1501 |
This works well with MPEG-2 where N==12 or so, but for MPEG-4 it's a |
This works well with MPEG-2 where N==12 or so, but for MPEG-4 it's a |
1502 |
little slow... |
little slow... |
1503 |
|
|
1504 |
|
TODO: Better control on VBVfill between scenes |
1505 |
*/ |
*/ |
1506 |
const float vbvsize = (float)rc->param.vbvsize/8.f; |
|
1507 |
const float vbvinitial = (float)rc->param.vbvinitial/8.f; |
const float vbv_size = (float)rc->param.vbv_size/8.f; |
1508 |
|
const float vbv_initial = (float)rc->param.vbv_initial/8.f; |
1509 |
|
|
1510 |
const float maxrate = 0.9*rc->param.vbv_maxrate; |
const float maxrate = 0.9*rc->param.vbv_maxrate; |
1511 |
const float vbvlow = 0.10f*vbvsize; |
const float vbv_low = 0.10f*vbv_size; |
1512 |
const float r0 = (int)(maxrate/fps+0.5)/8.f; |
const float r0 = (int)(maxrate/fps+0.5)/8.f; |
1513 |
|
|
1514 |
int i,k,l,n,violation = 0; |
int i,k,l,n,violation = 0; |
1520 |
we could get all this from existing keyframe_positions, somehow, but there we |
we could get all this from existing keyframe_positions, somehow, but there we |
1521 |
don't have a min_scenelength, and it's no big deal to get it again. */ |
don't have a min_scenelength, and it's no big deal to get it again. */ |
1522 |
|
|
1523 |
const int min_scenelength = 50; |
const int min_scenelength = (int)(fps+0.5); |
1524 |
int num_scenes = 0; |
int num_scenes = 0; |
1525 |
int last_scene = -999; |
int last_scene = -999; |
1526 |
for (i=0; i<rc->num_frames; i++) { |
for (i=0; i<rc->num_frames; i++) { |
1582 |
|
|
1583 |
k=0; |
k=0; |
1584 |
Skn = S0n; |
Skn = S0n; |
1585 |
f = (R(k,n-1) + (vbvinitial - vbvlow)) / Skn; |
f = (R(k,n-1) + (vbv_initial - vbv_low)) / Skn; |
1586 |
if (f < minf) |
if (f < minf) |
1587 |
minf = f; |
minf = f; |
1588 |
|
|
1590 |
{ |
{ |
1591 |
Skn -= frames[k].scaled_length; |
Skn -= frames[k].scaled_length; |
1592 |
|
|
1593 |
f = (R(k,n-1) + (vbvsize - vbvlow)) / Skn; |
f = (R(k,n-1) + (vbv_size - vbv_low)) / Skn; |
1594 |
if (f < minf) |
if (f < minf) |
1595 |
minf = f; |
minf = f; |
1596 |
} |
} |
1597 |
} |
} |
1598 |
|
|
1599 |
/* special case: at the end, fill buffer up to vbvinitial again |
/* special case: at the end, fill buffer up to vbv_initial again |
1600 |
TODO: Allow other values for buffer fill between scenes |
TODO: Allow other values for buffer fill between scenes |
1601 |
e.g. if n=N is smallest f-value, then check for better value */ |
e.g. if n=N is smallest f-value, then check for better value */ |
1602 |
|
|
1611 |
{ |
{ |
1612 |
Skn -= frames[k].scaled_length; |
Skn -= frames[k].scaled_length; |
1613 |
|
|
1614 |
f = (R(k,n-1) + (vbvinitial - vbvlow)) / Skn; |
f = (R(k,n-1) + (vbv_initial - vbv_low)) / Skn; |
1615 |
if (f < minf) |
if (f < minf) |
1616 |
minf = f; |
minf = f; |
1617 |
} |
} |
1710 |
} |
} |
1711 |
|
|
1712 |
|
|
|
#endif |
|
|
|
|
|
|
|
1713 |
/***************************************************************************** |
/***************************************************************************** |
1714 |
* Still more low level stuff (nothing to do with stats treatment) |
* Still more low level stuff (nothing to do with stats treatment) |
1715 |
****************************************************************************/ |
****************************************************************************/ |