| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_firstpass.c (revision 281795)
|
| +++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy)
|
| @@ -33,8 +33,7 @@
|
| #include "vp9/encoder/vp9_firstpass.h"
|
| #include "vp9/encoder/vp9_mcomp.h"
|
| #include "vp9/encoder/vp9_quantize.h"
|
| -#include "vp9/encoder/vp9_ratectrl.h"
|
| -#include "vp9/encoder/vp9_rdopt.h"
|
| +#include "vp9/encoder/vp9_rd.h"
|
| #include "vp9/encoder/vp9_variance.h"
|
|
|
| #define OUTPUT_FPF 0
|
| @@ -56,14 +55,7 @@
|
| #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
|
|
|
| #define MIN_KF_BOOST 300
|
| -
|
| -#if CONFIG_MULTIPLE_ARF
|
| -// Set MIN_GF_INTERVAL to 1 for the full decomposition.
|
| -#define MIN_GF_INTERVAL 2
|
| -#else
|
| -#define MIN_GF_INTERVAL 4
|
| -#endif
|
| -
|
| +#define MIN_GF_INTERVAL 4
|
| #define LONG_TERM_VBR_CORRECTION
|
|
|
| static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
|
| @@ -97,23 +89,43 @@
|
|
|
|
|
| // Read frame stats at an offset from the current position.
|
| -static int read_frame_stats(const TWO_PASS *p,
|
| - FIRSTPASS_STATS *frame_stats, int offset) {
|
| - const FIRSTPASS_STATS *fps_ptr = p->stats_in;
|
| -
|
| - // Check legality of offset.
|
| - if (offset >= 0) {
|
| - if (&fps_ptr[offset] >= p->stats_in_end)
|
| - return EOF;
|
| - } else if (offset < 0) {
|
| - if (&fps_ptr[offset] < p->stats_in_start)
|
| - return EOF;
|
| +static const FIRSTPASS_STATS *read_frame_stats(const TWO_PASS *p, int offset) {
|
| + if ((offset >= 0 && p->stats_in + offset >= p->stats_in_end) ||
|
| + (offset < 0 && p->stats_in + offset < p->stats_in_start)) {
|
| + return NULL;
|
| }
|
|
|
| - *frame_stats = fps_ptr[offset];
|
| + return &p->stats_in[offset];
|
| +}
|
| +
|
| +#if CONFIG_FP_MB_STATS
|
| +static int input_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
|
| + const VP9_COMMON *const cm) {
|
| + FILE *fpfile;
|
| + int ret;
|
| +
|
| + fpfile = fopen("firstpass_mb.stt", "r");
|
| + fseek(fpfile, cm->current_video_frame * cm->MBs * sizeof(FIRSTPASS_MB_STATS),
|
| + SEEK_SET);
|
| + ret = fread(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs,
|
| + fpfile);
|
| + fclose(fpfile);
|
| + if (ret < cm->MBs) {
|
| + return EOF;
|
| + }
|
| return 1;
|
| }
|
|
|
| +static void output_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
|
| + const VP9_COMMON *const cm) {
|
| + FILE *fpfile;
|
| +
|
| + fpfile = fopen("firstpass_mb.stt", "a");
|
| + fwrite(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs, fpfile);
|
| + fclose(fpfile);
|
| +}
|
| +#endif
|
| +
|
| static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
|
| if (p->stats_in >= p->stats_in_end)
|
| return EOF;
|
| @@ -460,6 +472,10 @@
|
| const MV zero_mv = {0, 0};
|
| const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
|
|
|
| +#if CONFIG_FP_MB_STATS
|
| + FIRSTPASS_FRAME_MB_STATS *this_frame_mb_stats = &twopass->this_frame_mb_stats;
|
| +#endif
|
| +
|
| vp9_clear_system_state();
|
|
|
| set_first_pass_params(cpi);
|
| @@ -497,6 +513,8 @@
|
| &cpi->scaled_source);
|
| }
|
|
|
| + vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
|
| +
|
| vp9_setup_src_planes(x, cpi->Source, 0, 0);
|
| vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
|
| vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
|
| @@ -504,8 +522,6 @@
|
| xd->mi = cm->mi_grid_visible;
|
| xd->mi[0] = cm->mi;
|
|
|
| - vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
|
| -
|
| vp9_frame_init_quantizer(cpi);
|
|
|
| for (i = 0; i < MAX_MB_PLANE; ++i) {
|
| @@ -587,6 +603,17 @@
|
| // Accumulate the intra error.
|
| intra_error += (int64_t)this_error;
|
|
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
|
| + DC_PRED;
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
|
| + this_error;
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.as_int
|
| + = 0;
|
| + }
|
| +#endif
|
| +
|
| // Set up limit values for motion vectors to prevent them extending
|
| // outside the UMV borders.
|
| x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
|
| @@ -615,7 +642,8 @@
|
| &unscaled_last_source_buf_2d);
|
|
|
| // TODO(pengchong): Replace the hard-coded threshold
|
| - if (raw_motion_error > 25) {
|
| + if (raw_motion_error > 25 ||
|
| + (cpi->use_svc && cpi->svc.number_temporal_layers == 1)) {
|
| // Test last reference frame using the previous best mv as the
|
| // starting point (best reference) for the search.
|
| first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
|
| @@ -711,6 +739,17 @@
|
|
|
| best_ref_mv.as_int = mv.as_int;
|
|
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
|
| + NEWMV;
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
|
| + motion_error;
|
| + this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.
|
| + as_int = mv.as_int;
|
| + }
|
| +#endif
|
| +
|
| if (mv.as_int) {
|
| ++mvcount;
|
|
|
| @@ -815,6 +854,12 @@
|
| twopass->this_frame_stats = fps;
|
| output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
|
| accumulate_stats(&twopass->total_stats, &fps);
|
| +
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + output_mb_stats(this_frame_mb_stats, cm);
|
| + }
|
| +#endif
|
| }
|
|
|
| // Copy the previous Last Frame back into gf and and arf buffers if
|
| @@ -1060,24 +1105,16 @@
|
| // score in the frame following a flash frame. The offset passed in should
|
| // reflect this.
|
| static int detect_flash(const TWO_PASS *twopass, int offset) {
|
| - FIRSTPASS_STATS next_frame;
|
| + const FIRSTPASS_STATS *const next_frame = read_frame_stats(twopass, offset);
|
|
|
| - int flash_detected = 0;
|
| -
|
| - // Read the frame data.
|
| - // The return is FALSE (no flash detected) if not a valid frame
|
| - if (read_frame_stats(twopass, &next_frame, offset) != EOF) {
|
| - // What we are looking for here is a situation where there is a
|
| - // brief break in prediction (such as a flash) but subsequent frames
|
| - // are reasonably well predicted by an earlier (pre flash) frame.
|
| - // The recovery after a flash is indicated by a high pcnt_second_ref
|
| - // compared to pcnt_inter.
|
| - if (next_frame.pcnt_second_ref > next_frame.pcnt_inter &&
|
| - next_frame.pcnt_second_ref >= 0.5)
|
| - flash_detected = 1;
|
| - }
|
| -
|
| - return flash_detected;
|
| + // What we are looking for here is a situation where there is a
|
| + // brief break in prediction (such as a flash) but subsequent frames
|
| + // are reasonably well predicted by an earlier (pre flash) frame.
|
| + // The recovery after a flash is indicated by a high pcnt_second_ref
|
| + // compared to pcnt_inter.
|
| + return next_frame != NULL &&
|
| + next_frame->pcnt_second_ref > next_frame->pcnt_inter &&
|
| + next_frame->pcnt_second_ref >= 0.5;
|
| }
|
|
|
| // Update the motion related elements to the GF arf boost calculation.
|
| @@ -1137,7 +1174,6 @@
|
| static int calc_arf_boost(VP9_COMP *cpi, int offset,
|
| int f_frames, int b_frames,
|
| int *f_boost, int *b_boost) {
|
| - FIRSTPASS_STATS this_frame;
|
| TWO_PASS *const twopass = &cpi->twopass;
|
| int i;
|
| double boost_score = 0.0;
|
| @@ -1151,11 +1187,12 @@
|
|
|
| // Search forward from the proposed arf/next gf position.
|
| for (i = 0; i < f_frames; ++i) {
|
| - if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF)
|
| + const FIRSTPASS_STATS *this_frame = read_frame_stats(twopass, i + offset);
|
| + if (this_frame == NULL)
|
| break;
|
|
|
| // Update the motion related elements to the boost calculation.
|
| - accumulate_frame_motion_stats(&this_frame,
|
| + accumulate_frame_motion_stats(this_frame,
|
| &this_frame_mv_in_out, &mv_in_out_accumulator,
|
| &abs_mv_in_out_accumulator,
|
| &mv_ratio_accumulator);
|
| @@ -1167,12 +1204,12 @@
|
|
|
| // Accumulate the effect of prediction quality decay.
|
| if (!flash_detected) {
|
| - decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame);
|
| + decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
|
| decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
|
| ? MIN_DECAY_FACTOR : decay_accumulator;
|
| }
|
|
|
| - boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
|
| + boost_score += decay_accumulator * calc_frame_boost(twopass, this_frame,
|
| this_frame_mv_in_out);
|
| }
|
|
|
| @@ -1188,11 +1225,12 @@
|
|
|
| // Search backward towards last gf position.
|
| for (i = -1; i >= -b_frames; --i) {
|
| - if (read_frame_stats(twopass, &this_frame, (i + offset)) == EOF)
|
| + const FIRSTPASS_STATS *this_frame = read_frame_stats(twopass, i + offset);
|
| + if (this_frame == NULL)
|
| break;
|
|
|
| // Update the motion related elements to the boost calculation.
|
| - accumulate_frame_motion_stats(&this_frame,
|
| + accumulate_frame_motion_stats(this_frame,
|
| &this_frame_mv_in_out, &mv_in_out_accumulator,
|
| &abs_mv_in_out_accumulator,
|
| &mv_ratio_accumulator);
|
| @@ -1204,12 +1242,12 @@
|
|
|
| // Cumulative effect of prediction quality decay.
|
| if (!flash_detected) {
|
| - decay_accumulator *= get_prediction_decay_rate(&cpi->common, &this_frame);
|
| + decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
|
| decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
|
| ? MIN_DECAY_FACTOR : decay_accumulator;
|
| }
|
|
|
| - boost_score += decay_accumulator * calc_frame_boost(twopass, &this_frame,
|
| + boost_score += decay_accumulator * calc_frame_boost(twopass, this_frame,
|
| this_frame_mv_in_out);
|
| }
|
| *b_boost = (int)boost_score;
|
| @@ -1221,144 +1259,6 @@
|
| return arf_boost;
|
| }
|
|
|
| -#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 and 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);
|
| -
|
| - cpi->twopass.gf_zeromotion_pct = 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->rc.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) {
|
| - // Setup a GF group close to the keyframe.
|
| - cpi->rc.source_alt_ref_pending = 0;
|
| - cpi->rc.baseline_gf_interval = cpi->rc.frames_to_key;
|
| - schedule_frames(cpi, 0, (cpi->rc.baseline_gf_interval - 1), 2, 0, 0);
|
| - } else {
|
| - // Setup a fixed period ARF group.
|
| - cpi->rc.source_alt_ref_pending = 1;
|
| - cpi->rc.baseline_gf_interval = FIXED_ARF_GROUP_SIZE;
|
| - schedule_frames(cpi, 0, -(cpi->rc.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
|
| -
|
| // Calculate a section intra ratio used in setting max loop filter.
|
| static int calculate_section_intra_ratio(const FIRSTPASS_STATS *begin,
|
| const FIRSTPASS_STATS *end,
|
| @@ -1428,6 +1328,18 @@
|
| return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
|
| }
|
|
|
| +// Current limit on maximum number of active arfs in a GF/ARF group.
|
| +#define MAX_ACTIVE_ARFS 2
|
| +#define ARF_SLOT1 2
|
| +#define ARF_SLOT2 3
|
| +// This function indirects the choice of buffers for arfs.
|
| +// At the moment the values are fixed but this may change as part of
|
| +// the integration process with other codec features that swap buffers around.
|
| +static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
|
| + arf_buffer_indices[0] = ARF_SLOT1;
|
| + arf_buffer_indices[1] = ARF_SLOT2;
|
| +}
|
| +
|
| static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
|
| double group_error, int gf_arf_bits) {
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -1435,42 +1347,80 @@
|
| TWO_PASS *twopass = &cpi->twopass;
|
| FIRSTPASS_STATS frame_stats;
|
| int i;
|
| - int group_frame_index = 1;
|
| + int frame_index = 1;
|
| int target_frame_size;
|
| int key_frame;
|
| const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
|
| int64_t total_group_bits = gf_group_bits;
|
| double modified_err = 0.0;
|
| double err_fraction;
|
| + int mid_boost_bits = 0;
|
| + int mid_frame_idx;
|
| + unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
|
|
|
| key_frame = cpi->common.frame_type == KEY_FRAME ||
|
| vp9_is_upper_layer_key_frame(cpi);
|
|
|
| + get_arf_buffer_indices(arf_buffer_indices);
|
| +
|
| // For key frames the frame target rate is already set and it
|
| // is also the golden frame.
|
| - // NOTE: We dont bother to check for the special case of ARF overlay
|
| - // frames here, as there is clamping code for this in the function
|
| - // vp9_rc_clamp_pframe_target_size(), which applies to one and two pass
|
| - // encodes.
|
| if (!key_frame) {
|
| - twopass->gf_group_bit_allocation[0] = gf_arf_bits;
|
| + if (rc->source_alt_ref_active) {
|
| + twopass->gf_group.update_type[0] = OVERLAY_UPDATE;
|
| + twopass->gf_group.rf_level[0] = INTER_NORMAL;
|
| + twopass->gf_group.bit_allocation[0] = 0;
|
| + twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
|
| + twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
|
| + } else {
|
| + twopass->gf_group.update_type[0] = GF_UPDATE;
|
| + twopass->gf_group.rf_level[0] = GF_ARF_STD;
|
| + twopass->gf_group.bit_allocation[0] = gf_arf_bits;
|
| + twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
|
| + twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
|
| + }
|
|
|
| // Step over the golden frame / overlay frame
|
| if (EOF == input_stats(twopass, &frame_stats))
|
| return;
|
| }
|
|
|
| + // Deduct the boost bits for arf (or gf if it is not a key frame)
|
| + // from the group total.
|
| + if (rc->source_alt_ref_pending || !key_frame)
|
| + total_group_bits -= gf_arf_bits;
|
| +
|
| // Store the bits to spend on the ARF if there is one.
|
| if (rc->source_alt_ref_pending) {
|
| - twopass->gf_group_bit_allocation[group_frame_index++] = gf_arf_bits;
|
| + twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
|
| + twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
|
| + twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits;
|
| + twopass->gf_group.arf_src_offset[frame_index] =
|
| + (unsigned char)(rc->baseline_gf_interval - 1);
|
| + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
|
| + twopass->gf_group.arf_ref_idx[frame_index] =
|
| + arf_buffer_indices[cpi->multi_arf_last_grp_enabled &&
|
| + rc->source_alt_ref_active];
|
| + ++frame_index;
|
| +
|
| + if (cpi->multi_arf_enabled) {
|
| + // Set aside a slot for a level 1 arf.
|
| + twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
|
| + twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW;
|
| + twopass->gf_group.arf_src_offset[frame_index] =
|
| + (unsigned char)((rc->baseline_gf_interval >> 1) - 1);
|
| + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[1];
|
| + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
|
| + ++frame_index;
|
| + }
|
| }
|
|
|
| - // Deduct the boost bits for arf or gf if it is not a key frame.
|
| - if (rc->source_alt_ref_pending || !key_frame)
|
| - total_group_bits -= gf_arf_bits;
|
| + // Define middle frame
|
| + mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
|
|
|
| // Allocate bits to the other frames in the group.
|
| for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
|
| + int arf_idx = 0;
|
| if (EOF == input_stats(twopass, &frame_stats))
|
| break;
|
|
|
| @@ -1482,11 +1432,52 @@
|
| err_fraction = 0.0;
|
|
|
| target_frame_size = (int)((double)total_group_bits * err_fraction);
|
| +
|
| + if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
|
| + mid_boost_bits += (target_frame_size >> 4);
|
| + target_frame_size -= (target_frame_size >> 4);
|
| +
|
| + if (frame_index <= mid_frame_idx)
|
| + arf_idx = 1;
|
| + }
|
| + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[arf_idx];
|
| + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx];
|
| +
|
| target_frame_size = clamp(target_frame_size, 0,
|
| MIN(max_bits, (int)total_group_bits));
|
|
|
| - twopass->gf_group_bit_allocation[group_frame_index++] = target_frame_size;
|
| + twopass->gf_group.update_type[frame_index] = LF_UPDATE;
|
| + twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
|
| +
|
| + twopass->gf_group.bit_allocation[frame_index] = target_frame_size;
|
| + ++frame_index;
|
| }
|
| +
|
| + // Note:
|
| + // We need to configure the frame at the end of the sequence + 1 that will be
|
| + // the start frame for the next group. Otherwise prior to the call to
|
| + // vp9_rc_get_second_pass_params() the data will be undefined.
|
| + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
|
| + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
|
| +
|
| + if (rc->source_alt_ref_pending) {
|
| + twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE;
|
| + twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
|
| +
|
| + // Final setup for second arf and its overlay.
|
| + if (cpi->multi_arf_enabled) {
|
| + twopass->gf_group.bit_allocation[2] =
|
| + twopass->gf_group.bit_allocation[mid_frame_idx] + mid_boost_bits;
|
| + twopass->gf_group.update_type[mid_frame_idx] = OVERLAY_UPDATE;
|
| + twopass->gf_group.bit_allocation[mid_frame_idx] = 0;
|
| + }
|
| + } else {
|
| + twopass->gf_group.update_type[frame_index] = GF_UPDATE;
|
| + twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
|
| + }
|
| +
|
| + // Note whether multi-arf was enabled this group for next time.
|
| + cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled;
|
| }
|
|
|
| // Analyse and define a gf/arf group.
|
| @@ -1528,8 +1519,7 @@
|
| // Reset the GF group data structures unless this is a key
|
| // frame in which case it will already have been done.
|
| if (cpi->common.frame_type != KEY_FRAME) {
|
| - twopass->gf_group_index = 0;
|
| - vp9_zero(twopass->gf_group_bit_allocation);
|
| + vp9_zero(twopass->gf_group);
|
| }
|
|
|
| vp9_clear_system_state();
|
| @@ -1552,19 +1542,22 @@
|
| // Motion breakout threshold for loop below depends on image size.
|
| mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 10.0;
|
|
|
| - // Work out a maximum interval for the GF.
|
| - // If the image appears completely static we can extend beyond this.
|
| - // The value chosen depends on the active Q range. At low Q we have
|
| - // bits to spare and are better with a smaller interval and smaller boost.
|
| - // At high Q when there are few bits to spare we are better with a longer
|
| - // interval to spread the cost of the GF.
|
| - //
|
| - active_max_gf_interval =
|
| - 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
|
| -
|
| - if (active_max_gf_interval > rc->max_gf_interval)
|
| + // Work out a maximum interval for the GF group.
|
| + // If the image appears almost completely static we can extend beyond this.
|
| + if (cpi->multi_arf_allowed) {
|
| active_max_gf_interval = rc->max_gf_interval;
|
| + } else {
|
| + // The value chosen depends on the active Q range. At low Q we have
|
| + // bits to spare and are better with a smaller interval and smaller boost.
|
| + // At high Q when there are few bits to spare we are better with a longer
|
| + // interval to spread the cost of the GF.
|
| + active_max_gf_interval =
|
| + 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5);
|
|
|
| + if (active_max_gf_interval > rc->max_gf_interval)
|
| + active_max_gf_interval = rc->max_gf_interval;
|
| + }
|
| +
|
| i = 0;
|
| while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
|
| ++i;
|
| @@ -1651,24 +1644,14 @@
|
| }
|
| }
|
|
|
| -#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
|
| -
|
| // Set the interval until the next gf.
|
| if (cpi->common.frame_type == KEY_FRAME || rc->source_alt_ref_active)
|
| rc->baseline_gf_interval = i - 1;
|
| else
|
| rc->baseline_gf_interval = i;
|
|
|
| + rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
| +
|
| // Should we use the alternate reference frame.
|
| if (allow_alt_ref &&
|
| (i < cpi->oxcf.lag_in_frames) &&
|
| @@ -1681,62 +1664,15 @@
|
| &b_boost);
|
| rc->source_alt_ref_pending = 1;
|
|
|
| -#if CONFIG_MULTIPLE_ARF
|
| - // Set the ARF schedule.
|
| - if (cpi->multi_arf_enabled) {
|
| - schedule_frames(cpi, 0, -(rc->baseline_gf_interval - 1), 2, 1, 0);
|
| - }
|
| -#endif
|
| + // Test to see if multi arf is appropriate.
|
| + cpi->multi_arf_enabled =
|
| + (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
|
| + (zero_motion_accumulator < 0.995)) ? 1 : 0;
|
| } else {
|
| rc->gfu_boost = (int)boost_score;
|
| rc->source_alt_ref_pending = 0;
|
| -#if CONFIG_MULTIPLE_ARF
|
| - // Set the GF schedule.
|
| - if (cpi->multi_arf_enabled) {
|
| - schedule_frames(cpi, 0, rc->baseline_gf_interval - 1, 2, 0, 0);
|
| - assert(cpi->new_frame_coding_order_period ==
|
| - rc->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
|
| // Reset the file position.
|
| reset_fpf_position(twopass, start_pos);
|
|
|
| @@ -1886,14 +1822,15 @@
|
| cpi->common.frame_type = KEY_FRAME;
|
|
|
| // Reset the GF group data structures.
|
| - twopass->gf_group_index = 0;
|
| - vp9_zero(twopass->gf_group_bit_allocation);
|
| + vp9_zero(twopass->gf_group);
|
|
|
| // Is this a forced key frame by interval.
|
| rc->this_key_frame_forced = rc->next_key_frame_forced;
|
|
|
| - // Clear the alt ref active flag as this can never be active on a key frame.
|
| + // Clear the alt ref active flag and last group multi arf flags as they
|
| + // can never be set for a key frame.
|
| rc->source_alt_ref_active = 0;
|
| + cpi->multi_arf_last_grp_enabled = 0;
|
|
|
| // KF is always a GF so clear frames till next gf counter.
|
| rc->frames_till_gf_update_due = 0;
|
| @@ -2078,7 +2015,9 @@
|
| twopass->kf_group_bits -= kf_bits;
|
|
|
| // Save the bits to spend on the key frame.
|
| - twopass->gf_group_bit_allocation[0] = kf_bits;
|
| + twopass->gf_group.bit_allocation[0] = kf_bits;
|
| + twopass->gf_group.update_type[0] = KF_UPDATE;
|
| + twopass->gf_group.rf_level[0] = KF_STD;
|
|
|
| // Note the total error score of the kf group minus the key frame itself.
|
| twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err);
|
| @@ -2106,6 +2045,44 @@
|
| }
|
| }
|
|
|
| +// Define the reference buffers that will be updated post encode.
|
| +void configure_buffer_updates(VP9_COMP *cpi) {
|
| + TWO_PASS *const twopass = &cpi->twopass;
|
| +
|
| + cpi->rc.is_src_frame_alt_ref = 0;
|
| + switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
|
| + case KF_UPDATE:
|
| + cpi->refresh_last_frame = 1;
|
| + cpi->refresh_golden_frame = 1;
|
| + cpi->refresh_alt_ref_frame = 1;
|
| + break;
|
| + case LF_UPDATE:
|
| + cpi->refresh_last_frame = 1;
|
| + cpi->refresh_golden_frame = 0;
|
| + cpi->refresh_alt_ref_frame = 0;
|
| + break;
|
| + case GF_UPDATE:
|
| + cpi->refresh_last_frame = 1;
|
| + cpi->refresh_golden_frame = 1;
|
| + cpi->refresh_alt_ref_frame = 0;
|
| + break;
|
| + case OVERLAY_UPDATE:
|
| + cpi->refresh_last_frame = 0;
|
| + cpi->refresh_golden_frame = 1;
|
| + cpi->refresh_alt_ref_frame = 0;
|
| + cpi->rc.is_src_frame_alt_ref = 1;
|
| + break;
|
| + case ARF_UPDATE:
|
| + cpi->refresh_last_frame = 0;
|
| + cpi->refresh_golden_frame = 0;
|
| + cpi->refresh_alt_ref_frame = 1;
|
| + break;
|
| + default:
|
| + assert(0);
|
| + }
|
| +}
|
| +
|
| +
|
| void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -2130,14 +2107,12 @@
|
| if (!twopass->stats_in)
|
| return;
|
|
|
| - // Increment the gf group index.
|
| - ++twopass->gf_group_index;
|
| -
|
| // If this is an arf frame then we dont want to read the stats file or
|
| // advance the input pointer as we already have what we need.
|
| - if (cpi->refresh_alt_ref_frame) {
|
| + if (twopass->gf_group.update_type[twopass->gf_group.index] == ARF_UPDATE) {
|
| int target_rate;
|
| - target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
|
| + configure_buffer_updates(cpi);
|
| + target_rate = twopass->gf_group.bit_allocation[twopass->gf_group.index];
|
| target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
|
| rc->base_frame_target = target_rate;
|
| #ifdef LONG_TERM_VBR_CORRECTION
|
| @@ -2201,15 +2176,7 @@
|
|
|
| // Define a new GF/ARF group. (Should always enter here for key frames).
|
| if (rc->frames_till_gf_update_due == 0) {
|
| -#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
|
| + define_gf_group(cpi, &this_frame_copy);
|
|
|
| if (twopass->gf_zeromotion_pct > 995) {
|
| // As long as max_thresh for encode breakout is small enough, it is ok
|
| @@ -2233,7 +2200,9 @@
|
| }
|
| }
|
|
|
| - target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
|
| + configure_buffer_updates(cpi);
|
| +
|
| + target_rate = twopass->gf_group.bit_allocation[twopass->gf_group.index];
|
| if (cpi->common.frame_type == KEY_FRAME)
|
| target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
|
| else
|
| @@ -2249,6 +2218,12 @@
|
|
|
| // Update the total stats remaining structure.
|
| subtract_stats(&twopass->total_left_stats, &this_frame);
|
| +
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + input_mb_stats(&twopass->this_frame_mb_stats, cm);
|
| + }
|
| +#endif
|
| }
|
|
|
| void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| @@ -2296,4 +2271,7 @@
|
| twopass->kf_group_bits -= bits_used;
|
| }
|
| twopass->kf_group_bits = MAX(twopass->kf_group_bits, 0);
|
| +
|
| + // Increment the gf group index ready for the next frame.
|
| + ++twopass->gf_group.index;
|
| }
|
|
|