1 /*
2 * Copyright (c) 2019, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <stdint.h>
13
14 #include "config/aom_config.h"
15 #include "config/aom_scale_rtcd.h"
16
17 #include "aom/aom_codec.h"
18 #include "aom/aom_encoder.h"
19
20 #include "aom_ports/system_state.h"
21
22 #include "av1/common/av1_common_int.h"
23
24 #include "av1/encoder/encoder.h"
25 #include "av1/encoder/firstpass.h"
26 #include "av1/encoder/gop_structure.h"
27
28 // Set parameters for frames between 'start' and 'end' (excluding both).
set_multi_layer_params(const TWO_PASS * twopass,GF_GROUP * const gf_group,RATE_CONTROL * rc,FRAME_INFO * frame_info,int start,int end,int * cur_frame_idx,int * frame_ind,int arf_ind,int layer_depth)29 static void set_multi_layer_params(const TWO_PASS *twopass,
30 GF_GROUP *const gf_group, RATE_CONTROL *rc,
31 FRAME_INFO *frame_info, int start, int end,
32 int *cur_frame_idx, int *frame_ind,
33 int arf_ind, int layer_depth) {
34 const int num_frames_to_process = end - start - 1;
35 assert(num_frames_to_process >= 0);
36 if (num_frames_to_process == 0) return;
37
38 // Either we are at the last level of the pyramid, or we don't have enough
39 // frames between 'l' and 'r' to create one more level.
40 if (layer_depth > gf_group->max_layer_depth_allowed ||
41 num_frames_to_process < 3) {
42 // Leaf nodes.
43 while (++start < end) {
44 gf_group->update_type[*frame_ind] = LF_UPDATE;
45 gf_group->arf_src_offset[*frame_ind] = 0;
46 ++*cur_frame_idx;
47 gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
48 gf_group->frame_disp_idx[*frame_ind] = start;
49 gf_group->layer_depth[*frame_ind] = MAX_ARF_LAYERS;
50 gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(
51 twopass, rc, frame_info, start, end - start, 0, NULL, NULL);
52 gf_group->max_layer_depth =
53 AOMMAX(gf_group->max_layer_depth, layer_depth);
54 ++(*frame_ind);
55 }
56 } else {
57 const int m = (start + end) / 2;
58
59 // Internal ARF.
60 gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
61 gf_group->arf_src_offset[*frame_ind] = m - start - 1;
62 gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
63 gf_group->frame_disp_idx[*frame_ind] = m;
64 gf_group->layer_depth[*frame_ind] = layer_depth;
65
66 // Get the boost factor for intermediate ARF frames.
67 gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(
68 twopass, rc, frame_info, m, end - m, m - start, NULL, NULL);
69 ++(*frame_ind);
70
71 // Frames displayed before this internal ARF.
72 set_multi_layer_params(twopass, gf_group, rc, frame_info, start, m,
73 cur_frame_idx, frame_ind, 1, layer_depth + 1);
74
75 // Overlay for internal ARF.
76 gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE;
77 gf_group->arf_src_offset[*frame_ind] = 0;
78 gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
79 gf_group->frame_disp_idx[*frame_ind] = m;
80 gf_group->arf_boost[*frame_ind] = 0;
81 gf_group->layer_depth[*frame_ind] = layer_depth;
82 ++(*frame_ind);
83
84 // Frames displayed after this internal ARF.
85 set_multi_layer_params(twopass, gf_group, rc, frame_info, m, end,
86 cur_frame_idx, frame_ind, arf_ind, layer_depth + 1);
87 }
88 }
89
construct_multi_layer_gf_structure(AV1_COMP * cpi,TWO_PASS * twopass,GF_GROUP * const gf_group,RATE_CONTROL * rc,FRAME_INFO * const frame_info,int gf_interval,FRAME_UPDATE_TYPE first_frame_update_type)90 static int construct_multi_layer_gf_structure(
91 AV1_COMP *cpi, TWO_PASS *twopass, GF_GROUP *const gf_group,
92 RATE_CONTROL *rc, FRAME_INFO *const frame_info, int gf_interval,
93 FRAME_UPDATE_TYPE first_frame_update_type) {
94 int frame_index = 0;
95
96 // Keyframe / Overlay frame / Golden frame.
97 assert(gf_interval >= 1);
98 assert(first_frame_update_type == KF_UPDATE ||
99 first_frame_update_type == OVERLAY_UPDATE ||
100 first_frame_update_type == GF_UPDATE);
101
102 gf_group->update_type[frame_index] = first_frame_update_type;
103 gf_group->arf_src_offset[frame_index] = 0;
104 gf_group->cur_frame_idx[frame_index] = 0;
105 gf_group->layer_depth[frame_index] =
106 first_frame_update_type == OVERLAY_UPDATE ? MAX_ARF_LAYERS + 1 : 0;
107 gf_group->max_layer_depth = 0;
108 ++frame_index;
109
110 // ALTREF.
111 const int use_altref = gf_group->max_layer_depth_allowed > 0;
112 if (use_altref) {
113 gf_group->update_type[frame_index] = ARF_UPDATE;
114 gf_group->arf_src_offset[frame_index] = gf_interval - 1;
115 gf_group->cur_frame_idx[frame_index] = 0;
116 gf_group->frame_disp_idx[frame_index] = gf_interval;
117 gf_group->layer_depth[frame_index] = 1;
118 gf_group->arf_boost[frame_index] = cpi->rc.gfu_boost;
119 gf_group->max_layer_depth = 1;
120 ++frame_index;
121 }
122
123 int cur_frame_index = 0;
124 // Rest of the frames.
125 set_multi_layer_params(twopass, gf_group, rc, frame_info, 0, gf_interval,
126 &cur_frame_index, &frame_index, 0, use_altref + 1);
127
128 // The end frame will be Overlay frame for an ARF GOP; otherwise set it to
129 // be GF, for consistency, which will be updated in the next GOP.
130 gf_group->update_type[frame_index] = use_altref ? OVERLAY_UPDATE : GF_UPDATE;
131 gf_group->arf_src_offset[frame_index] = 0;
132 return frame_index;
133 }
134
135 #define CHECK_GF_PARAMETER 0
136 #if CHECK_GF_PARAMETER
check_frame_params(GF_GROUP * const gf_group,int gf_interval)137 void check_frame_params(GF_GROUP *const gf_group, int gf_interval) {
138 static const char *update_type_strings[FRAME_UPDATE_TYPES] = {
139 "KF_UPDATE", "LF_UPDATE", "GF_UPDATE",
140 "ARF_UPDATE", "OVERLAY_UPDATE", "INTNL_OVERLAY_UPDATE",
141 "INTNL_ARF_UPDATE"
142 };
143 FILE *fid = fopen("GF_PARAMS.txt", "a");
144
145 fprintf(fid, "\ngf_interval = {%d}\n", gf_interval);
146 for (int i = 0; i < gf_group->size; ++i) {
147 fprintf(fid, "#%2d : %s %d %d %d %d\n", i,
148 update_type_strings[gf_group->update_type[i]],
149 gf_group->arf_src_offset[i], gf_group->arf_pos_in_gf[i],
150 gf_group->arf_update_idx[i], gf_group->pyramid_level[i]);
151 }
152
153 fprintf(fid, "number of nodes in each level: \n");
154 for (int i = 0; i < gf_group->pyramid_height; ++i) {
155 fprintf(fid, "lvl %d: %d ", i, gf_group->pyramid_lvl_nodes[i]);
156 }
157 fprintf(fid, "\n");
158 fclose(fid);
159 }
160 #endif // CHECK_GF_PARAMETER
161
162 #define REF_IDX(ref) ((ref)-LAST_FRAME)
163
reset_ref_frame_idx(int * ref_idx,int reset_value)164 static INLINE void reset_ref_frame_idx(int *ref_idx, int reset_value) {
165 for (int i = 0; i < REF_FRAMES; ++i) ref_idx[i] = reset_value;
166 }
167
set_ref_frame_disp_idx(GF_GROUP * const gf_group)168 static INLINE void set_ref_frame_disp_idx(GF_GROUP *const gf_group) {
169 for (int i = 0; i < gf_group->size; ++i) {
170 for (int ref = 0; ref < INTER_REFS_PER_FRAME + 1; ++ref) {
171 int ref_gop_idx = gf_group->ref_frame_gop_idx[i][ref];
172 if (ref_gop_idx == -1) {
173 gf_group->ref_frame_disp_idx[i][ref] = -1;
174 } else {
175 gf_group->ref_frame_disp_idx[i][ref] =
176 gf_group->frame_disp_idx[ref_gop_idx];
177 }
178 }
179 }
180 }
181
set_gop_ref_frame_map(GF_GROUP * const gf_group)182 static void set_gop_ref_frame_map(GF_GROUP *const gf_group) {
183 // Initialize the reference slots as all -1.
184 for (int frame_idx = 0; frame_idx < gf_group->size; ++frame_idx)
185 reset_ref_frame_idx(gf_group->ref_frame_gop_idx[frame_idx], -1);
186
187 // Set the map for frames in the current gop
188 for (int frame_idx = 0; frame_idx < gf_group->size; ++frame_idx) {
189 const FRAME_UPDATE_TYPE update_type = gf_group->update_type[frame_idx];
190 // TODO(yuec): need to figure out how to determine
191 // (1) whether a KEY_FRAME has show_frame on
192 // (2) whether a frame with INTNL_OVERLAY_UPDATE type has
193 // show_existing_frame on
194 const int show_frame =
195 update_type != ARF_UPDATE && update_type != INTNL_ARF_UPDATE;
196 const int show_existing_frame =
197 update_type == OVERLAY_UPDATE || update_type == INTNL_OVERLAY_UPDATE;
198
199 int this_ref_map[INTER_REFS_PER_FRAME + 1];
200 memcpy(this_ref_map, gf_group->ref_frame_gop_idx[frame_idx],
201 sizeof(this_ref_map));
202 int *next_ref_map = &gf_group->ref_frame_gop_idx[frame_idx + 1][0];
203
204 switch (update_type) {
205 case KF_UPDATE:
206 if (show_frame) {
207 reset_ref_frame_idx(this_ref_map, frame_idx);
208 } else {
209 this_ref_map[REF_IDX(LAST3_FRAME)] = frame_idx;
210 this_ref_map[REF_IDX(EXTREF_FRAME)] = frame_idx;
211 this_ref_map[REF_IDX(ALTREF2_FRAME)] = frame_idx;
212 this_ref_map[REF_IDX(GOLDEN_FRAME)] = frame_idx;
213 this_ref_map[REF_IDX(ALTREF_FRAME)] = frame_idx;
214 }
215 break;
216 case LF_UPDATE: this_ref_map[REF_IDX(LAST3_FRAME)] = frame_idx; break;
217 case GF_UPDATE:
218 this_ref_map[REF_IDX(LAST3_FRAME)] = frame_idx;
219 this_ref_map[REF_IDX(GOLDEN_FRAME)] = frame_idx;
220 break;
221 case OVERLAY_UPDATE:
222 this_ref_map[REF_IDX(ALTREF_FRAME)] = frame_idx;
223 break;
224 case ARF_UPDATE: this_ref_map[REF_IDX(ALTREF_FRAME)] = frame_idx; break;
225 case INTNL_OVERLAY_UPDATE:
226 if (!show_existing_frame)
227 this_ref_map[REF_IDX(LAST3_FRAME)] = frame_idx;
228 break;
229 case INTNL_ARF_UPDATE:
230 this_ref_map[REF_IDX(EXTREF_FRAME)] = frame_idx;
231 break;
232 default: assert(0); break;
233 }
234
235 memcpy(next_ref_map, this_ref_map, sizeof(this_ref_map));
236
237 switch (update_type) {
238 case LF_UPDATE:
239 case GF_UPDATE:
240 next_ref_map[REF_IDX(LAST3_FRAME)] = this_ref_map[REF_IDX(LAST2_FRAME)];
241 next_ref_map[REF_IDX(LAST2_FRAME)] = this_ref_map[REF_IDX(LAST_FRAME)];
242 next_ref_map[REF_IDX(LAST_FRAME)] = this_ref_map[REF_IDX(LAST3_FRAME)];
243 break;
244 case INTNL_OVERLAY_UPDATE:
245 if (!show_existing_frame) {
246 next_ref_map[REF_IDX(LAST3_FRAME)] =
247 this_ref_map[REF_IDX(LAST2_FRAME)];
248 next_ref_map[REF_IDX(LAST2_FRAME)] =
249 this_ref_map[REF_IDX(LAST_FRAME)];
250 next_ref_map[REF_IDX(LAST_FRAME)] =
251 this_ref_map[REF_IDX(LAST3_FRAME)];
252 } else {
253 next_ref_map[REF_IDX(LAST_FRAME)] =
254 this_ref_map[REF_IDX(BWDREF_FRAME)];
255 next_ref_map[REF_IDX(LAST2_FRAME)] =
256 this_ref_map[REF_IDX(LAST_FRAME)];
257 next_ref_map[REF_IDX(LAST3_FRAME)] =
258 this_ref_map[REF_IDX(LAST2_FRAME)];
259 next_ref_map[REF_IDX(BWDREF_FRAME)] =
260 this_ref_map[REF_IDX(ALTREF2_FRAME)];
261 next_ref_map[REF_IDX(ALTREF2_FRAME)] =
262 this_ref_map[REF_IDX(EXTREF_FRAME)];
263 next_ref_map[REF_IDX(EXTREF_FRAME)] =
264 this_ref_map[REF_IDX(LAST3_FRAME)];
265 }
266 break;
267 case INTNL_ARF_UPDATE:
268 if (!show_existing_frame) {
269 next_ref_map[REF_IDX(BWDREF_FRAME)] =
270 this_ref_map[REF_IDX(EXTREF_FRAME)];
271 next_ref_map[REF_IDX(ALTREF2_FRAME)] =
272 this_ref_map[REF_IDX(BWDREF_FRAME)];
273 next_ref_map[REF_IDX(EXTREF_FRAME)] =
274 this_ref_map[REF_IDX(ALTREF2_FRAME)];
275 }
276 break;
277 case OVERLAY_UPDATE:
278 next_ref_map[REF_IDX(ALTREF_FRAME)] =
279 this_ref_map[REF_IDX(GOLDEN_FRAME)];
280 next_ref_map[REF_IDX(GOLDEN_FRAME)] =
281 this_ref_map[REF_IDX(ALTREF_FRAME)];
282 break;
283 default: break;
284 }
285 }
286
287 // Set the map in display order index by converting from gop indices in the
288 // above map
289 set_ref_frame_disp_idx(gf_group);
290 }
291
av1_gop_setup_structure(AV1_COMP * cpi,const EncodeFrameParams * const frame_params)292 void av1_gop_setup_structure(AV1_COMP *cpi,
293 const EncodeFrameParams *const frame_params) {
294 RATE_CONTROL *const rc = &cpi->rc;
295 GF_GROUP *const gf_group = &cpi->gf_group;
296 TWO_PASS *const twopass = &cpi->twopass;
297 FRAME_INFO *const frame_info = &cpi->frame_info;
298 const int key_frame = (frame_params->frame_type == KEY_FRAME);
299 const FRAME_UPDATE_TYPE first_frame_update_type =
300 key_frame ? KF_UPDATE
301 : rc->source_alt_ref_active ? OVERLAY_UPDATE : GF_UPDATE;
302 gf_group->size = construct_multi_layer_gf_structure(
303 cpi, twopass, gf_group, rc, frame_info, rc->baseline_gf_interval,
304 first_frame_update_type);
305
306 set_gop_ref_frame_map(gf_group);
307
308 #if CHECK_GF_PARAMETER
309 check_frame_params(gf_group, rc->baseline_gf_interval);
310 #endif
311 }
312