[XviD-devel] dev-api-3 vfw 2pass fix
suxen_drol
xvid-devel@xvid.org
Mon, 27 Jan 2003 18:28:24 +1100
On Mon, 27 Jan 2003 07:50:41 +0100 Dirk Knop <dknop@gwdg.de> wrote:
> Good morning everyone,
>
> good news!
> I hacked an ugly fix for our issue that 2pass is broken in dev-api-3/vfw
> since the xvid-core pFrame->intra reports are "messed up". Just use this
> 2pass.c which treats all frame types different from intra/inter as
> bframes - thus scaling correctly again.
> This is only a temporary solution as the core does dynamic
> I/P/B-decision even in 2nd pass, it'll sure break things when this
> behaviour of the core gets fixed.
> This is no permanent solution, but it works for me (and now).
i havent really been following this (or doing any 2pass tests lately),
but what exactly is broken? fixing it at the core is a better solution.
Index: 2pass.c
===================================================================
RCS file: /xvid/vfw/src/2pass.c,v
retrieving revision 1.7.2.7
diff -u -r1.7.2.7 2pass.c
--- 2pass.c 20 Dec 2002 05:35:56 -0000 1.7.2.7
+++ 2pass.c 27 Jan 2003 07:26:13 -0000
@@ -285,12 +285,12 @@
memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
twopass->nns_array_pos++;
- // skip unnecessary frames.
+/* // skip unnecessary frames.
if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
twopass->nns1.dd_v & NNSTATS_PADFRAME ||
twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
continue;
-
+*/ // we need to treat it like usual frames now - someone broke core's reports
if (!codec_is_in_credits(&codec->config, frames))
{
if (twopass->nns1.quant & NNSTATS_KEYFRAME)
@@ -302,7 +302,10 @@
}
else
{
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
bframe_total += twopass->nns1.bytes;
bframe_total_ext += twopass->nns2.bytes;
@@ -434,19 +437,22 @@
twopass->minisize = recminisize;
}
- // skip unnecessary frames.
+/* // skip unnecessary frames.
if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
twopass->nns1.dd_v & NNSTATS_PADFRAME ||
twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
continue;
-
+*/ // broken in core, need to treat it differently now :-(
if (!codec_is_in_credits(&codec->config, frames) &&
!(twopass->nns1.quant & NNSTATS_KEYFRAME))
{
dbytes = twopass->nns2.bytes / twopass->movie_curve;
total1 += dbytes;
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
dbytes *= twopass->average_pframe / twopass->average_bframe;
if (codec->config.use_alt_curve)
@@ -510,7 +516,10 @@
}
}
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
dbytes2 *= twopass->average_bframe / twopass->average_pframe;
if (dbytes2 < twopass->minbsize)
@@ -553,12 +562,12 @@
memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
twopass->nns_array_pos++;
- // skip unnecessary frames.
+/* // skip unnecessary frames.
if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
twopass->nns1.dd_v & NNSTATS_PADFRAME ||
twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
continue;
-
+*/ // broken in core, have to treat this stuff differently now
if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
{
start += twopass->nns1.bytes;
@@ -577,7 +586,10 @@
}
else
{
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
bframe_total += twopass->nns1.bytes;
bframes++;
@@ -595,7 +607,10 @@
if (!(twopass->nns1.kblk + twopass->nns1.mblk))
recminisize = twopass->nns1.bytes;
}
- else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ else if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
if (!(twopass->nns1.kblk + twopass->nns1.mblk))
recminbsize = twopass->nns1.bytes;
@@ -752,19 +767,22 @@
twopass->minisize = recminisize;
}
- // skip unnecessary frames.
+/* // skip unnecessary frames.
if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
twopass->nns1.dd_v & NNSTATS_PADFRAME ||
twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
continue;
-
+*/ // broken in core, we need to handle it differently now :-((
if (!codec_is_in_credits(&codec->config, frames) &&
!(twopass->nns1.quant & NNSTATS_KEYFRAME))
{
dbytes = twopass->nns1.bytes / twopass->movie_curve;
total1 += dbytes;
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
dbytes *= twopass->average_pframe / twopass->average_bframe;
if (codec->config.use_alt_curve)
@@ -828,7 +846,10 @@
}
}
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
dbytes2 *= twopass->average_bframe / twopass->average_pframe;
if (dbytes2 < twopass->minbsize)
@@ -1013,7 +1034,7 @@
bytes1 = twopass->nns1.bytes;
- // skip unnecessary frames.
+/* // skip unnecessary frames.
if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
{
twopass->bytes1 = bytes1;
@@ -1038,13 +1059,16 @@
frame->intra = 5;
return ICERR_OK;
}
-
+*/ // broken in core, need to treat it differently :-((
overflow = twopass->overflow / 8;
// override codec i-frame choice (reenable in credits)
if (twopass->nns1.quant & NNSTATS_KEYFRAME)
frame->intra=1;
- else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ else if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
frame->intra=2;
else
frame->intra=0;
@@ -1136,7 +1160,10 @@
dbytes = bytes2 / twopass->movie_curve;
}
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
dbytes *= twopass->average_pframe / twopass->average_bframe;
// spread the compression error across payback_delay frames
@@ -1205,7 +1232,10 @@
}
}
}
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
curve_temp *= twopass->average_bframe / twopass->average_pframe;
curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
@@ -1215,7 +1245,10 @@
}
else
{
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
dbytes *= twopass->average_bframe / twopass->average_pframe;
bytes2 += ((int)dbytes);
@@ -1238,7 +1271,10 @@
codec->config.curve_compression_low / 100.0);
}
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
curve_temp *= twopass->average_bframe / twopass->average_pframe;
bytes2 += ((int)curve_temp);
@@ -1246,7 +1282,10 @@
}
else
{
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
dbytes *= twopass->average_bframe / twopass->average_pframe;
bytes2 += ((int)dbytes);
@@ -1269,7 +1308,10 @@
bytes2 = twopass->minisize;
}
}
- else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ else if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
if (bytes2 < twopass->minbsize)
bytes2 = twopass->minbsize;
@@ -1347,7 +1389,10 @@
if (bytes2 < twopass->minisize)
bytes2 = twopass->minisize;
}
- else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ else if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
if (bytes2 < twopass->minbsize)
bytes2 = twopass->minbsize;
@@ -1375,7 +1420,10 @@
else if (!(frame->intra==1))
{
// Foxer: aid desired quantizer precision by accumulating decision error
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
bytes1) / bytes2) - frame->quant;
@@ -1432,7 +1480,10 @@
// subsequent frame quants can only be +- 2
if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
{
- if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
{
// this bframe quantizer variation
// restriction needs to be redone.
@@ -1470,7 +1521,10 @@
last_bquant = frame->quant;
last_pquant = frame->quant;
}
- else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
+ else if (twopass->nns1.dd_v & NNSTATS_BFRAME ||
+ twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
+ twopass->nns1.dd_v & NNSTATS_PADFRAME ||
+ twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
last_bquant = frame->quant;
else
last_pquant = frame->quant;
@@ -1565,10 +1619,10 @@
case DLG_MODE_2PASS_2_INT :
case DLG_MODE_2PASS_2_EXT :
credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
- if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
+/* if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
!(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
!(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
- {
+ { */
if (!credits_pos)
{
codec->twopass.quant_count[frame->quant]++;
@@ -1616,16 +1670,19 @@
codec->twopass.KFoverflow_partial = 0;
// end of ugly fix.
}
- }
+// }
frame_type="inter";
if (frame->intra==1) {
frame_type="intra";
}
- else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
+ else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME ||
+ codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME ||
+ codec->twopass.nns1.dd_v & NNSTATS_PADFRAME ||
+ codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
frame_type="bframe";
}
- else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
+/* else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
frame_type="skipped";
frame->quant = 2;
codec->twopass.bytes1 = 1;
@@ -1645,8 +1702,8 @@
codec->twopass.bytes1 = 1;
codec->twopass.desired_bytes2 = 1;
frame->length = 1;
- }
-
+ }
+*/ // all broken in core... *grmblfx*
DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
break;
-- pete; life is like a box of ammo