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.14 2003-05-29 10:36:41 edgomez Exp $ |
* $Id: plugin_2pass2.c,v 1.1.2.15 2003-05-29 11:37:20 edgomez 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->num_frames < create->fbase/create->fincr) { |
if (rc->num_frames < create->fbase/create->fincr) { |
248 |
rc->target = rc->param.bitrate / 8; /* one second */ |
/* Source sequence is less than 1s long, we do as if it was 1s long */ |
249 |
|
rc->target = rc->param.bitrate / 8; |
250 |
} else { |
} else { |
251 |
|
/* Target filesize = bitrate/8 * numframes / framerate */ |
252 |
rc->target = |
rc->target = |
253 |
((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * (uint64_t)create->fincr) / \ |
((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * \ |
254 |
|
(uint64_t)create->fincr) / \ |
255 |
((uint64_t)create->fbase * 8); |
((uint64_t)create->fbase * 8); |
256 |
} |
} |
257 |
|
|
258 |
|
DPRINTF(XVID_DEBUG_RC, "Frame rate: %d/%d (%ffps)\n", |
259 |
|
create->fbase, create->fincr, |
260 |
|
(double)create->fbase/(double)create->fincr); |
261 |
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); |
|
262 |
DPRINTF(XVID_DEBUG_RC, "Target bitrate: %ld\n", rc->param.bitrate); |
DPRINTF(XVID_DEBUG_RC, "Target bitrate: %ld\n", rc->param.bitrate); |
263 |
DPRINTF(XVID_DEBUG_RC, "Target filesize: %lld\n", rc->target); |
DPRINTF(XVID_DEBUG_RC, "Target filesize: %lld\n", rc->target); |
264 |
|
|
265 |
/* Compensate the mean frame overhead caused by the container */ |
/* Compensate the average frame overhead caused by the container */ |
266 |
rc->target -= rc->num_frames*rc->param.container_frame_overhead; |
rc->target -= rc->num_frames*rc->param.container_frame_overhead; |
267 |
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); |
268 |
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); |
269 |
|
|
270 |
|
/* |
271 |
|
* First data pre processing: |
272 |
|
* - finds the minimum frame length for each frame type during 1st pass. |
273 |
|
* rc->min_size[] |
274 |
|
* - determines the maximum frame length observed (no frame type distinction). |
275 |
|
* rc->max_size |
276 |
|
* - count how many times each frame type has been used. |
277 |
|
* rc->count[] |
278 |
|
* - total bytes used per frame type |
279 |
|
* rc->total[] |
280 |
|
* - store keyframe location |
281 |
|
* rc->keyframe_locations[] |
282 |
|
*/ |
283 |
pre_process0(rc); |
pre_process0(rc); |
284 |
|
|
285 |
|
/* |
286 |
|
* When bitrate is not given it means it has been scaled by an external |
287 |
|
* application |
288 |
|
*/ |
289 |
if (rc->param.bitrate) { |
if (rc->param.bitrate) { |
290 |
|
/* Apply zone settings */ |
291 |
zone_process(rc, create); |
zone_process(rc, create); |
292 |
|
/* Perform curve scaling */ |
293 |
internal_scale(rc); |
internal_scale(rc); |
294 |
}else{ |
}else{ |
295 |
/* external scaler: ignore zone */ |
/* External scaling -- zones are ignored */ |
296 |
for (i=0;i<rc->num_frames;i++) { |
for (i=0;i<rc->num_frames;i++) { |
297 |
rc->stats[i].zone_mode = XVID_ZONE_WEIGHT; |
rc->stats[i].zone_mode = XVID_ZONE_WEIGHT; |
298 |
rc->stats[i].weight = 1.0; |
rc->stats[i].weight = 1.0; |
300 |
rc->avg_weight = 1.0; |
rc->avg_weight = 1.0; |
301 |
rc->tot_quant = 0; |
rc->tot_quant = 0; |
302 |
} |
} |
|
pre_process1(rc); |
|
|
|
|
|
for (i=0; i<32;i++) { |
|
|
rc->pquant_error[i] = 0; |
|
|
rc->bquant_error[i] = 0; |
|
|
rc->quant_count[i] = 0; |
|
|
} |
|
303 |
|
|
304 |
rc->fq_error = 0; |
pre_process1(rc); |
305 |
|
|
306 |
*handle = rc; |
*handle = rc; |
307 |
return(0); |
return(0); |
330 |
int desired; |
int desired; |
331 |
double dbytes; |
double dbytes; |
332 |
double curve_temp; |
double curve_temp; |
333 |
|
double scaled_quant; |
334 |
int capped_to_max_framesize = 0; |
int capped_to_max_framesize = 0; |
335 |
|
|
336 |
/* |
/* |
344 |
|
|
345 |
/* Second case: We are in a Quant zone */ |
/* Second case: We are in a Quant zone */ |
346 |
if (s->zone_mode == XVID_ZONE_QUANT) { |
if (s->zone_mode == XVID_ZONE_QUANT) { |
|
|
|
347 |
rc->fq_error += s->weight; |
rc->fq_error += s->weight; |
348 |
data->quant = (int)rc->fq_error; |
data->quant = (int)rc->fq_error; |
349 |
rc->fq_error -= data->quant; |
rc->fq_error -= data->quant; |
351 |
s->desired_length = s->length; |
s->desired_length = s->length; |
352 |
|
|
353 |
return(0); |
return(0); |
|
|
|
354 |
} |
} |
355 |
|
|
356 |
/* Third case: insufficent stats data */ |
/* Third case: insufficent stats data */ |
407 |
|
|
408 |
rc->curve_comp_error -= desired; |
rc->curve_comp_error -= desired; |
409 |
|
|
|
/* |
|
|
* 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 |
|
|
*/ |
|
|
|
|
410 |
/* XXX: warning */ |
/* XXX: warning */ |
411 |
curve_temp = 0; |
curve_temp = 0; |
412 |
|
|
463 |
s->desired_length = desired; |
s->desired_length = desired; |
464 |
|
|
465 |
|
|
466 |
/* if this keyframe is too close to the next, reduce it's byte allotment |
/* |
467 |
XXX: why do we do this after setting the desired length */ |
* if this keyframe is too close to the next, reduce it's byte allotment |
468 |
|
* XXX: why do we do this after setting the desired length ? |
469 |
|
*/ |
470 |
|
|
471 |
if (s->type == XVID_TYPE_IVOP) { |
if (s->type == XVID_TYPE_IVOP) { |
472 |
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]; |
526 |
* Don't laugh at this very 'simple' quant<->filesize relationship, it |
* Don't laugh at this very 'simple' quant<->filesize relationship, it |
527 |
* proves to be acurate enough for our algorithm |
* proves to be acurate enough for our algorithm |
528 |
*/ |
*/ |
529 |
data->quant = s->quant*s->length/desired; |
scaled_quant = (double)s->quant*(double)s->length/(double)desired; |
530 |
|
|
531 |
|
/* |
532 |
|
* Quantizer has been scaled using floating point operations/results, we |
533 |
|
* must cast it to integer |
534 |
|
*/ |
535 |
|
data->quant = (int)scaled_quant; |
536 |
|
|
537 |
/* Let's clip the computed quantizer, if needed */ |
/* Let's clip the computed quantizer, if needed */ |
538 |
if (data->quant < 1) { |
if (data->quant < 1) { |
542 |
} else if (s->type != XVID_TYPE_IVOP) { |
} else if (s->type != XVID_TYPE_IVOP) { |
543 |
|
|
544 |
/* |
/* |
545 |
* 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 |
546 |
* computed quantizer, however past frames give us some info about how |
* computed quantizer, do not loose quantizer decimal part that we |
547 |
* 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 |
|
548 |
*/ |
*/ |
549 |
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; |
|
550 |
|
|
551 |
if (rc->bquant_error[data->quant] >= 1.0) { |
if (rc->quant_error[s->type-1][data->quant] >= 1.0) { |
552 |
rc->bquant_error[data->quant] -= 1.0; |
rc->quant_error[s->type-1][data->quant] -= 1.0; |
553 |
data->quant++; |
data->quant++; |
554 |
|
} else if (rc->quant_error[s->type-1][data->quant] <= -1.0) { |
555 |
|
rc->quant_error[s->type-1][data->quant] += 1.0; |
556 |
|
data->quant--; |
557 |
} |
} |
|
} else { |
|
|
rc->pquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant; |
|
558 |
|
|
|
if (rc->pquant_error[data->quant] >= 1.0) { |
|
|
rc->pquant_error[data->quant] -= 1.0; |
|
|
data->quant++; |
|
|
} |
|
|
} |
|
559 |
} |
} |
560 |
|
|
561 |
/* |
/* |
638 |
rc->KFoverflow -= rc->KFoverflow_partial; |
rc->KFoverflow -= rc->KFoverflow_partial; |
639 |
} |
} |
640 |
|
|
641 |
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", |
642 |
data->frame_num, |
data->frame_num, |
643 |
frame_type[data->type-1], |
frame_type[data->type-1], |
644 |
data->quant, |
data->quant, |
645 |
s->length, |
s->length, |
646 |
s->scaled_length, |
s->scaled_length, |
647 |
data->length, |
data->length, |
648 |
|
s->desired_length, |
649 |
rc->overflow); |
rc->overflow); |
650 |
|
|
651 |
return(0); |
return(0); |
756 |
{ |
{ |
757 |
int i,j; |
int i,j; |
758 |
|
|
759 |
|
/* |
760 |
|
* *rc fields initialization |
761 |
|
* NB: INT_MAX and INT_MIN are used in order to be immediately replaced |
762 |
|
* with real values of the 1pass |
763 |
|
*/ |
764 |
for (i=0; i<3; i++) { |
for (i=0; i<3; i++) { |
765 |
rc->count[i]=0; |
rc->count[i]=0; |
766 |
rc->tot_length[i] = 0; |
rc->tot_length[i] = 0; |
|
rc->last_quant[i] = 0; |
|
767 |
rc->min_length[i] = INT_MAX; |
rc->min_length[i] = INT_MAX; |
768 |
} |
} |
769 |
|
|
770 |
rc->max_length = INT_MIN; |
rc->max_length = INT_MIN; |
771 |
|
|
772 |
|
/* |
773 |
|
* Loop through all frames and find/compute all the stuff this function |
774 |
|
* is supposed to do |
775 |
|
*/ |
776 |
for (i=j=0; i<rc->num_frames; i++) { |
for (i=j=0; i<rc->num_frames; i++) { |
777 |
stat_t * s = &rc->stats[i]; |
stat_t * s = &rc->stats[i]; |
778 |
|
|
912 |
continue; |
continue; |
913 |
} |
} |
914 |
|
|
915 |
/* Compute teh scaled length */ |
/* Compute the scaled length */ |
916 |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
len = (int)((double)s->length * scaler * s->weight / rc->avg_weight); |
917 |
|
|
918 |
/* Compare with the computed minimum */ |
/* Compare with the computed minimum */ |
948 |
if (s->scaled_length == 0) |
if (s->scaled_length == 0) |
949 |
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); |
950 |
} |
} |
|
|
|
951 |
} |
} |
952 |
|
|
953 |
static void |
static void |