23 |
* |
* |
24 |
* History: |
* History: |
25 |
* |
* |
26 |
|
* 17.04.2002 changed 1st pass quant to always be 2 (2pass_update()) |
27 |
|
* 07.04.2002 added max bitrate constraint, overflow controls (foxer) |
28 |
* 31.03.2002 inital version; |
* 31.03.2002 inital version; |
29 |
* |
* |
30 |
*************************************************************************/ |
*************************************************************************/ |
41 |
DWORD version = -20; |
DWORD version = -20; |
42 |
DWORD read, wrote; |
DWORD read, wrote; |
43 |
|
|
44 |
int frames = 0, credits_frames = 0, i_frames = 0; |
int frames = 0, credits_frames = 0, i_frames = 0, recminpsize = 0, recminisize = 0; |
45 |
__int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0; |
__int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0; |
46 |
__int64 desired = (__int64)codec->config.desired_size * 1024; |
__int64 desired = (__int64)codec->config.desired_size * 1024; |
47 |
|
|
48 |
double total1 = 0.0; |
double total1 = 0.0; |
49 |
double total2 = 0.0; |
double total2 = 0.0; |
50 |
|
double dbytes, dbytes2; |
51 |
|
|
52 |
if (codec->config.hinted_me) |
if (codec->config.hinted_me) |
53 |
{ |
{ |
162 |
{ |
{ |
163 |
if (twopass->nns1.quant & NNSTATS_KEYFRAME) |
if (twopass->nns1.quant & NNSTATS_KEYFRAME) |
164 |
{ |
{ |
165 |
i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100; |
i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100; |
166 |
i_total += twopass->nns2.bytes; |
i_total += twopass->nns2.bytes; |
167 |
|
twopass->keyframe_locations[i_frames] = frames; |
168 |
++i_frames; |
++i_frames; |
169 |
} |
} |
170 |
|
|
174 |
else |
else |
175 |
++credits_frames; |
++credits_frames; |
176 |
|
|
177 |
|
if (twopass->nns1.quant & NNSTATS_KEYFRAME) |
178 |
|
{ |
179 |
|
if (!(twopass->nns1.kblk + twopass->nns1.mblk)) |
180 |
|
recminisize = twopass->nns1.bytes; |
181 |
|
} |
182 |
|
else |
183 |
|
{ |
184 |
|
if (!(twopass->nns1.kblk + twopass->nns1.mblk)) |
185 |
|
recminpsize = twopass->nns1.bytes; |
186 |
|
} |
187 |
|
|
188 |
++frames; |
++frames; |
189 |
} |
} |
190 |
|
twopass->keyframe_locations[i_frames] = frames; |
191 |
|
|
192 |
twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext); |
twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext); |
193 |
twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve); |
twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve); |
264 |
} |
} |
265 |
} |
} |
266 |
|
|
267 |
|
if (frames == 0) |
268 |
|
{ |
269 |
|
twopass->minpsize = (twopass->nns1.kblk + 88) / 8; |
270 |
|
twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8; |
271 |
|
if (recminpsize > twopass->minpsize) |
272 |
|
twopass->minpsize = recminpsize; |
273 |
|
if (recminisize > twopass->minisize) |
274 |
|
twopass->minisize = recminisize; |
275 |
|
} |
276 |
|
|
277 |
if (!codec_is_in_credits(&codec->config, frames) && |
if (!codec_is_in_credits(&codec->config, frames) && |
278 |
!(twopass->nns1.quant & NNSTATS_KEYFRAME)) |
!(twopass->nns1.quant & NNSTATS_KEYFRAME)) |
279 |
{ |
{ |
280 |
double dbytes = twopass->nns2.bytes / twopass->movie_curve; |
dbytes = twopass->nns2.bytes / twopass->movie_curve; |
281 |
total1 += dbytes; |
total1 += dbytes; |
282 |
|
|
283 |
if (codec->config.use_alt_curve) |
if (codec->config.use_alt_curve) |
285 |
if (dbytes > twopass->average_frame) |
if (dbytes > twopass->average_frame) |
286 |
{ |
{ |
287 |
if (dbytes >= twopass->alt_curve_high) |
if (dbytes >= twopass->alt_curve_high) |
288 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); |
289 |
else |
else |
290 |
{ |
{ |
291 |
switch(codec->config.alt_curve_type) |
switch(codec->config.alt_curve_type) |
292 |
{ |
{ |
293 |
case 2: |
case 2: |
294 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
295 |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); |
296 |
break; |
break; |
297 |
case 1: |
case 1: |
298 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
299 |
(dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); |
(dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); |
300 |
break; |
break; |
301 |
case 0: |
case 0: |
302 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
303 |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); |
304 |
} |
} |
305 |
} |
} |
307 |
else |
else |
308 |
{ |
{ |
309 |
if (dbytes <= twopass->alt_curve_low) |
if (dbytes <= twopass->alt_curve_low) |
310 |
total2 += dbytes; |
dbytes2 = dbytes; |
311 |
else |
else |
312 |
{ |
{ |
313 |
switch(codec->config.alt_curve_type) |
switch(codec->config.alt_curve_type) |
314 |
{ |
{ |
315 |
case 2: |
case 2: |
316 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
317 |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); |
318 |
break; |
break; |
319 |
case 1: |
case 1: |
320 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
321 |
(dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); |
(dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); |
322 |
break; |
break; |
323 |
case 0: |
case 0: |
324 |
total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * |
325 |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); |
326 |
} |
} |
327 |
} |
} |
331 |
{ |
{ |
332 |
if (dbytes > twopass->average_frame) |
if (dbytes > twopass->average_frame) |
333 |
{ |
{ |
334 |
total2 += ((double)dbytes + (twopass->average_frame - dbytes) * |
dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) * |
335 |
codec->config.curve_compression_high / 100.0); |
codec->config.curve_compression_high / 100.0); |
336 |
} |
} |
337 |
else |
else |
338 |
{ |
{ |
339 |
total2 += ((double)dbytes + (twopass->average_frame - dbytes) * |
dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) * |
340 |
codec->config.curve_compression_low / 100.0); |
codec->config.curve_compression_low / 100.0); |
341 |
} |
} |
342 |
} |
} |
343 |
|
|
344 |
|
if (dbytes2 < twopass->minpsize) |
345 |
|
dbytes2 = twopass->minpsize; |
346 |
|
|
347 |
|
total2 += dbytes2; |
348 |
} |
} |
349 |
|
|
350 |
++frames; |
++frames; |
400 |
{ |
{ |
401 |
i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100; |
i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100; |
402 |
total += twopass->nns1.bytes * codec->config.keyframe_boost / 100; |
total += twopass->nns1.bytes * codec->config.keyframe_boost / 100; |
403 |
|
twopass->keyframe_locations[i_frames] = frames; |
404 |
++i_frames; |
++i_frames; |
405 |
} |
} |
406 |
|
|
407 |
total += twopass->nns1.bytes; |
total += twopass->nns1.bytes; |
408 |
|
|
409 |
|
if (twopass->nns1.quant & NNSTATS_KEYFRAME) |
410 |
|
{ |
411 |
|
if (!(twopass->nns1.kblk + twopass->nns1.mblk)) |
412 |
|
recminisize = twopass->nns1.bytes; |
413 |
|
} |
414 |
|
else |
415 |
|
{ |
416 |
|
if (!(twopass->nns1.kblk + twopass->nns1.mblk)) |
417 |
|
recminpsize = twopass->nns1.bytes; |
418 |
|
} |
419 |
|
|
420 |
++frames; |
++frames; |
421 |
} |
} |
422 |
|
twopass->keyframe_locations[i_frames] = frames; |
423 |
|
|
424 |
// compensate for avi frame overhead |
// compensate for avi frame overhead |
425 |
desired -= frames * 24; |
desired -= frames * 24; |
549 |
} |
} |
550 |
} |
} |
551 |
|
|
552 |
|
if (frames == 0) |
553 |
|
{ |
554 |
|
twopass->minpsize = (twopass->nns1.kblk + 88) / 8; |
555 |
|
twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8; |
556 |
|
if (recminpsize > twopass->minpsize) |
557 |
|
twopass->minpsize = recminpsize; |
558 |
|
if (recminisize > twopass->minisize) |
559 |
|
twopass->minisize = recminisize; |
560 |
|
} |
561 |
|
|
562 |
if (!codec_is_in_credits(&codec->config, frames) && |
if (!codec_is_in_credits(&codec->config, frames) && |
563 |
!(twopass->nns1.quant & NNSTATS_KEYFRAME)) |
!(twopass->nns1.quant & NNSTATS_KEYFRAME)) |
564 |
{ |
{ |
565 |
double dbytes = twopass->nns1.bytes / twopass->movie_curve; |
dbytes = twopass->nns1.bytes / twopass->movie_curve; |
566 |
total1 += dbytes; |
total1 += dbytes; |
567 |
|
|
568 |
if (codec->config.use_alt_curve) |
if (codec->config.use_alt_curve) |
570 |
if (dbytes > twopass->average_frame) |
if (dbytes > twopass->average_frame) |
571 |
{ |
{ |
572 |
if (dbytes >= twopass->alt_curve_high) |
if (dbytes >= twopass->alt_curve_high) |
573 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); |
574 |
else |
else |
575 |
{ |
{ |
576 |
switch(codec->config.alt_curve_type) |
switch(codec->config.alt_curve_type) |
577 |
{ |
{ |
578 |
case 2: |
case 2: |
579 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
580 |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); |
581 |
break; |
break; |
582 |
case 1: |
case 1: |
583 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
584 |
(dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); |
(dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); |
585 |
break; |
break; |
586 |
case 0: |
case 0: |
587 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
588 |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); |
589 |
} |
} |
590 |
} |
} |
592 |
else |
else |
593 |
{ |
{ |
594 |
if (dbytes <= twopass->alt_curve_low) |
if (dbytes <= twopass->alt_curve_low) |
595 |
total2 += dbytes; |
dbytes2 = dbytes; |
596 |
else |
else |
597 |
{ |
{ |
598 |
switch(codec->config.alt_curve_type) |
switch(codec->config.alt_curve_type) |
599 |
{ |
{ |
600 |
case 2: |
case 2: |
601 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
602 |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); |
sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); |
603 |
break; |
break; |
604 |
case 1: |
case 1: |
605 |
total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * |
606 |
(dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); |
(dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); |
607 |
break; |
break; |
608 |
case 0: |
case 0: |
609 |
total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * |
dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * |
610 |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); |
(1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); |
611 |
} |
} |
612 |
} |
} |
616 |
{ |
{ |
617 |
if (dbytes > twopass->average_frame) |
if (dbytes > twopass->average_frame) |
618 |
{ |
{ |
619 |
total2 += ((double)dbytes + (twopass->average_frame - dbytes) * |
dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) * |
620 |
codec->config.curve_compression_high / 100.0); |
codec->config.curve_compression_high / 100.0); |
621 |
} |
} |
622 |
else |
else |
623 |
{ |
{ |
624 |
total2 += ((double)dbytes + (twopass->average_frame - dbytes) * |
dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) * |
625 |
codec->config.curve_compression_low / 100.0); |
codec->config.curve_compression_low / 100.0); |
626 |
} |
} |
627 |
} |
} |
628 |
|
|
629 |
|
if (dbytes2 < twopass->minpsize) |
630 |
|
dbytes2 = twopass->minpsize; |
631 |
|
|
632 |
|
total2 += dbytes2; |
633 |
} |
} |
634 |
|
|
635 |
++frames; |
++frames; |
739 |
} |
} |
740 |
|
|
741 |
twopass->overflow = 0; |
twopass->overflow = 0; |
742 |
|
twopass->KFoverflow = 0; |
743 |
|
twopass->KFoverflow_partial = 0; |
744 |
|
twopass->KF_idx = 1; |
745 |
|
|
746 |
break; |
break; |
747 |
} |
} |
762 |
int bytes1, bytes2; |
int bytes1, bytes2; |
763 |
int overflow; |
int overflow; |
764 |
int credits_pos; |
int credits_pos; |
765 |
|
int capped_to_max_framesize = 0; |
766 |
|
int KFdistance, KF_min_size; |
767 |
|
|
768 |
if (codec->framenum == 0) |
if (codec->framenum == 0) |
769 |
{ |
{ |
772 |
for (i=0 ; i<32 ; ++i) |
for (i=0 ; i<32 ; ++i) |
773 |
{ |
{ |
774 |
quant_error[i] = 0.0; |
quant_error[i] = 0.0; |
775 |
|
twopass->quant_count[i] = 0; |
776 |
} |
} |
777 |
|
|
778 |
curve_comp_error = 0.0; |
curve_comp_error = 0.0; |
847 |
} |
} |
848 |
else // DLG_MODE_2PASS_2_EXT |
else // DLG_MODE_2PASS_2_EXT |
849 |
{ |
{ |
850 |
|
if (codec->config.credits_mode == CREDITS_MODE_QUANT) |
851 |
|
{ |
852 |
|
if (codec->config.credits_quant_i != codec->config.credits_quant_p) |
853 |
|
{ |
854 |
|
frame->quant = frame->intra ? |
855 |
|
codec->config.credits_quant_i : |
856 |
|
codec->config.credits_quant_p; |
857 |
|
} |
858 |
|
else |
859 |
|
{ |
860 |
|
frame->quant = codec->config.credits_quant_p; |
861 |
|
frame->intra = -1; |
862 |
|
} |
863 |
|
|
864 |
|
twopass->bytes1 = bytes1; |
865 |
|
twopass->bytes2 = bytes1; |
866 |
|
twopass->desired_bytes2 = bytes1; |
867 |
|
return ICERR_OK; |
868 |
|
} |
869 |
|
else |
870 |
bytes2 = twopass->nns2.bytes; |
bytes2 = twopass->nns2.bytes; |
871 |
} |
} |
872 |
} |
} |
994 |
curve_comp_error += bytes2 - bytes1; |
curve_comp_error += bytes2 - bytes1; |
995 |
bytes2 = bytes1; |
bytes2 = bytes1; |
996 |
} |
} |
997 |
else if (bytes2 < 1) |
else |
998 |
{ |
{ |
999 |
curve_comp_error += --bytes2; |
if (frame->intra) |
1000 |
bytes2 = 1; |
{ |
1001 |
|
if (bytes2 < twopass->minisize) |
1002 |
|
{ |
1003 |
|
curve_comp_error -= twopass->minisize - bytes2; |
1004 |
|
bytes2 = twopass->minisize; |
1005 |
|
} |
1006 |
|
} |
1007 |
|
else if (bytes2 < twopass->minpsize) |
1008 |
|
bytes2 = twopass->minpsize; |
1009 |
} |
} |
1010 |
} |
} |
1011 |
|
|
1012 |
twopass->desired_bytes2 = bytes2; |
twopass->desired_bytes2 = bytes2; |
1013 |
|
|
1014 |
|
// if this keyframe is too close to the next, |
1015 |
|
// reduce it's byte allotment |
1016 |
|
if (frame->intra && !credits_pos) |
1017 |
|
{ |
1018 |
|
KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] - |
1019 |
|
codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]; |
1020 |
|
|
1021 |
|
if (KFdistance < codec->config.kftreshold) |
1022 |
|
{ |
1023 |
|
KFdistance = KFdistance - codec->config.min_key_interval; |
1024 |
|
|
1025 |
|
if (KFdistance >= 0) |
1026 |
|
{ |
1027 |
|
KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100; |
1028 |
|
if (KF_min_size < 1) |
1029 |
|
KF_min_size = 1; |
1030 |
|
|
1031 |
|
bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance / |
1032 |
|
(codec->config.kftreshold - codec->config.min_key_interval); |
1033 |
|
|
1034 |
|
if (bytes2 < 1) |
1035 |
|
bytes2 = 1; |
1036 |
|
} |
1037 |
|
} |
1038 |
|
} |
1039 |
|
|
1040 |
// Foxer: scale overflow in relation to average size, so smaller frames don't get |
// Foxer: scale overflow in relation to average size, so smaller frames don't get |
1041 |
// too much/little bitrate |
// too much/little bitrate |
1042 |
overflow = (int)((double)overflow * bytes2 / twopass->average_frame); |
overflow = (int)((double)overflow * bytes2 / twopass->average_frame); |
1048 |
} |
} |
1049 |
|
|
1050 |
// Foxer: make sure overflow doesn't run away |
// Foxer: make sure overflow doesn't run away |
1051 |
if (overflow > bytes2 * 6 / 10) |
if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100) |
1052 |
{ |
{ |
1053 |
bytes2 += (overflow <= bytes2) ? bytes2 * 6 / 10 : overflow * 6 / 10; |
bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 : |
1054 |
|
overflow * codec->config.twopass_max_overflow_improvement / 100; |
1055 |
} |
} |
1056 |
else if (overflow < bytes2 * -6 / 10) |
else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100) |
1057 |
{ |
{ |
1058 |
bytes2 += bytes2 * -6 / 10; |
bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100; |
1059 |
} |
} |
1060 |
else |
else |
1061 |
{ |
{ |
1062 |
bytes2 += overflow; |
bytes2 += overflow; |
1063 |
} |
} |
1064 |
|
|
1065 |
if (bytes2 < 1) |
if (bytes2 > twopass->max_framesize) |
1066 |
{ |
{ |
1067 |
bytes2 = 1; |
capped_to_max_framesize = 1; |
1068 |
|
bytes2 = twopass->max_framesize; |
1069 |
} |
} |
1070 |
|
|
1071 |
|
// make sure to not scale below the minimum framesize |
1072 |
|
if (twopass->nns1.quant & NNSTATS_KEYFRAME) |
1073 |
|
{ |
1074 |
|
if (bytes2 < twopass->minisize) |
1075 |
|
bytes2 = twopass->minisize; |
1076 |
|
} |
1077 |
|
else if (bytes2 < twopass->minpsize) |
1078 |
|
bytes2 = twopass->minpsize; |
1079 |
|
|
1080 |
twopass->bytes1 = bytes1; |
twopass->bytes1 = bytes1; |
1081 |
twopass->bytes2 = bytes2; |
twopass->bytes2 = bytes2; |
1082 |
|
|
1135 |
} |
} |
1136 |
|
|
1137 |
// subsequent frame quants can only be +- 2 |
// subsequent frame quants can only be +- 2 |
1138 |
if (last_quant) |
if (last_quant && capped_to_max_framesize == 0) |
1139 |
{ |
{ |
1140 |
if (frame->quant > last_quant + 2) |
if (frame->quant > last_quant + 2) |
1141 |
{ |
{ |
1150 |
} |
} |
1151 |
} |
} |
1152 |
|
|
1153 |
|
if (capped_to_max_framesize == 0) |
1154 |
last_quant = frame->quant; |
last_quant = frame->quant; |
1155 |
|
|
1156 |
if (codec->config.quant_type == QUANT_MODE_MOD) |
if (codec->config.quant_type == QUANT_MODE_MOD) |
1169 |
|
|
1170 |
NNSTATS nns1; |
NNSTATS nns1; |
1171 |
DWORD wrote; |
DWORD wrote; |
1172 |
|
int credits_pos, tempdiv; |
1173 |
char* quant_type; |
char* quant_type; |
1174 |
|
|
1175 |
if (codec->framenum == 0) |
if (codec->framenum == 0) |
1192 |
nns1.md_u = nns1.md_y = 0; |
nns1.md_u = nns1.md_y = 0; |
1193 |
nns1.mk_u = nns1.mk_y = 0; |
nns1.mk_u = nns1.mk_y = 0; |
1194 |
|
|
1195 |
nns1.quant = stats->quant; |
// nns1.quant = stats->quant; |
1196 |
|
nns1.quant = 2; // ugly fix for lumi masking in 1st pass returning new quant |
1197 |
if (frame->intra) |
if (frame->intra) |
1198 |
{ |
{ |
1199 |
nns1.quant |= NNSTATS_KEYFRAME; |
nns1.quant |= NNSTATS_KEYFRAME; |
1216 |
|
|
1217 |
case DLG_MODE_2PASS_2_INT : |
case DLG_MODE_2PASS_2_INT : |
1218 |
case DLG_MODE_2PASS_2_EXT : |
case DLG_MODE_2PASS_2_EXT : |
1219 |
|
credits_pos = codec_is_in_credits(&codec->config, codec->framenum); |
1220 |
|
if (!credits_pos) |
1221 |
|
{ |
1222 |
|
codec->twopass.quant_count[frame->quant]++; |
1223 |
|
if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME)) |
1224 |
|
{ |
1225 |
|
// calculate how much to distribute per frame in |
1226 |
|
// order to make up for this keyframe's overflow |
1227 |
|
|
1228 |
|
codec->twopass.overflow += codec->twopass.KFoverflow; |
1229 |
|
codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length; |
1230 |
|
|
1231 |
|
tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] - |
1232 |
|
codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]); |
1233 |
|
|
1234 |
|
if (tempdiv > 1) |
1235 |
|
{ |
1236 |
|
// non-consecutive keyframes |
1237 |
|
codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1); |
1238 |
|
} |
1239 |
|
else |
1240 |
|
{ |
1241 |
|
// consecutive keyframes |
1242 |
|
codec->twopass.overflow += codec->twopass.KFoverflow; |
1243 |
|
codec->twopass.KFoverflow = 0; |
1244 |
|
codec->twopass.KFoverflow_partial = 0; |
1245 |
|
} |
1246 |
|
codec->twopass.KF_idx++; |
1247 |
|
} |
1248 |
|
else |
1249 |
|
{ |
1250 |
|
// distribute part of the keyframe overflow |
1251 |
|
|
1252 |
|
codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length + |
1253 |
|
codec->twopass.KFoverflow_partial; |
1254 |
|
codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial; |
1255 |
|
} |
1256 |
|
} |
1257 |
|
else |
1258 |
|
{ |
1259 |
codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; |
codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; |
1260 |
DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum)) |
|
1261 |
|
// ugly fix for credits.. |
1262 |
|
codec->twopass.overflow += codec->twopass.KFoverflow; |
1263 |
|
codec->twopass.KFoverflow = 0; |
1264 |
|
codec->twopass.KFoverflow_partial = 0; |
1265 |
|
// end of ugly fix. |
1266 |
|
} |
1267 |
|
|
1268 |
|
DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos) |
1269 |
break; |
break; |
1270 |
|
|
1271 |
default: |
default: |
1275 |
return ICERR_OK; |
return ICERR_OK; |
1276 |
} |
} |
1277 |
|
|
1278 |
|
void codec_2pass_finish(CODEC* codec) |
1279 |
|
{ |
1280 |
|
int i; |
1281 |
|
char s[100]; |
1282 |
|
if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT) |
1283 |
|
{ |
1284 |
|
// output the quantizer distribution for this encode. |
1285 |
|
|
1286 |
|
OutputDebugString("Quantizer distribution for 2nd pass:"); |
1287 |
|
for (i=1; i<=31; i++) |
1288 |
|
{ |
1289 |
|
if (codec->twopass.quant_count[i]) |
1290 |
|
{ |
1291 |
|
wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]); |
1292 |
|
OutputDebugString(s); |
1293 |
|
} |
1294 |
|
} |
1295 |
|
return; |
1296 |
|
} |
1297 |
|
} |
1298 |
|
|