📄 plugin_2pass2.c
字号:
case 'p': case 'P': case 'b': case 'B': case 's': case 'S': rc->num_frames++; break; default: DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- WARNING: L%d unknown frame type used (%c).\n", lines, type); } } else { DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- WARNING: L%d misses some stat fields (%d).\n", lines, 7-fields); } /* Free the line buffer */ free(line); } /* We are done with the file */ fclose(f); return(0);}/* open stats file(s) and read into rc->stats array */static intstatsfile_load(rc_2pass2_t *rc, char * filename){ FILE * f; int processed_entries; /* Opens the file */ if ((f = fopen(filename, "rb"))==NULL) return(-1); processed_entries = 0; while(processed_entries < rc->num_frames) { char type; int fields; twopass_stat_t * s = &rc->stats[processed_entries]; char *line, *ptr; /* Read the line from the file */ if((line = readline(f)) == NULL) break; /* We skip spaces */ ptr = skipspaces(line); /* Skip comment lines or empty lines */ if(iscomment(ptr) || *ptr == '\0') { free(line); continue; } /* Reset this field that is optional */ s->scaled_length = 0; /* Convert the fields */ fields = sscanf(ptr, "%c %d %d %d %d %d %d %d\n", &type, &s->quant, &s->blks[0], &s->blks[1], &s->blks[2], &s->length, &s->invariant /* not really yet */, &s->scaled_length); /* Free line buffer, we don't need it anymore */ free(line); /* Fail silently, this has probably been warned in * statsfile_count_frames */ if(fields != 7 && fields != 8) continue; /* Convert frame type and compute the invariant length part */ switch(type) { case 'i': case 'I': s->type = XVID_TYPE_IVOP; s->invariant /= INVARIANT_HEADER_PART_IVOP; break; case 'p': case 'P': case 's': case 'S': s->type = XVID_TYPE_PVOP; s->invariant /= INVARIANT_HEADER_PART_PVOP; break; case 'b': case 'B': s->type = XVID_TYPE_BVOP; s->invariant /= INVARIANT_HEADER_PART_BVOP; break; default: /* Same as before, fail silently */ continue; } /* Ok it seems it's been processed correctly */ processed_entries++; } /* Close the file */ fclose(f); return(0);}/* pre-process the statistics data * - for each type, count, tot_length, min_length, max_length * - set keyframes_locations, tot_prescaled */static voidfirst_pass_stats_prepare_data(rc_2pass2_t * rc){ int i,j; /* *rc fields initialization * NB: INT_MAX and INT_MIN are used in order to be immediately replaced * with real values of the 1pass */ for (i=0; i<3; i++) { rc->count[i]=0; rc->tot_length[i] = 0; rc->tot_invariant[i] = 0; rc->min_length[i] = INT_MAX; } rc->max_length = INT_MIN; rc->tot_weighted = 0; /* Loop through all frames and find/compute all the stuff this function * is supposed to do */ for (i=j=0; i<rc->num_frames; i++) { twopass_stat_t * s = &rc->stats[i]; rc->count[s->type-1]++; rc->tot_length[s->type-1] += s->length; rc->tot_invariant[s->type-1] += s->invariant; if (s->zone_mode != XVID_ZONE_QUANT) rc->tot_weighted += (int)(s->weight*(s->length - s->invariant)); if (s->length < rc->min_length[s->type-1]) { rc->min_length[s->type-1] = s->length; } if (s->length > rc->max_length) { rc->max_length = s->length; } if (s->type == XVID_TYPE_IVOP) { rc->keyframe_locations[j] = i; j++; } } /* NB: * The "per sequence" overflow system considers a natural sequence to be * formed by all frames between two iframes, so if we want to make sure * the system does not go nuts during last sequence, we force the last * frame to appear in the keyframe locations array. */ rc->keyframe_locations[j] = i; DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass IFrame length: %d\n", rc->min_length[0]); DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass PFrame length: %d\n", rc->min_length[1]); DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass BFrame length: %d\n", rc->min_length[2]);}/* calculate zone weight "center" */static voidzone_process(rc_2pass2_t *rc, const xvid_plg_create_t * create){ int i,j; int n = 0; rc->tot_quant = 0; rc->tot_quant_invariant = 0; if (create->num_zones == 0) { for (j = 0; j < rc->num_frames; j++) { rc->stats[j].zone_mode = XVID_ZONE_WEIGHT; rc->stats[j].weight = 1.0; } n += rc->num_frames; } for(i=0; i < create->num_zones; i++) { int next = (i+1<create->num_zones) ? create->zones[i+1].frame : rc->num_frames; /* Zero weight make no sense */ if (create->zones[i].increment == 0) create->zones[i].increment = 1; /* And obviously an undetermined infinite makes even less sense */ if (create->zones[i].base == 0) create->zones[i].base = 1; if (i==0 && create->zones[i].frame > 0) { for (j = 0; j < create->zones[i].frame && j < rc->num_frames; j++) { rc->stats[j].zone_mode = XVID_ZONE_WEIGHT; rc->stats[j].weight = 1.0; } n += create->zones[i].frame; } if (create->zones[i].mode == XVID_ZONE_WEIGHT) { for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) { rc->stats[j].zone_mode = XVID_ZONE_WEIGHT; rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base; } next -= create->zones[i].frame; n += next; } else{ /* XVID_ZONE_QUANT */ for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) { rc->stats[j].zone_mode = XVID_ZONE_QUANT; rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base; rc->tot_quant += rc->stats[j].length; rc->tot_quant_invariant += rc->stats[j].invariant; } } }}/* scale the curve */static voidfirst_pass_scale_curve_internal(rc_2pass2_t *rc){ int64_t target; int64_t total_invariant; double scaler; int i, num_MBs; /* We only scale texture data ! */ total_invariant = rc->tot_invariant[XVID_TYPE_IVOP-1]; total_invariant += rc->tot_invariant[XVID_TYPE_PVOP-1]; total_invariant += rc->tot_invariant[XVID_TYPE_BVOP-1]; /* don't forget to substract header bytes used in quant zones, otherwise we * counting them twice */ total_invariant -= rc->tot_quant_invariant; /* We remove the bytes used by the fixed quantizer zones during first pass * with the same quants, so we know very precisely how much that * represents */ target = rc->target; target -= rc->tot_quant; /* Let's compute a linear scaler in order to perform curve scaling */ scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted);#ifdef SMART_OVERFLOW_SETTING if (scaler > 0.9) { rc->param.max_overflow_degradation *= 5; rc->param.max_overflow_improvement *= 5; rc->param.overflow_control_strength *= 3; } else if (scaler > 0.6) { rc->param.max_overflow_degradation *= 2; rc->param.max_overflow_improvement *= 2; rc->param.overflow_control_strength *= 2; } else { rc->min_quant = 2; }#endif /* Compute min frame lengths (for each frame type) according to the number * of MBs. We sum all block type counters of frame 0, this gives us the * number of MBs. * * We compare these hardcoded values with observed values in first pass * (determined in pre_process0).Then we keep the real minimum. */ /* Number of MBs */ num_MBs = rc->stats[0].blks[0]; num_MBs += rc->stats[0].blks[1]; num_MBs += rc->stats[0].blks[2]; /* Minimum for I frames */ if(rc->min_length[XVID_TYPE_IVOP-1] > ((num_MBs*22) + 240) / 8) rc->min_length[XVID_TYPE_IVOP-1] = ((num_MBs*22) + 240) / 8; /* Minimum for P/S frames */ if(rc->min_length[XVID_TYPE_PVOP-1] > ((num_MBs) + 88) / 8) rc->min_length[XVID_TYPE_PVOP-1] = ((num_MBs) + 88) / 8; /* Minimum for B frames */ if(rc->min_length[XVID_TYPE_BVOP-1] > 8) rc->min_length[XVID_TYPE_BVOP-1] = 8; /* Perform an initial scale pass. * * If a frame size is scaled underneath our hardcoded minimums, then we * force the frame size to the minimum, and deduct the original & scaled * frame length from the original and target total lengths */ for (i=0; i<rc->num_frames; i++) { twopass_stat_t * s = &rc->stats[i]; int len; /* No need to scale frame length for which a specific quantizer is * specified thanks to zones */ if (s->zone_mode == XVID_ZONE_QUANT) { s->scaled_length = s->length; continue; } /* Compute the scaled length -- only non invariant data length is scaled */ len = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight); /* Compare with the computed minimum */ if (len < rc->min_length[s->type-1]) { /* This is a 'forced size' frame, set its frame size to the * computed minimum */ s->scaled_length = rc->min_length[s->type-1]; /* Remove both scaled and original size from their respective * total counters, as we prepare a second pass for 'regular' * frames */ target -= s->scaled_length; } else { /* Do nothing for now, we'll scale this later */ s->scaled_length = 0; } } /* The first pass on data substracted all 'forced size' frames from the * total counters. Now, it's possible to scale the 'regular' frames. */ /* Scaling factor for 'regular' frames */ scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted); /* Do another pass with the new scaler */ for (i=0; i<rc->num_frames; i++) { twopass_stat_t * s = &rc->stats[i]; /* Ignore frame with forced frame sizes */ if (s->scaled_length == 0) s->scaled_length = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight); } /* Job done */ return;}/* Apply all user settings to the scaled curve * This implies: * keyframe boosting * high/low compression */static voidscaled_curve_apply_advanced_parameters(rc_2pass2_t * rc){ int i; int64_t ivop_boost_total; /* Reset the rate controller (per frame type) total byte counters */ for (i=0; i<3; i++) rc->tot_scaled_length[i] = 0; /* Compute total bytes for each frame type */ for (i=0; i<rc->num_frames;i++) { twopass_stat_t *s = &rc->stats[i]; rc->tot_scaled_length[s->type-1] += s->scaled_length; } /* First we compute the total amount of bits needed, as being described by * the scaled distribution. During this pass over the complete stats data, * we see how much bits two user settings will get/give from/to p&b frames: * - keyframe boosting * - keyframe distance penalty */ rc->KF_idx = 0; ivop_boost_total = 0; for (i=0; i<rc->num_frames; i++) { twopass_stat_t * s = &rc->stats[i]; /* Some more work is needed for I frames */ if (s->type == XVID_TYPE_IVOP) { int ivop_boost; /* Accumulate bytes needed for keyframe boosting */ ivop_boost = s->scaled_length*rc->param.keyframe_boost/100;#if 0 /* ToDo: decide how to apply kfthresholding */#endif /* If the frame size drops under the minimum length, then cap ivop_boost */ if (ivop_boost + s->scaled_length < rc->min_length[XVID_TYPE_IVOP-1]) ivop_boost = rc->min_length[XVID_TYPE_IVOP-1] - s->scaled_length; /* Accumulate the ivop boost */ ivop_boost_total += ivop_boost; /* Don't forget to update the keyframe index */ rc->KF_idx++; } } /* Initialize the IBoost tax ratio for P/S/B frames * * This ratio has to be applied to p/b/s frames in order to reserve * additional bits for keyframes (keyframe boosting) or if too much * keyframe distance is applied, bits retrieved from the keyframes. * * ie pb_length *= rc->pb_iboost_tax_ratio; * * gives the ideal length of a p/b frame */ /* Compute the total length of p/b/s frames (temporary storage into * movie_curve) */ rc->pb_iboost_tax_ratio = (double)rc->tot_scaled_length[XVID_TYPE_PVOP-1]; rc->pb_iboost_tax_ratio += (double)rc->tot_scaled_length[XVID_TYPE_BVOP-1]; /* Compute the ratio described above * taxed_total = sum(0, n, tax*scaled_length) * <=> taxed_total = tax.sum(0, n, scaled_length) * <=> tax = taxed_total / original_total */ rc->pb_iboost_tax_ratio = (rc->pb_iboost_tax_ratio - ivop_boost_total) / rc->pb_iboost_tax_ratio; DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- IFrame boost tax ratio:%.2f\n", rc->pb_iboost_tax_ratio); /* Compute the average size of frames per frame type */ for(i=0; i<3; i++) { /* Special case for missing type or weird case */ if (rc->count[i] == 0 || rc->pb_iboost_tax_ratio == 0) { rc->avg_length[i] = 1; } else { rc->avg_length[i] = rc->tot_scaled_length[i]; if (i == (XVID_TYPE_IVOP-1)) { /* I Frames total has to be added the boost total */ rc->avg_length[i] += ivop_boost_total; } else { /* P/B frames has to taxed */ rc->avg_length[i] *= rc->pb_iboost_tax_ratio; } /* Finally compute the average frame size */ rc->avg_length[i] /= (double)rc->count[i]; } } /* Assymetric curve compression */ if (rc->param.curve_compression_high || rc->param.curve_compression_low) { double symetric_total; double assymetric_delta_total; /* Like I frame boosting, assymetric curve compression modifies the total * amount of needed bits, we must compute the ratio so we can prescale lengths */ symetric_total = 0; assymetric_delta_total = 0; for (i=0; i<rc->num_frames; i++) { double assymetric_delta; double dbytes; twopass_stat_t * s = &rc->stats[i]; /* I Frames are not concerned by assymetric scaling */ if (s->type == XVID_TYPE_IVOP) continue; /* During the real run, we would have to apply the iboost tax */ dbytes = s->scaled_length * rc->pb_iboost_tax_ratio; /* Update the symmetric curve compression total */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -