1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5 
6 #include <stdlib.h>
7 #include <string.h>
8 
9 #include "EbDefinitions.h"
10 #include "EbUtility.h"
11 #include "EbPictureControlSet.h"
12 #include "EbSequenceControlSet.h"
13 
14 #include "EbPictureAnalysisResults.h"
15 #include "EbPictureDecisionProcess.h"
16 #include "EbPictureDecisionResults.h"
17 #include "EbReferenceObject.h"
18 #include "EbComputeSAD.h"
19 #include "EbMeSadCalculation.h"
20 
21 #include "EbSvtVp9ErrorCodes.h"
22 #include "vp9_pred_common.h"
23 
24 /************************************************
25  * Defines
26  ************************************************/
27 #define POC_CIRCULAR_ADD(base, offset/*, bits*/)             (/*(((int32_t) (base)) + ((int32_t) (offset)) > ((int32_t) (1 << (bits))))   ? ((base) + (offset) - (1 << (bits))) : \
28                                                              (((int32_t) (base)) + ((int32_t) (offset)) < 0)                           ? ((base) + (offset) + (1 << (bits))) : \
29                                                                                                                                        */((base) + (offset)))
30 #define FUTURE_WINDOW_WIDTH                 4
31 #define FLASH_TH                            5
32 #define FADE_TH                             3
33 #define SCENE_TH                            3000
34 #define NOISY_SCENE_TH                      4500    // SCD TH in presence of noise
35 #define HIGH_PICTURE_VARIANCE_TH            1500
36 #define NUM64x64INPIC(w,h)          ((w*h)>> (LOG2F(MAX_SB_SIZE)<<1))
37 #define QUEUE_GET_PREVIOUS_SPOT(h)  ((h == 0) ? PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH - 1 : h - 1)
38 #define QUEUE_GET_NEXT_SPOT(h,off)  (( (h+off) >= PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH) ? h+off - PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH  : h + off)
39 
40 #define WTH 64
41 #define OTH 64
42 
43 /************************************************
44  * Picture Analysis Context Constructor
45  ************************************************/
eb_vp9_picture_decision_context_ctor(PictureDecisionContext ** context_dbl_ptr,EbFifo * picture_analysis_results_input_fifo_ptr,EbFifo * picture_decision_results_output_fifo_ptr)46 EbErrorType eb_vp9_picture_decision_context_ctor(
47     PictureDecisionContext **context_dbl_ptr,
48     EbFifo                  *picture_analysis_results_input_fifo_ptr,
49     EbFifo                  *picture_decision_results_output_fifo_ptr)
50 {
51     PictureDecisionContext *context_ptr;
52     uint32_t array_index;
53     uint32_t array_row , arrow_column;
54     EB_MALLOC(PictureDecisionContext*, context_ptr, sizeof(PictureDecisionContext), EB_N_PTR);
55     *context_dbl_ptr = context_ptr;
56 
57     context_ptr->picture_analysis_results_input_fifo_ptr  = picture_analysis_results_input_fifo_ptr;
58     context_ptr->picture_decision_results_output_fifo_ptr = picture_decision_results_output_fifo_ptr;
59 
60     EB_MALLOC(uint32_t**, context_ptr->ahd_running_avg_cb, sizeof(uint32_t*) * MAX_NUMBER_OF_REGIONS_IN_WIDTH, EB_N_PTR);
61 
62     EB_MALLOC(uint32_t**, context_ptr->ahd_running_avg_cr, sizeof(uint32_t*) * MAX_NUMBER_OF_REGIONS_IN_WIDTH, EB_N_PTR);
63 
64     EB_MALLOC(uint32_t**, context_ptr->ahd_running_avg, sizeof(uint32_t*) * MAX_NUMBER_OF_REGIONS_IN_WIDTH, EB_N_PTR);
65 
66     for (array_index = 0; array_index < MAX_NUMBER_OF_REGIONS_IN_WIDTH; array_index++)
67     {
68         EB_MALLOC(uint32_t*, context_ptr->ahd_running_avg_cb[array_index], sizeof(uint32_t) * MAX_NUMBER_OF_REGIONS_IN_HEIGHT, EB_N_PTR);
69 
70         EB_MALLOC(uint32_t*, context_ptr->ahd_running_avg_cr[array_index], sizeof(uint32_t) * MAX_NUMBER_OF_REGIONS_IN_HEIGHT, EB_N_PTR);
71 
72         EB_MALLOC(uint32_t*, context_ptr->ahd_running_avg[array_index], sizeof(uint32_t) * MAX_NUMBER_OF_REGIONS_IN_HEIGHT, EB_N_PTR);
73     }
74 
75     for (array_row = 0; array_row < MAX_NUMBER_OF_REGIONS_IN_HEIGHT; array_row++)
76     {
77         for (arrow_column = 0; arrow_column < MAX_NUMBER_OF_REGIONS_IN_WIDTH; arrow_column++) {
78             context_ptr->ahd_running_avg_cb[arrow_column][array_row] = 0;
79             context_ptr->ahd_running_avg_cr[arrow_column][array_row] = 0;
80             context_ptr->ahd_running_avg[arrow_column][array_row] = 0;
81         }
82     }
83 
84     context_ptr->reset_running_avg = EB_TRUE;
85 
86     return EB_ErrorNone;
87 }
88 
eb_vp9_SceneTransitionDetector(PictureDecisionContext * context_ptr,SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet ** parent_pcs_window,uint32_t window_width_future)89 EB_BOOL eb_vp9_SceneTransitionDetector(
90     PictureDecisionContext   *context_ptr,
91     SequenceControlSet       *sequence_control_set_ptr,
92     PictureParentControlSet **parent_pcs_window,
93     uint32_t                  window_width_future)
94 {
95     PictureParentControlSet *previouspicture_control_set_ptr = parent_pcs_window[0];
96     PictureParentControlSet *currentpicture_control_set_ptr = parent_pcs_window[1];
97     PictureParentControlSet *futurepicture_control_set_ptr = parent_pcs_window[2];
98 
99     // calculating the frame threshold based on the number of 64x64 blocks in the frame
100     uint32_t  region_thresh_hold;
101     uint32_t  region_thresh_hold_chroma;
102     // this variable determines whether the running average should be reset to equal the ahd or not after detecting a scene change.
103     //EB_BOOL reset_running_avg = context_ptr->reset_running_avg;
104 
105     EB_BOOL is_abrupt_change;  // this variable signals an abrubt change (scene change or flash)
106     EB_BOOL is_scene_change;   // this variable signals a frame representing a scene change
107     EB_BOOL is_flash;          // this variable signals a frame that contains a flash
108     EB_BOOL is_fade;           // this variable signals a frame that contains a fade
109     EB_BOOL gradual_change;    // this signals the detection of a light scene change a small/localized flash or the start of a fade
110 
111     uint32_t  ahd;             // accumulative histogram (absolute) differences between the past and current frame
112 
113     uint32_t  ahd_cb;
114     uint32_t  ahd_cr;
115 
116     uint32_t  ahd_error_cb = 0;
117     uint32_t  ahd_error_cr = 0;
118 
119     uint32_t **ahd_running_avg_cb = context_ptr->ahd_running_avg_cb;
120     uint32_t **ahd_running_avg_cr = context_ptr->ahd_running_avg_cr;
121     uint32_t **ahd_running_avg = context_ptr->ahd_running_avg;
122 
123     uint32_t  ahd_error = 0; // the difference between the ahd and the running average at the current frame.
124 
125     uint8_t   aid_future_past = 0; // this variable denotes the average intensity difference between the next and the past frames
126     uint8_t   aid_future_present = 0;
127     uint8_t   aid_present_past = 0;
128 
129     uint32_t  bin = 0; // variable used to iterate through the bins of the histograms
130 
131     uint32_t  region_in_picture_width_index;
132     uint32_t  region_in_picture_height_index;
133 
134     uint32_t  region_width;
135     uint32_t  region_height;
136     uint32_t  region_width_offset;
137     uint32_t  region_height_offset;
138 
139     uint32_t  is_abrupt_change_count = 0;
140     uint32_t  is_scene_change_count = 0;
141 
142     uint32_t  region_count_threshold = (sequence_control_set_ptr->scd_mode == SCD_MODE_2) ?
143         (uint32_t)(((float)((sequence_control_set_ptr->picture_analysis_number_of_regions_per_width * sequence_control_set_ptr->picture_analysis_number_of_regions_per_height) * 75) / 100) + 0.5) :
144         (uint32_t)(((float)((sequence_control_set_ptr->picture_analysis_number_of_regions_per_width * sequence_control_set_ptr->picture_analysis_number_of_regions_per_height) * 50) / 100) + 0.5) ;
145 
146     region_width = parent_pcs_window[1]->enhanced_picture_ptr->width / sequence_control_set_ptr->picture_analysis_number_of_regions_per_width;
147     region_height = parent_pcs_window[1]->enhanced_picture_ptr->height / sequence_control_set_ptr->picture_analysis_number_of_regions_per_height;
148 
149     // Loop over regions inside the picture
150     for (region_in_picture_width_index = 0; region_in_picture_width_index < sequence_control_set_ptr->picture_analysis_number_of_regions_per_width; region_in_picture_width_index++){  // loop over horizontal regions
151         for (region_in_picture_height_index = 0; region_in_picture_height_index < sequence_control_set_ptr->picture_analysis_number_of_regions_per_height; region_in_picture_height_index++){ // loop over vertical regions
152 
153             is_abrupt_change = EB_FALSE;
154             is_scene_change = EB_FALSE;
155             is_flash = EB_FALSE;
156             gradual_change = EB_FALSE;
157 
158             // Reset accumulative histogram (absolute) differences between the past and current frame
159             ahd = 0;
160             ahd_cb = 0;
161             ahd_cr = 0;
162 
163             region_width_offset = (region_in_picture_width_index == sequence_control_set_ptr->picture_analysis_number_of_regions_per_width - 1) ?
164                 parent_pcs_window[1]->enhanced_picture_ptr->width - (sequence_control_set_ptr->picture_analysis_number_of_regions_per_width * region_width) :
165                 0;
166 
167             region_height_offset = (region_in_picture_height_index == sequence_control_set_ptr->picture_analysis_number_of_regions_per_height - 1) ?
168                 parent_pcs_window[1]->enhanced_picture_ptr->height - (sequence_control_set_ptr->picture_analysis_number_of_regions_per_height * region_height) :
169                 0;
170 
171             region_width += region_width_offset;
172             region_height += region_height_offset;
173 
174             region_thresh_hold = (
175                 // Noise insertion/removal detection
176                 ((ABS((int64_t)currentpicture_control_set_ptr->pic_avg_variance - (int64_t)previouspicture_control_set_ptr->pic_avg_variance)) > NOISE_VARIANCE_TH) &&
177                 (currentpicture_control_set_ptr->pic_avg_variance > HIGH_PICTURE_VARIANCE_TH || previouspicture_control_set_ptr->pic_avg_variance > HIGH_PICTURE_VARIANCE_TH)) ?
178                 NOISY_SCENE_TH * NUM64x64INPIC(region_width, region_height) : // SCD TH function of noise insertion/removal.
179                 SCENE_TH * NUM64x64INPIC(region_width, region_height) ;
180 
181             region_thresh_hold_chroma = region_thresh_hold / 4;
182 
183             for (bin = 0; bin < HISTOGRAM_NUMBER_OF_BINS; ++bin) {
184                 ahd += ABS((int32_t)currentpicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][0][bin] - (int32_t)previouspicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][0][bin]);
185                 ahd_cb += ABS((int32_t)currentpicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][1][bin] - (int32_t)previouspicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][1][bin]);
186                 ahd_cr += ABS((int32_t)currentpicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][2][bin] - (int32_t)previouspicture_control_set_ptr->picture_histogram[region_in_picture_width_index][region_in_picture_height_index][2][bin]);
187 
188             }
189 
190             if (context_ptr->reset_running_avg){
191                 ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] = ahd;
192                 ahd_running_avg_cb[region_in_picture_width_index][region_in_picture_height_index] = ahd_cb;
193                 ahd_running_avg_cr[region_in_picture_width_index][region_in_picture_height_index] = ahd_cr;
194             }
195 
196             ahd_error = ABS((int32_t)ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] - (int32_t)ahd);
197             ahd_error_cb = ABS((int32_t)ahd_running_avg_cb[region_in_picture_width_index][region_in_picture_height_index] - (int32_t)ahd_cb);
198             ahd_error_cr = ABS((int32_t)ahd_running_avg_cr[region_in_picture_width_index][region_in_picture_height_index] - (int32_t)ahd_cr);
199 
200             if ((ahd_error   > region_thresh_hold       && ahd >= ahd_error) ||
201                 (ahd_error_cb > region_thresh_hold_chroma && ahd_cb >= ahd_error_cb) ||
202                 (ahd_error_cr > region_thresh_hold_chroma && ahd_cr >= ahd_error_cr)){
203 
204                 is_abrupt_change = EB_TRUE;
205 
206             }
207             else if ((ahd_error > (region_thresh_hold >> 1)) && ahd >= ahd_error){
208                 gradual_change = EB_TRUE;
209             }
210 
211             if (is_abrupt_change)
212             {
213                 aid_future_past = (uint8_t) ABS((int16_t)futurepicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0] - (int16_t)previouspicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0]);
214                 aid_future_present = (uint8_t)ABS((int16_t)futurepicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0] - (int16_t)currentpicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0]);
215                 aid_present_past = (uint8_t)ABS((int16_t)currentpicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0] - (int16_t)previouspicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0]);
216 
217                 if (aid_future_past < FLASH_TH && aid_future_present >= FLASH_TH && aid_present_past >= FLASH_TH){
218                     is_flash = EB_TRUE;
219                     //SVT_LOG ("\nFlash in frame# %i , %i\n", currentpicture_control_set_ptr->picture_number,aid_future_past);
220                 }
221                 else if (aid_future_present < FADE_TH && aid_present_past < FADE_TH){
222                     is_fade = EB_TRUE;
223                     //SVT_LOG ("\nFlash in frame# %i , %i\n", currentpicture_control_set_ptr->picture_number,aid_future_past);
224                 } else {
225                     is_scene_change = EB_TRUE;
226                     //SVT_LOG ("\nScene Change in frame# %i , %i\n", currentpicture_control_set_ptr->picture_number,aid_future_past);
227                 }
228 
229             }
230             else if (gradual_change){
231 
232                 aid_future_past = (uint8_t) ABS((int16_t)futurepicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0] - (int16_t)previouspicture_control_set_ptr->average_intensity_per_region[region_in_picture_width_index][region_in_picture_height_index][0]);
233                 if (aid_future_past < FLASH_TH){
234                     // proper action to be signalled
235                     //SVT_LOG ("\nLight Flash in frame# %i , %i\n", currentpicture_control_set_ptr->picture_number,aid_future_past);
236                     ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] = (3 * ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] + ahd) / 4;
237                 }
238                 else{
239                     // proper action to be signalled
240                     //SVT_LOG ("\nLight Scene Change / fade detected in frame# %i , %i\n", currentpicture_control_set_ptr->picture_number,aid_future_past);
241                     ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] = (3 * ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] + ahd) / 4;
242                 }
243 
244             }
245             else{
246                 ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] = (3 * ahd_running_avg[region_in_picture_width_index][region_in_picture_height_index] + ahd) / 4;
247             }
248 
249             is_abrupt_change_count += is_abrupt_change;
250             is_scene_change_count += is_scene_change;
251         }
252     }
253 
254     (void)window_width_future;
255     (void)is_flash;
256     (void)is_fade;
257 
258     if (is_abrupt_change_count >= region_count_threshold) {
259         context_ptr->reset_running_avg = EB_TRUE;
260     }
261     else {
262         context_ptr->reset_running_avg = EB_FALSE;
263     }
264 
265     if ((is_scene_change_count >= region_count_threshold)){
266 
267         return(EB_TRUE);
268     }
269     else {
270         return(EB_FALSE);
271     }
272 
273 }
274 
275 /***************************************************************************************************
276 * release_prev_picture_from_reorder_queue
277 ***************************************************************************************************/
release_prev_picture_from_reorder_queue(EncodeContext * encode_context_ptr)278 static EbErrorType release_prev_picture_from_reorder_queue(
279     EncodeContext *encode_context_ptr) {
280 
281     EbErrorType return_error = EB_ErrorNone;
282 
283     PictureDecisionReorderEntry *queue_previous_entry_ptr;
284     int32_t                      previous_entry_index;
285 
286     // Get the previous entry from the Picture Decision Reordering Queue (Entry N-1)
287     // P.S. The previous entry in display order is needed for Scene Change Detection
288     previous_entry_index = (encode_context_ptr->picture_decision_reorder_queue_head_index == 0) ? PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH - 1 : encode_context_ptr->picture_decision_reorder_queue_head_index - 1;
289     queue_previous_entry_ptr = encode_context_ptr->picture_decision_reorder_queue[previous_entry_index];
290 
291     // LCU activity classification based on (0,0) SAD & picture activity derivation
292     if (queue_previous_entry_ptr->parent_pcs_wrapper_ptr) {
293 
294         // Reset the Picture Decision Reordering Queue Entry
295         // P.S. The reset of the Picture Decision Reordering Queue Entry could not be done before running the Scene Change Detector
296         queue_previous_entry_ptr->picture_number += PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH;
297         queue_previous_entry_ptr->parent_pcs_wrapper_ptr = (EbObjectWrapper *)EB_NULL;
298     }
299 
300     return return_error;
301 }
302 #if NEW_PRED_STRUCT
303 
304 /***************************************************************************************************
305 * Initializes mini GOP activity array
306 *
307 ***************************************************************************************************/
eb_vp9_initialize_mini_gop_activity_array(PictureDecisionContext * context_ptr)308 EbErrorType eb_vp9_initialize_mini_gop_activity_array(
309     PictureDecisionContext        *context_ptr) {
310 
311     EbErrorType return_error = EB_ErrorNone;
312 
313     uint32_t mini_gop_index;
314 
315     // Loop over all mini GOPs
316     for (mini_gop_index = 0; mini_gop_index < MINI_GOP_MAX_COUNT; ++mini_gop_index) {
317 
318         context_ptr->mini_gop_activity_array[mini_gop_index] = (eb_vp9_get_mini_gop_stats(mini_gop_index)->hierarchical_levels == MIN_HIERARCHICAL_LEVEL) ?
319             EB_FALSE :
320             EB_TRUE;
321 
322     }
323 
324     return return_error;
325 }
326 
327 /***************************************************************************************************
328 * Generates block picture map
329 *
330 *
331 ***************************************************************************************************/
eb_vp9_generate_picture_window_split(PictureDecisionContext * context_ptr,EncodeContext * encode_context_ptr)332 EbErrorType eb_vp9_generate_picture_window_split(
333     PictureDecisionContext        *context_ptr,
334     EncodeContext                 *encode_context_ptr) {
335 
336     EbErrorType return_error = EB_ErrorNone;
337 
338     uint32_t    mini_gop_index;
339 
340     context_ptr->total_number_of_mini_gops = 0;
341 
342     // Loop over all mini GOPs
343     mini_gop_index = 0;
344     while (mini_gop_index < MINI_GOP_MAX_COUNT) {
345 
346         // Only for a valid mini GOP
347         if (eb_vp9_get_mini_gop_stats(mini_gop_index)->end_index < encode_context_ptr->pre_assignment_buffer_count && context_ptr->mini_gop_activity_array[mini_gop_index] == EB_FALSE) {
348 
349             context_ptr->mini_gop_start_index[context_ptr->total_number_of_mini_gops] = eb_vp9_get_mini_gop_stats(mini_gop_index)->start_index;
350             context_ptr->mini_gop_end_index[context_ptr->total_number_of_mini_gops] = eb_vp9_get_mini_gop_stats(mini_gop_index)->end_index;
351             context_ptr->mini_gop_length[context_ptr->total_number_of_mini_gops] = eb_vp9_get_mini_gop_stats(mini_gop_index)->lenght;
352             context_ptr->mini_gop_hierarchical_levels[context_ptr->total_number_of_mini_gops] = eb_vp9_get_mini_gop_stats(mini_gop_index)->hierarchical_levels;
353             context_ptr->mini_gop_intra_count[context_ptr->total_number_of_mini_gops] = 0;
354             context_ptr->mini_gop_idr_count[context_ptr->total_number_of_mini_gops] = 0;
355 
356             context_ptr->total_number_of_mini_gops++;
357         }
358 
359         mini_gop_index += context_ptr->mini_gop_activity_array[mini_gop_index] ?
360             1 :
361             mini_gop_offset[eb_vp9_get_mini_gop_stats(mini_gop_index)->hierarchical_levels - MIN_HIERARCHICAL_LEVEL];
362 
363     }
364 
365     // Only in presence of at least 1 valid mini GOP
366     if (context_ptr->total_number_of_mini_gops != 0) {
367         context_ptr->mini_gop_intra_count[context_ptr->total_number_of_mini_gops - 1] = encode_context_ptr->pre_assignment_buffer_intra_count;
368         context_ptr->mini_gop_idr_count[context_ptr->total_number_of_mini_gops - 1] = encode_context_ptr->pre_assignment_buffer_idr_count;
369     }
370 
371     return return_error;
372 }
373 
374 /***************************************************************************************************
375 * Handles an incomplete picture window map
376 *
377 *
378 ***************************************************************************************************/
eb_vp9_handle_incomplete_picture_window_map(PictureDecisionContext * context_ptr,EncodeContext * encode_context_ptr)379 EbErrorType eb_vp9_handle_incomplete_picture_window_map(
380     PictureDecisionContext        *context_ptr,
381     EncodeContext                 *encode_context_ptr) {
382 
383     EbErrorType return_error = EB_ErrorNone;
384 
385     if (context_ptr->total_number_of_mini_gops == 0) {
386 
387         context_ptr->mini_gop_start_index[context_ptr->total_number_of_mini_gops] = 0;
388         context_ptr->mini_gop_end_index[context_ptr->total_number_of_mini_gops] = encode_context_ptr->pre_assignment_buffer_count - 1;
389         context_ptr->mini_gop_length[context_ptr->total_number_of_mini_gops] = encode_context_ptr->pre_assignment_buffer_count - context_ptr->mini_gop_start_index[context_ptr->total_number_of_mini_gops];
390         context_ptr->mini_gop_hierarchical_levels[context_ptr->total_number_of_mini_gops] = 3;// MIN_HIERARCHICAL_LEVEL; // AMIR to be updated after other predictions are supported
391 
392         context_ptr->total_number_of_mini_gops++;
393 
394     }
395     else if (context_ptr->mini_gop_end_index[context_ptr->total_number_of_mini_gops - 1] < encode_context_ptr->pre_assignment_buffer_count - 1) {
396 
397         context_ptr->mini_gop_start_index[context_ptr->total_number_of_mini_gops] = context_ptr->mini_gop_end_index[context_ptr->total_number_of_mini_gops - 1] + 1;
398         context_ptr->mini_gop_end_index[context_ptr->total_number_of_mini_gops] = encode_context_ptr->pre_assignment_buffer_count - 1;
399         context_ptr->mini_gop_length[context_ptr->total_number_of_mini_gops] = encode_context_ptr->pre_assignment_buffer_count - context_ptr->mini_gop_start_index[context_ptr->total_number_of_mini_gops];
400         context_ptr->mini_gop_hierarchical_levels[context_ptr->total_number_of_mini_gops] = 3;// MIN_HIERARCHICAL_LEVEL;// AMIR
401         context_ptr->mini_gop_intra_count[context_ptr->total_number_of_mini_gops - 1] = 0;
402         context_ptr->mini_gop_idr_count[context_ptr->total_number_of_mini_gops - 1] = 0;
403 
404         context_ptr->total_number_of_mini_gops++;
405     }
406 
407     context_ptr->mini_gop_intra_count[context_ptr->total_number_of_mini_gops - 1] = encode_context_ptr->pre_assignment_buffer_intra_count;
408     context_ptr->mini_gop_idr_count[context_ptr->total_number_of_mini_gops - 1] = encode_context_ptr->pre_assignment_buffer_idr_count;
409 
410     return return_error;
411 }
412 /***************************************************************************************************
413 * If a switch happens, then update the RPS of the base layer frame separating the 2 different prediction structures
414 * Clean up the reference queue dependant counts of the base layer frame separating the 2 different prediction structures
415 *
416 ***************************************************************************************************/
update_base_layer_reference_queue_dependent_count(PictureDecisionContext * context_ptr,EncodeContext * encode_context_ptr,uint32_t mini_gop_index)417 static EbErrorType update_base_layer_reference_queue_dependent_count(
418     PictureDecisionContext        *context_ptr,
419     EncodeContext                 *encode_context_ptr,
420     uint32_t                       mini_gop_index) {
421 
422     EbErrorType return_error = EB_ErrorNone;
423 
424     PaReferenceQueueEntry         *inputEntryPtr;
425     uint32_t                       inputQueueIndex;
426 
427     PredictionStructure          *nextPredStructPtr;
428     PredictionStructureEntry      *nextBaseLayerPredPositionPtr;
429 
430     uint32_t                       dependantListPositiveEntries;
431     uint32_t                       dependantListRemovedEntries;
432     uint32_t                       depListCount;
433 
434     uint32_t                       depIdx;
435     uint64_t                       depPoc;
436 
437     PictureParentControlSet       *picture_control_set_ptr;
438 
439     // Get the 1st PCS mini GOP
440     picture_control_set_ptr = (PictureParentControlSet*)encode_context_ptr->pre_assignment_buffer[context_ptr->mini_gop_start_index[mini_gop_index]]->object_ptr;
441 
442     // Derive the temporal layer difference between the current mini GOP and the previous mini GOP
443     picture_control_set_ptr->hierarchical_layers_diff = (uint8_t)(encode_context_ptr->previous_mini_gop_hierarchical_levels - picture_control_set_ptr->hierarchical_levels);
444 
445     // Set init_pred_struct_position_flag to TRUE if mini GOP switch
446     picture_control_set_ptr->init_pred_struct_position_flag = (picture_control_set_ptr->hierarchical_layers_diff != 0) ?
447         EB_TRUE :
448         EB_FALSE;
449 
450     // If the current mini GOP is different than the previous mini GOP update then update the positive dependant counts of the reference entry separating the 2 mini GOPs
451     if (picture_control_set_ptr->hierarchical_layers_diff != 0) {
452 
453         inputQueueIndex = encode_context_ptr->picture_decision_pa_reference_queue_head_index;
454 
455         while (inputQueueIndex != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) {
456 
457             inputEntryPtr = encode_context_ptr->picture_decision_pa_reference_queue[inputQueueIndex];
458 
459             // Find the reference entry separating the 2 mini GOPs  (picture_control_set_ptr->picture_number is the POC of the first isput in the mini GOP)
460             if (inputEntryPtr->picture_number == (picture_control_set_ptr->picture_number - 1)) {
461 
462                 // Update the positive dependant counts
463 
464                 // 1st step: remove all positive entries from the dependant list0 and dependant list1
465                 dependantListPositiveEntries = 0;
466                 for (depIdx = 0; depIdx < inputEntryPtr->list0.list_count; ++depIdx) {
467                     if (inputEntryPtr->list0.list[depIdx] >= 0) {
468                         dependantListPositiveEntries++;
469                     }
470                 }
471                 inputEntryPtr->list0.list_count = inputEntryPtr->list0.list_count - dependantListPositiveEntries;
472                 dependantListPositiveEntries = 0;
473                 for (depIdx = 0; depIdx < inputEntryPtr->list1.list_count; ++depIdx) {
474                     if (inputEntryPtr->list1.list[depIdx] >= 0) {
475                         dependantListPositiveEntries++;
476                     }
477                 }
478                 inputEntryPtr->list1.list_count = inputEntryPtr->list1.list_count - dependantListPositiveEntries;
479 
480                 // 2nd step: inherit the positive dependant counts of the current mini GOP
481                 // Get the RPS set of the current mini GOP
482                 nextPredStructPtr = eb_vp9_get_prediction_structure(
483                     encode_context_ptr->prediction_structure_group_ptr,
484                     picture_control_set_ptr->pred_structure,
485                     1,
486                     picture_control_set_ptr->hierarchical_levels);            // Number of temporal layer in the current mini GOP
487 
488                 // Get the RPS of a base layer input
489                 nextBaseLayerPredPositionPtr = nextPredStructPtr->pred_struct_entry_ptr_array[nextPredStructPtr->pred_struct_entry_count - 1];
490 
491                 for (depIdx = 0; depIdx < nextBaseLayerPredPositionPtr->dep_list0.list_count; ++depIdx) {
492                     if (nextBaseLayerPredPositionPtr->dep_list0.list[depIdx] >= 0) {
493                         inputEntryPtr->list0.list[inputEntryPtr->list0.list_count++] = nextBaseLayerPredPositionPtr->dep_list0.list[depIdx];
494                     }
495                 }
496 
497                 for (depIdx = 0; depIdx < nextBaseLayerPredPositionPtr->dep_list1.list_count; ++depIdx) {
498                     if (nextBaseLayerPredPositionPtr->dep_list1.list[depIdx] >= 0) {
499                         inputEntryPtr->list1.list[inputEntryPtr->list1.list_count++] = nextBaseLayerPredPositionPtr->dep_list1.list[depIdx];
500                     }
501                 }
502 
503                 // 3rd step: update the dependant count
504                 dependantListRemovedEntries = inputEntryPtr->dep_list0_count + inputEntryPtr->dep_list1_count - inputEntryPtr->dependent_count;
505                 inputEntryPtr->dep_list0_count = inputEntryPtr->list0.list_count;
506                 inputEntryPtr->dep_list1_count = inputEntryPtr->list1.list_count;
507                 inputEntryPtr->dependent_count = inputEntryPtr->dep_list0_count + inputEntryPtr->dep_list1_count - dependantListRemovedEntries;
508 
509             }
510             else {
511 
512                 // Modify Dependent List0
513                 depListCount = inputEntryPtr->list0.list_count;
514                 for (depIdx = 0; depIdx < depListCount; ++depIdx) {
515 
516                     // Adjust the latest currentInputPoc in case we're in a POC rollover scenario
517                     // currentInputPoc += (currentInputPoc < inputEntryPtr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
518 
519                     depPoc = POC_CIRCULAR_ADD(
520                         inputEntryPtr->picture_number, // can't use a value that gets reset
521                         inputEntryPtr->list0.list[depIdx]/*,
522                                                          sequence_control_set_ptr->bitsForPictureOrderCount*/);
523 
524                                                          // If Dependent POC is greater or equal to the IDR POC
525                     if (depPoc >= picture_control_set_ptr->picture_number && inputEntryPtr->list0.list[depIdx]) {
526 
527                         inputEntryPtr->list0.list[depIdx] = 0;
528 
529                         // Decrement the Reference's reference_count
530                         --inputEntryPtr->dependent_count;
531 
532                         CHECK_REPORT_ERROR(
533                             (inputEntryPtr->dependent_count != ~0u),
534                             encode_context_ptr->app_callback_ptr,
535                             EB_ENC_PD_ERROR3);
536                     }
537                 }
538 
539                 // Modify Dependent List1
540                 depListCount = inputEntryPtr->list1.list_count;
541                 for (depIdx = 0; depIdx < depListCount; ++depIdx) {
542 
543                     // Adjust the latest currentInputPoc in case we're in a POC rollover scenario
544                     // currentInputPoc += (currentInputPoc < inputEntryPtr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
545 
546                     depPoc = POC_CIRCULAR_ADD(
547                         inputEntryPtr->picture_number,
548                         inputEntryPtr->list1.list[depIdx]/*,
549                                                          sequence_control_set_ptr->bitsForPictureOrderCount*/);
550 
551                                                          // If Dependent POC is greater or equal to the IDR POC
552                     if ((depPoc >= picture_control_set_ptr->picture_number) && inputEntryPtr->list1.list[depIdx]) {
553                         inputEntryPtr->list1.list[depIdx] = 0;
554 
555                         // Decrement the Reference's reference_count
556                         --inputEntryPtr->dependent_count;
557 
558                         CHECK_REPORT_ERROR(
559                             (inputEntryPtr->dependent_count != ~0u),
560                             encode_context_ptr->app_callback_ptr,
561                             EB_ENC_PD_ERROR3);
562                     }
563                 }
564             }
565 
566             // Increment the inputQueueIndex Iterator
567             inputQueueIndex = (inputQueueIndex == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : inputQueueIndex + 1;
568         }
569     }
570 
571     return return_error;
572 }
573 
574 #endif
575 
576 /***************************************************************************************************
577 * Generates mini GOP RPSs
578 *
579 *
580 ***************************************************************************************************/
generate_mini_gop_rps(PictureDecisionContext * context_ptr,EncodeContext * encode_context_ptr)581 static EbErrorType generate_mini_gop_rps(
582     PictureDecisionContext *context_ptr,
583     EncodeContext          *encode_context_ptr) {
584 
585     EbErrorType return_error = EB_ErrorNone;
586 
587     uint32_t                 mini_gop_index;
588     PictureParentControlSet *picture_control_set_ptr;
589     uint32_t                 picture_index;
590 
591     SequenceControlSet      *sequence_control_set_ptr;
592 
593     // Loop over all mini GOPs
594     for (mini_gop_index = 0; mini_gop_index < context_ptr->total_number_of_mini_gops; ++mini_gop_index) {
595 
596         // Loop over picture within the mini GOP
597         for (picture_index = context_ptr->mini_gop_start_index[mini_gop_index]; picture_index <= context_ptr->mini_gop_end_index[mini_gop_index]; picture_index++) {
598 
599             picture_control_set_ptr    = (PictureParentControlSet  *)    encode_context_ptr->pre_assignment_buffer[picture_index]->object_ptr;
600             sequence_control_set_ptr = (SequenceControlSet *)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
601             picture_control_set_ptr->pred_structure = sequence_control_set_ptr->static_config.pred_structure;
602 
603             picture_control_set_ptr->hierarchical_levels = (uint8_t)context_ptr->mini_gop_hierarchical_levels[mini_gop_index];
604 
605             picture_control_set_ptr->pred_struct_ptr = eb_vp9_get_prediction_structure(
606                 encode_context_ptr->prediction_structure_group_ptr,
607                 picture_control_set_ptr->pred_structure,
608                 1,
609                 picture_control_set_ptr->hierarchical_levels);
610         }
611     }
612     return return_error;
613 }
614 
615 /***************************************************************************
616 * Set the default subPel enble/disable flag for each frame
617 ****************************************************************************/
618 
picture_level_sub_pel_settings_oq(uint8_t input_resolution,uint8_t enc_mode,uint8_t temporal_layer_index,EB_BOOL is_used_as_reference_flag)619 uint8_t picture_level_sub_pel_settings_oq(
620     uint8_t input_resolution,
621     uint8_t enc_mode,
622     uint8_t temporal_layer_index,
623     EB_BOOL is_used_as_reference_flag) {
624 
625     uint8_t sub_pel_mode;
626 
627     if (enc_mode <= ENC_MODE_8) {
628         sub_pel_mode = 1;
629     }
630     else if (enc_mode <= ENC_MODE_9) {
631         if (input_resolution >= INPUT_SIZE_4K_RANGE) {
632             sub_pel_mode = (temporal_layer_index == 0) ? 1 : 0;
633         }
634         else {
635             sub_pel_mode = 1;
636         }
637     }
638     else {
639         if (input_resolution >= INPUT_SIZE_4K_RANGE) {
640             sub_pel_mode = (temporal_layer_index == 0) ? 1 : 0;
641         }
642         else {
643             sub_pel_mode = is_used_as_reference_flag ? 1 : 0;
644         }
645     }
646 
647     return sub_pel_mode;
648 }
649 
picture_level_sub_pel_settings_vmaf(uint8_t input_resolution,uint8_t enc_mode,uint8_t temporal_layer_index)650 uint8_t picture_level_sub_pel_settings_vmaf(
651     uint8_t input_resolution,
652     uint8_t enc_mode,
653     uint8_t temporal_layer_index) {
654 
655     uint8_t sub_pel_mode;
656 
657     if (enc_mode <= ENC_MODE_8) {
658         sub_pel_mode = 1;
659     }
660     else {
661         if (input_resolution >= INPUT_SIZE_4K_RANGE) {
662             sub_pel_mode = (temporal_layer_index == 0) ? 1 : 0;
663         }
664         else {
665             sub_pel_mode = 1;
666         }
667     }
668 
669     return sub_pel_mode;
670 }
671 
picture_level_sub_pel_settings_sq(uint8_t input_resolution,uint8_t enc_mode,uint8_t temporal_layer_index,EB_BOOL is_used_as_reference_flag)672 uint8_t picture_level_sub_pel_settings_sq(
673     uint8_t input_resolution,
674     uint8_t enc_mode,
675     uint8_t temporal_layer_index,
676     EB_BOOL is_used_as_reference_flag) {
677     uint8_t sub_pel_mode;
678 
679     if (input_resolution >= INPUT_SIZE_4K_RANGE) {
680         if (enc_mode <= ENC_MODE_4) {
681             sub_pel_mode = 1;
682         }
683         else if (enc_mode <= ENC_MODE_7) {
684             sub_pel_mode = is_used_as_reference_flag ? 1 : 0;
685         }
686         else if (enc_mode <= ENC_MODE_10) {
687             sub_pel_mode = (temporal_layer_index == 0) ? 1 : 0;
688         }
689         else {
690             sub_pel_mode = 0;
691         }
692     }
693     else {
694         if (enc_mode <= ENC_MODE_4) {
695             sub_pel_mode = 1;
696         }
697         else if (enc_mode <= ENC_MODE_8) {
698             sub_pel_mode = is_used_as_reference_flag ? 1 : 0;
699         }
700         else if (enc_mode <= ENC_MODE_9) {
701             sub_pel_mode = (temporal_layer_index == 0) ? 1 : 0;
702         }
703         else {
704             sub_pel_mode = 0;
705         }
706     }
707 
708     return sub_pel_mode;
709 }
710 
711 /******************************************************
712 * Derive Multi-Processes Settings for SQ
713 Input   : encoder mode and tune
714 Output  : Multi-Processes signal(s)
715 ******************************************************/
eb_vp9_signal_derivation_multi_processes_sq(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)716 EbErrorType eb_vp9_signal_derivation_multi_processes_sq(
717     SequenceControlSet      *sequence_control_set_ptr,
718     PictureParentControlSet *picture_control_set_ptr) {
719 
720     EbErrorType return_error = EB_ErrorNone;
721 
722     // Set MD Partitioning Method
723     if (picture_control_set_ptr->enc_mode <= ENC_MODE_3) {
724         if (picture_control_set_ptr->slice_type == I_SLICE) {
725             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
726         }
727         else {
728             picture_control_set_ptr->pic_depth_mode = PIC_FULL85_DEPTH_MODE;
729         }
730     }
731     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_4) {
732         if (sequence_control_set_ptr->input_resolution == INPUT_SIZE_4K_RANGE) {
733             if (picture_control_set_ptr->slice_type == I_SLICE) {
734                 picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
735             }
736             else {
737                 picture_control_set_ptr->pic_depth_mode = PIC_FULL85_DEPTH_MODE;
738             }
739         }
740         else {
741             if (picture_control_set_ptr->slice_type == I_SLICE) {
742                 picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
743             }
744             else {
745                 picture_control_set_ptr->pic_depth_mode = PIC_SB_SWITCH_DEPTH_MODE;
746             }
747         }
748     }
749     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_9) {
750         if (picture_control_set_ptr->slice_type == I_SLICE) {
751             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
752         }
753         else {
754             picture_control_set_ptr->pic_depth_mode = PIC_SB_SWITCH_DEPTH_MODE;
755         }
756     }
757     else {
758         if (picture_control_set_ptr->slice_type == I_SLICE) {
759             if (sequence_control_set_ptr->input_resolution <= INPUT_SIZE_1080p_RANGE) {
760                 picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
761             }
762             else {
763                 picture_control_set_ptr->pic_depth_mode = PIC_BDP_DEPTH_MODE;
764             }
765         }
766         else {
767             picture_control_set_ptr->pic_depth_mode = PIC_SB_SWITCH_DEPTH_MODE;
768         }
769     }
770 
771     // Set the default settings of  subpel
772     picture_control_set_ptr->use_subpel_flag = picture_level_sub_pel_settings_sq(
773         sequence_control_set_ptr->input_resolution,
774         picture_control_set_ptr->enc_mode,
775         picture_control_set_ptr->temporal_layer_index,
776         picture_control_set_ptr->is_used_as_reference_flag);
777 
778     // CU_8x8 Search Mode
779     if (picture_control_set_ptr->enc_mode <= ENC_MODE_1) {
780         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_0;
781     }
782     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_6) {
783         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->is_used_as_reference_flag) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
784     }
785     else if (picture_control_set_ptr->enc_mode == ENC_MODE_7) {
786         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->temporal_layer_index == 0) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
787     }
788     else {
789         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_1;
790     }
791 
792     // CU_16x16 Search Mode
793     picture_control_set_ptr->cu16x16_mode = CU_16x16_MODE_0;
794 
795     return return_error;
796 }
797 
798 /******************************************************
799 * Derive Multi-Processes Settings for OQ
800 Input   : encoder mode and tune
801 Output  : Multi-Processes signal(s)
802 ******************************************************/
eb_vp9_signal_derivation_multi_processes_oq(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)803 EbErrorType eb_vp9_signal_derivation_multi_processes_oq(
804     SequenceControlSet      *sequence_control_set_ptr,
805     PictureParentControlSet *picture_control_set_ptr) {
806 
807     EbErrorType return_error = EB_ErrorNone;
808 
809     // Set MD Partitioning Method
810     if (picture_control_set_ptr->enc_mode <= ENC_MODE_3) {
811         if (picture_control_set_ptr->slice_type == I_SLICE) {
812             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
813         }
814         else {
815             picture_control_set_ptr->pic_depth_mode = PIC_FULL85_DEPTH_MODE;
816         }
817     }
818     else {
819         if (picture_control_set_ptr->slice_type == I_SLICE) {
820             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
821 
822         }
823         else {
824             picture_control_set_ptr->pic_depth_mode = PIC_SB_SWITCH_DEPTH_MODE;
825         }
826     }
827 
828     // Set the default settings of  subpel
829     picture_control_set_ptr->use_subpel_flag = picture_level_sub_pel_settings_oq(
830         sequence_control_set_ptr->input_resolution,
831         picture_control_set_ptr->enc_mode,
832         picture_control_set_ptr->temporal_layer_index,
833         picture_control_set_ptr->is_used_as_reference_flag);
834 
835     // CU_8x8 Search Mode
836     if (picture_control_set_ptr->enc_mode <= ENC_MODE_1) {
837         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_0;
838     }
839     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_6) {
840         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->is_used_as_reference_flag) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
841     }
842     else if (picture_control_set_ptr->enc_mode == ENC_MODE_7) {
843         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->temporal_layer_index == 0) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
844     }
845     else {
846         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_1;
847     }
848 
849     // CU_16x16 Search Mode
850     picture_control_set_ptr->cu16x16_mode = CU_16x16_MODE_0;
851 
852     return return_error;
853 }
854 
855 /******************************************************
856 * Derive Multi-Processes Settings for VMAF
857 Input   : encoder mode and tune
858 Output  : Multi-Processes signal(s)
859 ******************************************************/
eb_vp9_signal_derivation_multi_processes_vmaf(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)860 EbErrorType eb_vp9_signal_derivation_multi_processes_vmaf(
861     SequenceControlSet      *sequence_control_set_ptr,
862     PictureParentControlSet *picture_control_set_ptr) {
863 
864     EbErrorType return_error = EB_ErrorNone;
865 
866     // Set MD Partitioning Method
867     if (picture_control_set_ptr->enc_mode <= ENC_MODE_1) {
868         if (picture_control_set_ptr->slice_type == I_SLICE) {
869             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
870         }
871         else {
872             picture_control_set_ptr->pic_depth_mode = PIC_FULL85_DEPTH_MODE;
873         }
874     }
875     else {
876         if (picture_control_set_ptr->slice_type == I_SLICE) {
877             picture_control_set_ptr->pic_depth_mode = PIC_FULL84_DEPTH_MODE;
878         }
879         else {
880             picture_control_set_ptr->pic_depth_mode = PIC_SB_SWITCH_DEPTH_MODE;
881         }
882     }
883 
884     // Set the default settings of  subpel
885     picture_control_set_ptr->use_subpel_flag = picture_level_sub_pel_settings_vmaf(
886         sequence_control_set_ptr->input_resolution,
887         picture_control_set_ptr->enc_mode,
888         picture_control_set_ptr->temporal_layer_index);
889 
890     // CU_8x8 Search Mode
891     if (picture_control_set_ptr->enc_mode <= ENC_MODE_1) {
892         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_0;
893     }
894     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_6) {
895         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->is_used_as_reference_flag) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
896     }
897     else if (picture_control_set_ptr->enc_mode == ENC_MODE_7) {
898         picture_control_set_ptr->cu8x8_mode = (picture_control_set_ptr->temporal_layer_index == 0) ? CU_8x8_MODE_0 : CU_8x8_MODE_1;
899     }
900     else {
901         picture_control_set_ptr->cu8x8_mode = CU_8x8_MODE_1;
902     }
903 
904     // CU_16x16 Search Mode
905     picture_control_set_ptr->cu16x16_mode = CU_16x16_MODE_0;
906 
907     return return_error;
908 }
909 
910 /*************************************************
911 * Reference Picture Signalling:
912 * Stateless derivation of RPS info to be stored in
913 * Picture Header
914 *
915 * This function uses the picture index from the just
916 * collected miniGop to derive the RPS(refIndexes+refresh)
917 * the miniGop is always 4L but could be complete (8 pictures)
918 or non-complete (less than 8 pictures).
919 * We get to this function if the picture is:
920 * 1) first Key frame
921 * 2) part of a complete RA MiniGop where the last frame could be a regular I for open GOP
922 * 3) part of complete LDP MiniGop where the last frame could be Key frame for closed GOP
923 * 4) part of non-complete LDP MiniGop where the last frame is a regularI.
924 This miniGOP has P frames with predStruct=LDP, and the last frame=I with pred struct=RA.
925 * 5) part of non-complete LDP MiniGop at the end of the stream.This miniGOP has P frames with
926 predStruct=LDP, and the last frame=I with pred struct=RA.
927 *
928 *************************************************/
generate_rps_info(PictureParentControlSet * picture_control_set_ptr,PictureDecisionContext * context_ptr,uint32_t picture_index,uint32_t mini_gop_index)929 void  generate_rps_info(
930     PictureParentControlSet *picture_control_set_ptr,
931     PictureDecisionContext  *context_ptr,
932     uint32_t                 picture_index,
933     uint32_t                 mini_gop_index
934 )
935 {
936     RpsNode *rps = &picture_control_set_ptr->ref_signal;
937 
938     // Set restrictRefMvsDerivation
939     picture_control_set_ptr->cpi->common.use_prev_frame_mvs = EB_TRUE;
940 
941     // Set Frame Type
942     if (picture_control_set_ptr->slice_type == I_SLICE) {
943         picture_control_set_ptr->cpi->common.frame_type = (picture_control_set_ptr->idr_flag) ? KEY_FRAME : INTER_FRAME;
944         picture_control_set_ptr->cpi->common.intra_only = 1;
945     }
946     else {
947         picture_control_set_ptr->cpi->common.frame_type = INTER_FRAME;
948         picture_control_set_ptr->cpi->common.intra_only = 0;
949     }
950 
951     // RPS for Flat GOP
952     if (picture_control_set_ptr->hierarchical_levels == 0)
953     {
954 
955         memset(rps->ref_dpb_index, 0, 3);
956         rps->refresh_frame_mask = 1;
957         picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
958         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
959 
960     }
961     else if (picture_control_set_ptr->hierarchical_levels == 3)//RPS for 4L GOP
962     {
963 
964         //Reset miniGop Toggling. The first miniGop after a KEY frame has toggle=0
965         if (picture_control_set_ptr->cpi->common.frame_type == KEY_FRAME)
966         {
967             context_ptr->mini_gop_toggle = 0;
968             picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
969             picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
970             return;
971         }
972 
973         //picture_index has this order:
974         //        0      2    4      6
975         //            1          5
976         //                 3
977         //                             8(could be an I)
978 
979         //DPB: Loc7|Loc6|Loc5|Loc4|Loc3|Loc2|Loc1|Loc0
980         //Layer 0 : toggling bwteween DPB Location 0, and  locations 3-4-5-6-7
981         //Layer 1 : DPB Location 1
982         //Layer 2 : DPB Location 2
983 
984         //         1     3    5      7
985         //            2          6
986         //                 4
987         //base0:0                      base1:8
988         const uint8_t  base0_idx = context_ptr->mini_gop_toggle ? 0 : 3; //Base layer for prediction from past
989         const uint8_t  base1_idx = context_ptr->mini_gop_toggle ? 3 : 0; //Base layer for prediction from future
990         const uint8_t  layer1_idx = 1;
991         const uint8_t  layer2_idx = 2;
992         const uint8_t  layer3_idx1 = 4;
993         const uint8_t  layer3_idx2 = 5;
994 
995         switch (picture_control_set_ptr->temporal_layer_index) {
996 
997         case 0:
998             rps->ref_dpb_index[0] = base0_idx;
999             rps->ref_dpb_index[2] = base0_idx;
1000             rps->refresh_frame_mask = context_ptr->mini_gop_toggle ? 200 : 1;
1001             break;
1002         case 1:
1003             rps->ref_dpb_index[0] = base0_idx;
1004             rps->ref_dpb_index[2] = base1_idx;
1005             rps->refresh_frame_mask = 2;
1006             break;
1007         case 2:
1008 
1009             if (picture_index == 1) {
1010                 rps->ref_dpb_index[0] = base0_idx;
1011                 rps->ref_dpb_index[2] = layer1_idx;
1012             }
1013             else if (picture_index == 5) {
1014                 rps->ref_dpb_index[0] = layer1_idx;
1015                 rps->ref_dpb_index[2] = base1_idx;
1016             }
1017             else {
1018                 SVT_LOG("Error in GOP indexing\n");
1019             }
1020             rps->refresh_frame_mask = 4;
1021             break;
1022         case 3:
1023             if (picture_index == 0) {
1024                 rps->ref_dpb_index[0] = base0_idx;
1025                 rps->ref_dpb_index[2] = layer2_idx;
1026                 rps->refresh_frame_mask = 16;
1027             }
1028             else if (picture_index == 2) {
1029                 rps->ref_dpb_index[0] = layer2_idx;
1030                 rps->ref_dpb_index[2] = layer1_idx;
1031                 rps->refresh_frame_mask = 32;
1032             }
1033             else if (picture_index == 4) {
1034                 rps->ref_dpb_index[0] = layer1_idx;
1035                 rps->ref_dpb_index[2] = layer2_idx;
1036                 rps->refresh_frame_mask = 16;
1037             }
1038             else if (picture_index == 6) {
1039                 rps->ref_dpb_index[0] = layer2_idx;
1040                 rps->ref_dpb_index[2] = base1_idx;
1041                 rps->refresh_frame_mask = 32;
1042             }
1043             else {
1044                 SVT_LOG("Error in GOp indexing\n");
1045             }
1046             break;
1047         default:
1048             SVT_LOG("Error: unexpected picture mini Gop number\n");
1049             break;
1050         }
1051         picture_control_set_ptr->cpi->common.use_prev_frame_mvs = EB_FALSE;
1052 
1053         if (picture_control_set_ptr->pred_struct_ptr->pred_type == EB_PRED_LOW_DELAY_P)
1054         {
1055             //P frames.
1056             rps->ref_dpb_index[1] = rps->ref_dpb_index[0];
1057             picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
1058             picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1059         }
1060         else if (picture_control_set_ptr->pred_struct_ptr->pred_type == EB_PRED_RANDOM_ACCESS)
1061         {
1062 
1063             rps->ref_dpb_index[1] = rps->ref_dpb_index[0];
1064 
1065             //Decide on Show Mecanism
1066             if (picture_control_set_ptr->slice_type == I_SLICE)
1067             {
1068                 //3 cases for I slice:  1:Key Frame treated above.  2: broken MiniGop due to sc or intra refresh  3: complete miniGop due to sc or intra refresh
1069                 if (context_ptr->mini_gop_length[mini_gop_index] < picture_control_set_ptr->pred_struct_ptr->pred_struct_period)
1070                 {
1071                     //Scene Change that breaks the mini gop and switch to LDP (if I scene change happens to be aligned with a complete miniGop, then we do not break the pred structure)
1072                     picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
1073                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1074                 }
1075                 else
1076                 {
1077                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1078                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1079                 }
1080             }
1081             else//B pic
1082             {
1083                 if (context_ptr->mini_gop_length[0] != picture_control_set_ptr->pred_struct_ptr->pred_struct_period)
1084                     SVT_LOG("Error in GOp indexing3\n");
1085 
1086                 if (picture_control_set_ptr->is_used_as_reference_flag)
1087                 {
1088                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1089                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1090                 }
1091                 else
1092                 {
1093 
1094                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1095                     if (picture_index == 0) {
1096                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1097                     }
1098                     else if (picture_index == 2) {
1099                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1100                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer3_idx1;
1101                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer2_idx;
1102                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer3_idx2;
1103                         picture_control_set_ptr->show_existing_frame_index_array[3] = layer1_idx;
1104                     }
1105                     else if (picture_index == 4) {
1106                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1107                     }
1108                     else if (picture_index == 6) {
1109                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1110                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer3_idx1;
1111                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer2_idx;
1112                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer3_idx2;
1113                         picture_control_set_ptr->show_existing_frame_index_array[3] = base1_idx;
1114                     }
1115                     else {
1116                         SVT_LOG("Error in GOp indexing2\n");
1117                     }
1118 
1119                 }
1120 
1121             }
1122 
1123         }
1124 
1125         else {
1126             SVT_LOG("SVT [ERROR]: Not supported GOP structure!");
1127             return;
1128         }
1129 
1130         //last pic in MiniGop: mGop Toggling
1131         //mini GOP toggling since last Key Frame.
1132         //a regular I keeps the toggling process and does not reset the toggle.  K-0-1-0-1-0-K-0-1-0-1-K-0-1.....
1133         if (picture_index == context_ptr->mini_gop_end_index[mini_gop_index])
1134             context_ptr->mini_gop_toggle = 1 - context_ptr->mini_gop_toggle;
1135 
1136     }
1137 #if NEW_PRED_STRUCT
1138     else if (picture_control_set_ptr->hierarchical_levels == 4)//RPS for 4L GOP
1139     {
1140 
1141         //Reset miniGop Toggling. The first miniGop after a KEY frame has toggle=0
1142         if (picture_control_set_ptr->cpi->common.frame_type == KEY_FRAME)
1143         {
1144             context_ptr->mini_gop_toggle = 0;
1145             picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
1146             picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1147             return;
1148         }
1149 
1150         //         0     2    4      6    8     10     12      14
1151         //            1          5           9            13
1152         //                 3                        11
1153         //                              7
1154 
1155         //DPB: Loc7|Loc6|Loc5|Loc4|Loc3|Loc2|Loc1|Loc0
1156         //Layer 0 : toggling bwteween DPB Location 0, and  locations 3-4-5-6-7
1157         //Layer 1 : DPB Location 1
1158         //Layer 2 : DPB Location 2
1159         //Layer 3 : DPB Location 3
1160 
1161         //         1     3    5      7    9     11     13      15
1162         //            2          6           10            14
1163         //                 4                        12
1164         //                              8
1165         //base0:0                                               base1:16
1166         const uint8_t  base0_idx = context_ptr->mini_gop_toggle ? 0 : 3; //Base layer for prediction from past
1167         const uint8_t  base1_idx = context_ptr->mini_gop_toggle ? 3 : 0; //Base layer for prediction from future
1168         const uint8_t  layer1_idx = 1;
1169         const uint8_t  layer2_idx = 2;
1170         const uint8_t  layer3_idx1 = 4;
1171         const uint8_t  layer3_idx2 = 5;
1172         const uint8_t  layer4_idx1 = 6;
1173         const uint8_t  layer4_idx2 = 7;
1174 
1175         switch (picture_control_set_ptr->temporal_layer_index) {
1176 
1177         case 0:
1178             rps->ref_dpb_index[0] = base0_idx;
1179             rps->ref_dpb_index[2] = base0_idx;
1180             rps->refresh_frame_mask = context_ptr->mini_gop_toggle ? 8 : 1;
1181             break;
1182         case 1:
1183             rps->ref_dpb_index[0] = base0_idx;
1184             rps->ref_dpb_index[2] = base1_idx;
1185             rps->refresh_frame_mask = 2;
1186             break;
1187         case 2:
1188 
1189             if (picture_index == 3) {
1190                 rps->ref_dpb_index[0] = base0_idx;
1191                 rps->ref_dpb_index[2] = layer1_idx;
1192             }
1193             else if (picture_index == 11) {
1194                 rps->ref_dpb_index[0] = layer1_idx;
1195                 rps->ref_dpb_index[2] = base1_idx;
1196             }
1197             rps->refresh_frame_mask = 4;
1198             break;
1199         case 3:
1200 
1201             if (picture_index == 1) {
1202                 rps->ref_dpb_index[0] = base0_idx;
1203                 rps->ref_dpb_index[2] = layer2_idx;
1204                 rps->refresh_frame_mask = 16;
1205             }
1206             else if (picture_index == 5) {
1207                 rps->ref_dpb_index[0] = layer2_idx;
1208                 rps->ref_dpb_index[2] = layer1_idx;
1209                 rps->refresh_frame_mask = 32;
1210             }
1211             else if (picture_index == 9) {
1212                 rps->ref_dpb_index[0] = layer1_idx;
1213                 rps->ref_dpb_index[2] = layer2_idx;
1214                 rps->refresh_frame_mask = 16;
1215             }
1216             else if (picture_index == 13) {
1217                 rps->ref_dpb_index[0] = layer2_idx;
1218                 rps->ref_dpb_index[2] = base1_idx;
1219                 rps->refresh_frame_mask = 32;
1220             }
1221             else {
1222                 SVT_LOG("Error in GOP indexing\n");
1223             }
1224             break;
1225         case 4:
1226             if (picture_index == 0) {
1227                 rps->ref_dpb_index[0] = base0_idx;
1228                 rps->ref_dpb_index[2] = layer3_idx1;
1229                 rps->refresh_frame_mask = 64;
1230             }
1231             else if (picture_index == 2) {
1232                 rps->ref_dpb_index[0] = layer3_idx1;
1233                 rps->ref_dpb_index[2] = layer2_idx;
1234                 rps->refresh_frame_mask = 128;
1235 
1236             }
1237             else if (picture_index == 4) {
1238                 rps->ref_dpb_index[0] = layer2_idx;
1239                 rps->ref_dpb_index[2] = layer3_idx2;
1240                 rps->refresh_frame_mask = 64;
1241 
1242             }
1243             else if (picture_index == 6) {
1244                 rps->ref_dpb_index[0] = layer3_idx2;
1245                 rps->ref_dpb_index[2] = layer1_idx;
1246                 rps->refresh_frame_mask = 128;
1247 
1248             }
1249             else if (picture_index == 8) {
1250                 rps->ref_dpb_index[0] = layer1_idx;
1251                 rps->ref_dpb_index[2] = layer3_idx1;
1252                 rps->refresh_frame_mask = 64;
1253 
1254             }
1255             else if (picture_index == 10) {
1256                 rps->ref_dpb_index[0] = layer3_idx1;
1257                 rps->ref_dpb_index[2] = layer2_idx;
1258                 rps->refresh_frame_mask = 128;
1259 
1260             }
1261             else if (picture_index == 12) {
1262                 rps->ref_dpb_index[0] = layer2_idx;
1263                 rps->ref_dpb_index[2] = layer3_idx2;
1264                 rps->refresh_frame_mask = 64;
1265 
1266             }
1267             else if (picture_index == 14) {
1268                 rps->ref_dpb_index[0] = layer3_idx2;
1269                 rps->ref_dpb_index[2] = base1_idx;
1270                 rps->refresh_frame_mask = 128;
1271 
1272             }
1273             else {
1274                 SVT_LOG("Error in GOp indexing\n");
1275             }
1276 
1277             break;
1278         default:
1279             SVT_LOG("Error: unexpected picture mini Gop number\n");
1280             break;
1281         }
1282         picture_control_set_ptr->cpi->common.use_prev_frame_mvs = EB_FALSE;
1283 
1284         if (picture_control_set_ptr->pred_struct_ptr->pred_type == EB_PRED_LOW_DELAY_P)
1285         {
1286             //P frames.
1287             rps->ref_dpb_index[1] = rps->ref_dpb_index[0];
1288             picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
1289             picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1290         }
1291         else if (picture_control_set_ptr->pred_struct_ptr->pred_type == EB_PRED_RANDOM_ACCESS)
1292         {
1293 
1294             rps->ref_dpb_index[1] = rps->ref_dpb_index[0];
1295 
1296             //Decide on Show Mecanism
1297             if (picture_control_set_ptr->slice_type == I_SLICE)
1298             {
1299                 //3 cases for I slice:  1:Key Frame treated above.  2: broken MiniGop due to sc or intra refresh  3: complete miniGop due to sc or intra refresh
1300                 if (context_ptr->mini_gop_length[0] < picture_control_set_ptr->pred_struct_ptr->pred_struct_period)
1301                 {
1302                     //Scene Change that breaks the mini gop and switch to LDP (if I scene change happens to be aligned with a complete miniGop, then we do not break the pred structure)
1303                     picture_control_set_ptr->cpi->common.show_frame = EB_TRUE;
1304                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1305                 }
1306                 else
1307                 {
1308                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1309                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1310                 }
1311             }
1312             else//B pic
1313             {
1314                 if (context_ptr->mini_gop_length[0] != picture_control_set_ptr->pred_struct_ptr->pred_struct_period)
1315                     SVT_LOG("Error in GOp indexing3\n");
1316 
1317                 if (picture_control_set_ptr->is_used_as_reference_flag)
1318                 {
1319                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1320                     picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1321                 }
1322                 else
1323                 {
1324 
1325                     picture_control_set_ptr->cpi->common.show_frame = EB_FALSE;
1326                     if (picture_index == 0) {
1327                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1328                     }
1329                     else if (picture_index == 2) {
1330                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1331                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer4_idx1;
1332                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer3_idx1;
1333                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer4_idx2;
1334                         picture_control_set_ptr->show_existing_frame_index_array[3] = layer2_idx;
1335                     }
1336                     else if (picture_index == 4) {
1337                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1338                     }
1339                     else if (picture_index == 6) {
1340                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1341                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer4_idx1;
1342                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer3_idx2;
1343                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer4_idx2;
1344                         picture_control_set_ptr->show_existing_frame_index_array[3] = layer1_idx;
1345                     }
1346                     else if (picture_index == 8) {
1347                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1348                     }
1349                     else if (picture_index == 10) {
1350                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1351                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer4_idx1;
1352                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer3_idx1;
1353                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer4_idx2;
1354                         picture_control_set_ptr->show_existing_frame_index_array[3] = layer2_idx;
1355                     }
1356                     else if (picture_index == 12) {
1357                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_FALSE;
1358                     }
1359                     else if (picture_index == 14) {
1360                         picture_control_set_ptr->cpi->common.show_existing_frame = EB_TRUE;
1361                         picture_control_set_ptr->show_existing_frame_index_array[0] = layer4_idx1;
1362                         picture_control_set_ptr->show_existing_frame_index_array[1] = layer3_idx2;
1363                         picture_control_set_ptr->show_existing_frame_index_array[2] = layer4_idx2;
1364                         picture_control_set_ptr->show_existing_frame_index_array[3] = base1_idx;
1365                     }
1366                     else {
1367                         SVT_LOG("Error in GOp indexing2\n");
1368                     }
1369 
1370                 }
1371 
1372             }
1373 
1374         }
1375 
1376         else {
1377             SVT_LOG("SVT [ERROR]: Not supported GOP structure!");
1378             return;
1379         }
1380 
1381         //last pic in MiniGop: mGop Toggling
1382         //mini GOP toggling since last Key Frame.
1383         //a regular I keeps the toggling process and does not reset the toggle.  K-0-1-0-1-0-K-0-1-0-1-K-0-1.....
1384         if (picture_index == context_ptr->mini_gop_end_index[mini_gop_index])
1385             context_ptr->mini_gop_toggle = 1 - context_ptr->mini_gop_toggle;
1386     }
1387 
1388 #endif
1389     else
1390     {
1391         SVT_LOG("SVT [ERROR]: Not supported GOP structure!");
1392         return;
1393     }
1394 }
1395 
1396 /***************************************************************************************************
1397  * Picture Decision Kernel
1398  *
1399  * Notes on the Picture Decision:
1400  *
1401  * The Picture Decision process performs multi-picture level decisions, including setting of the prediction structure,
1402  * setting the picture type and scene change detection.
1403  *
1404  * Inputs:
1405  * Input Picture
1406  *   -Input Picture Data
1407  *
1408  *  Outputs:
1409  *   -Picture Control Set with fully available PA Reference List
1410  *
1411  *  For Low Delay Sequences, pictures are started into the encoder pipeline immediately.
1412  *
1413  *  For Random Access Sequences, pictures are held for up to a PredictionStructurePeriod
1414  *    in order to determine if a Scene Change or Intra Frame is forthcoming. Either of
1415  *    those events (and additionally a End of Sequence Flag) will change the expected
1416  *    prediction structure.
1417  *
1418  *  Below is an example worksheet for how Intra Flags and Scene Change Flags interact
1419  *    together to affect the prediction structure.
1420  *
1421  *  The base prediction structure for this example is a 3-Level Hierarchical Random Access,
1422  *    Single Reference Prediction Structure:
1423  *
1424  *        b   b
1425  *       / \ / \
1426  *      /   B   \
1427  *     /   / \   \
1428  *    I-----------B
1429  *
1430  *  From this base structure, the following RPS positions are derived:
1431  *
1432  *    p   p       b   b       p   p
1433  *     \   \     / \ / \     /   /
1434  *      P   \   /   B   \   /   P
1435  *       \   \ /   / \   \ /   /
1436  *        ----I-----------B----
1437  *
1438  *    L L L   I  [ Normal ]   T T T
1439  *    2 1 0   n               0 1 2
1440  *            t
1441  *            r
1442  *            a
1443  *
1444  *  The RPS is composed of Leading Picture [L2-L0], Intra (CRA), Base/Normal Pictures,
1445  *    and Trailing Pictures [T0-T2]. Generally speaking, Leading Pictures are useful
1446  *    for handling scene changes without adding extraneous I-pictures and the Trailing
1447  *    pictures are useful for terminating GOPs.
1448  *
1449  *  Here is a table of possible combinations of pictures needed to handle intra and
1450  *    scene changes happening in quick succession.
1451  *
1452  *        Distance to scene change ------------>
1453  *
1454  *                  0              1                 2                3+
1455  *   I
1456  *   n
1457  *   t   0        I   I           n/a               n/a              n/a
1458  *   r
1459  *   a              p              p
1460  *                   \            /
1461  *   P   1        I   I          I   I              n/a              n/a
1462  *   e
1463  *   r               p                               p
1464  *   i                \                             /
1465  *   o            p    \         p   p             /   p
1466  *   d             \    \       /     \           /   /
1467  *       2     I    -----I     I       I         I----    I          n/a
1468  *   |
1469  *   |            p   p           p   p            p   p            p   p
1470  *   |             \   \         /     \          /     \          /   /
1471  *   |              P   \       /   p   \        /   p   \        /   P
1472  *   |               \   \     /     \   \      /   /     \      /   /
1473  *   V   3+   I       ----I   I       ----I    I----       I    I----       I
1474  *
1475  *   The table is interpreted as follows:
1476  *
1477  *   If there are no SCs or Intras encountered for a PredPeriod, then the normal
1478  *     prediction structure is applied.
1479  *
1480  *   If there is an intra in the PredPeriod, then one of the above combinations of
1481  *     Leading and Trailing pictures is used.  If there is no scene change, the last
1482  *     valid column consisting of Trailing Pictures only is used.  However, if there
1483  *     is an upcoming scene change before the next intra, then one of the above patterns
1484  *     is used. In the case of End of Sequence flags, only the last valid column of Trailing
1485  *     Pictures is used. The intention here is that any combination of Intra Flag and Scene
1486  *     Change flag can be coded.
1487  *
1488  ***************************************************************************************************/
eb_vp9_picture_decision_kernel(void * input_ptr)1489 void* eb_vp9_picture_decision_kernel(void *input_ptr)
1490 {
1491     PictureDecisionContext      *context_ptr = (PictureDecisionContext*) input_ptr;
1492 
1493     PictureParentControlSet     *picture_control_set_ptr;
1494 
1495     EncodeContext               *encode_context_ptr;
1496     SequenceControlSet          *sequence_control_set_ptr;
1497 
1498     EbObjectWrapper             *input_results_wrapper_ptr;
1499     PictureAnalysisResults      *input_results_ptr;
1500 
1501     EbObjectWrapper             *output_results_wrapper_ptr;
1502     PictureDecisionResults      *output_results_ptr;
1503 
1504     PredictionStructureEntry    *pred_position_ptr;
1505 
1506     EB_BOOL                      pre_assignment_buffer_first_pass_flag;
1507     EB_SLICE                     picture_type;
1508 
1509     PictureDecisionReorderEntry *queue_entry_ptr;
1510     int32_t                      queue_entry_index;
1511 
1512     int32_t                      previous_entry_index;
1513 
1514     PaReferenceQueueEntry       *input_entry_ptr;
1515     uint32_t                     input_queue_index;
1516 
1517     PaReferenceQueueEntry       *pa_reference_entry_ptr;
1518     uint32_t                     pa_reference_queue_index;
1519 
1520     uint64_t                     ref_poc;
1521 
1522     uint32_t                     dep_idx;
1523     uint64_t                     dep_poc;
1524 
1525     uint32_t                     dep_list_count;
1526 
1527     // Dynamic GOP
1528     uint32_t                     mini_gop_index;
1529     uint32_t                     picture_index;
1530 
1531     EB_BOOL                      window_avail,frame_passe_thru;
1532     uint32_t                     window_index;
1533     uint32_t                     entry_index;
1534     PictureParentControlSet     *parent_pcs_window[FUTURE_WINDOW_WIDTH+2];
1535     UNUSED(parent_pcs_window);
1536     // Debug
1537     uint64_t                     loop_count = 0;
1538 
1539     for(;;) {
1540 
1541         // Get Input Full Object
1542         eb_vp9_get_full_object(
1543             context_ptr->picture_analysis_results_input_fifo_ptr,
1544             &input_results_wrapper_ptr);
1545 
1546         input_results_ptr         = (PictureAnalysisResults*)   input_results_wrapper_ptr->object_ptr;
1547         picture_control_set_ptr    = (PictureParentControlSet  *)  input_results_ptr->picture_control_set_wrapper_ptr->object_ptr;
1548         sequence_control_set_ptr   = (SequenceControlSet *)       picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
1549         encode_context_ptr        = (EncodeContext*)            sequence_control_set_ptr->encode_context_ptr;
1550 
1551         loop_count ++;
1552 
1553         // Input Picture Analysis Results into the Picture Decision Reordering Queue
1554         // P.S. Since the prior Picture Analysis processes stage is multithreaded, inputs to the Picture Decision Process
1555         // can arrive out-of-display-order, so a the Picture Decision Reordering Queue is used to enforce processing of
1556         // pictures in display order
1557 
1558         queue_entry_index                                         =   (int32_t) (picture_control_set_ptr->picture_number - encode_context_ptr->picture_decision_reorder_queue[encode_context_ptr->picture_decision_reorder_queue_head_index]->picture_number);
1559         queue_entry_index                                         +=  encode_context_ptr->picture_decision_reorder_queue_head_index;
1560         queue_entry_index                                         =   (queue_entry_index > PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH - 1) ? queue_entry_index - PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH : queue_entry_index;
1561         queue_entry_ptr                                           =   encode_context_ptr->picture_decision_reorder_queue[queue_entry_index];
1562         if(queue_entry_ptr->parent_pcs_wrapper_ptr != NULL){
1563             CHECK_REPORT_ERROR_NC(
1564                 encode_context_ptr->app_callback_ptr,
1565                 EB_ENC_PD_ERROR7);
1566         }else{
1567             queue_entry_ptr->parent_pcs_wrapper_ptr                      =   input_results_ptr->picture_control_set_wrapper_ptr;
1568             queue_entry_ptr->picture_number                            =   picture_control_set_ptr->picture_number;
1569         }
1570         // Process the head of the Picture Decision Reordering Queue (Entry N)
1571         // P.S. The Picture Decision Reordering Queue should be parsed in the display order to be able to construct a pred structure
1572         queue_entry_ptr = encode_context_ptr->picture_decision_reorder_queue[encode_context_ptr->picture_decision_reorder_queue_head_index];
1573 
1574         while(queue_entry_ptr->parent_pcs_wrapper_ptr != EB_NULL) {
1575 
1576             if(  queue_entry_ptr->picture_number == 0  ||
1577                 ((PictureParentControlSet   *)(queue_entry_ptr->parent_pcs_wrapper_ptr->object_ptr))->end_of_sequence_flag == EB_TRUE){
1578                     frame_passe_thru = EB_TRUE;
1579             }else{
1580                  frame_passe_thru = EB_FALSE;
1581             }
1582             window_avail                = EB_TRUE;
1583             previous_entry_index         = QUEUE_GET_PREVIOUS_SPOT(encode_context_ptr->picture_decision_reorder_queue_head_index);
1584 
1585             if(encode_context_ptr->picture_decision_reorder_queue[previous_entry_index]->parent_pcs_wrapper_ptr == NULL){
1586                 window_avail = EB_FALSE;
1587             }else{
1588                 parent_pcs_window[0] =(PictureParentControlSet   *) encode_context_ptr->picture_decision_reorder_queue[previous_entry_index]->parent_pcs_wrapper_ptr->object_ptr;
1589                 parent_pcs_window[1] =(PictureParentControlSet   *) encode_context_ptr->picture_decision_reorder_queue[encode_context_ptr->picture_decision_reorder_queue_head_index]->parent_pcs_wrapper_ptr->object_ptr;
1590                 for(window_index=0;    window_index<FUTURE_WINDOW_WIDTH;     window_index++){
1591                     entry_index = QUEUE_GET_NEXT_SPOT(encode_context_ptr->picture_decision_reorder_queue_head_index , window_index+1 ) ;
1592 
1593                     if(encode_context_ptr->picture_decision_reorder_queue[entry_index]->parent_pcs_wrapper_ptr == NULL ){
1594                         window_avail = EB_FALSE;
1595                         break;
1596                     }
1597                     else if (((PictureParentControlSet   *)(encode_context_ptr->picture_decision_reorder_queue[entry_index]->parent_pcs_wrapper_ptr->object_ptr))->end_of_sequence_flag == EB_TRUE) {
1598                         window_avail = EB_FALSE;
1599                         frame_passe_thru = EB_TRUE;
1600                         break;
1601                     }else{
1602                         parent_pcs_window[2+window_index] =(PictureParentControlSet   *) encode_context_ptr->picture_decision_reorder_queue[entry_index]->parent_pcs_wrapper_ptr->object_ptr;
1603                     }
1604                 }
1605             }
1606             picture_control_set_ptr                        = (PictureParentControlSet  *)  queue_entry_ptr->parent_pcs_wrapper_ptr->object_ptr;
1607 
1608            if(picture_control_set_ptr->idr_flag == EB_TRUE)
1609                  context_ptr->last_solid_color_frame_poc = 0xFFFFFFFF;
1610 
1611             if(window_avail == EB_TRUE){
1612                 picture_control_set_ptr->scene_change_flag           = EB_FALSE;
1613             }
1614 
1615             if(window_avail == EB_TRUE ||frame_passe_thru == EB_TRUE)
1616             {
1617             // Place the PCS into the Pre-Assignment Buffer
1618             // P.S. The Pre-Assignment Buffer is used to store a whole pre-structure
1619             encode_context_ptr->pre_assignment_buffer[encode_context_ptr->pre_assignment_buffer_count] = queue_entry_ptr->parent_pcs_wrapper_ptr;
1620 
1621             // Setup the PCS & SCS
1622             picture_control_set_ptr                        = (PictureParentControlSet  *)  encode_context_ptr->pre_assignment_buffer[encode_context_ptr->pre_assignment_buffer_count]->object_ptr;
1623 
1624             // Set the POC Number
1625             picture_control_set_ptr->picture_number    = (encode_context_ptr->current_input_poc + 1) /*& ((1 << sequence_control_set_ptr->bitsForPictureOrderCount)-1)*/;
1626             encode_context_ptr->current_input_poc      = picture_control_set_ptr->picture_number;
1627 
1628             picture_control_set_ptr->pred_structure = sequence_control_set_ptr->static_config.pred_structure;
1629 
1630             picture_control_set_ptr->hierarchical_layers_diff = 0;
1631 
1632            picture_control_set_ptr->init_pred_struct_position_flag    = EB_FALSE;
1633 
1634            picture_control_set_ptr->target_bit_rate          = sequence_control_set_ptr->static_config.target_bit_rate;
1635 
1636            release_prev_picture_from_reorder_queue(
1637                encode_context_ptr);
1638 
1639            // If the Intra period length is 0, then introduce an intra for every picture
1640            if (sequence_control_set_ptr->intra_period == 0 || picture_control_set_ptr->picture_number == 0 ) {
1641                picture_control_set_ptr->idr_flag = EB_TRUE;
1642            }
1643            // If an #IntraPeriodLength has passed since the last Intra, then introduce a CRA or IDR based on Intra Refresh type
1644            else if (sequence_control_set_ptr->intra_period != -1) {
1645                if ((encode_context_ptr->intra_period_position == (uint32_t)sequence_control_set_ptr->intra_period) ||
1646                    (picture_control_set_ptr->scene_change_flag == EB_TRUE)) {
1647                    picture_control_set_ptr->idr_flag = EB_TRUE;
1648                }
1649            }
1650 
1651             encode_context_ptr->pre_assignment_buffer_eos_flag             = (picture_control_set_ptr->end_of_sequence_flag) ? (uint32_t)EB_TRUE : encode_context_ptr->pre_assignment_buffer_eos_flag;
1652 
1653             // Increment the Pre-Assignment Buffer Intra Count
1654             encode_context_ptr->pre_assignment_buffer_intra_count         += picture_control_set_ptr->idr_flag;
1655             encode_context_ptr->pre_assignment_buffer_idr_count           += picture_control_set_ptr->idr_flag;
1656             encode_context_ptr->pre_assignment_buffer_count              += 1;
1657 
1658             if (sequence_control_set_ptr->static_config.rate_control_mode)
1659             {
1660                 // Increment the Intra Period Position
1661                 encode_context_ptr->intra_period_position = (encode_context_ptr->intra_period_position == (uint32_t)sequence_control_set_ptr->intra_period) ? 0 : encode_context_ptr->intra_period_position + 1;
1662             }
1663             else
1664             {
1665                 // Increment the Intra Period Position
1666 #if BEA_SCENE_CHANGE
1667                 encode_context_ptr->intra_period_position = ((encode_context_ptr->intra_period_position == (uint32_t)sequence_control_set_ptr->intra_period) ) ? 0 : encode_context_ptr->intra_period_position + 1;
1668 
1669 #else
1670                 encode_context_ptr->intra_period_position = ((encode_context_ptr->intra_period_position == (uint32_t)sequence_control_set_ptr->intra_period) || (picture_control_set_ptr->scene_change_flag == EB_TRUE)) ? 0 : encode_context_ptr->intra_period_position + 1;
1671 #endif
1672             }
1673 
1674             // Determine if Pictures can be released from the Pre-Assignment Buffer
1675             if ((encode_context_ptr->pre_assignment_buffer_intra_count > 0) ||
1676                 (encode_context_ptr->pre_assignment_buffer_count == (uint32_t) (1 << sequence_control_set_ptr->hierarchical_levels)) ||
1677                 (encode_context_ptr->pre_assignment_buffer_eos_flag == EB_TRUE) ||
1678                 (picture_control_set_ptr->pred_structure == EB_PRED_LOW_DELAY_P) ||
1679                 (picture_control_set_ptr->pred_structure == EB_PRED_LOW_DELAY_B))
1680             {
1681 
1682                 // Initialize Picture Block Params
1683                 context_ptr->mini_gop_start_index[0]         = 0;
1684                 context_ptr->mini_gop_end_index     [0]         = encode_context_ptr->pre_assignment_buffer_count - 1;
1685                 context_ptr->mini_gop_length     [0]         = encode_context_ptr->pre_assignment_buffer_count;
1686 
1687                 context_ptr->mini_gop_hierarchical_levels[0] = sequence_control_set_ptr->hierarchical_levels;
1688                 context_ptr->mini_gop_intra_count[0]         = encode_context_ptr->pre_assignment_buffer_intra_count;
1689                 context_ptr->mini_gop_idr_count  [0]         = encode_context_ptr->pre_assignment_buffer_idr_count;
1690                 context_ptr->total_number_of_mini_gops         = 1;
1691 
1692                 encode_context_ptr->previous_mini_gop_hierarchical_levels = (picture_control_set_ptr->picture_number == 0) ?
1693                     sequence_control_set_ptr->hierarchical_levels :
1694                     encode_context_ptr->previous_mini_gop_hierarchical_levels;
1695 
1696 #if NEW_PRED_STRUCT
1697                 {
1698                     if (encode_context_ptr->pre_assignment_buffer_count > 1)
1699                     {
1700                         eb_vp9_initialize_mini_gop_activity_array(
1701                             context_ptr);
1702 
1703                         if (encode_context_ptr->pre_assignment_buffer_count == 16)
1704                             context_ptr->mini_gop_activity_array[L5_0_INDEX] = EB_FALSE;
1705                         else {
1706                             context_ptr->mini_gop_activity_array[L4_0_INDEX] = EB_FALSE;
1707                             context_ptr->mini_gop_activity_array[L4_1_INDEX] = EB_FALSE;
1708                         }
1709                         eb_vp9_generate_picture_window_split(
1710                             context_ptr,
1711                             encode_context_ptr);
1712 
1713                         eb_vp9_handle_incomplete_picture_window_map(
1714                             context_ptr,
1715                             encode_context_ptr);
1716                     }
1717                 }
1718 #endif
1719                 generate_mini_gop_rps(
1720                     context_ptr,
1721                     encode_context_ptr);
1722 
1723                 // Loop over Mini GOPs
1724 
1725                 for (mini_gop_index = 0; mini_gop_index < context_ptr->total_number_of_mini_gops; ++mini_gop_index) {
1726 
1727                     pre_assignment_buffer_first_pass_flag = EB_TRUE;
1728 #if NEW_PRED_STRUCT
1729                     {
1730                         update_base_layer_reference_queue_dependent_count(
1731                             context_ptr,
1732                             encode_context_ptr,
1733                             mini_gop_index);
1734 
1735                         // Keep track of the number of hierarchical levels of the latest implemented mini GOP
1736                         encode_context_ptr->previous_mini_gop_hierarchical_levels = context_ptr->mini_gop_hierarchical_levels[mini_gop_index];
1737                     }
1738 #endif
1739                     // 1st Loop over Pictures in the Pre-Assignment Buffer
1740                     for (picture_index = context_ptr->mini_gop_start_index[mini_gop_index]; picture_index <= context_ptr->mini_gop_end_index[mini_gop_index]; ++picture_index) {
1741 
1742                         picture_control_set_ptr = (PictureParentControlSet  *)encode_context_ptr->pre_assignment_buffer[picture_index]->object_ptr;
1743                         sequence_control_set_ptr = (SequenceControlSet *)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
1744 
1745                         // Keep track of the mini GOP size to which the input picture belongs - needed @ PictureManagerProcess()
1746                         picture_control_set_ptr->pre_assignment_buffer_count = context_ptr->mini_gop_length[mini_gop_index];
1747 
1748                         // Update the Pred Structure if cutting short a Random Access period
1749                         if ((context_ptr->mini_gop_length[mini_gop_index] < picture_control_set_ptr->pred_struct_ptr->pred_struct_period || context_ptr->mini_gop_idr_count[mini_gop_index] > 0) &&
1750 
1751                             picture_control_set_ptr->pred_struct_ptr->pred_type == EB_PRED_RANDOM_ACCESS &&
1752                             picture_control_set_ptr->idr_flag == EB_FALSE)
1753                         {
1754                             // Correct the Pred Index before switching structures
1755                             if (pre_assignment_buffer_first_pass_flag == EB_TRUE) {
1756                                 encode_context_ptr->pred_struct_position -= picture_control_set_ptr->pred_struct_ptr->init_pic_index;
1757                             }
1758 
1759                             picture_control_set_ptr->pred_struct_ptr = eb_vp9_get_prediction_structure(
1760                                 encode_context_ptr->prediction_structure_group_ptr,
1761                                 EB_PRED_LOW_DELAY_P,
1762                                 1,
1763                                 picture_control_set_ptr->hierarchical_levels);
1764 
1765                             // Set the RPS Override Flag - this current only will convert a Random Access structure to a Low Delay structure
1766                             picture_control_set_ptr->use_rps_in_sps = EB_FALSE;
1767 
1768                             picture_type = P_SLICE;
1769 
1770                         }
1771                         else {
1772 
1773                             picture_control_set_ptr->use_rps_in_sps = EB_FALSE;
1774 
1775                             // Set the Picture Type
1776                             picture_type =
1777                                 (picture_control_set_ptr->idr_flag) ? I_SLICE :
1778                                 (picture_control_set_ptr->pred_structure == EB_PRED_LOW_DELAY_P) ? P_SLICE :
1779                                 (picture_control_set_ptr->pred_structure == EB_PRED_LOW_DELAY_B) ? B_SLICE :
1780                                 (picture_control_set_ptr->pre_assignment_buffer_count == picture_control_set_ptr->pred_struct_ptr->pred_struct_period) ? ((picture_index == context_ptr->mini_gop_end_index[mini_gop_index] && sequence_control_set_ptr->static_config.base_layer_switch_mode) ? P_SLICE : B_SLICE) :
1781 
1782                                 (encode_context_ptr->pre_assignment_buffer_eos_flag) ? P_SLICE :
1783                                 B_SLICE;
1784                         }
1785 #if NEW_PRED_STRUCT
1786                         // If mini GOP switch, reset position
1787                         encode_context_ptr->pred_struct_position = (picture_control_set_ptr->init_pred_struct_position_flag) ?
1788                             picture_control_set_ptr->pred_struct_ptr->init_pic_index :
1789                             encode_context_ptr->pred_struct_position;
1790 #endif
1791                         // If Intra, reset position
1792                         if (picture_control_set_ptr->idr_flag == EB_TRUE) {
1793                             encode_context_ptr->pred_struct_position = picture_control_set_ptr->pred_struct_ptr->init_pic_index;
1794                         }
1795                         else if (encode_context_ptr->elapsed_non_idr_count == 0) {
1796                             // If we are the picture directly after a IDR, we have to not use references that violate the IDR
1797                             encode_context_ptr->pred_struct_position = picture_control_set_ptr->pred_struct_ptr->init_pic_index + 1;
1798                         }
1799                         // Elif Scene Change, determine leading and trailing pictures
1800                         //else if (encode_context_ptr->pre_assignment_buffer_scene_change_count > 0) {
1801                         //    if(buffer_index < encode_context_ptr->pre_assignment_buffer_scene_change_index) {
1802                         //        ++encode_context_ptr->pred_struct_position;
1803                         //        picture_type = P_SLICE;
1804                         //    }
1805                         //    else {
1806                         //        encode_context_ptr->pred_struct_position = picture_control_set_ptr->pred_struct_ptr->init_pic_index + encode_context_ptr->pre_assignment_buffer_count - buffer_index - 1;
1807                         //    }
1808                         //}
1809                         // Else, Increment the position normally
1810                         else {
1811                             ++encode_context_ptr->pred_struct_position;
1812                         }
1813 
1814                         // The poc number of the latest IDR picture is stored so that last_idr_picture (present in PCS) for the incoming pictures can be updated.
1815                         // The last_idr_picture is used in reseting the poc (in entropy coding) whenever IDR is encountered.
1816                         // Note IMP: This logic only works when display and decode order are the same. Currently for Random Access, IDR is inserted (similar to CRA) by using trailing P pictures (low delay fashion) and breaking prediction structure.
1817                         // Note: When leading P pictures are implemented, this logic has to change..
1818                         if (picture_control_set_ptr->idr_flag == EB_TRUE) {
1819                             encode_context_ptr->last_idr_picture = picture_control_set_ptr->picture_number;
1820                         }
1821                         else {
1822                             picture_control_set_ptr->last_idr_picture = encode_context_ptr->last_idr_picture;
1823                         }
1824 
1825                         // Cycle the pred_struct_position if its overflowed
1826                         encode_context_ptr->pred_struct_position = (encode_context_ptr->pred_struct_position == picture_control_set_ptr->pred_struct_ptr->pred_struct_entry_count) ?
1827                             encode_context_ptr->pred_struct_position - picture_control_set_ptr->pred_struct_ptr->pred_struct_period :
1828                             encode_context_ptr->pred_struct_position;
1829 
1830                         pred_position_ptr = picture_control_set_ptr->pred_struct_ptr->pred_struct_entry_ptr_array[encode_context_ptr->pred_struct_position];
1831 
1832                         // Set the Slice type
1833                         picture_control_set_ptr->slice_type = picture_type;
1834                         ((EbPaReferenceObject  *)picture_control_set_ptr->pareference_picture_wrapper_ptr->object_ptr)->slice_type = picture_control_set_ptr->slice_type;
1835 
1836                         switch (picture_type) {
1837 
1838                         case I_SLICE:
1839 
1840                             // Reset Prediction Structure Position & Reference Struct Position
1841                             if (picture_control_set_ptr->picture_number == 0){
1842                                 encode_context_ptr->intra_period_position = 0;
1843                             }
1844 
1845                             //-------------------------------
1846                             // IDR
1847                             //-------------------------------
1848                             if (picture_control_set_ptr->idr_flag == EB_TRUE) {
1849 
1850                                 // Reset the pictures since last IDR counter
1851                                 encode_context_ptr->elapsed_non_idr_count = 0;
1852 
1853                             }
1854                             break;
1855 
1856                         case P_SLICE:
1857                         case B_SLICE:
1858 
1859                             // Reset IDR Flag
1860                             picture_control_set_ptr->idr_flag = EB_FALSE;
1861 
1862                             // Increment & Clip the elapsed Non-IDR Counter. This is clipped rather than allowed to free-run
1863                             // inorder to avoid rollover issues.  This assumes that any the GOP period is less than MAX_ELAPSED_IDR_COUNT
1864                             encode_context_ptr->elapsed_non_idr_count = MIN(encode_context_ptr->elapsed_non_idr_count + 1, MAX_ELAPSED_IDR_COUNT);
1865 
1866                             CHECK_REPORT_ERROR(
1867                                 (picture_control_set_ptr->pred_struct_ptr->pred_struct_entry_count < MAX_ELAPSED_IDR_COUNT),
1868                                 encode_context_ptr->app_callback_ptr,
1869                                 EB_ENC_PD_ERROR1);
1870 
1871                             break;
1872 
1873                         default:
1874 
1875                             CHECK_REPORT_ERROR_NC(
1876                                 encode_context_ptr->app_callback_ptr,
1877                                 EB_ENC_PD_ERROR2);
1878 
1879                             break;
1880                         }
1881                         picture_control_set_ptr->pred_struct_index = (uint8_t)encode_context_ptr->pred_struct_position;
1882                         picture_control_set_ptr->temporal_layer_index = (uint8_t)pred_position_ptr->temporal_layer_index;
1883                         picture_control_set_ptr->is_used_as_reference_flag = pred_position_ptr->is_referenced;
1884 
1885                         // Set the Decode Order
1886                         if ((context_ptr->mini_gop_idr_count[mini_gop_index] == 0) &&
1887                             (context_ptr->mini_gop_length[mini_gop_index] == picture_control_set_ptr->pred_struct_ptr->pred_struct_period))
1888 
1889                         {
1890                             picture_control_set_ptr->decode_order = encode_context_ptr->decode_base_number + pred_position_ptr->decode_order;
1891                         }
1892                         else {
1893                             picture_control_set_ptr->decode_order = picture_control_set_ptr->picture_number;
1894                         }
1895 
1896                         encode_context_ptr->terminating_sequence_flag_received = (picture_control_set_ptr->end_of_sequence_flag == EB_TRUE) ?
1897                             EB_TRUE :
1898                             encode_context_ptr->terminating_sequence_flag_received;
1899 
1900                         encode_context_ptr->terminating_picture_number = (picture_control_set_ptr->end_of_sequence_flag == EB_TRUE) ?
1901                             picture_control_set_ptr->picture_number :
1902                             encode_context_ptr->terminating_picture_number;
1903 
1904                         pre_assignment_buffer_first_pass_flag = EB_FALSE;
1905 
1906                         generate_rps_info(
1907                             picture_control_set_ptr,
1908                             context_ptr,
1909 #if NEW_PRED_STRUCT
1910                             picture_index - context_ptr->mini_gop_start_index[mini_gop_index],
1911                             mini_gop_index);
1912 #else
1913                             picture_index,
1914                             mini_gop_index);
1915 #endif
1916                         picture_control_set_ptr->cpi->allow_comp_inter_inter = 0;
1917                         picture_control_set_ptr->cpi->common.reference_mode = (REFERENCE_MODE)0xFF;
1918                         if (picture_control_set_ptr->slice_type != I_SLICE) {
1919                             picture_control_set_ptr->cpi->allow_comp_inter_inter = 1;
1920                             if (picture_control_set_ptr->temporal_layer_index == 0 || picture_control_set_ptr->slice_type == P_SLICE) {
1921                                 picture_control_set_ptr->cpi->common.reference_mode = SINGLE_REFERENCE;
1922                             }
1923                             else {
1924                                 picture_control_set_ptr->cpi->common.reference_mode = REFERENCE_MODE_SELECT;
1925                             }
1926                         }
1927                         picture_control_set_ptr->cpi->common.refresh_frame_context = 1; /* Two state 0 = NO, 1 = YES */
1928                         memset(picture_control_set_ptr->cpi->common.ref_frame_sign_bias, 0, MAX_REF_FRAMES * sizeof(int));
1929 
1930                         if (picture_control_set_ptr->cpi->common.reference_mode == REFERENCE_MODE_SELECT)
1931                         {
1932                             picture_control_set_ptr->cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1;
1933                         }
1934 
1935                         if (picture_control_set_ptr->cpi->common.reference_mode != SINGLE_REFERENCE)
1936                             eb_vp9_setup_compound_reference_mode(&picture_control_set_ptr->cpi->common);
1937 
1938 #if USE_SRC_REF
1939                         picture_control_set_ptr->use_src_ref = (picture_control_set_ptr->temporal_layer_index > 0) ?
1940                             EB_TRUE :
1941                             EB_FALSE;
1942 #else
1943                         picture_control_set_ptr->use_src_ref = (sequence_control_set_ptr->input_resolution == INPUT_SIZE_4K_RANGE && picture_control_set_ptr->temporal_layer_index > 0) ?
1944                             EB_TRUE :
1945                             EB_FALSE;
1946 #endif
1947 
1948                         // Set QP Scaling Mode
1949                         picture_control_set_ptr->qp_scaling_mode = (picture_control_set_ptr->slice_type == I_SLICE) ?
1950                             QP_SCALING_MODE_1 :
1951                             QP_SCALING_MODE_0 ;
1952 
1953                         // ME Kernel Multi-Processes Signal(s) derivation
1954                         if (sequence_control_set_ptr->static_config.tune == TUNE_SQ) {
1955                             eb_vp9_signal_derivation_multi_processes_sq(
1956                                 sequence_control_set_ptr,
1957                                 picture_control_set_ptr);
1958                         }
1959                         else if (sequence_control_set_ptr->static_config.tune == TUNE_VMAF) {
1960                             eb_vp9_signal_derivation_multi_processes_vmaf(
1961                                 sequence_control_set_ptr,
1962                                 picture_control_set_ptr);
1963                         }
1964                         else {
1965                             eb_vp9_signal_derivation_multi_processes_oq(
1966                                 sequence_control_set_ptr,
1967                                 picture_control_set_ptr);
1968                         }
1969 
1970                         // Update the Dependant List Count - If there was an I-frame or Scene Change, then cleanup the Picture Decision PA Reference Queue Dependent Counts
1971                         if (picture_control_set_ptr->slice_type == I_SLICE)
1972                         {
1973 
1974                             input_queue_index = encode_context_ptr->picture_decision_pa_reference_queue_head_index;
1975 
1976                             while(input_queue_index != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) {
1977 
1978                                 input_entry_ptr = encode_context_ptr->picture_decision_pa_reference_queue[input_queue_index];
1979 
1980                                 // Modify Dependent List0
1981                                 dep_list_count = input_entry_ptr->list0.list_count;
1982                                 for(dep_idx=0; dep_idx < dep_list_count; ++dep_idx) {
1983 
1984                                     // Adjust the latest current_input_poc in case we're in a POC rollover scenario
1985                                     // current_input_poc += (current_input_poc < input_entry_ptr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
1986 
1987                                     dep_poc = POC_CIRCULAR_ADD(
1988                                         input_entry_ptr->picture_number, // can't use a value that gets reset
1989                                         input_entry_ptr->list0.list[dep_idx]/*,
1990                                         sequence_control_set_ptr->bitsForPictureOrderCount*/);
1991 
1992                                     // If Dependent POC is greater or equal to the IDR POC
1993                                     if(dep_poc >= picture_control_set_ptr->picture_number && input_entry_ptr->list0.list[dep_idx]) {
1994 
1995                                         input_entry_ptr->list0.list[dep_idx] = 0;
1996 
1997                                         // Decrement the Reference's referenceCount
1998                                         --input_entry_ptr->dependent_count;
1999 
2000                                         CHECK_REPORT_ERROR(
2001                                             (input_entry_ptr->dependent_count != ~0u),
2002                                             encode_context_ptr->app_callback_ptr,
2003                                             EB_ENC_PD_ERROR3);
2004                                     }
2005                                 }
2006 
2007                                 // Modify Dependent List1
2008                                 dep_list_count = input_entry_ptr->list1.list_count;
2009                                 for(dep_idx=0; dep_idx < dep_list_count; ++dep_idx) {
2010 
2011                                     // Adjust the latest current_input_poc in case we're in a POC rollover scenario
2012                                     // current_input_poc += (current_input_poc < input_entry_ptr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
2013 
2014                                     dep_poc = POC_CIRCULAR_ADD(
2015                                         input_entry_ptr->picture_number,
2016                                         input_entry_ptr->list1.list[dep_idx]/*,
2017                                         sequence_control_set_ptr->bitsForPictureOrderCount*/);
2018 
2019                                     // If Dependent POC is greater or equal to the IDR POC
2020                                     if(((dep_poc >= picture_control_set_ptr->picture_number) || (((picture_control_set_ptr->pre_assignment_buffer_count != picture_control_set_ptr->pred_struct_ptr->pred_struct_period) || (picture_control_set_ptr->idr_flag == EB_TRUE)) && (dep_poc >  (picture_control_set_ptr->picture_number - picture_control_set_ptr->pre_assignment_buffer_count)))) && input_entry_ptr->list1.list[dep_idx]) {
2021                                         input_entry_ptr->list1.list[dep_idx] = 0;
2022 
2023                                         // Decrement the Reference's referenceCount
2024                                         --input_entry_ptr->dependent_count;
2025 
2026                                         CHECK_REPORT_ERROR(
2027                                             (input_entry_ptr->dependent_count != ~0u),
2028                                             encode_context_ptr->app_callback_ptr,
2029                                             EB_ENC_PD_ERROR3);
2030                                     }
2031 
2032                                 }
2033 
2034                                 // Increment the input_queue_index Iterator
2035                                 input_queue_index = (input_queue_index == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : input_queue_index + 1;
2036                             }
2037 
2038                         } else if(picture_control_set_ptr->idr_flag == EB_TRUE) {
2039 
2040                             // Set the Picture Decision PA Reference Entry pointer
2041                             input_entry_ptr                           = (PaReferenceQueueEntry*) EB_NULL;
2042                         }
2043 
2044                         // Place Picture in Picture Decision PA Reference Queue
2045                         input_entry_ptr                                       = encode_context_ptr->picture_decision_pa_reference_queue[encode_context_ptr->picture_decision_pa_reference_queue_tail_index];
2046                         input_entry_ptr->input_object_ptr                       = picture_control_set_ptr->pareference_picture_wrapper_ptr;
2047                         input_entry_ptr->picture_number                        = picture_control_set_ptr->picture_number;
2048                         input_entry_ptr->reference_entry_index                  = encode_context_ptr->picture_decision_pa_reference_queue_tail_index;
2049                         input_entry_ptr->p_pcs_ptr = picture_control_set_ptr;
2050                         encode_context_ptr->picture_decision_pa_reference_queue_tail_index     =
2051                             (encode_context_ptr->picture_decision_pa_reference_queue_tail_index == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->picture_decision_pa_reference_queue_tail_index + 1;
2052 
2053                         // Check if the Picture Decision PA Reference is full
2054                         CHECK_REPORT_ERROR(
2055                             (((encode_context_ptr->picture_decision_pa_reference_queue_head_index != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) ||
2056                             (encode_context_ptr->picture_decision_pa_reference_queue[encode_context_ptr->picture_decision_pa_reference_queue_head_index]->input_object_ptr == EB_NULL))),
2057                             encode_context_ptr->app_callback_ptr,
2058                             EB_ENC_PD_ERROR4);
2059 
2060                         // Copy the reference lists into the inputEntry and
2061                         // set the Reference Counts Based on Temporal Layer and how many frames are active
2062                         picture_control_set_ptr->ref_list0_count = (picture_type == I_SLICE) ? 0 : (uint8_t)pred_position_ptr->ref_list0.reference_list_count;
2063                         picture_control_set_ptr->ref_list1_count = (picture_type == I_SLICE) ? 0 : (uint8_t)pred_position_ptr->ref_list1.reference_list_count;
2064 
2065                         input_entry_ptr->list0_ptr             = &pred_position_ptr->ref_list0;
2066                         input_entry_ptr->list1_ptr             = &pred_position_ptr->ref_list1;
2067 
2068                         {
2069 
2070                             // Copy the Dependent Lists
2071                             // *Note - we are removing any leading picture dependencies for now
2072                             input_entry_ptr->list0.list_count = 0;
2073                             for(dep_idx = 0; dep_idx < pred_position_ptr->dep_list0.list_count; ++dep_idx) {
2074                                 if(pred_position_ptr->dep_list0.list[dep_idx] >= 0) {
2075                                     input_entry_ptr->list0.list[input_entry_ptr->list0.list_count++] = pred_position_ptr->dep_list0.list[dep_idx];
2076                                 }
2077                             }
2078 
2079                             input_entry_ptr->list1.list_count = pred_position_ptr->dep_list1.list_count;
2080                             for(dep_idx = 0; dep_idx < pred_position_ptr->dep_list1.list_count; ++dep_idx) {
2081                                 input_entry_ptr->list1.list[dep_idx] = pred_position_ptr->dep_list1.list[dep_idx];
2082                             }
2083 
2084                             input_entry_ptr->dep_list0_count                = input_entry_ptr->list0.list_count;
2085                             input_entry_ptr->dep_list1_count                = input_entry_ptr->list1.list_count;
2086                             input_entry_ptr->dependent_count               = input_entry_ptr->dep_list0_count + input_entry_ptr->dep_list1_count;
2087 
2088                         }
2089 
2090                         ((EbPaReferenceObject  *)picture_control_set_ptr->pareference_picture_wrapper_ptr->object_ptr)->dependent_pictures_count = input_entry_ptr->dependent_count;
2091 
2092                         /* uint32_t depCnt = ((EbPaReferenceObject  *)picture_control_set_ptr->pareference_picture_wrapper_ptr->object_ptr)->dependent_pictures_count;
2093                         if (picture_control_set_ptr->picture_number>0 && picture_control_set_ptr->slice_type==I_SLICE && depCnt!=8 )
2094                         SVT_LOG("depCnt Error1  POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);
2095                         else if (picture_control_set_ptr->slice_type==B_SLICE && picture_control_set_ptr->temporal_layer_index == 0 && depCnt!=8)
2096                         SVT_LOG("depCnt Error2  POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);
2097                         else if (picture_control_set_ptr->slice_type==B_SLICE && picture_control_set_ptr->temporal_layer_index == 1 && depCnt!=4)
2098                         SVT_LOG("depCnt Error3  POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);
2099                         else if (picture_control_set_ptr->slice_type==B_SLICE && picture_control_set_ptr->temporal_layer_index == 2 && depCnt!=2)
2100                         SVT_LOG("depCnt Error4  POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);
2101                         else if (picture_control_set_ptr->slice_type==B_SLICE && picture_control_set_ptr->temporal_layer_index == 3 && depCnt!=0)
2102                         SVT_LOG("depCnt Error5  POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);*/
2103                         //if (picture_control_set_ptr->slice_type==P_SLICE )
2104                         //     SVT_LOG("POC:%i  TL:%i   is needed:%i\n",picture_control_set_ptr->picture_number,picture_control_set_ptr->temporal_layer_index,input_entry_ptr->dependent_count);
2105 
2106                         CHECK_REPORT_ERROR(
2107                             (picture_control_set_ptr->pred_struct_ptr->pred_struct_period < MAX_ELAPSED_IDR_COUNT),
2108                             encode_context_ptr->app_callback_ptr,
2109                             EB_ENC_PD_ERROR5);
2110 
2111                         // Reset the PA Reference Lists
2112                         EB_MEMSET(picture_control_set_ptr->ref_pa_pic_ptr_array, 0, 2 * sizeof(EbObjectWrapper*));
2113 
2114                         EB_MEMSET(picture_control_set_ptr->ref_pa_pic_ptr_array, 0, 2 * sizeof(uint32_t));
2115 
2116                     }
2117 
2118                     // 2nd Loop over Pictures in the Pre-Assignment Buffer
2119                     for (picture_index = context_ptr->mini_gop_start_index[mini_gop_index]; picture_index <= context_ptr->mini_gop_end_index[mini_gop_index]; ++picture_index) {
2120 
2121                         picture_control_set_ptr = (PictureParentControlSet  *)    encode_context_ptr->pre_assignment_buffer[picture_index]->object_ptr;
2122 
2123                         // Find the Reference in the Picture Decision PA Reference Queue
2124                         input_queue_index = encode_context_ptr->picture_decision_pa_reference_queue_head_index;
2125 
2126                         do {
2127 
2128                             // Setup the Picture Decision PA Reference Queue Entry
2129                             input_entry_ptr   = encode_context_ptr->picture_decision_pa_reference_queue[input_queue_index];
2130 
2131                             // Increment the reference_queue_index Iterator
2132                             input_queue_index = (input_queue_index == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : input_queue_index + 1;
2133 
2134                         } while ((input_queue_index != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) && (input_entry_ptr->picture_number != picture_control_set_ptr->picture_number));
2135 
2136                         CHECK_REPORT_ERROR(
2137                             (input_entry_ptr->picture_number == picture_control_set_ptr->picture_number),
2138                             encode_context_ptr->app_callback_ptr,
2139                             EB_ENC_PD_ERROR6);
2140 
2141                         // Reset the PA Reference Lists
2142                         EB_MEMSET(picture_control_set_ptr->ref_pa_pic_ptr_array, 0, 2 * sizeof(EbObjectWrapper*));
2143 
2144                         EB_MEMSET(picture_control_set_ptr->ref_pic_poc_array, 0, 2 * sizeof(uint64_t));
2145 
2146                         // Configure List0
2147                         if ((picture_control_set_ptr->slice_type == P_SLICE) || (picture_control_set_ptr->slice_type == B_SLICE)) {
2148 
2149                             if (picture_control_set_ptr->ref_list0_count){
2150                                 pa_reference_queue_index = (uint32_t) CIRCULAR_ADD(
2151                                     ((int32_t) input_entry_ptr->reference_entry_index) - input_entry_ptr->list0_ptr->reference_list,
2152                                     PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH);                                                                                             // Max
2153 
2154                                 pa_reference_entry_ptr = encode_context_ptr->picture_decision_pa_reference_queue[pa_reference_queue_index];
2155 
2156                                 // Calculate the Ref POC
2157                                 ref_poc = POC_CIRCULAR_ADD(
2158                                     picture_control_set_ptr->picture_number,
2159                                     -input_entry_ptr->list0_ptr->reference_list/*,
2160                                     sequence_control_set_ptr->bitsForPictureOrderCount*/);
2161 
2162                                 // Set the Reference Object
2163                                 picture_control_set_ptr->ref_pa_pic_ptr_array[REF_LIST_0] = pa_reference_entry_ptr->input_object_ptr;
2164                                 picture_control_set_ptr->ref_pic_poc_array[REF_LIST_0] = ref_poc;
2165                                 picture_control_set_ptr->ref_pa_pcs_array[REF_LIST_0] = pa_reference_entry_ptr->p_pcs_ptr;
2166 
2167                                 // Increment the PA Reference's live_count by the number of tiles in the input picture
2168                                 eb_vp9_object_inc_live_count(
2169                                     pa_reference_entry_ptr->input_object_ptr,
2170                                     1);
2171 
2172                                 ((EbPaReferenceObject  *)picture_control_set_ptr->ref_pa_pic_ptr_array[REF_LIST_0]->object_ptr)->p_pcs_ptr = pa_reference_entry_ptr->p_pcs_ptr;
2173 
2174                                 eb_vp9_object_inc_live_count(
2175                                     pa_reference_entry_ptr->p_pcs_ptr->p_pcs_wrapper_ptr,
2176                                     1);
2177 
2178                                 --pa_reference_entry_ptr->dependent_count;
2179                             }
2180                         }
2181 
2182                         // Configure List1
2183                         if (picture_control_set_ptr->slice_type == B_SLICE) {
2184 
2185                             if (picture_control_set_ptr->ref_list1_count){
2186                                 pa_reference_queue_index = (uint32_t) CIRCULAR_ADD(
2187                                     ((int32_t) input_entry_ptr->reference_entry_index) - input_entry_ptr->list1_ptr->reference_list,
2188                                     PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH);                                                                                             // Max
2189 
2190                                 pa_reference_entry_ptr = encode_context_ptr->picture_decision_pa_reference_queue[pa_reference_queue_index];
2191 
2192                                 // Calculate the Ref POC
2193                                 ref_poc = POC_CIRCULAR_ADD(
2194                                     picture_control_set_ptr->picture_number,
2195                                     -input_entry_ptr->list1_ptr->reference_list/*,
2196                                     sequence_control_set_ptr->bitsForPictureOrderCount*/);
2197                                 picture_control_set_ptr->ref_pa_pcs_array[REF_LIST_1] = pa_reference_entry_ptr->p_pcs_ptr;
2198                                 // Set the Reference Object
2199                                 picture_control_set_ptr->ref_pa_pic_ptr_array[REF_LIST_1] = pa_reference_entry_ptr->input_object_ptr;
2200                                 picture_control_set_ptr->ref_pic_poc_array[REF_LIST_1] = ref_poc;
2201 
2202                                 // Increment the PA Reference's live_count by the number of tiles in the input picture
2203                                 eb_vp9_object_inc_live_count(
2204                                     pa_reference_entry_ptr->input_object_ptr,
2205                                     1);
2206 
2207                                 ((EbPaReferenceObject  *)picture_control_set_ptr->ref_pa_pic_ptr_array[REF_LIST_1]->object_ptr)->p_pcs_ptr = pa_reference_entry_ptr->p_pcs_ptr;
2208 
2209                                 eb_vp9_object_inc_live_count(
2210                                     pa_reference_entry_ptr->p_pcs_ptr->p_pcs_wrapper_ptr,
2211                                     1);
2212 
2213                                 --pa_reference_entry_ptr->dependent_count;
2214                             }
2215                         }
2216 
2217                         // Initialize Segments
2218                         picture_control_set_ptr->me_segments_column_count    =  (uint8_t)(sequence_control_set_ptr->me_segment_column_count_array[picture_control_set_ptr->temporal_layer_index]);
2219                         picture_control_set_ptr->me_segments_row_count       =  (uint8_t)(sequence_control_set_ptr->me_segment_row_count_array[picture_control_set_ptr->temporal_layer_index]);
2220                         picture_control_set_ptr->me_segments_total_count     =  (uint16_t)(picture_control_set_ptr->me_segments_column_count  * picture_control_set_ptr->me_segments_row_count);
2221                         picture_control_set_ptr->me_segments_completion_mask = 0;
2222 
2223                         // Post the results to the ME processes
2224                         {
2225                             uint32_t segment_index;
2226 
2227                             for(segment_index=0; segment_index < picture_control_set_ptr->me_segments_total_count; ++segment_index)
2228                             {
2229                                 // Get Empty Results Object
2230                                 eb_vp9_get_empty_object(
2231                                     context_ptr->picture_decision_results_output_fifo_ptr,
2232                                     &output_results_wrapper_ptr);
2233 
2234                                 output_results_ptr = (PictureDecisionResults*) output_results_wrapper_ptr->object_ptr;
2235 
2236                                 output_results_ptr->picture_control_set_wrapper_ptr = encode_context_ptr->pre_assignment_buffer[picture_index];
2237 
2238                                 output_results_ptr->segment_index = segment_index;
2239 
2240                                 // Post the Full Results Object
2241                                 eb_vp9_post_full_object(output_results_wrapper_ptr);
2242                             }
2243                         }
2244 
2245                         if (picture_index == context_ptr->mini_gop_end_index[mini_gop_index]) {
2246 
2247                             // Increment the Decode Base Number
2248                             encode_context_ptr->decode_base_number  += context_ptr->mini_gop_length[mini_gop_index];
2249                         }
2250 
2251                         if (picture_index == encode_context_ptr->pre_assignment_buffer_count - 1) {
2252 
2253                             // Reset the Pre-Assignment Buffer
2254                             encode_context_ptr->pre_assignment_buffer_count              = 0;
2255                             encode_context_ptr->pre_assignment_buffer_idr_count           = 0;
2256                             encode_context_ptr->pre_assignment_buffer_intra_count         = 0;
2257                             encode_context_ptr->pre_assignment_buffer_scene_change_count   = 0;
2258                             encode_context_ptr->pre_assignment_buffer_eos_flag            = EB_FALSE;
2259                             encode_context_ptr->number_of_active_pictures                = 0;
2260                         }
2261                     }
2262 
2263                 } // End MINI GOPs loop
2264             }
2265 
2266             // Walk the picture_decision_pa_reference_queue and remove entries that have been completely referenced.
2267             input_queue_index = encode_context_ptr->picture_decision_pa_reference_queue_head_index;
2268 
2269             while(input_queue_index != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) {
2270 
2271                 input_entry_ptr = encode_context_ptr->picture_decision_pa_reference_queue[input_queue_index];
2272 
2273                 // Remove the entry
2274                 if((input_entry_ptr->dependent_count == 0) &&
2275                    (input_entry_ptr->input_object_ptr)) {
2276                     eb_vp9_release_object(input_entry_ptr->p_pcs_ptr->p_pcs_wrapper_ptr);
2277                        // Release the nominal live_count value
2278                        eb_vp9_release_object(input_entry_ptr->input_object_ptr);
2279                        input_entry_ptr->input_object_ptr = (EbObjectWrapper*) EB_NULL;
2280                 }
2281 
2282                 // Increment the head_index if the head is null
2283                 encode_context_ptr->picture_decision_pa_reference_queue_head_index =
2284                     (encode_context_ptr->picture_decision_pa_reference_queue[encode_context_ptr->picture_decision_pa_reference_queue_head_index]->input_object_ptr)   ? encode_context_ptr->picture_decision_pa_reference_queue_head_index :
2285                     (encode_context_ptr->picture_decision_pa_reference_queue_head_index == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1)                 ? 0
2286                                                                                                                                                         : encode_context_ptr->picture_decision_pa_reference_queue_head_index + 1;
2287 
2288                  CHECK_REPORT_ERROR(
2289                     (((encode_context_ptr->picture_decision_pa_reference_queue_head_index != encode_context_ptr->picture_decision_pa_reference_queue_tail_index) ||
2290                     (encode_context_ptr->picture_decision_pa_reference_queue[encode_context_ptr->picture_decision_pa_reference_queue_head_index]->input_object_ptr == EB_NULL))),
2291                     encode_context_ptr->app_callback_ptr,
2292                     EB_ENC_PD_ERROR4);
2293 
2294                 // Increment the input_queue_index Iterator
2295                 input_queue_index = (input_queue_index == PICTURE_DECISION_PA_REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : input_queue_index + 1;
2296             }
2297 
2298             // Increment the Picture Decision Reordering Queue Head Ptr
2299             encode_context_ptr->picture_decision_reorder_queue_head_index  =   (encode_context_ptr->picture_decision_reorder_queue_head_index == PICTURE_DECISION_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->picture_decision_reorder_queue_head_index + 1;
2300 
2301             // Get the next entry from the Picture Decision Reordering Queue (Entry N+1)
2302             queue_entry_ptr                                           = encode_context_ptr->picture_decision_reorder_queue[encode_context_ptr->picture_decision_reorder_queue_head_index];
2303         }
2304             if(window_avail == EB_FALSE  && frame_passe_thru == EB_FALSE)
2305                 break;
2306         }
2307 
2308         // Release the Input Results
2309         eb_vp9_release_object(input_results_wrapper_ptr);
2310     }
2311 
2312     return EB_NULL;
2313 }
unused_variable_void_func_pic_decision()2314 void unused_variable_void_func_pic_decision()
2315 {
2316     (void)n_x_m_sad_kernel_func_ptr_array;
2317     (void)nx_m_sad_loop_kernel_func_ptr_array;
2318     (void)nx_m_sad_averaging_kernel_func_ptr_array;
2319     (void)eb_vp9_sad_calculation_8x8_16x16_func_ptr_array;
2320     (void)eb_vp9_sad_calculation_32x32_64x64_func_ptr_array;
2321     (void)eb_vp9_initialize_buffer_32bits_func_ptr_array;
2322 }
2323