}
static int get_refresh_mask(VP9_COMP *cpi) {
- // Should the GF or ARF be updated using the transmitted frame or buffer
-#if CONFIG_MULTIPLE_ARF
- if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
- !cpi->refresh_alt_ref_frame) {
-#else
if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
-#endif
// Preserve the previously existing golden frame and update the frame in
// the alt ref slot instead. This is highly specific to the use of
// alt-ref as a forward reference, and this needs to be generalized as
(cpi->refresh_golden_frame << cpi->alt_fb_idx);
} else {
int arf_idx = cpi->alt_fb_idx;
-#if CONFIG_MULTIPLE_ARF
- // Determine which ARF buffer to use to encode this ARF frame.
- if (cpi->multi_arf_enabled) {
- int sn = cpi->sequence_number;
- arf_idx = (cpi->frame_coding_order[sn] < 0) ?
- cpi->arf_buffer_idx[sn + 1] :
- cpi->arf_buffer_idx[sn];
- }
-#endif
+
if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
}
-
return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
(cpi->refresh_golden_frame << cpi->gld_fb_idx) |
(cpi->refresh_alt_ref_frame << arf_idx);
(int)cpi->oxcf.target_bandwidth);
}
-#if CONFIG_MULTIPLE_ARF
- vp9_zero(cpi->alt_ref_source);
-#else
cpi->alt_ref_source = NULL;
-#endif
rc->is_src_frame_alt_ref = 0;
#if 0
cpi->multi_arf_enabled = 0;
else
cpi->multi_arf_enabled = 0;
-#if CONFIG_MULTIPLE_ARF
- // Turn multiple ARF usage on/off. This is a quick hack for the initial test
- // version. It should eventually be set via the codec API.
- cpi->multi_arf_enabled = 1;
-
- if (cpi->multi_arf_enabled) {
- cpi->sequence_number = 0;
- cpi->frame_coding_order_period = 0;
- vp9_zero(cpi->frame_coding_order);
- vp9_zero(cpi->arf_buffer_idx);
- }
-#endif
cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
#if CONFIG_INTERNAL_STATS
ref_cnt_fb(cm->frame_bufs,
&cm->ref_frame_map[cpi->alt_fb_idx], cm->new_fb_idx);
}
-#if CONFIG_MULTIPLE_ARF
- else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
- !cpi->refresh_alt_ref_frame) {
-#else
else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
-#endif
/* Preserve the previously existing golden frame and update the frame in
* the alt ref slot instead. This is highly specific to the current use of
* alt-ref as a forward reference, and this needs to be generalized as
} else { /* For non key/golden frames */
if (cpi->refresh_alt_ref_frame) {
int arf_idx = cpi->alt_fb_idx;
-#if CONFIG_MULTIPLE_ARF
- if (cpi->multi_arf_enabled) {
- arf_idx = cpi->arf_buffer_idx[cpi->sequence_number + 1];
- }
-#endif
if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
if (cm->frame_type == KEY_FRAME) {
// Tell the caller that the frame was coded as a key frame
*frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
-
-#if CONFIG_MULTIPLE_ARF
- // Reset the sequence number.
- if (cpi->multi_arf_enabled) {
- cpi->sequence_number = 0;
- cpi->frame_coding_order_period = cpi->new_frame_coding_order_period;
- cpi->new_frame_coding_order_period = -1;
- }
-#endif
} else {
*frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
-
-#if CONFIG_MULTIPLE_ARF
- /* Increment position in the coded frame sequence. */
- if (cpi->multi_arf_enabled) {
- ++cpi->sequence_number;
- if (cpi->sequence_number >= cpi->frame_coding_order_period) {
- cpi->sequence_number = 0;
- cpi->frame_coding_order_period = cpi->new_frame_coding_order_period;
- cpi->new_frame_coding_order_period = -1;
- }
- cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number];
- assert(cpi->this_frame_weight >= 0);
- }
-#endif
}
// Clear the one shot update flags for segmentation map and mode/ref loop
cm->seg.update_data;
}
-#if CONFIG_MULTIPLE_ARF
-int is_next_frame_arf(VP9_COMP *cpi) {
- // Negative entry in frame_coding_order indicates an ARF at this position.
- return cpi->frame_coding_order[cpi->sequence_number + 1] < 0 ? 1 : 0;
-}
-#endif
-
void adjust_frame_rate(VP9_COMP *cpi) {
int64_t this_duration;
int step = 0;
static void is_src_altref(VP9_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
-#if CONFIG_MULTIPLE_ARF
- int i;
- // Is this frame the ARF overlay.
- rc->is_src_frame_alt_ref = 0;
- for (i = 0; i < cpi->arf_buffered; ++i) {
- if (cpi->source == cpi->alt_ref_source[i]) {
- rc->is_src_frame_alt_ref = 1;
- cpi->refresh_golden_frame = 1;
- break;
- }
- }
-#else
if (cpi->pass == 2) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
rc->is_src_frame_alt_ref =
rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
(cpi->source == cpi->alt_ref_source);
}
-#endif
if (rc->is_src_frame_alt_ref) {
// Current frame is an ARF overlay frame.
-#if CONFIG_MULTIPLE_ARF
- cpi->alt_ref_source[i] = NULL;
-#else
cpi->alt_ref_source = NULL;
-#endif
+
// Don't refresh the last buffer for an ARF overlay frame. It will
// become the GF so preserve last as an alternative prediction option.
cpi->refresh_last_frame = 0;
}
-
-#if CONFIG_MULTIPLE_ARF
- ++cpi->next_frame_in_order;
-#endif
}
int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
assert(arf_src_index <= rc->frames_to_key);
if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index))) {
-#if CONFIG_MULTIPLE_ARF
- cpi->alt_ref_source[cpi->arf_buffered] = cpi->source;
-#else
cpi->alt_ref_source = cpi->source;
-#endif
if (cpi->oxcf.arnr_max_frames > 0) {
// Produce the filtered ARF frame.
*time_stamp = cpi->source->ts_start;
*time_end = cpi->source->ts_end;
*frame_flags = cpi->source->flags;
-
-#if CONFIG_MULTIPLE_ARF
- if (cm->frame_type != KEY_FRAME && cpi->pass == 2)
- rc->source_alt_ref_pending = is_next_frame_arf(cpi);
-#endif
} else {
*size = 0;
if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done) {
cm->frame_bufs[cm->new_fb_idx].ref_count--;
cm->new_fb_idx = get_free_fb(cm);
-#if CONFIG_MULTIPLE_ARF
- /* Set up the correct ARF frame. */
- if (cpi->refresh_alt_ref_frame) {
- ++cpi->arf_buffered;
- }
- if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
- (cpi->pass == 2)) {
- cpi->alt_fb_idx = cpi->arf_buffer_idx[cpi->sequence_number];
- }
-#endif
if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
(cpi->pass == 2)) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
VP9EncoderConfig oxcf;
struct lookahead_ctx *lookahead;
struct lookahead_entry *source;
-#if CONFIG_MULTIPLE_ARF
- struct lookahead_entry *alt_ref_source[REF_FRAMES];
-#else
struct lookahead_entry *alt_ref_source;
-#endif
struct lookahead_entry *last_source;
YV12_BUFFER_CONFIG *Source;
int gld_fb_idx;
int alt_fb_idx;
-#if CONFIG_MULTIPLE_ARF
- int alt_ref_fb_idx[REF_FRAMES - 3];
-#endif
int refresh_last_frame;
int refresh_golden_frame;
int refresh_alt_ref_frame;
TOKENEXTRA *tok;
unsigned int tok_count[4][1 << 6];
-#if CONFIG_MULTIPLE_ARF
- // Position within a frame coding order (including any additional ARF frames).
- unsigned int sequence_number;
- // Next frame in naturally occurring order that has not yet been coded.
- int next_frame_in_order;
-#endif
-
// Ambient reconstruction err target for force key frames
int ambient_err;
int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES];
int multi_arf_enabled;
-#if CONFIG_MULTIPLE_ARF
- // ARF tracking variables.
- unsigned int frame_coding_order_period;
- unsigned int new_frame_coding_order_period;
- int frame_coding_order[MAX_LAG_BUFFERS * 2];
- int arf_buffer_idx[MAX_LAG_BUFFERS * 3 / 2];
- int arf_weight[MAX_LAG_BUFFERS];
- int arf_buffered;
- int this_frame_weight;
- int max_arf_level;
-#endif
#if CONFIG_DENOISING
VP9_DENOISER denoiser;
#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) {
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,
}
}
-#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;
&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
} 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);
// 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
if (frame_is_intra_only(cm)) {
active_best_quality = rc->best_quality;
-#if !CONFIG_MULTIPLE_ARF
- // Handle the special case for key frames forced when we have75 reached
+
+ // Handle the special case for key frames forced when we have reached
// the maximum key frame interval. Here force the Q to a range
// based on the ambient Q to reduce the risk of popping.
if (rc->this_key_frame_forced) {
active_best_quality += vp9_compute_qdelta(rc, q_val,
q_val * q_adj_factor);
}
-#else
- double current_q;
- // Force the KF quantizer to be 30% of the active_worst_quality.
- current_q = vp9_convert_qindex_to_q(active_worst_quality);
- active_best_quality = active_worst_quality
- + vp9_compute_qdelta(rc, current_q, current_q * 0.3);
-#endif
} else if (!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
// Use the lower of active_worst_quality and recent
q = *top_index;
}
}
-#if CONFIG_MULTIPLE_ARF
- // Force the quantizer determined by the coding order pattern.
- if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
- cpi->oxcf.rc_mode != VPX_Q) {
- double new_q;
- double current_q = vp9_convert_qindex_to_q(active_worst_quality);
- int level = cpi->this_frame_weight;
- assert(level >= 0);
- new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
- q = active_worst_quality +
- vp9_compute_qdelta(rc, current_q, new_q);
-
- *bottom_index = q;
- *top_index = q;
- printf("frame:%d q:%d\n", cm->current_video_frame, q);
- }
-#endif
+
assert(*top_index <= rc->worst_quality &&
*top_index >= rc->best_quality);
assert(*bottom_index <= rc->worst_quality &&
int q;
if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) {
-#if !CONFIG_MULTIPLE_ARF
// Handle the special case for key frames forced when we have75 reached
// the maximum key frame interval. Here force the Q to a range
// based on the ambient Q to reduce the risk of popping.
active_best_quality += vp9_compute_qdelta(rc, q_val,
q_val * q_adj_factor);
}
-#else
- double current_q;
- // Force the KF quantizer to be 30% of the active_worst_quality.
- current_q = vp9_convert_qindex_to_q(active_worst_quality);
- active_best_quality = active_worst_quality
- + vp9_compute_qdelta(rc, current_q, current_q * 0.3);
-#endif
} else if (!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
// Use the lower of active_worst_quality and recent
q = *top_index;
}
}
-#if CONFIG_MULTIPLE_ARF
- // Force the quantizer determined by the coding order pattern.
- if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
- cpi->oxcf.rc_mode != VPX_Q) {
- double new_q;
- double current_q = vp9_convert_qindex_to_q(active_worst_quality);
- int level = cpi->this_frame_weight;
- assert(level >= 0);
- new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
- q = active_worst_quality +
- vp9_compute_qdelta(rc, current_q, new_q);
-
- *bottom_index = q;
- *top_index = q;
- printf("frame:%d q:%d\n", cm->current_video_frame, q);
- }
-#endif
+
assert(*top_index <= rc->worst_quality &&
*top_index >= rc->best_quality);
assert(*bottom_index <= rc->worst_quality &&