--- branches/dev-api-3/vfw/src/2pass.c 2002/11/19 13:23:17 660 +++ branches/dev-api-3/vfw/src/2pass.c 2003/02/02 10:05:27 814 @@ -49,6 +49,11 @@ double total2 = 0.0; double dbytes, dbytes2; + /* ensure free() is called safely */ + codec->twopass.hintstream = NULL; + twopass->nns1_array = NULL; + twopass->nns2_array = NULL; + if (codec->config.hinted_me) { codec->twopass.hintstream = malloc(100000); @@ -337,8 +342,20 @@ twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) / (bframe_total_ext + pframe_total_ext)); - twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve; - twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve; + + if (bframes) + twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve; + + if (pframes) + twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve; + else + if (bframes) + twopass->average_pframe = twopass->average_bframe; // b-frame packed bitstream fix + else + { + DEBUGERR("ERROR: No p-frames or b-frames were present in the 1st pass. Rate control cannot function properly!"); + return ICERR_ERROR; + } @@ -648,8 +665,19 @@ break; } - twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve; - twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve; + if (bframes) + twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve; + + if (pframes) + twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve; + else + if (bframes) + twopass->average_pframe = twopass->average_bframe; // b-frame packed bitstream fix + else + { + DEBUGERR("ERROR: No p-frames or b-frames were present in the 1st pass. Rate control cannot function properly!"); + return ICERR_ERROR; + } @@ -965,10 +993,17 @@ if (twopass->nns_array_pos >= twopass->nns_array_length) { - twopass->nns_array_pos = 0; - DEBUG("ERROR: VIDEO EXCEEDS 1ST PASS!!!"); - frame->intra = -1; - return 2; + // fix for VirtualDub 1.4.13 bframe handling + if (codec->config.max_bframes > 0 && + codec->framenum < twopass->nns_array_length + codec->config.max_bframes) + { + return ICERR_OK; + } + else + { + DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!"); + return ICERR_ERROR; + } } memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS)); @@ -985,7 +1020,7 @@ twopass->bytes2 = bytes1; twopass->desired_bytes2 = bytes1; frame->intra = 3; - return 2; + return ICERR_OK; } else if (twopass->nns1.dd_v & NNSTATS_PADFRAME) { @@ -993,7 +1028,7 @@ twopass->bytes2 = bytes1; twopass->desired_bytes2 = bytes1; frame->intra = 4; - return 2; + return ICERR_OK; } else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME) { @@ -1001,7 +1036,7 @@ twopass->bytes2 = bytes1; twopass->desired_bytes2 = bytes1; frame->intra = 5; - return 2; + return ICERR_OK; } overflow = twopass->overflow / 8; @@ -1170,11 +1205,11 @@ } } } - curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus; - if (twopass->nns1.dd_v & NNSTATS_BFRAME) curve_temp *= twopass->average_bframe / twopass->average_pframe; + curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus; + bytes2 += ((int)curve_temp); curve_comp_error += curve_temp - ((int)curve_temp); } @@ -1430,7 +1465,12 @@ if (capped_to_max_framesize == 0) { - if (twopass->nns1.dd_v & NNSTATS_BFRAME) + if (twopass->nns1.quant & NNSTATS_KEYFRAME) + { + last_bquant = frame->quant; + last_pquant = frame->quant; + } + else if (twopass->nns1.dd_v & NNSTATS_BFRAME) last_bquant = frame->quant; else last_pquant = frame->quant; @@ -1441,13 +1481,13 @@ frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT; frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT; } -/* + if (codec->config.quant_type == QUANT_MODE_MOD_NEW) { frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT; frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT; } -*/ + return ICERR_OK; } @@ -1475,8 +1515,9 @@ { case DLG_MODE_2PASS_1 : nns1.bytes = frame->length; // total bytes - nns1.dd_v = stats->hlength; // header bytes - +// THIS small bugger messed up 2pass encoding! +// nns1.dd_v = stats->hlength; // header bytes + nns1.dd_v = 0; nns1.dd_u = nns1.dd_y = 0; nns1.dk_v = nns1.dk_u = nns1.dk_y = 0; nns1.md_u = nns1.md_y = 0; @@ -1588,23 +1629,23 @@ else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) { frame_type="skipped"; frame->quant = 2; - codec->twopass.bytes1 = 8; - codec->twopass.desired_bytes2 = 8; - frame->length = 8; + codec->twopass.bytes1 = 1; + codec->twopass.desired_bytes2 = 1; + frame->length = 1; } else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) { frame_type="padded"; frame->quant = 2; - codec->twopass.bytes1 = 8; - codec->twopass.desired_bytes2 = 8; - frame->length = 8; + codec->twopass.bytes1 = 7; + codec->twopass.desired_bytes2 = 7; + frame->length = 7; } else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) { frame_type="delayed"; frame->quant = 2; - codec->twopass.bytes1 = 8; - codec->twopass.desired_bytes2 = 8; - frame->length = 8; + codec->twopass.bytes1 = 1; + codec->twopass.desired_bytes2 = 1; + frame->length = 1; } DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos) @@ -1623,9 +1664,15 @@ char s[100]; if (codec->twopass.nns1_array) + { free(codec->twopass.nns1_array); + codec->twopass.nns1_array = NULL; + } if (codec->twopass.nns2_array) + { free(codec->twopass.nns2_array); + codec->twopass.nns2_array = NULL; + } codec->twopass.nns_array_size = 0; codec->twopass.nns_array_length = 0; codec->twopass.nns_array_pos = 0;