diff options
Diffstat (limited to 'vp9/encoder/vp9_firstpass.c')
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 321 |
1 files changed, 273 insertions, 48 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 70f9e3153..1dd2a7dd8 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -317,15 +317,20 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) { } -// This function returns the current per frame maximum bitrate target +// This function returns the current per frame maximum bitrate target. static int frame_max_bits(VP9_COMP *cpi) { - // Max allocation for a single frame based on the max section guidelines passed in and how many bits are left + // Max allocation for a single frame based on the max section guidelines + // passed in and how many bits are left. int max_bits; - // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user - max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0)); + // For VBR base this on the bits and frames left plus the + // two_pass_vbrmax_section rate passed in by the user. + max_bits = (int) (((double) cpi->twopass.bits_left + / (cpi->twopass.total_stats->count - (double) cpi->common + .current_video_frame)) + * ((double) cpi->oxcf.two_pass_vbrmax_section / 100.0)); - // Trap case where we are out of bits + // Trap case where we are out of bits. if (max_bits < 0) max_bits = 0; @@ -746,7 +751,7 @@ void vp9_first_pass(VP9_COMP *cpi) { } // TODO: handle the case when duration is set to 0, or something less - // than the full time between subsequent cpi->source_time_stamp s . + // than the full time between subsequent values of cpi->source_time_stamp. fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start); @@ -873,7 +878,7 @@ static double calc_correction_factor(double err_per_mb, // Given a current maxQ value sets a range for future values. // PGW TODO.. -// This code removes direct dependency on QIndex to determin the range +// This code removes direct dependency on QIndex to determine the range // (now uses the actual quantizer) but has not been tuned. static void adjust_maxq_qrange(VP9_COMP *cpi) { int i; @@ -991,7 +996,7 @@ static int estimate_max_q(VP9_COMP *cpi, } // Adjust maxq_min_limit and maxq_max_limit limits based on - // averaga q observed in clip for non kf/gf/arf frames + // average q observed in clip for non kf/gf/arf frames // Give average a chance to settle though. // PGW TODO.. This code is broken for the extended Q range if ((cpi->ni_frames > @@ -1379,7 +1384,7 @@ static int calc_arf_boost( &this_frame_mv_in_out, &mv_in_out_accumulator, &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - // We want to discount the the flash frame itself and the recovery + // We want to discount the flash frame itself and the recovery // frame that follows as both will have poor scores. flash_detected = detect_flash(cpi, (i + offset)) || detect_flash(cpi, (i + offset + 1)); @@ -1442,9 +1447,8 @@ static int calc_arf_boost( return arf_boost; } -static void configure_arnr_filter(VP9_COMP *cpi, - FIRSTPASS_STATS *this_frame, - int group_boost) { +void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame, + int group_boost) { int half_gf_int; int frames_after_arf; int frames_bwd = cpi->oxcf.arnr_max_frames - 1; @@ -1458,8 +1462,7 @@ static void configure_arnr_filter(VP9_COMP *cpi, // Note: this_frame->frame has been updated in the loop // so it now points at the ARF frame. half_gf_int = cpi->baseline_gf_interval >> 1; - frames_after_arf = (int)(cpi->twopass.total_stats->count - - this_frame->frame - 1); + frames_after_arf = (int)(cpi->twopass.total_stats->count - this_frame - 1); switch (cpi->oxcf.arnr_type) { case 1: // Backward filter @@ -1515,7 +1518,144 @@ static void configure_arnr_filter(VP9_COMP *cpi, } } -// Analyse and define a gf/arf group . +#if CONFIG_MULTIPLE_ARF +// Work out the frame coding order for a GF or an ARF group. +// The current implementation codes frames in their natural order for a +// GF group, and inserts additional ARFs into an ARF group using a +// binary split approach. +// NOTE: this function is currently implemented recursively. +static void schedule_frames(VP9_COMP *cpi, const int start, const int end, + const int arf_idx, const int gf_or_arf_group, + const int level) { + int i, abs_end, half_range; + int *cfo = cpi->frame_coding_order; + int idx = cpi->new_frame_coding_order_period; + + // If (end < 0) an ARF should be coded at position (-end). + assert(start >= 0); + + // printf("start:%d end:%d\n", start, end); + + // GF Group: code frames in logical order. + if (gf_or_arf_group == 0) { + assert(end >= start); + for (i = start; i <= end; ++i) { + cfo[idx] = i; + cpi->arf_buffer_idx[idx] = arf_idx; + cpi->arf_weight[idx] = -1; + ++idx; + } + cpi->new_frame_coding_order_period = idx; + return; + } + + // ARF Group: work out the ARF schedule. + // Mark ARF frames as negative. + if (end < 0) { + // printf("start:%d end:%d\n", -end, -end); + // ARF frame is at the end of the range. + cfo[idx] = end; + // What ARF buffer does this ARF use as predictor. + cpi->arf_buffer_idx[idx] = (arf_idx > 2) ? (arf_idx - 1) : 2; + cpi->arf_weight[idx] = level; + ++idx; + abs_end = -end; + } else { + abs_end = end; + } + + half_range = (abs_end - start) >> 1; + + // ARFs may not be adjacent, they must be separated by at least + // MIN_GF_INTERVAL non-ARF frames. + if ((start + MIN_GF_INTERVAL) >= (abs_end - MIN_GF_INTERVAL)) { + // printf("start:%d end:%d\n", start, abs_end); + // Update the coding order and active ARF. + for (i = start; i <= abs_end; ++i) { + cfo[idx] = i; + cpi->arf_buffer_idx[idx] = arf_idx; + cpi->arf_weight[idx] = -1; + ++idx; + } + cpi->new_frame_coding_order_period = idx; + } else { + // Place a new ARF at the mid-point of the range. + cpi->new_frame_coding_order_period = idx; + schedule_frames(cpi, start, -(start + half_range), arf_idx + 1, + gf_or_arf_group, level + 1); + schedule_frames(cpi, start + half_range + 1, abs_end, arf_idx, + gf_or_arf_group, level + 1); + } +} + +#define FIXED_ARF_GROUP_SIZE 16 + +void define_fixed_arf_period(VP9_COMP *cpi) { + int i; + int max_level = INT_MIN; + + assert(cpi->multi_arf_enabled); + assert(cpi->oxcf.lag_in_frames >= FIXED_ARF_GROUP_SIZE); + + // Save the weight of the last frame in the sequence before next + // sequence pattern overwrites it. + cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number]; + assert(cpi->this_frame_weight >= 0); + + // Initialize frame coding order variables. + cpi->new_frame_coding_order_period = 0; + cpi->next_frame_in_order = 0; + cpi->arf_buffered = 0; + vp9_zero(cpi->frame_coding_order); + vp9_zero(cpi->arf_buffer_idx); + vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight)); + + if (cpi->twopass.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) { + // Setup a GF group close to the keyframe. + cpi->source_alt_ref_pending = FALSE; + cpi->baseline_gf_interval = cpi->twopass.frames_to_key; + schedule_frames(cpi, 0, (cpi->baseline_gf_interval - 1), 2, 0, 0); + } else { + // Setup a fixed period ARF group. + cpi->source_alt_ref_pending = TRUE; + cpi->baseline_gf_interval = FIXED_ARF_GROUP_SIZE; + schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); + } + + // Replace level indicator of -1 with correct level. + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + if (cpi->arf_weight[i] > max_level) { + max_level = cpi->arf_weight[i]; + } + } + ++max_level; + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + if (cpi->arf_weight[i] == -1) { + cpi->arf_weight[i] = max_level; + } + } + cpi->max_arf_level = max_level; +#if 0 + printf("\nSchedule: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->frame_coding_order[i]); + } + printf("\n"); + printf("ARFref: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->arf_buffer_idx[i]); + } + printf("\n"); + printf("Weight: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->arf_weight[i]); + } + printf("\n"); +#endif +} +#endif + +// Analyse and define a gf/arf group. static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { FIRSTPASS_STATS next_frame; FIRSTPASS_STATS *start_pos; @@ -1619,7 +1759,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { } // Break clause to detect very still sections after motion - // (for example a staic image after a fade or other transition). + // (for example a static image after a fade or other transition). if (detect_transition_to_still(cpi, i, 5, loop_decay_rate, last_loop_decay_rate)) { allow_alt_ref = FALSE; @@ -1637,9 +1777,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Break at cpi->max_gf_interval unless almost totally static (i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) || ( - // Dont break out with a very short interval + // Don't break out with a very short interval (i > MIN_GF_INTERVAL) && - // Dont break out very close to a key frame + // Don't break out very close to a key frame ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) && ((boost_score > 125.0) || (next_frame.pcnt_inter < 0.75)) && (!flash_detected) && @@ -1657,7 +1797,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { old_boost_score = boost_score; } - // Dont allow a gf too near the next kf + // Don't allow a gf too near the next kf if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) { while (i < cpi->twopass.frames_to_key) { i++; @@ -1672,10 +1812,22 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { } } - // Set the interval till the next gf or arf. + // Set the interval until the next gf or arf. cpi->baseline_gf_interval = i; - // Should we use the alternate refernce frame +#if CONFIG_MULTIPLE_ARF + if (cpi->multi_arf_enabled) { + // Initialize frame coding order variables. + cpi->new_frame_coding_order_period = 0; + cpi->next_frame_in_order = 0; + cpi->arf_buffered = 0; + vp9_zero(cpi->frame_coding_order); + vp9_zero(cpi->arf_buffer_idx); + vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight)); + } +#endif + + // Should we use the alternate reference frame if (allow_alt_ref && (i < cpi->oxcf.lag_in_frames) && (i >= MIN_GF_INTERVAL) && @@ -1686,16 +1838,66 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) && (boost_score > 100)) { - // Alterrnative boost calculation for alt ref + // Alternative boost calculation for alt ref cpi->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost); cpi->source_alt_ref_pending = TRUE; - configure_arnr_filter(cpi, this_frame, cpi->gfu_boost); +#if CONFIG_MULTIPLE_ARF + // Set the ARF schedule. + if (cpi->multi_arf_enabled) { + schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); + } +#endif } else { cpi->gfu_boost = (int)boost_score; cpi->source_alt_ref_pending = FALSE; +#if CONFIG_MULTIPLE_ARF + // Set the GF schedule. + if (cpi->multi_arf_enabled) { + schedule_frames(cpi, 0, cpi->baseline_gf_interval - 1, 2, 0, 0); + assert(cpi->new_frame_coding_order_period == cpi->baseline_gf_interval); + } +#endif } +#if CONFIG_MULTIPLE_ARF + if (cpi->multi_arf_enabled && (cpi->common.frame_type != KEY_FRAME)) { + int max_level = INT_MIN; + // Replace level indicator of -1 with correct level. + for (i = 0; i < cpi->frame_coding_order_period; ++i) { + if (cpi->arf_weight[i] > max_level) { + max_level = cpi->arf_weight[i]; + } + } + ++max_level; + for (i = 0; i < cpi->frame_coding_order_period; ++i) { + if (cpi->arf_weight[i] == -1) { + cpi->arf_weight[i] = max_level; + } + } + cpi->max_arf_level = max_level; + } +#if 0 + if (cpi->multi_arf_enabled) { + printf("\nSchedule: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->frame_coding_order[i]); + } + printf("\n"); + printf("ARFref: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->arf_buffer_idx[i]); + } + printf("\n"); + printf("Weight: "); + for (i = 0; i < cpi->new_frame_coding_order_period; ++i) { + printf("%4d ", cpi->arf_weight[i]); + } + printf("\n"); + } +#endif +#endif + // Now decide how many bits should be allocated to the GF group as a // proportion of those remaining in the kf group. // The final key frame group in the clip is treated as a special case @@ -1736,10 +1938,13 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->twopass.modified_error_used += gf_group_err; // Assign bits to the arf or gf. - for (i = 0; i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); i++) { + for (i = 0; + i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); + ++i) { int boost; int allocation_chunks; - int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; + int Q = + (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; int gf_bits; boost = (cpi->gfu_boost * vp9_gfboost_qadjust(Q)) / 100; @@ -1758,7 +1963,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { (cpi->baseline_gf_interval * 100) + (boost - 100); // Prevent overflow - if (boost > 1028) { + if (boost > 1028) { // TODO(agrange) Should this be 1024? int divisor = boost >> 10; boost /= divisor; allocation_chunks /= divisor; @@ -1807,18 +2012,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { if (gf_bits < 0) gf_bits = 0; - gf_bits += cpi->min_frame_bandwidth; // Add in minimum for a frame + // Add in minimum for a frame + gf_bits += cpi->min_frame_bandwidth; if (i == 0) { cpi->twopass.gf_bits = gf_bits; } - if (i == 1 || (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))) { - cpi->per_frame_bandwidth = gf_bits; // Per frame bit target for this frame + if (i == 1 || (!cpi->source_alt_ref_pending + && (cpi->common.frame_type != KEY_FRAME))) { + // Per frame bit target for this frame + cpi->per_frame_bandwidth = gf_bits; } } { - // Adjust KF group bits and error remainin + // Adjust KF group bits and error remaining cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err; cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits; @@ -1835,13 +2043,14 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { else cpi->twopass.gf_group_error_left = (int64_t)gf_group_err; - cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits - cpi->min_frame_bandwidth; + cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits + - cpi->min_frame_bandwidth; if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; // This condition could fail if there are two kfs very close together - // despite (MIN_GF_INTERVAL) and would cause a devide by 0 in the + // despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the // calculation of cpi->twopass.alt_extra_bits. if (cpi->baseline_gf_interval >= 3) { int boost = (cpi->source_alt_ref_pending) @@ -1853,6 +2062,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { pct_extra = (boost - 100) / 50; pct_extra = (pct_extra > 20) ? 20 : pct_extra; + // TODO(agrange) Remove cpi->twopass.alt_extra_bits. cpi->twopass.alt_extra_bits = (int) ((cpi->twopass.gf_group_bits * pct_extra) / 100); cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits; @@ -1887,24 +2097,28 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Allocate bits to a normal frame that is neither a gf an arf or a key frame. static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { - int target_frame_size; // gf_group_error_left + int target_frame_size; double modified_err; - double err_fraction; // What portion of the remaining GF group error is used by this frame + double err_fraction; - int max_bits = frame_max_bits(cpi); // Max for a single frame + // Max for a single frame. + int max_bits = frame_max_bits(cpi); - // Calculate modified prediction error used in bit allocation + // Calculate modified prediction error used in bit allocation. modified_err = calculate_modified_err(cpi, this_frame); if (cpi->twopass.gf_group_error_left > 0) - err_fraction = modified_err / cpi->twopass.gf_group_error_left; // What portion of the remaining GF group error is used by this frame + // What portion of the remaining GF group error is used by this frame. + err_fraction = modified_err / cpi->twopass.gf_group_error_left; else err_fraction = 0.0; - target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction); // How many of those bits available for allocation should we give it? + // How many of those bits available for allocation should we give it? + target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction); - // Clip to target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at the top end. + // Clip target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at + // the top end. if (target_frame_size < 0) target_frame_size = 0; else { @@ -1915,17 +2129,18 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { target_frame_size = (int)cpi->twopass.gf_group_bits; } - // Adjust error remaining + // Adjust error and bits remaining. cpi->twopass.gf_group_error_left -= (int64_t)modified_err; - cpi->twopass.gf_group_bits -= target_frame_size; // Adjust bits remaining + cpi->twopass.gf_group_bits -= target_frame_size; if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; - target_frame_size += cpi->min_frame_bandwidth; // Add in the minimum number of bits that is set aside for every frame. - + // Add in the minimum number of bits that is set aside for every frame. + target_frame_size += cpi->min_frame_bandwidth; - cpi->per_frame_bandwidth = target_frame_size; // Per frame bit target for this frame + // Per frame bit target for this frame. + cpi->per_frame_bandwidth = target_frame_size; } // Make a damped adjustment to the active max q. @@ -2059,7 +2274,16 @@ void vp9_second_pass(VP9_COMP *cpi) { if (cpi->frames_till_gf_update_due == 0) { // Define next gf group and assign bits to it vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - define_gf_group(cpi, &this_frame_copy); + +#if CONFIG_MULTIPLE_ARF + if (cpi->multi_arf_enabled) { + define_fixed_arf_period(cpi); + } else { +#endif + define_gf_group(cpi, &this_frame_copy); +#if CONFIG_MULTIPLE_ARF + } +#endif // If we are going to code an altref frame at the end of the group // and the current frame is not a key frame.... @@ -2101,7 +2325,7 @@ void vp9_second_pass(VP9_COMP *cpi) { cpi->twopass.frames_to_key--; - // Update the total stats remaining sturcture + // Update the total stats remaining structure subtract_stats(cpi->twopass.total_left_stats, &this_frame); } @@ -2178,7 +2402,8 @@ static int test_candidate_kf(VP9_COMP *cpi, break; } - // If there is tolerable prediction for at least the next 3 frames then break out else discard this pottential key frame and move on + // If there is tolerable prediction for at least the next 3 frames then + // break out else discard this potential key frame and move on if (boost_score > 30.0 && (i > 3)) is_viable_kf = TRUE; else { @@ -2231,7 +2456,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Take a copy of the initial frame details vpx_memcpy(&first_frame, this_frame, sizeof(*this_frame)); - cpi->twopass.kf_group_bits = 0; // Total bits avaialable to kf group + cpi->twopass.kf_group_bits = 0; // Total bits available to kf group cpi->twopass.kf_group_error_left = 0; // Group modified error score. kf_mod_err = calculate_modified_err(cpi, this_frame); |