/src/libvpx/vp9/encoder/vp9_svc_layercontext.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2014 The WebM project authors. All Rights Reserved. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license |
5 | | * that can be found in the LICENSE file in the root of the source |
6 | | * tree. An additional intellectual property rights grant can be found |
7 | | * in the file PATENTS. All contributing project authors may |
8 | | * be found in the AUTHORS file in the root of the source tree. |
9 | | */ |
10 | | |
11 | | #include <math.h> |
12 | | |
13 | | #include "vp9/encoder/vp9_aq_cyclicrefresh.h" |
14 | | #include "vp9/encoder/vp9_encoder.h" |
15 | | #include "vp9/encoder/vp9_svc_layercontext.h" |
16 | | #include "vp9/encoder/vp9_extend.h" |
17 | | #include "vpx_dsp/vpx_dsp_common.h" |
18 | | |
19 | 0 | #define SMALL_FRAME_WIDTH 32 |
20 | 0 | #define SMALL_FRAME_HEIGHT 16 |
21 | | |
22 | 0 | static void swap_ptr(void *a, void *b) { |
23 | 0 | void **a_p = (void **)a; |
24 | 0 | void **b_p = (void **)b; |
25 | 0 | void *c = *a_p; |
26 | 0 | *a_p = *b_p; |
27 | 0 | *b_p = c; |
28 | 0 | } |
29 | | |
30 | 0 | void vp9_init_layer_context(VP9_COMP *const cpi) { |
31 | 0 | SVC *const svc = &cpi->svc; |
32 | 0 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
33 | 0 | int mi_rows = cpi->common.mi_rows; |
34 | 0 | int mi_cols = cpi->common.mi_cols; |
35 | 0 | int sl, tl, i; |
36 | 0 | int alt_ref_idx = svc->number_spatial_layers; |
37 | |
|
38 | 0 | svc->spatial_layer_id = 0; |
39 | 0 | svc->temporal_layer_id = 0; |
40 | 0 | svc->force_zero_mode_spatial_ref = 0; |
41 | 0 | svc->use_base_mv = 0; |
42 | 0 | svc->use_partition_reuse = 0; |
43 | 0 | svc->use_gf_temporal_ref = 1; |
44 | 0 | svc->use_gf_temporal_ref_current_layer = 0; |
45 | 0 | svc->scaled_temp_is_alloc = 0; |
46 | 0 | svc->scaled_one_half = 0; |
47 | 0 | svc->current_superframe = 0; |
48 | 0 | svc->non_reference_frame = 0; |
49 | 0 | svc->skip_enhancement_layer = 0; |
50 | 0 | svc->disable_inter_layer_pred = INTER_LAYER_PRED_ON; |
51 | 0 | svc->framedrop_mode = CONSTRAINED_LAYER_DROP; |
52 | 0 | svc->set_intra_only_frame = 0; |
53 | 0 | svc->previous_frame_is_intra_only = 0; |
54 | 0 | svc->superframe_has_layer_sync = 0; |
55 | 0 | svc->use_set_ref_frame_config = 0; |
56 | 0 | svc->num_encoded_top_layer = 0; |
57 | 0 | svc->simulcast_mode = 0; |
58 | 0 | svc->single_layer_svc = 0; |
59 | 0 | svc->resize_set = 0; |
60 | |
|
61 | 0 | for (i = 0; i < REF_FRAMES; ++i) { |
62 | 0 | svc->fb_idx_spatial_layer_id[i] = 0xff; |
63 | 0 | svc->fb_idx_temporal_layer_id[i] = 0xff; |
64 | 0 | svc->fb_idx_base[i] = 0; |
65 | 0 | } |
66 | 0 | for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { |
67 | 0 | svc->last_layer_dropped[sl] = 0; |
68 | 0 | svc->drop_spatial_layer[sl] = 0; |
69 | 0 | svc->ext_frame_flags[sl] = 0; |
70 | 0 | svc->lst_fb_idx[sl] = 0; |
71 | 0 | svc->gld_fb_idx[sl] = 1; |
72 | 0 | svc->alt_fb_idx[sl] = 2; |
73 | 0 | svc->downsample_filter_type[sl] = BILINEAR; |
74 | 0 | svc->downsample_filter_phase[sl] = 8; // Set to 8 for averaging filter. |
75 | 0 | svc->framedrop_thresh[sl] = oxcf->drop_frames_water_mark; |
76 | 0 | svc->fb_idx_upd_tl0[sl] = -1; |
77 | 0 | svc->drop_count[sl] = 0; |
78 | 0 | svc->spatial_layer_sync[sl] = 0; |
79 | 0 | svc->force_drop_constrained_from_above[sl] = 0; |
80 | 0 | } |
81 | 0 | svc->max_consec_drop = INT_MAX; |
82 | |
|
83 | 0 | svc->buffer_gf_temporal_ref[1].idx = 7; |
84 | 0 | svc->buffer_gf_temporal_ref[0].idx = 6; |
85 | 0 | svc->buffer_gf_temporal_ref[1].is_used = 0; |
86 | 0 | svc->buffer_gf_temporal_ref[0].is_used = 0; |
87 | |
|
88 | 0 | if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { |
89 | 0 | if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH, |
90 | 0 | SMALL_FRAME_HEIGHT, cpi->common.subsampling_x, |
91 | 0 | cpi->common.subsampling_y, |
92 | 0 | #if CONFIG_VP9_HIGHBITDEPTH |
93 | 0 | cpi->common.use_highbitdepth, |
94 | 0 | #endif |
95 | 0 | VP9_ENC_BORDER_IN_PIXELS, |
96 | 0 | cpi->common.byte_alignment, NULL, NULL, NULL)) |
97 | 0 | vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, |
98 | 0 | "Failed to allocate empty frame for multiple frame " |
99 | 0 | "contexts"); |
100 | |
|
101 | 0 | memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80, |
102 | 0 | cpi->svc.empty_frame.img.buffer_alloc_sz); |
103 | 0 | } |
104 | |
|
105 | 0 | for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { |
106 | 0 | for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { |
107 | 0 | int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); |
108 | 0 | LAYER_CONTEXT *const lc = &svc->layer_context[layer]; |
109 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
110 | 0 | lc->current_video_frame_in_layer = 0; |
111 | 0 | lc->layer_size = 0; |
112 | 0 | lc->frames_from_key_frame = 0; |
113 | 0 | lc->last_frame_type = FRAME_TYPES; |
114 | 0 | lrc->ni_av_qi = oxcf->worst_allowed_q; |
115 | 0 | lrc->total_actual_bits = 0; |
116 | 0 | lrc->total_target_vs_actual = 0; |
117 | 0 | lrc->ni_tot_qi = 0; |
118 | 0 | lrc->tot_q = 0.0; |
119 | 0 | lrc->avg_q = 0.0; |
120 | 0 | lrc->ni_frames = 0; |
121 | 0 | lrc->decimation_count = 0; |
122 | 0 | lrc->decimation_factor = 0; |
123 | 0 | lrc->worst_quality = oxcf->worst_allowed_q; |
124 | 0 | lrc->best_quality = oxcf->best_allowed_q; |
125 | |
|
126 | 0 | for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { |
127 | 0 | lrc->rate_correction_factors[i] = 1.0; |
128 | 0 | } |
129 | |
|
130 | 0 | if (cpi->oxcf.rc_mode == VPX_CBR) { |
131 | 0 | lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; |
132 | 0 | lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q; |
133 | 0 | lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q; |
134 | 0 | lrc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q; |
135 | 0 | } else { |
136 | 0 | lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; |
137 | 0 | lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q; |
138 | 0 | lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q; |
139 | 0 | lrc->avg_frame_qindex[KEY_FRAME] = |
140 | 0 | (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; |
141 | 0 | lrc->avg_frame_qindex[INTER_FRAME] = |
142 | 0 | (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; |
143 | 0 | if (oxcf->ss_enable_auto_arf[sl]) |
144 | 0 | lc->alt_ref_idx = alt_ref_idx++; |
145 | 0 | else |
146 | 0 | lc->alt_ref_idx = INVALID_IDX; |
147 | 0 | lc->gold_ref_idx = INVALID_IDX; |
148 | 0 | } |
149 | |
|
150 | 0 | lrc->buffer_level = |
151 | 0 | oxcf->starting_buffer_level_ms * lc->target_bandwidth / 1000; |
152 | 0 | lrc->bits_off_target = lrc->buffer_level; |
153 | | |
154 | | // Initialize the cyclic refresh parameters. If spatial layers are used |
155 | | // (i.e., ss_number_layers > 1), these need to be updated per spatial |
156 | | // layer. |
157 | | // Cyclic refresh is only applied on base temporal layer. |
158 | 0 | if (oxcf->ss_number_layers > 1 && tl == 0) { |
159 | 0 | size_t last_coded_q_map_size; |
160 | 0 | size_t consec_zero_mv_size; |
161 | 0 | VP9_COMMON *const cm = &cpi->common; |
162 | 0 | lc->sb_index = 0; |
163 | 0 | lc->actual_num_seg1_blocks = 0; |
164 | 0 | lc->actual_num_seg2_blocks = 0; |
165 | 0 | lc->counter_encode_maxq_scene_change = 0; |
166 | 0 | CHECK_MEM_ERROR(&cm->error, lc->map, |
167 | 0 | vpx_malloc(mi_rows * mi_cols * sizeof(*lc->map))); |
168 | 0 | memset(lc->map, 0, mi_rows * mi_cols); |
169 | 0 | last_coded_q_map_size = |
170 | 0 | mi_rows * mi_cols * sizeof(*lc->last_coded_q_map); |
171 | 0 | CHECK_MEM_ERROR(&cm->error, lc->last_coded_q_map, |
172 | 0 | vpx_malloc(last_coded_q_map_size)); |
173 | 0 | assert(MAXQ <= 255); |
174 | 0 | memset(lc->last_coded_q_map, MAXQ, last_coded_q_map_size); |
175 | 0 | consec_zero_mv_size = mi_rows * mi_cols * sizeof(*lc->consec_zero_mv); |
176 | 0 | CHECK_MEM_ERROR(&cm->error, lc->consec_zero_mv, |
177 | 0 | vpx_malloc(consec_zero_mv_size)); |
178 | 0 | memset(lc->consec_zero_mv, 0, consec_zero_mv_size); |
179 | 0 | } |
180 | 0 | } |
181 | 0 | } |
182 | | |
183 | | // Still have extra buffer for base layer golden frame |
184 | 0 | if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) && |
185 | 0 | alt_ref_idx < REF_FRAMES) |
186 | 0 | svc->layer_context[0].gold_ref_idx = alt_ref_idx; |
187 | 0 | } |
188 | | |
189 | | // Update the layer context from a change_config() call. |
190 | | void vp9_update_layer_context_change_config(VP9_COMP *const cpi, |
191 | 0 | const int target_bandwidth) { |
192 | 0 | SVC *const svc = &cpi->svc; |
193 | 0 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
194 | 0 | const RATE_CONTROL *const rc = &cpi->rc; |
195 | 0 | int sl, tl, layer = 0, spatial_layer_target; |
196 | 0 | float bitrate_alloc = 1.0; |
197 | 0 | int num_spatial_layers_nonzero_rate = 0; |
198 | |
|
199 | 0 | cpi->svc.temporal_layering_mode = oxcf->temporal_layering_mode; |
200 | |
|
201 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { |
202 | 0 | for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { |
203 | 0 | for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { |
204 | 0 | layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); |
205 | 0 | svc->layer_context[layer].target_bandwidth = |
206 | 0 | oxcf->layer_target_bitrate[layer]; |
207 | 0 | } |
208 | |
|
209 | 0 | layer = LAYER_IDS_TO_IDX( |
210 | 0 | sl, |
211 | 0 | ((oxcf->ts_number_layers - 1) < 0 ? 0 : (oxcf->ts_number_layers - 1)), |
212 | 0 | oxcf->ts_number_layers); |
213 | 0 | spatial_layer_target = svc->layer_context[layer].target_bandwidth = |
214 | 0 | oxcf->layer_target_bitrate[layer]; |
215 | |
|
216 | 0 | for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { |
217 | 0 | LAYER_CONTEXT *const lc = |
218 | 0 | &svc->layer_context[sl * oxcf->ts_number_layers + tl]; |
219 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
220 | |
|
221 | 0 | lc->spatial_layer_target_bandwidth = spatial_layer_target; |
222 | 0 | if (target_bandwidth != 0) { |
223 | 0 | bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth; |
224 | 0 | } |
225 | 0 | lrc->starting_buffer_level = |
226 | 0 | (int64_t)(rc->starting_buffer_level * bitrate_alloc + 0.5); |
227 | 0 | lrc->optimal_buffer_level = |
228 | 0 | (int64_t)(rc->optimal_buffer_level * bitrate_alloc + 0.5); |
229 | 0 | lrc->maximum_buffer_size = |
230 | 0 | (int64_t)(rc->maximum_buffer_size * bitrate_alloc + 0.5); |
231 | 0 | lrc->bits_off_target = |
232 | 0 | VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); |
233 | 0 | lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size); |
234 | 0 | lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl]; |
235 | 0 | lrc->avg_frame_bandwidth = saturate_cast_double_to_int( |
236 | 0 | round(lc->target_bandwidth / lc->framerate)); |
237 | 0 | lrc->max_frame_bandwidth = rc->max_frame_bandwidth; |
238 | 0 | lrc->worst_quality = rc->worst_quality; |
239 | 0 | lrc->best_quality = rc->best_quality; |
240 | 0 | } |
241 | 0 | } |
242 | 0 | } else { |
243 | 0 | int layer_end; |
244 | |
|
245 | 0 | if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { |
246 | 0 | layer_end = svc->number_temporal_layers; |
247 | 0 | } else { |
248 | 0 | layer_end = svc->number_spatial_layers; |
249 | 0 | } |
250 | |
|
251 | 0 | for (layer = 0; layer < layer_end; ++layer) { |
252 | 0 | LAYER_CONTEXT *const lc = &svc->layer_context[layer]; |
253 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
254 | |
|
255 | 0 | lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; |
256 | |
|
257 | 0 | if (target_bandwidth != 0) { |
258 | 0 | bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth; |
259 | 0 | } |
260 | | // Update buffer-related quantities. |
261 | 0 | lrc->starting_buffer_level = |
262 | 0 | (int64_t)(rc->starting_buffer_level * bitrate_alloc); |
263 | 0 | lrc->optimal_buffer_level = |
264 | 0 | (int64_t)(rc->optimal_buffer_level * bitrate_alloc); |
265 | 0 | lrc->maximum_buffer_size = |
266 | 0 | (int64_t)(rc->maximum_buffer_size * bitrate_alloc); |
267 | 0 | lrc->bits_off_target = |
268 | 0 | VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); |
269 | 0 | lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size); |
270 | | // Update framerate-related quantities. |
271 | 0 | if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { |
272 | 0 | lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer]; |
273 | 0 | } else { |
274 | 0 | lc->framerate = cpi->framerate; |
275 | 0 | } |
276 | 0 | lrc->avg_frame_bandwidth = saturate_cast_double_to_int( |
277 | 0 | round(lc->target_bandwidth / lc->framerate)); |
278 | 0 | lrc->max_frame_bandwidth = rc->max_frame_bandwidth; |
279 | | // Update qp-related quantities. |
280 | 0 | lrc->worst_quality = rc->worst_quality; |
281 | 0 | lrc->best_quality = rc->best_quality; |
282 | 0 | } |
283 | 0 | } |
284 | 0 | for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { |
285 | | // Check bitrate of spatia layer. |
286 | 0 | layer = LAYER_IDS_TO_IDX(sl, oxcf->ts_number_layers - 1, |
287 | 0 | oxcf->ts_number_layers); |
288 | 0 | if (oxcf->layer_target_bitrate[layer] > 0) |
289 | 0 | num_spatial_layers_nonzero_rate += 1; |
290 | 0 | } |
291 | 0 | if (num_spatial_layers_nonzero_rate == 1) |
292 | 0 | svc->single_layer_svc = 1; |
293 | 0 | else |
294 | 0 | svc->single_layer_svc = 0; |
295 | 0 | } |
296 | | |
297 | 0 | static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) { |
298 | 0 | if (is_one_pass_svc(cpi)) |
299 | 0 | return &cpi->svc.layer_context[cpi->svc.spatial_layer_id * |
300 | 0 | cpi->svc.number_temporal_layers + |
301 | 0 | cpi->svc.temporal_layer_id]; |
302 | 0 | else |
303 | 0 | return (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) |
304 | 0 | ? &cpi->svc.layer_context[cpi->svc.temporal_layer_id] |
305 | 0 | : &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; |
306 | 0 | } |
307 | | |
308 | 0 | void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) { |
309 | 0 | SVC *const svc = &cpi->svc; |
310 | 0 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
311 | 0 | LAYER_CONTEXT *const lc = get_layer_context(cpi); |
312 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
313 | | // Index into spatial+temporal arrays. |
314 | 0 | const int st_idx = svc->spatial_layer_id * svc->number_temporal_layers + |
315 | 0 | svc->temporal_layer_id; |
316 | 0 | const int tl = svc->temporal_layer_id; |
317 | |
|
318 | 0 | lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl]; |
319 | 0 | lrc->avg_frame_bandwidth = |
320 | 0 | saturate_cast_double_to_int(round(lc->target_bandwidth / lc->framerate)); |
321 | 0 | lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth; |
322 | | // Update the average layer frame size (non-cumulative per-frame-bw). |
323 | 0 | if (tl == 0) { |
324 | 0 | lc->avg_frame_size = lrc->avg_frame_bandwidth; |
325 | 0 | } else { |
326 | 0 | const double prev_layer_framerate = |
327 | 0 | cpi->framerate / oxcf->ts_rate_decimator[tl - 1]; |
328 | 0 | const int prev_layer_target_bandwidth = |
329 | 0 | oxcf->layer_target_bitrate[st_idx - 1]; |
330 | 0 | lc->avg_frame_size = |
331 | 0 | (int)round((lc->target_bandwidth - prev_layer_target_bandwidth) / |
332 | 0 | (lc->framerate - prev_layer_framerate)); |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | 0 | void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) { |
337 | 0 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
338 | 0 | LAYER_CONTEXT *const lc = get_layer_context(cpi); |
339 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
340 | |
|
341 | 0 | lc->framerate = framerate; |
342 | 0 | lrc->avg_frame_bandwidth = |
343 | 0 | saturate_cast_double_to_int(round(lc->target_bandwidth / lc->framerate)); |
344 | 0 | const int64_t vbr_min_bits = |
345 | 0 | (int64_t)lrc->avg_frame_bandwidth * oxcf->two_pass_vbrmin_section / 100; |
346 | 0 | lrc->min_frame_bandwidth = (int)VPXMIN(vbr_min_bits, INT_MAX); |
347 | 0 | const int64_t vbr_max_bits = |
348 | 0 | (int64_t)lrc->avg_frame_bandwidth * oxcf->two_pass_vbrmax_section / 100; |
349 | 0 | lrc->max_frame_bandwidth = (int)VPXMIN(vbr_max_bits, INT_MAX); |
350 | 0 | vp9_rc_set_gf_interval_range(cpi, lrc); |
351 | 0 | } |
352 | | |
353 | 0 | void vp9_restore_layer_context(VP9_COMP *const cpi) { |
354 | 0 | LAYER_CONTEXT *const lc = get_layer_context(cpi); |
355 | 0 | const int old_frame_since_key = cpi->rc.frames_since_key; |
356 | 0 | const int old_frame_to_key = cpi->rc.frames_to_key; |
357 | 0 | const int old_ext_use_post_encode_drop = cpi->rc.ext_use_post_encode_drop; |
358 | |
|
359 | 0 | cpi->rc = lc->rc; |
360 | 0 | cpi->twopass = lc->twopass; |
361 | 0 | cpi->oxcf.target_bandwidth = lc->target_bandwidth; |
362 | 0 | cpi->alt_ref_source = lc->alt_ref_source; |
363 | | // Check if it is one_pass_cbr_svc mode and lc->speed > 0 (real-time mode |
364 | | // does not use speed = 0). |
365 | 0 | if (is_one_pass_svc(cpi) && lc->speed > 0) { |
366 | 0 | cpi->oxcf.speed = lc->speed; |
367 | 0 | } |
368 | 0 | cpi->loopfilter_ctrl = lc->loopfilter_ctrl; |
369 | | // Reset the frames_since_key and frames_to_key counters to their values |
370 | | // before the layer restore. Keep these defined for the stream (not layer). |
371 | 0 | if (cpi->svc.number_temporal_layers > 1 || |
372 | 0 | cpi->svc.number_spatial_layers > 1) { |
373 | 0 | cpi->rc.frames_since_key = old_frame_since_key; |
374 | 0 | cpi->rc.frames_to_key = old_frame_to_key; |
375 | 0 | } |
376 | 0 | cpi->rc.ext_use_post_encode_drop = old_ext_use_post_encode_drop; |
377 | | // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers, |
378 | | // for the base temporal layer. |
379 | 0 | if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && |
380 | 0 | cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) { |
381 | 0 | CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
382 | 0 | swap_ptr(&cr->map, &lc->map); |
383 | 0 | swap_ptr(&cr->last_coded_q_map, &lc->last_coded_q_map); |
384 | 0 | swap_ptr(&cpi->consec_zero_mv, &lc->consec_zero_mv); |
385 | 0 | cr->sb_index = lc->sb_index; |
386 | 0 | cr->actual_num_seg1_blocks = lc->actual_num_seg1_blocks; |
387 | 0 | cr->actual_num_seg2_blocks = lc->actual_num_seg2_blocks; |
388 | 0 | cr->counter_encode_maxq_scene_change = lc->counter_encode_maxq_scene_change; |
389 | 0 | } |
390 | 0 | } |
391 | | |
392 | 0 | void vp9_save_layer_context(VP9_COMP *const cpi) { |
393 | 0 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
394 | 0 | LAYER_CONTEXT *const lc = get_layer_context(cpi); |
395 | |
|
396 | 0 | lc->rc = cpi->rc; |
397 | 0 | lc->twopass = cpi->twopass; |
398 | 0 | lc->target_bandwidth = (int)oxcf->target_bandwidth; |
399 | 0 | lc->alt_ref_source = cpi->alt_ref_source; |
400 | 0 | lc->frame_qp = cpi->common.base_qindex; |
401 | 0 | lc->MBs = cpi->common.MBs; |
402 | | |
403 | | // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers, |
404 | | // for the base temporal layer. |
405 | 0 | if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && |
406 | 0 | cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) { |
407 | 0 | CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |
408 | 0 | signed char *temp = lc->map; |
409 | 0 | uint8_t *temp2 = lc->last_coded_q_map; |
410 | 0 | uint8_t *temp3 = lc->consec_zero_mv; |
411 | 0 | lc->map = cr->map; |
412 | 0 | cr->map = temp; |
413 | 0 | lc->last_coded_q_map = cr->last_coded_q_map; |
414 | 0 | cr->last_coded_q_map = temp2; |
415 | 0 | lc->consec_zero_mv = cpi->consec_zero_mv; |
416 | 0 | cpi->consec_zero_mv = temp3; |
417 | 0 | lc->sb_index = cr->sb_index; |
418 | 0 | lc->actual_num_seg1_blocks = cr->actual_num_seg1_blocks; |
419 | 0 | lc->actual_num_seg2_blocks = cr->actual_num_seg2_blocks; |
420 | 0 | lc->counter_encode_maxq_scene_change = cr->counter_encode_maxq_scene_change; |
421 | 0 | lc->qindex_delta[0] = cr->qindex_delta[0]; |
422 | 0 | lc->qindex_delta[1] = cr->qindex_delta[1]; |
423 | 0 | lc->qindex_delta[2] = cr->qindex_delta[2]; |
424 | 0 | } |
425 | 0 | } |
426 | | |
427 | | #if !CONFIG_REALTIME_ONLY |
428 | 0 | void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) { |
429 | 0 | SVC *const svc = &cpi->svc; |
430 | 0 | int i; |
431 | |
|
432 | 0 | for (i = 0; i < svc->number_spatial_layers; ++i) { |
433 | 0 | TWO_PASS *const twopass = &svc->layer_context[i].twopass; |
434 | |
|
435 | 0 | svc->spatial_layer_id = i; |
436 | 0 | vp9_init_second_pass(cpi); |
437 | |
|
438 | 0 | twopass->total_stats.spatial_layer_id = i; |
439 | 0 | twopass->total_left_stats.spatial_layer_id = i; |
440 | 0 | } |
441 | 0 | svc->spatial_layer_id = 0; |
442 | 0 | } |
443 | | #endif // !CONFIG_REALTIME_ONLY |
444 | | |
445 | 0 | void vp9_inc_frame_in_layer(VP9_COMP *const cpi) { |
446 | 0 | LAYER_CONTEXT *const lc = |
447 | 0 | &cpi->svc.layer_context[cpi->svc.spatial_layer_id * |
448 | 0 | cpi->svc.number_temporal_layers]; |
449 | 0 | ++lc->current_video_frame_in_layer; |
450 | 0 | ++lc->frames_from_key_frame; |
451 | 0 | if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) |
452 | 0 | ++cpi->svc.current_superframe; |
453 | 0 | } |
454 | | |
455 | | void get_layer_resolution(const int width_org, const int height_org, |
456 | | const int num, const int den, int *width_out, |
457 | 0 | int *height_out) { |
458 | 0 | int w, h; |
459 | |
|
460 | 0 | if (width_out == NULL || height_out == NULL || den == 0) return; |
461 | | |
462 | 0 | w = width_org * num / den; |
463 | 0 | h = height_org * num / den; |
464 | | |
465 | | // make height and width even to make chrome player happy |
466 | 0 | w += w % 2; |
467 | 0 | h += h % 2; |
468 | |
|
469 | 0 | *width_out = w; |
470 | 0 | *height_out = h; |
471 | 0 | } |
472 | | |
473 | 0 | static void reset_fb_idx_unused(VP9_COMP *const cpi) { |
474 | | // If a reference frame is not referenced or refreshed, then set the |
475 | | // fb_idx for that reference to the first one used/referenced. |
476 | | // This is to avoid setting fb_idx for a reference to a slot that is not |
477 | | // used/needed (i.e., since that reference is not referenced or refreshed). |
478 | 0 | MV_REFERENCE_FRAME ref_frame; |
479 | 0 | MV_REFERENCE_FRAME first_ref = 0; |
480 | 0 | int first_fb_idx = 0; |
481 | 0 | int fb_idx[3] = { cpi->lst_fb_idx, cpi->gld_fb_idx, cpi->alt_fb_idx }; |
482 | 0 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { |
483 | 0 | if (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) { |
484 | 0 | first_ref = ref_frame; |
485 | 0 | first_fb_idx = fb_idx[ref_frame - 1]; |
486 | 0 | break; |
487 | 0 | } |
488 | 0 | } |
489 | 0 | if (first_ref > 0) { |
490 | 0 | if (first_ref != LAST_FRAME && !(cpi->ref_frame_flags & VP9_LAST_FLAG) && |
491 | 0 | !cpi->ext_refresh_last_frame) |
492 | 0 | cpi->lst_fb_idx = first_fb_idx; |
493 | 0 | else if (first_ref != GOLDEN_FRAME && |
494 | 0 | !(cpi->ref_frame_flags & VP9_GOLD_FLAG) && |
495 | 0 | !cpi->ext_refresh_golden_frame) |
496 | 0 | cpi->gld_fb_idx = first_fb_idx; |
497 | 0 | else if (first_ref != ALTREF_FRAME && |
498 | 0 | !(cpi->ref_frame_flags & VP9_ALT_FLAG) && |
499 | 0 | !cpi->ext_refresh_alt_ref_frame) |
500 | 0 | cpi->alt_fb_idx = first_fb_idx; |
501 | 0 | } |
502 | 0 | } |
503 | | |
504 | | // Never refresh any reference frame buffers on top temporal layers in |
505 | | // simulcast mode, which has interlayer prediction disabled. |
506 | 0 | static void non_reference_frame_simulcast(VP9_COMP *const cpi) { |
507 | 0 | if (cpi->svc.temporal_layer_id == cpi->svc.number_temporal_layers - 1 && |
508 | 0 | cpi->svc.temporal_layer_id > 0) { |
509 | 0 | cpi->ext_refresh_last_frame = 0; |
510 | 0 | cpi->ext_refresh_golden_frame = 0; |
511 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | // The function sets proper ref_frame_flags, buffer indices, and buffer update |
516 | | // variables for temporal layering mode 3 - that does 0-2-1-2 temporal layering |
517 | | // scheme. |
518 | 0 | static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) { |
519 | 0 | int frame_num_within_temporal_struct = 0; |
520 | 0 | int spatial_id, temporal_id; |
521 | 0 | spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; |
522 | 0 | frame_num_within_temporal_struct = |
523 | 0 | cpi->svc |
524 | 0 | .layer_context[cpi->svc.spatial_layer_id * |
525 | 0 | cpi->svc.number_temporal_layers] |
526 | 0 | .current_video_frame_in_layer % |
527 | 0 | 4; |
528 | 0 | temporal_id = cpi->svc.temporal_layer_id = |
529 | 0 | (frame_num_within_temporal_struct & 1) |
530 | 0 | ? 2 |
531 | 0 | : (frame_num_within_temporal_struct >> 1); |
532 | 0 | cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = |
533 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
534 | 0 | if (!temporal_id) { |
535 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
536 | 0 | cpi->ext_refresh_last_frame = 1; |
537 | 0 | if (!spatial_id) { |
538 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
539 | 0 | } else if (cpi->svc.layer_context[temporal_id].is_key_frame) { |
540 | | // base layer is a key frame. |
541 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
542 | 0 | cpi->ext_refresh_last_frame = 0; |
543 | 0 | cpi->ext_refresh_golden_frame = 1; |
544 | 0 | } else { |
545 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
546 | 0 | } |
547 | 0 | } else if (temporal_id == 1) { |
548 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
549 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
550 | 0 | if (!spatial_id) { |
551 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
552 | 0 | } else { |
553 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
554 | 0 | } |
555 | 0 | } else { |
556 | 0 | if (frame_num_within_temporal_struct == 1) { |
557 | | // the first tl2 picture |
558 | 0 | if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer |
559 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
560 | 0 | if (!spatial_id) |
561 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
562 | 0 | else |
563 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
564 | 0 | } else if (!spatial_id) { |
565 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
566 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
567 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
568 | 0 | } else if (spatial_id < cpi->svc.number_spatial_layers - 1) { |
569 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
570 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
571 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
572 | 0 | } |
573 | 0 | } else { |
574 | | // The second tl2 picture |
575 | 0 | if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer |
576 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
577 | 0 | if (!spatial_id) |
578 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
579 | 0 | else |
580 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
581 | 0 | } else if (!spatial_id) { |
582 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
583 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
584 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
585 | 0 | } else { // top layer |
586 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
587 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
588 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
589 | 0 | } |
590 | 0 | } |
591 | 0 | } |
592 | 0 | if (temporal_id == 0) { |
593 | 0 | cpi->lst_fb_idx = spatial_id; |
594 | 0 | if (spatial_id) { |
595 | 0 | if (cpi->svc.layer_context[temporal_id].is_key_frame) { |
596 | 0 | cpi->lst_fb_idx = spatial_id - 1; |
597 | 0 | cpi->gld_fb_idx = spatial_id; |
598 | 0 | } else { |
599 | 0 | cpi->gld_fb_idx = spatial_id - 1; |
600 | 0 | } |
601 | 0 | } else { |
602 | 0 | cpi->gld_fb_idx = 0; |
603 | 0 | } |
604 | 0 | cpi->alt_fb_idx = 0; |
605 | 0 | } else if (temporal_id == 1) { |
606 | 0 | cpi->lst_fb_idx = spatial_id; |
607 | 0 | cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; |
608 | 0 | cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; |
609 | 0 | } else if (frame_num_within_temporal_struct == 1) { |
610 | 0 | cpi->lst_fb_idx = spatial_id; |
611 | 0 | cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; |
612 | 0 | cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; |
613 | 0 | } else { |
614 | 0 | cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id; |
615 | 0 | cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; |
616 | 0 | cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; |
617 | 0 | } |
618 | |
|
619 | 0 | if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); |
620 | |
|
621 | 0 | reset_fb_idx_unused(cpi); |
622 | 0 | } |
623 | | |
624 | | // The function sets proper ref_frame_flags, buffer indices, and buffer update |
625 | | // variables for temporal layering mode 2 - that does 0-1-0-1 temporal layering |
626 | | // scheme. |
627 | 0 | static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) { |
628 | 0 | int spatial_id, temporal_id; |
629 | 0 | spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; |
630 | 0 | temporal_id = cpi->svc.temporal_layer_id = |
631 | 0 | cpi->svc |
632 | 0 | .layer_context[cpi->svc.spatial_layer_id * |
633 | 0 | cpi->svc.number_temporal_layers] |
634 | 0 | .current_video_frame_in_layer & |
635 | 0 | 1; |
636 | 0 | cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = |
637 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
638 | 0 | if (!temporal_id) { |
639 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
640 | 0 | cpi->ext_refresh_last_frame = 1; |
641 | 0 | if (!spatial_id) { |
642 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
643 | 0 | } else if (cpi->svc.layer_context[temporal_id].is_key_frame) { |
644 | | // base layer is a key frame. |
645 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
646 | 0 | cpi->ext_refresh_last_frame = 0; |
647 | 0 | cpi->ext_refresh_golden_frame = 1; |
648 | 0 | } else { |
649 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
650 | 0 | } |
651 | 0 | } else if (temporal_id == 1) { |
652 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
653 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
654 | 0 | if (!spatial_id) { |
655 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
656 | 0 | } else { |
657 | 0 | if (spatial_id == cpi->svc.number_spatial_layers - 1) |
658 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
659 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
660 | 0 | } |
661 | 0 | } |
662 | |
|
663 | 0 | if (temporal_id == 0) { |
664 | 0 | cpi->lst_fb_idx = spatial_id; |
665 | 0 | if (spatial_id) { |
666 | 0 | if (cpi->svc.layer_context[temporal_id].is_key_frame) { |
667 | 0 | cpi->lst_fb_idx = spatial_id - 1; |
668 | 0 | cpi->gld_fb_idx = spatial_id; |
669 | 0 | } else { |
670 | 0 | cpi->gld_fb_idx = spatial_id - 1; |
671 | 0 | } |
672 | 0 | } else { |
673 | 0 | cpi->gld_fb_idx = 0; |
674 | 0 | } |
675 | 0 | cpi->alt_fb_idx = 0; |
676 | 0 | } else if (temporal_id == 1) { |
677 | 0 | cpi->lst_fb_idx = spatial_id; |
678 | 0 | cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; |
679 | 0 | cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; |
680 | 0 | } |
681 | |
|
682 | 0 | if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); |
683 | |
|
684 | 0 | reset_fb_idx_unused(cpi); |
685 | 0 | } |
686 | | |
687 | | // The function sets proper ref_frame_flags, buffer indices, and buffer update |
688 | | // variables for temporal layering mode 0 - that has no temporal layering. |
689 | | static void set_flags_and_fb_idx_for_temporal_mode_noLayering( |
690 | 0 | VP9_COMP *const cpi) { |
691 | 0 | int spatial_id; |
692 | 0 | spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; |
693 | 0 | cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = |
694 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
695 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
696 | 0 | cpi->ext_refresh_last_frame = 1; |
697 | 0 | if (!spatial_id) { |
698 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
699 | 0 | } else if (cpi->svc.layer_context[0].is_key_frame) { |
700 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG; |
701 | 0 | cpi->ext_refresh_last_frame = 0; |
702 | 0 | cpi->ext_refresh_golden_frame = 1; |
703 | 0 | } else { |
704 | 0 | cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; |
705 | 0 | } |
706 | 0 | cpi->lst_fb_idx = spatial_id; |
707 | 0 | if (spatial_id) { |
708 | 0 | if (cpi->svc.layer_context[0].is_key_frame) { |
709 | 0 | cpi->lst_fb_idx = spatial_id - 1; |
710 | 0 | cpi->gld_fb_idx = spatial_id; |
711 | 0 | } else { |
712 | 0 | cpi->gld_fb_idx = spatial_id - 1; |
713 | 0 | } |
714 | 0 | } else { |
715 | 0 | cpi->gld_fb_idx = 0; |
716 | 0 | } |
717 | |
|
718 | 0 | if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); |
719 | |
|
720 | 0 | reset_fb_idx_unused(cpi); |
721 | 0 | } |
722 | | |
723 | | static void set_flags_and_fb_idx_bypass_via_set_ref_frame_config( |
724 | 0 | VP9_COMP *const cpi) { |
725 | 0 | SVC *const svc = &cpi->svc; |
726 | 0 | int sl = svc->spatial_layer_id = svc->spatial_layer_to_encode; |
727 | 0 | cpi->svc.temporal_layer_id = cpi->svc.temporal_layer_id_per_spatial[sl]; |
728 | 0 | cpi->ext_refresh_frame_flags_pending = 1; |
729 | 0 | cpi->lst_fb_idx = svc->lst_fb_idx[sl]; |
730 | 0 | cpi->gld_fb_idx = svc->gld_fb_idx[sl]; |
731 | 0 | cpi->alt_fb_idx = svc->alt_fb_idx[sl]; |
732 | 0 | cpi->ext_refresh_last_frame = 0; |
733 | 0 | cpi->ext_refresh_golden_frame = 0; |
734 | 0 | cpi->ext_refresh_alt_ref_frame = 0; |
735 | 0 | cpi->ref_frame_flags = 0; |
736 | 0 | if (svc->reference_last[sl]) cpi->ref_frame_flags |= VP9_LAST_FLAG; |
737 | 0 | if (svc->reference_golden[sl]) cpi->ref_frame_flags |= VP9_GOLD_FLAG; |
738 | 0 | if (svc->reference_altref[sl]) cpi->ref_frame_flags |= VP9_ALT_FLAG; |
739 | 0 | } |
740 | | |
741 | 0 | void vp9_copy_flags_ref_update_idx(VP9_COMP *const cpi) { |
742 | 0 | SVC *const svc = &cpi->svc; |
743 | 0 | int sl = svc->spatial_layer_id; |
744 | 0 | svc->lst_fb_idx[sl] = cpi->lst_fb_idx; |
745 | 0 | svc->gld_fb_idx[sl] = cpi->gld_fb_idx; |
746 | 0 | svc->alt_fb_idx[sl] = cpi->alt_fb_idx; |
747 | | // For the fixed SVC mode: pass the refresh_lst/gld/alt_frame flags to the |
748 | | // update_buffer_slot, this is needed for the GET_SVC_REF_FRAME_CONFIG api. |
749 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { |
750 | 0 | int ref; |
751 | 0 | for (ref = 0; ref < REF_FRAMES; ++ref) { |
752 | 0 | svc->update_buffer_slot[sl] &= ~(1 << ref); |
753 | 0 | if ((ref == svc->lst_fb_idx[sl] && cpi->refresh_last_frame) || |
754 | 0 | (ref == svc->gld_fb_idx[sl] && cpi->refresh_golden_frame) || |
755 | 0 | (ref == svc->alt_fb_idx[sl] && cpi->refresh_alt_ref_frame)) |
756 | 0 | svc->update_buffer_slot[sl] |= (1 << ref); |
757 | 0 | } |
758 | 0 | } |
759 | | |
760 | | // TODO(jianj): Remove these 3, deprecated. |
761 | 0 | svc->update_last[sl] = (uint8_t)cpi->refresh_last_frame; |
762 | 0 | svc->update_golden[sl] = (uint8_t)cpi->refresh_golden_frame; |
763 | 0 | svc->update_altref[sl] = (uint8_t)cpi->refresh_alt_ref_frame; |
764 | |
|
765 | 0 | svc->reference_last[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_LAST_FLAG); |
766 | 0 | svc->reference_golden[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_GOLD_FLAG); |
767 | 0 | svc->reference_altref[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_ALT_FLAG); |
768 | 0 | } |
769 | | |
770 | 0 | int vp9_one_pass_svc_start_layer(VP9_COMP *const cpi) { |
771 | 0 | int width = 0, height = 0; |
772 | 0 | SVC *const svc = &cpi->svc; |
773 | 0 | LAYER_CONTEXT *lc = NULL; |
774 | 0 | int scaling_factor_num = 1; |
775 | 0 | int scaling_factor_den = 1; |
776 | 0 | svc->skip_enhancement_layer = 0; |
777 | |
|
778 | 0 | if (svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF && |
779 | 0 | svc->number_spatial_layers > 1 && svc->number_spatial_layers <= 3 && |
780 | 0 | svc->number_temporal_layers <= 3) |
781 | 0 | svc->simulcast_mode = 1; |
782 | 0 | else |
783 | 0 | svc->simulcast_mode = 0; |
784 | |
|
785 | 0 | if (svc->number_spatial_layers > 1) { |
786 | 0 | svc->use_base_mv = 1; |
787 | 0 | svc->use_partition_reuse = 1; |
788 | 0 | } |
789 | 0 | svc->force_zero_mode_spatial_ref = 1; |
790 | 0 | svc->mi_stride[svc->spatial_layer_id] = cpi->common.mi_stride; |
791 | 0 | svc->mi_rows[svc->spatial_layer_id] = cpi->common.mi_rows; |
792 | 0 | svc->mi_cols[svc->spatial_layer_id] = cpi->common.mi_cols; |
793 | | |
794 | | // For constrained_from_above drop mode: before encoding superframe (i.e., |
795 | | // at SL0 frame) check all spatial layers (starting from top) for possible |
796 | | // drop, and if so, set a flag to force drop of that layer and all its lower |
797 | | // layers. |
798 | 0 | if (svc->spatial_layer_to_encode == svc->first_spatial_layer_to_encode) { |
799 | 0 | int sl; |
800 | 0 | for (sl = 0; sl < svc->number_spatial_layers; sl++) |
801 | 0 | svc->force_drop_constrained_from_above[sl] = 0; |
802 | 0 | if (svc->framedrop_mode == CONSTRAINED_FROM_ABOVE_DROP) { |
803 | 0 | for (sl = svc->number_spatial_layers - 1; |
804 | 0 | sl >= svc->first_spatial_layer_to_encode; sl--) { |
805 | 0 | int layer = sl * svc->number_temporal_layers + svc->temporal_layer_id; |
806 | 0 | LAYER_CONTEXT *const sl_lc = &svc->layer_context[layer]; |
807 | 0 | cpi->rc = sl_lc->rc; |
808 | 0 | cpi->oxcf.target_bandwidth = sl_lc->target_bandwidth; |
809 | 0 | if (vp9_test_drop(cpi)) { |
810 | 0 | int sl2; |
811 | | // Set flag to force drop in encoding for this mode. |
812 | 0 | for (sl2 = sl; sl2 >= svc->first_spatial_layer_to_encode; sl2--) |
813 | 0 | svc->force_drop_constrained_from_above[sl2] = 1; |
814 | 0 | break; |
815 | 0 | } |
816 | 0 | } |
817 | 0 | } |
818 | 0 | } |
819 | |
|
820 | 0 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { |
821 | 0 | set_flags_and_fb_idx_for_temporal_mode3(cpi); |
822 | 0 | } else if (svc->temporal_layering_mode == |
823 | 0 | VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { |
824 | 0 | set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi); |
825 | 0 | } else if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0101) { |
826 | 0 | set_flags_and_fb_idx_for_temporal_mode2(cpi); |
827 | 0 | } else if (svc->temporal_layering_mode == |
828 | 0 | VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
829 | 0 | svc->use_set_ref_frame_config) { |
830 | 0 | set_flags_and_fb_idx_bypass_via_set_ref_frame_config(cpi); |
831 | 0 | } |
832 | |
|
833 | 0 | if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[0].idx || |
834 | 0 | cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[0].idx || |
835 | 0 | cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[0].idx) |
836 | 0 | svc->buffer_gf_temporal_ref[0].is_used = 1; |
837 | 0 | if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[1].idx || |
838 | 0 | cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[1].idx || |
839 | 0 | cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[1].idx) |
840 | 0 | svc->buffer_gf_temporal_ref[1].is_used = 1; |
841 | | |
842 | | // For the fixed (non-flexible/bypass) SVC mode: |
843 | | // If long term temporal reference is enabled at the sequence level |
844 | | // (use_gf_temporal_ref == 1), and inter_layer is disabled (on inter-frames), |
845 | | // we can use golden as a second temporal reference |
846 | | // (since the spatial/inter-layer reference is disabled). |
847 | | // We check that the fb_idx for this reference (buffer_gf_temporal_ref.idx) is |
848 | | // unused (slot 7 and 6 should be available for 3-3 layer system). |
849 | | // For now usage of this second temporal reference will only be used for |
850 | | // highest and next to highest spatial layer (i.e., top and middle layer for |
851 | | // 3 spatial layers). |
852 | 0 | svc->use_gf_temporal_ref_current_layer = 0; |
853 | 0 | if (svc->use_gf_temporal_ref && !svc->buffer_gf_temporal_ref[0].is_used && |
854 | 0 | !svc->buffer_gf_temporal_ref[1].is_used && |
855 | 0 | svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
856 | 0 | svc->disable_inter_layer_pred != INTER_LAYER_PRED_ON && |
857 | 0 | svc->number_spatial_layers <= 3 && svc->number_temporal_layers <= 3 && |
858 | 0 | svc->spatial_layer_id >= svc->number_spatial_layers - 2) { |
859 | | // Enable the second (long-term) temporal reference at the frame-level. |
860 | 0 | svc->use_gf_temporal_ref_current_layer = 1; |
861 | 0 | } |
862 | | |
863 | | // Check if current superframe has any layer sync, only check once on |
864 | | // base layer. |
865 | 0 | if (svc->spatial_layer_id == 0) { |
866 | 0 | int sl = 0; |
867 | | // Default is no sync. |
868 | 0 | svc->superframe_has_layer_sync = 0; |
869 | 0 | for (sl = 0; sl < svc->number_spatial_layers; ++sl) { |
870 | 0 | if (cpi->svc.spatial_layer_sync[sl]) svc->superframe_has_layer_sync = 1; |
871 | 0 | } |
872 | 0 | } |
873 | | |
874 | | // Reset the drop flags for all spatial layers, on the |
875 | | // first_spatial_layer_to_encode. |
876 | 0 | if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) { |
877 | 0 | vp9_zero(svc->drop_spatial_layer); |
878 | | // TODO(jianj/marpan): Investigate why setting svc->lst/gld/alt_fb_idx |
879 | | // causes an issue with frame dropping and temporal layers, when the frame |
880 | | // flags are passed via the encode call (bypass mode). Issue is that we're |
881 | | // resetting ext_refresh_frame_flags_pending to 0 on frame drops. |
882 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { |
883 | 0 | memset(&svc->lst_fb_idx, -1, sizeof(svc->lst_fb_idx)); |
884 | 0 | memset(&svc->gld_fb_idx, -1, sizeof(svc->lst_fb_idx)); |
885 | 0 | memset(&svc->alt_fb_idx, -1, sizeof(svc->lst_fb_idx)); |
886 | | // These are set by API before the superframe is encoded and they are |
887 | | // passed to encoder layer by layer. Don't reset them on layer 0 in bypass |
888 | | // mode. |
889 | 0 | vp9_zero(svc->update_buffer_slot); |
890 | 0 | vp9_zero(svc->reference_last); |
891 | 0 | vp9_zero(svc->reference_golden); |
892 | 0 | vp9_zero(svc->reference_altref); |
893 | | // TODO(jianj): Remove these 3, deprecated. |
894 | 0 | vp9_zero(svc->update_last); |
895 | 0 | vp9_zero(svc->update_golden); |
896 | 0 | vp9_zero(svc->update_altref); |
897 | 0 | } |
898 | 0 | } |
899 | |
|
900 | 0 | lc = &svc->layer_context[svc->spatial_layer_id * svc->number_temporal_layers + |
901 | 0 | svc->temporal_layer_id]; |
902 | | |
903 | | // Setting the worst/best_quality via the encoder control: SET_SVC_PARAMETERS, |
904 | | // only for non-BYPASS mode for now. |
905 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS || |
906 | 0 | svc->use_set_ref_frame_config) { |
907 | 0 | RATE_CONTROL *const lrc = &lc->rc; |
908 | 0 | lrc->worst_quality = vp9_quantizer_to_qindex(lc->max_q); |
909 | 0 | lrc->best_quality = vp9_quantizer_to_qindex(lc->min_q); |
910 | 0 | if (cpi->fixed_qp_onepass) { |
911 | 0 | lrc->worst_quality = cpi->rc.worst_quality; |
912 | 0 | lrc->best_quality = cpi->rc.best_quality; |
913 | 0 | } |
914 | 0 | } |
915 | |
|
916 | 0 | if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 && |
917 | 0 | svc->spatial_layer_id == svc->first_spatial_layer_to_encode && |
918 | 0 | cpi->resize_state != ORIG) { |
919 | 0 | scaling_factor_num = lc->scaling_factor_num_resize; |
920 | 0 | scaling_factor_den = lc->scaling_factor_den_resize; |
921 | 0 | } else { |
922 | 0 | scaling_factor_num = lc->scaling_factor_num; |
923 | 0 | scaling_factor_den = lc->scaling_factor_den; |
924 | 0 | } |
925 | |
|
926 | 0 | get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height, scaling_factor_num, |
927 | 0 | scaling_factor_den, &width, &height); |
928 | | |
929 | | // Use Eightap_smooth for low resolutions. |
930 | 0 | if (width * height <= 320 * 240) |
931 | 0 | svc->downsample_filter_type[svc->spatial_layer_id] = EIGHTTAP_SMOOTH; |
932 | | // For scale factors > 0.75, set the phase to 0 (aligns decimated pixel |
933 | | // to source pixel). |
934 | 0 | if (scaling_factor_num > (3 * scaling_factor_den) >> 2) |
935 | 0 | svc->downsample_filter_phase[svc->spatial_layer_id] = 0; |
936 | | |
937 | | // The usage of use_base_mv or partition_reuse assumes down-scale of 2x2. |
938 | | // For now, turn off use of base motion vectors and partition reuse if the |
939 | | // spatial scale factors for any layers are not 2, |
940 | | // keep the case of 3 spatial layers with scale factor of 4x4 for base layer. |
941 | | // TODO(marpan): Fix this to allow for use_base_mv for scale factors != 2. |
942 | 0 | if (svc->number_spatial_layers > 1) { |
943 | 0 | int sl; |
944 | 0 | for (sl = 0; sl < svc->number_spatial_layers - 1; ++sl) { |
945 | 0 | lc = &svc->layer_context[sl * svc->number_temporal_layers + |
946 | 0 | svc->temporal_layer_id]; |
947 | 0 | if ((lc->scaling_factor_num != lc->scaling_factor_den >> 1) && |
948 | 0 | !(lc->scaling_factor_num == lc->scaling_factor_den >> 2 && sl == 0 && |
949 | 0 | svc->number_spatial_layers == 3)) { |
950 | 0 | svc->use_base_mv = 0; |
951 | 0 | svc->use_partition_reuse = 0; |
952 | 0 | break; |
953 | 0 | } |
954 | 0 | } |
955 | | // For non-zero spatial layers: if the previous spatial layer was dropped |
956 | | // disable the base_mv and partition_reuse features. |
957 | 0 | if (svc->spatial_layer_id > 0 && |
958 | 0 | svc->drop_spatial_layer[svc->spatial_layer_id - 1]) { |
959 | 0 | svc->use_base_mv = 0; |
960 | 0 | svc->use_partition_reuse = 0; |
961 | 0 | } |
962 | 0 | } |
963 | |
|
964 | 0 | svc->non_reference_frame = 0; |
965 | 0 | if (cpi->common.frame_type != KEY_FRAME && !cpi->ext_refresh_last_frame && |
966 | 0 | !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame) |
967 | 0 | svc->non_reference_frame = 1; |
968 | | // For flexible mode, where update_buffer_slot is used, need to check if |
969 | | // all buffer slots are not refreshed. |
970 | 0 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { |
971 | 0 | if (svc->update_buffer_slot[svc->spatial_layer_id] != 0) |
972 | 0 | svc->non_reference_frame = 0; |
973 | 0 | } |
974 | |
|
975 | 0 | if (svc->spatial_layer_id == 0) { |
976 | 0 | svc->high_source_sad_superframe = 0; |
977 | 0 | svc->high_num_blocks_with_motion = 0; |
978 | 0 | } |
979 | |
|
980 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
981 | 0 | svc->last_layer_dropped[svc->spatial_layer_id] && |
982 | 0 | svc->fb_idx_upd_tl0[svc->spatial_layer_id] != -1 && |
983 | 0 | !svc->layer_context[svc->temporal_layer_id].is_key_frame) { |
984 | | // For fixed/non-flexible mode, if the previous frame (same spatial layer |
985 | | // from previous superframe) was dropped, make sure the lst_fb_idx |
986 | | // for this frame corresponds to the buffer index updated on (last) encoded |
987 | | // TL0 frame (with same spatial layer). |
988 | 0 | cpi->lst_fb_idx = svc->fb_idx_upd_tl0[svc->spatial_layer_id]; |
989 | 0 | } |
990 | |
|
991 | 0 | if (vp9_set_size_literal(cpi, width, height) != 0) |
992 | 0 | return VPX_CODEC_INVALID_PARAM; |
993 | | |
994 | 0 | return 0; |
995 | 0 | } |
996 | | |
997 | | struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, |
998 | | struct lookahead_ctx *ctx, |
999 | 0 | int drain) { |
1000 | 0 | struct lookahead_entry *buf = NULL; |
1001 | 0 | if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { |
1002 | 0 | buf = vp9_lookahead_peek(ctx, 0); |
1003 | 0 | if (buf != NULL) { |
1004 | | // Only remove the buffer when pop the highest layer. |
1005 | 0 | if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { |
1006 | 0 | vp9_lookahead_pop(ctx, drain); |
1007 | 0 | } |
1008 | 0 | } |
1009 | 0 | } |
1010 | 0 | return buf; |
1011 | 0 | } |
1012 | | |
1013 | 2.98k | void vp9_free_svc_cyclic_refresh(VP9_COMP *const cpi) { |
1014 | 2.98k | int sl, tl; |
1015 | 2.98k | SVC *const svc = &cpi->svc; |
1016 | 2.98k | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
1017 | 5.96k | for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { |
1018 | 5.96k | for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { |
1019 | 2.98k | int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); |
1020 | 2.98k | LAYER_CONTEXT *const lc = &svc->layer_context[layer]; |
1021 | 2.98k | if (lc->map) vpx_free(lc->map); |
1022 | 2.98k | if (lc->last_coded_q_map) vpx_free(lc->last_coded_q_map); |
1023 | 2.98k | if (lc->consec_zero_mv) vpx_free(lc->consec_zero_mv); |
1024 | 2.98k | } |
1025 | 2.98k | } |
1026 | 2.98k | } |
1027 | | |
1028 | | // Reset on key frame: reset counters, references and buffer updates. |
1029 | 0 | void vp9_svc_reset_temporal_layers(VP9_COMP *const cpi, int is_key) { |
1030 | 0 | int sl, tl; |
1031 | 0 | SVC *const svc = &cpi->svc; |
1032 | 0 | LAYER_CONTEXT *lc = NULL; |
1033 | 0 | for (sl = 0; sl < svc->number_spatial_layers; ++sl) { |
1034 | 0 | for (tl = 0; tl < svc->number_temporal_layers; ++tl) { |
1035 | 0 | lc = &cpi->svc.layer_context[sl * svc->number_temporal_layers + tl]; |
1036 | 0 | lc->current_video_frame_in_layer = 0; |
1037 | 0 | if (is_key) lc->frames_from_key_frame = 0; |
1038 | 0 | } |
1039 | 0 | } |
1040 | 0 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { |
1041 | 0 | set_flags_and_fb_idx_for_temporal_mode3(cpi); |
1042 | 0 | } else if (svc->temporal_layering_mode == |
1043 | 0 | VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { |
1044 | 0 | set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi); |
1045 | 0 | } else if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0101) { |
1046 | 0 | set_flags_and_fb_idx_for_temporal_mode2(cpi); |
1047 | 0 | } |
1048 | 0 | vp9_update_temporal_layer_framerate(cpi); |
1049 | 0 | vp9_restore_layer_context(cpi); |
1050 | 0 | } |
1051 | | |
1052 | 0 | void vp9_svc_check_reset_layer_rc_flag(VP9_COMP *const cpi) { |
1053 | 0 | SVC *svc = &cpi->svc; |
1054 | 0 | int sl, tl; |
1055 | 0 | for (sl = 0; sl < svc->number_spatial_layers; ++sl) { |
1056 | | // Check for reset based on avg_frame_bandwidth for spatial layer sl. |
1057 | 0 | const int spatial_layer_idx = LAYER_IDS_TO_IDX( |
1058 | 0 | sl, svc->number_temporal_layers - 1, svc->number_temporal_layers); |
1059 | 0 | LAYER_CONTEXT *lc = &svc->layer_context[spatial_layer_idx]; |
1060 | 0 | RATE_CONTROL *lrc = &lc->rc; |
1061 | 0 | if (lrc->avg_frame_bandwidth > (3 * lrc->last_avg_frame_bandwidth >> 1) || |
1062 | 0 | lrc->avg_frame_bandwidth < (lrc->last_avg_frame_bandwidth >> 1)) { |
1063 | | // Reset for all temporal layers with spatial layer sl. |
1064 | 0 | for (tl = 0; tl < svc->number_temporal_layers; ++tl) { |
1065 | 0 | int temporal_layer_idx = |
1066 | 0 | LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); |
1067 | 0 | lrc = &svc->layer_context[temporal_layer_idx].rc; |
1068 | 0 | lrc->rc_1_frame = 0; |
1069 | 0 | lrc->rc_2_frame = 0; |
1070 | 0 | lrc->bits_off_target = lrc->optimal_buffer_level; |
1071 | 0 | lrc->buffer_level = lrc->optimal_buffer_level; |
1072 | 0 | } |
1073 | 0 | } |
1074 | 0 | } |
1075 | 0 | } |
1076 | | |
1077 | 0 | void vp9_svc_constrain_inter_layer_pred(VP9_COMP *const cpi) { |
1078 | 0 | VP9_COMMON *const cm = &cpi->common; |
1079 | 0 | SVC *const svc = &cpi->svc; |
1080 | 0 | const int sl = svc->spatial_layer_id; |
1081 | | // Check for disabling inter-layer (spatial) prediction, if |
1082 | | // svc.disable_inter_layer_pred is set. If the previous spatial layer was |
1083 | | // dropped then disable the prediction from this (scaled) reference. |
1084 | | // For INTER_LAYER_PRED_OFF_NONKEY: inter-layer prediction is disabled |
1085 | | // on key frames or if any spatial layer is a sync layer. |
1086 | 0 | if ((svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY && |
1087 | 0 | !svc->layer_context[svc->temporal_layer_id].is_key_frame && |
1088 | 0 | !svc->superframe_has_layer_sync) || |
1089 | 0 | svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF || |
1090 | 0 | svc->drop_spatial_layer[sl - 1]) { |
1091 | 0 | MV_REFERENCE_FRAME ref_frame; |
1092 | 0 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { |
1093 | 0 | const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); |
1094 | 0 | if (yv12 != NULL && |
1095 | 0 | (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) { |
1096 | 0 | const struct scale_factors *const scale_fac = |
1097 | 0 | &cm->frame_refs[ref_frame - 1].sf; |
1098 | 0 | if (vp9_is_scaled(scale_fac)) { |
1099 | 0 | cpi->ref_frame_flags &= (~ref_frame_to_flag(ref_frame)); |
1100 | | // Point golden/altref frame buffer index to last. |
1101 | 0 | if (!svc->simulcast_mode) { |
1102 | 0 | if (ref_frame == GOLDEN_FRAME) |
1103 | 0 | cpi->gld_fb_idx = cpi->lst_fb_idx; |
1104 | 0 | else if (ref_frame == ALTREF_FRAME) |
1105 | 0 | cpi->alt_fb_idx = cpi->lst_fb_idx; |
1106 | 0 | } |
1107 | 0 | } |
1108 | 0 | } |
1109 | 0 | } |
1110 | 0 | } |
1111 | | // For fixed/non-flexible SVC: check for disabling inter-layer prediction. |
1112 | | // If the reference for inter-layer prediction (the reference that is scaled) |
1113 | | // is not the previous spatial layer from the same superframe, then we disable |
1114 | | // inter-layer prediction. Only need to check when inter_layer prediction is |
1115 | | // not set to OFF mode. |
1116 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
1117 | 0 | svc->disable_inter_layer_pred != INTER_LAYER_PRED_OFF) { |
1118 | | // We only use LAST and GOLDEN for prediction in real-time mode, so we |
1119 | | // check both here. |
1120 | 0 | MV_REFERENCE_FRAME ref_frame; |
1121 | 0 | for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ref_frame++) { |
1122 | 0 | struct scale_factors *scale_fac = &cm->frame_refs[ref_frame - 1].sf; |
1123 | 0 | if (vp9_is_scaled(scale_fac)) { |
1124 | | // If this reference was updated on the previous spatial layer of the |
1125 | | // current superframe, then we keep this reference (don't disable). |
1126 | | // Otherwise we disable the inter-layer prediction. |
1127 | | // This condition is verified by checking if the current frame buffer |
1128 | | // index is equal to any of the slots for the previous spatial layer, |
1129 | | // and if so, check if that slot was updated/refreshed. If that is the |
1130 | | // case, then this reference is valid for inter-layer prediction under |
1131 | | // the mode INTER_LAYER_PRED_ON_CONSTRAINED. |
1132 | 0 | int fb_idx = |
1133 | 0 | ref_frame == LAST_FRAME ? cpi->lst_fb_idx : cpi->gld_fb_idx; |
1134 | 0 | int ref_flag = ref_frame == LAST_FRAME ? VP9_LAST_FLAG : VP9_GOLD_FLAG; |
1135 | 0 | int disable = 1; |
1136 | 0 | if (fb_idx < 0) continue; |
1137 | 0 | if ((fb_idx == svc->lst_fb_idx[sl - 1] && |
1138 | 0 | (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) || |
1139 | 0 | (fb_idx == svc->gld_fb_idx[sl - 1] && |
1140 | 0 | (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) || |
1141 | 0 | (fb_idx == svc->alt_fb_idx[sl - 1] && |
1142 | 0 | (svc->update_buffer_slot[sl - 1] & (1 << fb_idx)))) |
1143 | 0 | disable = 0; |
1144 | 0 | if (disable) cpi->ref_frame_flags &= (~ref_flag); |
1145 | 0 | } |
1146 | 0 | } |
1147 | 0 | } |
1148 | 0 | } |
1149 | | |
1150 | 0 | void vp9_svc_assert_constraints_pattern(VP9_COMP *const cpi) { |
1151 | 0 | SVC *const svc = &cpi->svc; |
1152 | | // For fixed/non-flexible mode, the following constraint are expected, |
1153 | | // when inter-layer prediction is on (default). |
1154 | 0 | if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
1155 | 0 | svc->disable_inter_layer_pred == INTER_LAYER_PRED_ON && |
1156 | 0 | svc->framedrop_mode != LAYER_DROP) { |
1157 | 0 | if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) { |
1158 | | // On non-key frames: LAST is always temporal reference, GOLDEN is |
1159 | | // spatial reference. |
1160 | 0 | if (svc->temporal_layer_id == 0) |
1161 | | // Base temporal only predicts from base temporal. |
1162 | 0 | assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] == 0); |
1163 | 0 | else |
1164 | | // Non-base temporal only predicts from lower temporal layer. |
1165 | 0 | assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] < |
1166 | 0 | svc->temporal_layer_id); |
1167 | 0 | if (svc->spatial_layer_id > 0 && cpi->ref_frame_flags & VP9_GOLD_FLAG && |
1168 | 0 | svc->spatial_layer_id > svc->first_spatial_layer_to_encode) { |
1169 | | // Non-base spatial only predicts from lower spatial layer with same |
1170 | | // temporal_id. |
1171 | 0 | assert(svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] == |
1172 | 0 | svc->spatial_layer_id - 1); |
1173 | 0 | assert(svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] == |
1174 | 0 | svc->temporal_layer_id); |
1175 | 0 | } |
1176 | 0 | } else if (svc->spatial_layer_id > 0 && |
1177 | 0 | svc->spatial_layer_id > svc->first_spatial_layer_to_encode) { |
1178 | | // Only 1 reference for frame whose base is key; reference may be LAST |
1179 | | // or GOLDEN, so we check both. |
1180 | 0 | if (cpi->ref_frame_flags & VP9_LAST_FLAG) { |
1181 | 0 | assert(svc->fb_idx_spatial_layer_id[cpi->lst_fb_idx] == |
1182 | 0 | svc->spatial_layer_id - 1); |
1183 | 0 | assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] == |
1184 | 0 | svc->temporal_layer_id); |
1185 | 0 | } else if (cpi->ref_frame_flags & VP9_GOLD_FLAG) { |
1186 | 0 | assert(svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] == |
1187 | 0 | svc->spatial_layer_id - 1); |
1188 | 0 | assert(svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] == |
1189 | 0 | svc->temporal_layer_id); |
1190 | 0 | } |
1191 | 0 | } |
1192 | 0 | } else if (svc->use_gf_temporal_ref_current_layer && |
1193 | 0 | !svc->layer_context[svc->temporal_layer_id].is_key_frame) { |
1194 | | // For the usage of golden as second long term reference: the |
1195 | | // temporal_layer_id of that reference must be base temporal layer 0, and |
1196 | | // spatial_layer_id of that reference must be same as current |
1197 | | // spatial_layer_id. If not, disable feature. |
1198 | | // TODO(marpan): Investigate when this can happen, and maybe put this check |
1199 | | // and reset in a different place. |
1200 | 0 | if (svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] != |
1201 | 0 | svc->spatial_layer_id || |
1202 | 0 | svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] != 0) |
1203 | 0 | svc->use_gf_temporal_ref_current_layer = 0; |
1204 | 0 | } |
1205 | 0 | } |
1206 | | |
1207 | | #if CONFIG_VP9_TEMPORAL_DENOISING |
1208 | | int vp9_denoise_svc_non_key(VP9_COMP *const cpi) { |
1209 | | int layer = |
1210 | | LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id, cpi->svc.temporal_layer_id, |
1211 | | cpi->svc.number_temporal_layers); |
1212 | | LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; |
1213 | | return denoise_svc(cpi) && !lc->is_key_frame; |
1214 | | } |
1215 | | #endif |
1216 | | |
1217 | 0 | void vp9_svc_check_spatial_layer_sync(VP9_COMP *const cpi) { |
1218 | 0 | SVC *const svc = &cpi->svc; |
1219 | | // Only for superframes whose base is not key, as those are |
1220 | | // already sync frames. |
1221 | 0 | if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) { |
1222 | 0 | if (svc->spatial_layer_id == 0) { |
1223 | | // On base spatial layer: if the current superframe has a layer sync then |
1224 | | // reset the pattern counters and reset to base temporal layer. |
1225 | 0 | if (svc->superframe_has_layer_sync) |
1226 | 0 | vp9_svc_reset_temporal_layers(cpi, cpi->common.frame_type == KEY_FRAME); |
1227 | 0 | } |
1228 | | // If the layer sync is set for this current spatial layer then |
1229 | | // disable the temporal reference. |
1230 | 0 | if (svc->spatial_layer_id > 0 && |
1231 | 0 | svc->spatial_layer_sync[svc->spatial_layer_id]) { |
1232 | 0 | cpi->ref_frame_flags &= (~VP9_LAST_FLAG); |
1233 | 0 | if (svc->use_gf_temporal_ref_current_layer) { |
1234 | 0 | int index = svc->spatial_layer_id; |
1235 | | // If golden is used as second reference: need to remove it from |
1236 | | // prediction, reset refresh period to 0, and update the reference. |
1237 | 0 | svc->use_gf_temporal_ref_current_layer = 0; |
1238 | 0 | cpi->rc.baseline_gf_interval = 0; |
1239 | 0 | cpi->rc.frames_till_gf_update_due = 0; |
1240 | | // On layer sync frame we must update the buffer index used for long |
1241 | | // term reference. Use the alt_ref since it is not used or updated on |
1242 | | // sync frames. |
1243 | 0 | if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1; |
1244 | 0 | assert(index >= 0); |
1245 | 0 | cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx; |
1246 | 0 | cpi->ext_refresh_alt_ref_frame = 1; |
1247 | 0 | } |
1248 | 0 | } |
1249 | 0 | } |
1250 | 0 | } |
1251 | | |
1252 | 0 | void vp9_svc_update_ref_frame_buffer_idx(VP9_COMP *const cpi) { |
1253 | 0 | SVC *const svc = &cpi->svc; |
1254 | 0 | int i = 0; |
1255 | | // Update the usage of frame buffer index for base spatial layers. |
1256 | 0 | if (svc->spatial_layer_id == 0) { |
1257 | 0 | if ((cpi->ref_frame_flags & VP9_LAST_FLAG) || cpi->refresh_last_frame) |
1258 | 0 | svc->fb_idx_base[cpi->lst_fb_idx] = 1; |
1259 | 0 | if ((cpi->ref_frame_flags & VP9_GOLD_FLAG) || cpi->refresh_golden_frame) |
1260 | 0 | svc->fb_idx_base[cpi->gld_fb_idx] = 1; |
1261 | 0 | if ((cpi->ref_frame_flags & VP9_ALT_FLAG) || cpi->refresh_alt_ref_frame) |
1262 | 0 | svc->fb_idx_base[cpi->alt_fb_idx] = 1; |
1263 | | // For bypass/flexible mode: check for refresh slots. |
1264 | 0 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { |
1265 | 0 | for (i = 0; i < REF_FRAMES; ++i) |
1266 | 0 | if (svc->update_buffer_slot[0] & (1 << i)) svc->fb_idx_base[i] = 1; |
1267 | 0 | } |
1268 | 0 | } |
1269 | 0 | } |
1270 | | |
1271 | 0 | static void vp9_svc_update_ref_frame_bypass_mode(VP9_COMP *const cpi) { |
1272 | | // For non-flexible/bypass SVC mode: check for refreshing other buffer |
1273 | | // slots. |
1274 | 0 | SVC *const svc = &cpi->svc; |
1275 | 0 | VP9_COMMON *const cm = &cpi->common; |
1276 | 0 | BufferPool *const pool = cm->buffer_pool; |
1277 | 0 | int i; |
1278 | 0 | for (i = 0; i < REF_FRAMES; i++) { |
1279 | 0 | if ((cm->frame_type == KEY_FRAME && !svc->simulcast_mode) || |
1280 | 0 | svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) { |
1281 | 0 | ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx); |
1282 | 0 | svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id; |
1283 | 0 | svc->fb_idx_temporal_layer_id[i] = svc->temporal_layer_id; |
1284 | 0 | } |
1285 | 0 | } |
1286 | 0 | } |
1287 | | |
1288 | 0 | void vp9_svc_update_ref_frame(VP9_COMP *const cpi) { |
1289 | 0 | VP9_COMMON *const cm = &cpi->common; |
1290 | 0 | SVC *const svc = &cpi->svc; |
1291 | 0 | BufferPool *const pool = cm->buffer_pool; |
1292 | |
|
1293 | 0 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS && |
1294 | 0 | svc->use_set_ref_frame_config) { |
1295 | 0 | vp9_svc_update_ref_frame_bypass_mode(cpi); |
1296 | 0 | } else if (cm->frame_type == KEY_FRAME && !svc->simulcast_mode) { |
1297 | | // Keep track of frame index for each reference frame. |
1298 | 0 | int i; |
1299 | | // On key frame update all reference frame slots. |
1300 | 0 | for (i = 0; i < REF_FRAMES; i++) { |
1301 | 0 | svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id; |
1302 | 0 | svc->fb_idx_temporal_layer_id[i] = svc->temporal_layer_id; |
1303 | | // LAST/GOLDEN/ALTREF is already updated above. |
1304 | 0 | if (i != cpi->lst_fb_idx && i != cpi->gld_fb_idx && i != cpi->alt_fb_idx) |
1305 | 0 | ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx); |
1306 | 0 | } |
1307 | 0 | } else { |
1308 | 0 | if (cpi->refresh_last_frame) { |
1309 | 0 | svc->fb_idx_spatial_layer_id[cpi->lst_fb_idx] = svc->spatial_layer_id; |
1310 | 0 | svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] = svc->temporal_layer_id; |
1311 | 0 | } |
1312 | 0 | if (cpi->refresh_golden_frame) { |
1313 | 0 | svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] = svc->spatial_layer_id; |
1314 | 0 | svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] = svc->temporal_layer_id; |
1315 | 0 | } |
1316 | 0 | if (cpi->refresh_alt_ref_frame) { |
1317 | 0 | svc->fb_idx_spatial_layer_id[cpi->alt_fb_idx] = svc->spatial_layer_id; |
1318 | 0 | svc->fb_idx_temporal_layer_id[cpi->alt_fb_idx] = svc->temporal_layer_id; |
1319 | 0 | } |
1320 | 0 | } |
1321 | | // Copy flags from encoder to SVC struct. |
1322 | 0 | vp9_copy_flags_ref_update_idx(cpi); |
1323 | 0 | vp9_svc_update_ref_frame_buffer_idx(cpi); |
1324 | 0 | } |
1325 | | |
1326 | 0 | void vp9_svc_adjust_frame_rate(VP9_COMP *const cpi) { |
1327 | 0 | int64_t this_duration = |
1328 | 0 | cpi->svc.timebase_fac * cpi->svc.duration[cpi->svc.spatial_layer_id]; |
1329 | 0 | vp9_new_framerate(cpi, 10000000.0 / this_duration); |
1330 | 0 | } |
1331 | | |
1332 | 0 | void vp9_svc_adjust_avg_frame_qindex(VP9_COMP *const cpi) { |
1333 | 0 | VP9_COMMON *const cm = &cpi->common; |
1334 | 0 | SVC *const svc = &cpi->svc; |
1335 | 0 | RATE_CONTROL *const rc = &cpi->rc; |
1336 | | // On key frames in CBR mode: reset the avg_frame_index for base layer |
1337 | | // (to level closer to worst_quality) if the overshoot is significant. |
1338 | | // Reset it for all temporal layers on base spatial layer. |
1339 | 0 | if (cm->frame_type == KEY_FRAME && cpi->oxcf.rc_mode == VPX_CBR && |
1340 | 0 | !svc->simulcast_mode && |
1341 | 0 | rc->projected_frame_size / 3 > rc->avg_frame_bandwidth) { |
1342 | 0 | int tl; |
1343 | 0 | rc->avg_frame_qindex[INTER_FRAME] = |
1344 | 0 | VPXMAX(rc->avg_frame_qindex[INTER_FRAME], |
1345 | 0 | (cm->base_qindex + rc->worst_quality) >> 1); |
1346 | 0 | for (tl = 0; tl < svc->number_temporal_layers; ++tl) { |
1347 | 0 | const int layer = LAYER_IDS_TO_IDX(0, tl, svc->number_temporal_layers); |
1348 | 0 | LAYER_CONTEXT *lc = &svc->layer_context[layer]; |
1349 | 0 | RATE_CONTROL *lrc = &lc->rc; |
1350 | 0 | lrc->avg_frame_qindex[INTER_FRAME] = rc->avg_frame_qindex[INTER_FRAME]; |
1351 | 0 | } |
1352 | 0 | } |
1353 | 0 | } |
1354 | | |
1355 | | // SVC: skip encoding of enhancement layer if the layer target bandwidth = 0. |
1356 | | // No need to set svc.skip_enhancement_layer if whole superframe will be |
1357 | | // dropped. |
1358 | 42.2k | int vp9_svc_check_skip_enhancement_layer(VP9_COMP *const cpi) { |
1359 | 42.2k | if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 && |
1360 | 42.2k | cpi->oxcf.target_bandwidth == 0 && |
1361 | 42.2k | !(cpi->svc.framedrop_mode != LAYER_DROP && |
1362 | 0 | (cpi->svc.framedrop_mode != CONSTRAINED_FROM_ABOVE_DROP || |
1363 | 0 | cpi->svc |
1364 | 0 | .force_drop_constrained_from_above[cpi->svc.number_spatial_layers - |
1365 | 0 | 1]) && |
1366 | 0 | cpi->svc.drop_spatial_layer[0])) { |
1367 | 0 | cpi->svc.skip_enhancement_layer = 1; |
1368 | 0 | vp9_rc_postencode_update_drop_frame(cpi); |
1369 | 0 | cpi->ext_refresh_frame_flags_pending = 0; |
1370 | 0 | cpi->last_frame_dropped = 1; |
1371 | 0 | cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1; |
1372 | 0 | cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1; |
1373 | 0 | vp9_inc_frame_in_layer(cpi); |
1374 | 0 | return 1; |
1375 | 0 | } |
1376 | 42.2k | return 0; |
1377 | 42.2k | } |