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