• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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