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 #include <stdint.h>
9 
10 #include "EbDefinitions.h"
11 #include "EbSystemResourceManager.h"
12 #include "EbPictureControlSet.h"
13 #include "EbSequenceControlSet.h"
14 #include "EbPictureBufferDesc.h"
15 
16 #include "EbResourceCoordinationProcess.h"
17 
18 #include "EbResourceCoordinationResults.h"
19 #include "EbReferenceObject.h"
20 #include "EbTime.h"
21 
22 #include "vp9_alloccommon.h"
23 #include "vp9_common.h"
24 #include "vp9_reconintra.h"
25 #include "vp9_quantize.h"
26 #include "vp9_entropy.h"
27 #include "vp9_encodemv.h"
28 #include "vp9_ratectrl.h"
29 
30 /************************************************
31  * Resource Coordination Context Constructor
32  ************************************************/
eb_vp9_resource_coordination_context_ctor(ResourceCoordinationContext ** context_dbl_ptr,EbFifo * input_buffer_fifo_ptr,EbFifo * resource_coordination_results_output_fifo_ptr,EbFifo ** picture_control_set_fifo_ptr_array,EbSequenceControlSetInstance ** sequence_control_set_instance_array,EbFifo * sequence_control_set_empty_fifo_ptr,EbCallback ** app_callback_ptr_array,uint32_t * compute_segments_total_count_array,uint32_t encode_instances_total_count)33 EbErrorType eb_vp9_resource_coordination_context_ctor(
34     ResourceCoordinationContext  **context_dbl_ptr,
35     EbFifo                        *input_buffer_fifo_ptr,
36     EbFifo                        *resource_coordination_results_output_fifo_ptr,
37     EbFifo                       **picture_control_set_fifo_ptr_array,
38     EbSequenceControlSetInstance **sequence_control_set_instance_array,
39     EbFifo                        *sequence_control_set_empty_fifo_ptr,
40     EbCallback                   **app_callback_ptr_array,
41     uint32_t                      *compute_segments_total_count_array,
42     uint32_t                       encode_instances_total_count)
43 {
44     uint32_t instance_index;
45 
46     ResourceCoordinationContext   *context_ptr;
47     EB_MALLOC(ResourceCoordinationContext  *, context_ptr, sizeof(ResourceCoordinationContext  ), EB_N_PTR);
48 
49     *context_dbl_ptr = context_ptr;
50 
51     context_ptr->input_buffer_fifo_ptr                            = input_buffer_fifo_ptr;
52     context_ptr->resource_coordination_results_output_fifo_ptr    = resource_coordination_results_output_fifo_ptr;
53     context_ptr->picture_control_set_fifo_ptr_array               = picture_control_set_fifo_ptr_array;
54     context_ptr->sequence_control_set_instance_array              = sequence_control_set_instance_array;
55     context_ptr->sequence_control_set_empty_fifo_ptr              = sequence_control_set_empty_fifo_ptr;
56     context_ptr->app_callback_ptr_array                           = app_callback_ptr_array;
57     context_ptr->compute_segments_total_count_array               = compute_segments_total_count_array;
58     context_ptr->encode_instances_total_count                     = encode_instances_total_count;
59 
60     // Allocate sequence_control_set_active_array
61     EB_MALLOC(EbObjectWrapper**, context_ptr->sequence_control_set_active_array, sizeof(EbObjectWrapper*) * context_ptr->encode_instances_total_count, EB_N_PTR);
62 
63     for(instance_index=0; instance_index < context_ptr->encode_instances_total_count; ++instance_index) {
64         context_ptr->sequence_control_set_active_array[instance_index] = 0;
65     }
66 
67     // Picture Stats
68     EB_MALLOC(uint64_t*, context_ptr->picture_number_array, sizeof(uint64_t) * context_ptr->encode_instances_total_count, EB_N_PTR);
69 
70     for(instance_index=0; instance_index < context_ptr->encode_instances_total_count; ++instance_index) {
71         context_ptr->picture_number_array[instance_index] = 0;
72     }
73 
74     context_ptr->average_enc_mod                    = 0;
75     context_ptr->prev_enc_mod                       = 0;
76     context_ptr->prev_enc_mode_delta                = 0;
77     context_ptr->cur_speed                          = 0; // speed x 1000
78     context_ptr->previous_mode_change_buffer        = 0;
79     context_ptr->first_in_pic_arrived_time_seconds  = 0;
80     context_ptr->first_in_pic_arrived_timeu_seconds = 0;
81     context_ptr->previous_frame_in_check1           = 0;
82     context_ptr->previous_frame_in_check2           = 0;
83     context_ptr->previous_frame_in_check3           = 0;
84     context_ptr->previous_mode_change_frame_in      = 0;
85     context_ptr->prevs_time_seconds                 = 0;
86     context_ptr->prevs_timeu_seconds                = 0;
87     context_ptr->prev_frame_out                     = 0;
88     context_ptr->start_flag                         = EB_FALSE;
89     context_ptr->previous_buffer_check1             = 0;
90     context_ptr->prev_change_cond                   = 0;
91 
92     return EB_ErrorNone;
93 }
94 
95 //******************************************************************************//
96 // Modify the Enc mode based on the buffer Status
97 // Inputs: TargetSpeed, Status of the sc_buffer
98 // Output: EncMod
99 //******************************************************************************//
eb_vp9_SpeedBufferControl(ResourceCoordinationContext * context_ptr,PictureParentControlSet * picture_control_set_ptr,SequenceControlSet * sequence_control_set_ptr)100 void eb_vp9_SpeedBufferControl(
101     ResourceCoordinationContext *context_ptr,
102     PictureParentControlSet     *picture_control_set_ptr,
103     SequenceControlSet          *sequence_control_set_ptr)
104 {
105 
106     uint64_t curs_time_seconds  = 0;
107     uint64_t curs_timeu_seconds = 0;
108     double overall_duration = 0.0;
109     double inst_duration = 0.0;
110     int8_t   encoder_mode_delta = 0;
111     int64_t  input_frames_count = 0;
112     int8_t   change_cond        = 0;
113     int64_t  target_fps         = (sequence_control_set_ptr->static_config.injector_frame_rate >> 16);
114 
115     int64_t buffer_trshold1 = SC_FRAMES_INTERVAL_T1;
116     int64_t buffer_trshold2 = SC_FRAMES_INTERVAL_T2;
117     int64_t buffer_trshold3 = SC_FRAMES_INTERVAL_T3;
118     int64_t buffer_trshold4 = MAX(SC_FRAMES_INTERVAL_T1, target_fps);
119     eb_vp9_block_on_mutex(sequence_control_set_ptr->encode_context_ptr->sc_buffer_mutex);
120 
121     if (sequence_control_set_ptr->encode_context_ptr->sc_frame_in == 0) {
122         svt_vp9_get_time(&context_ptr->first_in_pic_arrived_time_seconds,
123                         &context_ptr->first_in_pic_arrived_timeu_seconds);
124     }
125     else if (sequence_control_set_ptr->encode_context_ptr->sc_frame_in == SC_FRAMES_TO_IGNORE) {
126         context_ptr->start_flag = EB_TRUE;
127     }
128 
129     // Compute duration since the start of the encode and since the previous checkpoint
130     svt_vp9_get_time(&curs_time_seconds, &curs_timeu_seconds);
131 
132     overall_duration = svt_vp9_compute_overall_elapsed_time_ms(
133         context_ptr->first_in_pic_arrived_time_seconds,
134         context_ptr->first_in_pic_arrived_timeu_seconds, curs_time_seconds,
135         curs_timeu_seconds);
136 
137     inst_duration = svt_vp9_compute_overall_elapsed_time_ms(
138         context_ptr->prevs_time_seconds, context_ptr->prevs_timeu_seconds,
139         curs_time_seconds, curs_timeu_seconds);
140 
141     input_frames_count = (int64_t)overall_duration *(sequence_control_set_ptr->static_config.injector_frame_rate >> 16) / 1000;
142     sequence_control_set_ptr->encode_context_ptr->sc_buffer = input_frames_count - sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
143 
144     encoder_mode_delta = 0;
145 
146     // Check every bufferTsshold1 for the changes (previous_frame_in_check1 variable)
147     if ((sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_frame_in_check1 + buffer_trshold1 && sequence_control_set_ptr->encode_context_ptr->sc_frame_in >= SC_FRAMES_TO_IGNORE)) {
148         // Go to a slower mode based on the fullness and changes of the buffer
149         if (sequence_control_set_ptr->encode_context_ptr->sc_buffer < buffer_trshold4 && (context_ptr->prev_enc_mode_delta >-1 || (context_ptr->prev_enc_mode_delta < 0 && sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_mode_change_frame_in + buffer_trshold4 * 2))) {
150             if (context_ptr->previous_buffer_check1 > sequence_control_set_ptr->encode_context_ptr->sc_buffer + buffer_trshold1) {
151                 encoder_mode_delta += -1;
152                 change_cond = 2;
153             }
154             else if (context_ptr->previous_mode_change_buffer > buffer_trshold1 + sequence_control_set_ptr->encode_context_ptr->sc_buffer && sequence_control_set_ptr->encode_context_ptr->sc_buffer < buffer_trshold1) {
155                 encoder_mode_delta += -1;
156                 change_cond = 4;
157             }
158         }
159 
160         // Go to a faster mode based on the fullness and changes of the buffer
161         if (sequence_control_set_ptr->encode_context_ptr->sc_buffer >buffer_trshold1 + context_ptr->previous_buffer_check1) {
162             encoder_mode_delta += +1;
163             change_cond = 1;
164         }
165         else if (sequence_control_set_ptr->encode_context_ptr->sc_buffer > buffer_trshold1 + context_ptr->previous_mode_change_buffer) {
166             encoder_mode_delta += +1;
167             change_cond = 3;
168         }
169 
170         // Update the encode mode based on the fullness of the buffer
171         // If previous change_cond was the same, double the threshold2
172         if (sequence_control_set_ptr->encode_context_ptr->sc_buffer > buffer_trshold3 &&
173             (context_ptr->prev_change_cond != 7 || sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_mode_change_frame_in + buffer_trshold2 * 2) &&
174             sequence_control_set_ptr->encode_context_ptr->sc_buffer > context_ptr->previous_mode_change_buffer) {
175             encoder_mode_delta += 1;
176             change_cond = 7;
177         }
178         encoder_mode_delta = CLIP3(-1, 1, encoder_mode_delta);
179         sequence_control_set_ptr->encode_context_ptr->enc_mode = (EB_ENC_MODE)CLIP3(ENC_MODE_0, sequence_control_set_ptr->max_enc_mode, (int8_t)sequence_control_set_ptr->encode_context_ptr->enc_mode + encoder_mode_delta);
180 
181         // Update previous stats
182         context_ptr->previous_frame_in_check1 = sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
183         context_ptr->previous_buffer_check1 = sequence_control_set_ptr->encode_context_ptr->sc_buffer;
184 
185         if (encoder_mode_delta) {
186             context_ptr->previous_mode_change_buffer = sequence_control_set_ptr->encode_context_ptr->sc_buffer;
187             context_ptr->previous_mode_change_frame_in = sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
188             context_ptr->prev_enc_mode_delta = encoder_mode_delta;
189         }
190     }
191 
192     // Check every buffer_trshold2 for the changes (previous_frame_in_check2 variable)
193     if ((sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_frame_in_check2 + buffer_trshold2 && sequence_control_set_ptr->encode_context_ptr->sc_frame_in >= SC_FRAMES_TO_IGNORE)) {
194         encoder_mode_delta = 0;
195 
196         // if no change in the encoder mode and buffer is low enough and level is not increasing, switch to a slower encoder mode
197         // If previous change_cond was the same, double the threshold2
198         if (encoder_mode_delta == 0 && sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_mode_change_frame_in + buffer_trshold2 &&
199             (context_ptr->prev_change_cond != 8 || sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_mode_change_frame_in + buffer_trshold2 * 2) &&
200             ((sequence_control_set_ptr->encode_context_ptr->sc_buffer - context_ptr->previous_mode_change_buffer < (buffer_trshold4 / 3)) || context_ptr->previous_mode_change_buffer == 0) &&
201             sequence_control_set_ptr->encode_context_ptr->sc_buffer < buffer_trshold3) {
202             encoder_mode_delta = -1;
203             change_cond = 8;
204         }
205 
206         encoder_mode_delta = CLIP3(-1, 1, encoder_mode_delta);
207         sequence_control_set_ptr->encode_context_ptr->enc_mode = (EB_ENC_MODE)CLIP3(ENC_MODE_0, sequence_control_set_ptr->max_enc_mode, (int8_t)sequence_control_set_ptr->encode_context_ptr->enc_mode + encoder_mode_delta);
208         // Update previous stats
209         context_ptr->previous_frame_in_check2 = sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
210 
211         if (encoder_mode_delta) {
212             context_ptr->previous_mode_change_buffer = sequence_control_set_ptr->encode_context_ptr->sc_buffer;
213             context_ptr->previous_mode_change_frame_in = sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
214             context_ptr->prev_enc_mode_delta = encoder_mode_delta;
215         }
216 
217     }
218     // Check every SC_FRAMES_INTERVAL_SPEED frames for the speed calculation (previous_frame_in_check3 variable)
219     if (context_ptr->start_flag || (sequence_control_set_ptr->encode_context_ptr->sc_frame_in > context_ptr->previous_frame_in_check3 + SC_FRAMES_INTERVAL_SPEED && sequence_control_set_ptr->encode_context_ptr->sc_frame_in >= SC_FRAMES_TO_IGNORE)) {
220         if (context_ptr->start_flag) {
221             context_ptr->cur_speed = (uint64_t)(sequence_control_set_ptr->encode_context_ptr->sc_frame_out - 0) * 1000 / (uint64_t)(overall_duration);
222         }
223         else {
224             if (inst_duration != 0)
225                 context_ptr->cur_speed = (uint64_t)(sequence_control_set_ptr->encode_context_ptr->sc_frame_out - context_ptr->prev_frame_out) * 1000 / (uint64_t)(inst_duration);
226         }
227         context_ptr->start_flag = EB_FALSE;
228 
229         // Update previous stats
230         context_ptr->previous_frame_in_check3 = sequence_control_set_ptr->encode_context_ptr->sc_frame_in;
231         context_ptr->prevs_time_seconds = curs_time_seconds;
232         context_ptr->prevs_timeu_seconds = curs_timeu_seconds;
233         context_ptr->prev_frame_out = sequence_control_set_ptr->encode_context_ptr->sc_frame_out;
234 
235     }
236     else if (sequence_control_set_ptr->encode_context_ptr->sc_frame_in < SC_FRAMES_TO_IGNORE && (overall_duration != 0)) {
237         context_ptr->cur_speed = (uint64_t)(sequence_control_set_ptr->encode_context_ptr->sc_frame_out - 0) * 1000 / (uint64_t)(overall_duration);
238     }
239 
240     if (change_cond) {
241         context_ptr->prev_change_cond = change_cond;
242     }
243     sequence_control_set_ptr->encode_context_ptr->sc_frame_in++;
244     if (sequence_control_set_ptr->encode_context_ptr->sc_frame_in >= SC_FRAMES_TO_IGNORE) {
245         context_ptr->average_enc_mod += sequence_control_set_ptr->encode_context_ptr->enc_mode;
246     }
247     else {
248         context_ptr->average_enc_mod = 0;
249     }
250 
251     // Set the encoder level
252     picture_control_set_ptr->enc_mode = sequence_control_set_ptr->encode_context_ptr->enc_mode;
253 
254     eb_vp9_release_mutex(sequence_control_set_ptr->encode_context_ptr->sc_buffer_mutex);
255 
256     context_ptr->prev_enc_mod = sequence_control_set_ptr->encode_context_ptr->enc_mode;
257 }
258 
259 /******************************************************
260 * Derive Pre-Analysis settings for SQ
261 Input   : encoder mode and tune
262 Output  : Pre-Analysis signal(s)
263 ******************************************************/
eb_vp9_signal_derivation_pre_analysis_sq(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)264 EbErrorType eb_vp9_signal_derivation_pre_analysis_sq(
265     SequenceControlSet      *sequence_control_set_ptr,
266     PictureParentControlSet *picture_control_set_ptr) {
267 
268     EbErrorType return_error = EB_ErrorNone;
269 
270     uint8_t input_resolution = sequence_control_set_ptr->input_resolution;
271 
272     // Derive Noise Detection Method
273     if (input_resolution == INPUT_SIZE_4K_RANGE) {
274         if (picture_control_set_ptr->enc_mode <= ENC_MODE_8) {
275             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
276         }
277         else {
278             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_HALF_PRECISION;
279         }
280 
281     }
282     else if (input_resolution == INPUT_SIZE_1080p_RANGE) {
283         if (picture_control_set_ptr->enc_mode <= ENC_MODE_8) {
284             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
285         }
286         else {
287             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_QUARTER_PRECISION;
288         }
289 
290     }
291     else {
292         picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
293     }
294 #if TURN_OFF_PRE_PROCESSING
295     picture_control_set_ptr->enable_denoise_src_flag = EB_FALSE;
296 #else
297     picture_control_set_ptr->enable_denoise_src_flag = picture_control_set_ptr->enc_mode <= ENC_MODE_11 ? sequence_control_set_ptr->enable_denoise_flag : EB_FALSE;
298 #endif
299 
300     // Derive Noise Detection Threshold
301     if (picture_control_set_ptr->enc_mode <= ENC_MODE_8) {
302         picture_control_set_ptr->noise_detection_th = 0;
303     }
304     else {
305         picture_control_set_ptr->noise_detection_th = 1;
306     }
307 
308     // Derive HME Flag
309     uint8_t hme_me_level = picture_control_set_ptr->enc_mode;
310 
311     uint32_t input_ratio = sequence_control_set_ptr->luma_width / sequence_control_set_ptr->luma_height;
312     uint8_t resolution_index = input_resolution <= INPUT_SIZE_576p_RANGE_OR_LOWER ? 0 : // 480P
313         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio < 2) ? 1 : // 720P
314         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio > 3) ? 2 : // 1080I
315         (input_resolution <= INPUT_SIZE_1080p_RANGE) ? 3 : // 1080I
316         4;    // 4K
317     if (sequence_control_set_ptr->static_config.use_default_me_hme) {
318 
319         picture_control_set_ptr->enable_hme_flag = EB_TRUE;
320 
321     }
322     else {
323         picture_control_set_ptr->enable_hme_flag = sequence_control_set_ptr->static_config.enable_hme_flag;
324 
325     }
326     picture_control_set_ptr->enable_hme_level_0_flag = enable_hme_level0_flag_sq[resolution_index][hme_me_level];
327     picture_control_set_ptr->enable_hme_level_1_flag = enable_hme_level1_flag_sq[resolution_index][hme_me_level];
328     picture_control_set_ptr->enable_hme_level_2_flag = enable_hme_level2_flag_sq[resolution_index][hme_me_level];
329     return return_error;
330 }
331 
332 /******************************************************
333 * Derive Pre-Analysis settings for OQ
334 Input   : encoder mode and tune
335 Output  : Pre-Analysis signal(s)
336 ******************************************************/
eb_vp9_signal_derivation_pre_analysis_oq(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)337 EbErrorType eb_vp9_signal_derivation_pre_analysis_oq(
338     SequenceControlSet      *sequence_control_set_ptr,
339     PictureParentControlSet *picture_control_set_ptr) {
340 
341     EbErrorType return_error = EB_ErrorNone;
342 
343     uint8_t input_resolution = sequence_control_set_ptr->input_resolution;
344 
345     // Derive Noise Detection Method
346     if (input_resolution == INPUT_SIZE_4K_RANGE) {
347         if (picture_control_set_ptr->enc_mode <= ENC_MODE_3) {
348             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
349         }
350         else {
351             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_HALF_PRECISION;
352         }
353     }
354     else if (input_resolution == INPUT_SIZE_1080p_RANGE) {
355         if (picture_control_set_ptr->enc_mode <= ENC_MODE_3) {
356             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
357         }
358         else {
359             picture_control_set_ptr->noise_detection_method = NOISE_DETECT_QUARTER_PRECISION;
360         }
361     }
362     else {
363         picture_control_set_ptr->noise_detection_method = NOISE_DETECT_FULL_PRECISION;
364     }
365 
366     // Derive Noise Detection Threshold
367     if (picture_control_set_ptr->enc_mode <= ENC_MODE_3) {
368         picture_control_set_ptr->noise_detection_th = 0;
369     }
370     else if (picture_control_set_ptr->enc_mode <= ENC_MODE_8) {
371         if (input_resolution <= INPUT_SIZE_1080p_RANGE) {
372             picture_control_set_ptr->noise_detection_th = 1;
373         }
374         else {
375             picture_control_set_ptr->noise_detection_th = 0;
376         }
377     }
378     else {
379         picture_control_set_ptr->noise_detection_th = 1;
380     }
381 
382     // Derive HME Flag
383     uint8_t  hme_me_level = picture_control_set_ptr->enc_mode;
384 
385     uint32_t input_ratio = sequence_control_set_ptr->luma_width / sequence_control_set_ptr->luma_height;
386     uint8_t resolution_index = input_resolution <= INPUT_SIZE_576p_RANGE_OR_LOWER ? 0 : // 480P
387         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio < 2) ? 1 : // 720P
388         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio > 3) ? 2 : // 1080I
389         (input_resolution <= INPUT_SIZE_1080p_RANGE) ? 3 : // 1080I
390         4;    // 4K
391     if (sequence_control_set_ptr->static_config.use_default_me_hme) {
392 
393         picture_control_set_ptr->enable_hme_flag = EB_TRUE;
394 
395     }
396     else {
397         picture_control_set_ptr->enable_hme_flag = sequence_control_set_ptr->static_config.enable_hme_flag;
398 
399     }
400     picture_control_set_ptr->enable_hme_level_0_flag = enable_hme_level0_flag_oq[resolution_index][hme_me_level];
401     picture_control_set_ptr->enable_hme_level_1_flag = enable_hme_level1_flag_oq[resolution_index][hme_me_level];
402     picture_control_set_ptr->enable_hme_level_2_flag = enable_hme_level2_flag_oq[resolution_index][hme_me_level];
403 
404     picture_control_set_ptr->enable_denoise_src_flag = EB_FALSE;
405 
406     return return_error;
407 }
408 
409 /******************************************************
410 * Derive Pre-Analysis settings for VMAF
411 Input   : encoder mode and tune
412 Output  : Pre-Analysis signal(s)
413 ******************************************************/
eb_vp9_signal_derivation_pre_analysis_vmaf(SequenceControlSet * sequence_control_set_ptr,PictureParentControlSet * picture_control_set_ptr)414 EbErrorType eb_vp9_signal_derivation_pre_analysis_vmaf(
415     SequenceControlSet       *sequence_control_set_ptr,
416     PictureParentControlSet  *picture_control_set_ptr) {
417 
418     EbErrorType return_error = EB_ErrorNone;
419 
420     uint8_t input_resolution = sequence_control_set_ptr->input_resolution;
421 
422     // Derive Noise Detection Method
423     picture_control_set_ptr->noise_detection_method = NOISE_DETECT_QUARTER_PRECISION;
424 
425     // Derive Noise Detection Threshold
426     picture_control_set_ptr->noise_detection_th = 1;
427 
428     // Derive HME Flag
429     uint8_t  hme_me_level = picture_control_set_ptr->enc_mode;
430     uint32_t input_ratio = sequence_control_set_ptr->luma_width / sequence_control_set_ptr->luma_height;
431     uint8_t resolution_index = input_resolution <= INPUT_SIZE_576p_RANGE_OR_LOWER ? 0 : // 480P
432         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio < 2) ? 1 : // 720P
433         (input_resolution <= INPUT_SIZE_1080i_RANGE && input_ratio > 3) ? 2 : // 1080I
434         (input_resolution <= INPUT_SIZE_1080p_RANGE) ? 3 : // 1080I
435         4;    // 4K
436     resolution_index = 3;
437     if (sequence_control_set_ptr->static_config.use_default_me_hme) {
438 
439         picture_control_set_ptr->enable_hme_flag = EB_TRUE;
440 
441     }
442     else {
443         picture_control_set_ptr->enable_hme_flag = sequence_control_set_ptr->static_config.enable_hme_flag;
444 
445     }
446     picture_control_set_ptr->enable_hme_level_0_flag = enable_hme_level0_flag_vmaf[resolution_index][hme_me_level];
447     picture_control_set_ptr->enable_hme_level_1_flag = enable_hme_level1_flag_vmaf[resolution_index][hme_me_level];
448     picture_control_set_ptr->enable_hme_level_2_flag = enable_hme_level2_flag_vmaf[resolution_index][hme_me_level];
449 
450     picture_control_set_ptr->enable_denoise_src_flag = EB_FALSE;
451 
452     return return_error;
453 }
454 
455 /***************************************
456  * ResourceCoordination Kernel
457  ***************************************/
eb_vp9_resource_coordination_kernel(void * input_ptr)458 void* eb_vp9_resource_coordination_kernel(void *input_ptr)
459 {
460     ResourceCoordinationContext   *context_ptr = (ResourceCoordinationContext*) input_ptr;
461 
462     EbObjectWrapper               *picture_control_set_wrapper_ptr;
463 
464     PictureParentControlSet       *picture_control_set_ptr;
465 
466     EbObjectWrapper               *previoussequence_control_set_wrapper_ptr;
467     SequenceControlSet            *sequence_control_set_ptr;
468 
469     EbObjectWrapper               *ebInputWrapperPtr;
470     EbBufferHeaderType            *eb_input_ptr;
471     EbObjectWrapper               *output_wrapper_ptr;
472     ResourceCoordinationResults   *output_results_ptr;
473 
474     EbObjectWrapper               *input_picture_wrapper_ptr;
475     EbObjectWrapper               *reference_picture_wrapper_ptr;
476     EbObjectWrapper               *prev_picture_control_set_wrapper_ptr = NULL;
477     uint32_t                       instance_index;
478 
479     EB_BOOL                        end_of_sequence_flag = EB_FALSE;
480     uint32_t                       input_size = 0;
481 
482     for(;;) {
483 
484         // Tie instance_index to zero for now...
485         instance_index = 0;
486 
487         // Get the Next Input Buffer [BLOCKING]
488         eb_vp9_get_full_object(
489             context_ptr->input_buffer_fifo_ptr,
490             &ebInputWrapperPtr);
491         eb_input_ptr = (EbBufferHeaderType*) ebInputWrapperPtr->object_ptr;
492 
493         sequence_control_set_ptr       = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr;
494 
495         // If config changes occured since the last picture began encoding, then
496         //   prepare a new sequence_control_set_ptr containing the new changes and update the state
497         //   of the previous Active SequenceControlSet
498         eb_vp9_block_on_mutex(context_ptr->sequence_control_set_instance_array[instance_index]->config_mutex);
499         if(context_ptr->sequence_control_set_instance_array[instance_index]->encode_context_ptr->initial_picture) {
500 
501             // Update picture width, picture height, cropping right offset, cropping bottom offset, and conformance windows
502             if(context_ptr->sequence_control_set_instance_array[instance_index]->encode_context_ptr->initial_picture)
503 
504             {
505                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->luma_width = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_luma_width;
506                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->luma_height = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_luma_height;
507                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->chroma_width = (context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_luma_width >> 1);
508                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->chroma_height = (context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_luma_height >> 1);
509 
510                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->pad_right = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_pad_right;
511                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->cropping_right_offset = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->pad_right;
512                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->pad_bottom = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->max_input_pad_bottom;
513                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->cropping_bottom_offset = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->pad_bottom;
514 
515                 input_size = context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->luma_width * context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr->luma_height;
516             }
517 
518             // Copy previous Active sequence_control_set_ptr to a place holder
519             previoussequence_control_set_wrapper_ptr = context_ptr->sequence_control_set_active_array[instance_index];
520 
521             // Get empty SequenceControlSet [BLOCKING]
522             eb_vp9_get_empty_object(
523                 context_ptr->sequence_control_set_empty_fifo_ptr,
524                 &context_ptr->sequence_control_set_active_array[instance_index]);
525 
526             // Copy the contents of the active SequenceControlSet into the new empty SequenceControlSet
527             eb_vp9_copy_sequence_control_set(
528                 (SequenceControlSet *) context_ptr->sequence_control_set_active_array[instance_index]->object_ptr,
529                 context_ptr->sequence_control_set_instance_array[instance_index]->sequence_control_set_ptr);
530 
531             // Disable releaseFlag of new SequenceControlSet
532             eb_vp9_object_release_disable(
533                 context_ptr->sequence_control_set_active_array[instance_index]);
534 
535             if(previoussequence_control_set_wrapper_ptr != EB_NULL) {
536 
537                 // Enable releaseFlag of old SequenceControlSet
538                 eb_vp9_object_release_enable(
539                     previoussequence_control_set_wrapper_ptr);
540 
541                 // Check to see if previous SequenceControlSet is already inactive, if TRUE then release the SequenceControlSet
542                 if(previoussequence_control_set_wrapper_ptr->live_count == 0) {
543                     eb_vp9_release_object(
544                         previoussequence_control_set_wrapper_ptr);
545                 }
546             }
547         }
548         eb_vp9_release_mutex(context_ptr->sequence_control_set_instance_array[instance_index]->config_mutex);
549 
550         // Sequence Control Set is released by Rate Control after passing through MDC->MD->ENCDEC->Packetization->RateControl
551         //   and in the PictureManager
552         eb_vp9_object_inc_live_count(
553             context_ptr->sequence_control_set_active_array[instance_index],
554             2);
555 
556         // Set the current SequenceControlSet
557         sequence_control_set_ptr   = (SequenceControlSet*) context_ptr->sequence_control_set_active_array[instance_index]->object_ptr;
558 
559         // Init LCU Params
560         if (context_ptr->sequence_control_set_instance_array[instance_index]->encode_context_ptr->initial_picture) {
561             eb_vp9_derive_input_resolution(
562                 sequence_control_set_ptr,
563                 input_size);
564 
565             eb_vp9_sb_params_init(sequence_control_set_ptr);
566         }
567 
568         //Get a New ParentPCS where we will hold the new inputPicture
569         eb_vp9_get_empty_object(
570             context_ptr->picture_control_set_fifo_ptr_array[instance_index],
571             &picture_control_set_wrapper_ptr);
572 
573         // Parent PCS is released by the Rate Control after passing through MDC->MD->ENCDEC->Packetization
574         eb_vp9_object_inc_live_count(
575             picture_control_set_wrapper_ptr,
576             1);
577 
578         picture_control_set_ptr        = (PictureParentControlSet*) picture_control_set_wrapper_ptr->object_ptr;
579 
580         picture_control_set_ptr->p_pcs_wrapper_ptr = picture_control_set_wrapper_ptr;
581 
582         // VP9 code
583         // Hsan - to clean up
584 
585         picture_control_set_ptr->cpi->alt_fb_idx = 2;
586         picture_control_set_ptr->cpi->common.error_resilient_mode = 0;
587         picture_control_set_ptr->cpi->common.reset_frame_context = 0;
588         picture_control_set_ptr->cpi->max_mv_magnitude = 0;
589         picture_control_set_ptr->cpi->common.allow_high_precision_mv = 0;
590 #if 0 // Hsan: switchable interp_filter not supported
591         picture_control_set_ptr->cpi->common.interp_filter = 0;
592 #endif
593         memset(picture_control_set_ptr->cpi->interp_filter_selected, 0, sizeof(picture_control_set_ptr->cpi->interp_filter_selected[0][0]) * SWITCHABLE);
594         picture_control_set_ptr->cpi->sf.mv.auto_mv_step_size = 0;
595 
596         eb_vp9_entropy_mv_init();
597 
598         // variable
599         picture_control_set_ptr->cpi->common.bit_depth = VPX_BITS_8;
600         picture_control_set_ptr->cpi->common.width = sequence_control_set_ptr->luma_width;
601         picture_control_set_ptr->cpi->common.height = sequence_control_set_ptr->luma_height;
602         picture_control_set_ptr->cpi->common.render_width = picture_control_set_ptr->cpi->common.width;
603         picture_control_set_ptr->cpi->common.render_height = picture_control_set_ptr->cpi->common.height;
604 
605         eb_vp9_set_mb_mi(
606             &picture_control_set_ptr->cpi->common,
607             picture_control_set_ptr->cpi->common.width,
608             picture_control_set_ptr->cpi->common.height);
609 
610         picture_control_set_ptr->cpi->common.profile = PROFILE_0;
611         picture_control_set_ptr->cpi->common.color_space = VPX_CS_UNKNOWN;
612         picture_control_set_ptr->cpi->common.color_range = VPX_CR_STUDIO_RANGE;
613         picture_control_set_ptr->cpi->common.subsampling_x = 1;
614         picture_control_set_ptr->cpi->common.subsampling_y = 1;
615 
616         picture_control_set_ptr->cpi->common.frame_parallel_decoding_mode = 1;
617         picture_control_set_ptr->cpi->common.frame_context_idx = 0;
618         picture_control_set_ptr->cpi->common.y_dc_delta_q = 0;
619 #if CHROMA_QP_OFFSET
620         if (sequence_control_set_ptr->static_config.tune == TUNE_OQ) {
621             picture_control_set_ptr->cpi->common.uv_dc_delta_q = -15;
622             picture_control_set_ptr->cpi->common.uv_ac_delta_q = -15;
623         }
624         else {
625             picture_control_set_ptr->cpi->common.uv_dc_delta_q = 0;
626             picture_control_set_ptr->cpi->common.uv_ac_delta_q = 0;
627         }
628 #else
629         picture_control_set_ptr->cpi->common.uv_dc_delta_q = 0;
630         picture_control_set_ptr->cpi->common.uv_ac_delta_q = 0;
631 #endif
632         picture_control_set_ptr->cpi->common.seg.enabled = 0;
633         picture_control_set_ptr->cpi->common.seg.update_map = 0;
634         picture_control_set_ptr->cpi->common.log2_tile_cols = 0;
635         picture_control_set_ptr->cpi->common.log2_tile_rows = 0;
636         picture_control_set_ptr->cpi->use_svc = 0;
637         picture_control_set_ptr->cpi->common.tx_mode = ALLOW_32X32;
638 
639         // Hsan: is it the right spot ?
640         eb_vp9_default_coef_probs(&picture_control_set_ptr->cpi->common);
641         eb_vp9_init_mv_probs(&picture_control_set_ptr->cpi->common);
642 
643         eb_vp9_init_mode_probs(picture_control_set_ptr->cpi->common.fc);
644         vp9_zero(*picture_control_set_ptr->cpi->td.counts);        // Hsan  could be completely removed
645         vp9_zero(picture_control_set_ptr->cpi->td.rd_counts);      // Hsan  could be completely removed
646 
647         eb_vp9_init_intra_predictors();
648 
649         /* eb_vp9_init_quantizer() `is first called here. Add check in
650          * vp9_frame_init_quantizer() so that eb_vp9_init_quantizer is only
651          * called later when needed. This will avoid unnecessary calls of
652          * eb_vp9_init_quantizer() for every frame.
653          */
654         eb_vp9_init_quantizer(picture_control_set_ptr->cpi);
655 
656         eb_vp9_rc_init_minq_luts();
657 #if SEG_SUPPORT
658         eb_vp9_reset_segment_features(&picture_control_set_ptr->cpi->common.seg);
659 #endif
660         // Set the Encoder mode
661         picture_control_set_ptr->enc_mode = sequence_control_set_ptr->static_config.enc_mode;
662 
663         // Keep track of the previous input for the ZZ SADs computation
664         picture_control_set_ptr->previous_picture_control_set_wrapper_ptr = (context_ptr->sequence_control_set_instance_array[instance_index]->encode_context_ptr->initial_picture) ?
665             picture_control_set_wrapper_ptr :
666             sequence_control_set_ptr->encode_context_ptr->previous_picture_control_set_wrapper_ptr;
667 
668         sequence_control_set_ptr->encode_context_ptr->previous_picture_control_set_wrapper_ptr = picture_control_set_wrapper_ptr;
669 
670         // Copy data from the buffer to the input frame
671         // *Note - Assumes 4:2:0 planar
672 
673         input_picture_wrapper_ptr = ebInputWrapperPtr;
674         picture_control_set_ptr->enhanced_picture_ptr = (EbPictureBufferDesc*)eb_input_ptr->p_buffer;
675         picture_control_set_ptr->eb_input_ptr = eb_input_ptr;
676         end_of_sequence_flag = (picture_control_set_ptr->eb_input_ptr->flags & EB_BUFFERFLAG_EOS) ? EB_TRUE : EB_FALSE;
677         svt_vp9_get_time(&picture_control_set_ptr->start_time_seconds,
678                         &picture_control_set_ptr->start_timeu_seconds);
679 
680         picture_control_set_ptr->sequence_control_set_wrapper_ptr    = context_ptr->sequence_control_set_active_array[instance_index];
681         picture_control_set_ptr->input_picture_wrapper_ptr          = input_picture_wrapper_ptr;
682         picture_control_set_ptr->end_of_sequence_flag               = end_of_sequence_flag;
683 
684         // Set Picture Control Flags
685         picture_control_set_ptr->idr_flag = sequence_control_set_ptr->encode_context_ptr->initial_picture || (picture_control_set_ptr->eb_input_ptr->pic_type == EB_IDR_PICTURE);
686         picture_control_set_ptr->scene_change_flag                 = EB_FALSE;
687 
688         picture_control_set_ptr->qp_on_the_fly                      = EB_FALSE;
689 
690         picture_control_set_ptr->sb_total_count                      = sequence_control_set_ptr->sb_total_count;
691 
692         if (sequence_control_set_ptr->static_config.speed_control_flag) {
693             eb_vp9_SpeedBufferControl(
694                 context_ptr,
695                 picture_control_set_ptr,
696                 sequence_control_set_ptr);
697         }
698         else {
699             picture_control_set_ptr->enc_mode = (EB_ENC_MODE)sequence_control_set_ptr->static_config.enc_mode;
700         }
701 
702         // Set the SCD Mode
703         sequence_control_set_ptr->scd_mode = SCD_MODE_0;
704 
705         // Pre-Analysis Signal(s) derivation
706         if (sequence_control_set_ptr->static_config.tune == TUNE_SQ) {
707             eb_vp9_signal_derivation_pre_analysis_sq(
708                 sequence_control_set_ptr,
709                 picture_control_set_ptr);
710         }
711         else if (sequence_control_set_ptr->static_config.tune == TUNE_VMAF) {
712             eb_vp9_signal_derivation_pre_analysis_vmaf(
713                 sequence_control_set_ptr,
714                 picture_control_set_ptr);
715         }
716         else {
717             eb_vp9_signal_derivation_pre_analysis_oq(
718                 sequence_control_set_ptr,
719                 picture_control_set_ptr);
720         }
721 
722         // Rate Control
723         // Set the ME Distortion and OIS Historgrams to zero
724         if (sequence_control_set_ptr->static_config.rate_control_mode){
725                 EB_MEMSET(picture_control_set_ptr->me_distortion_histogram, 0, NUMBER_OF_SAD_INTERVALS*sizeof(uint16_t));
726                 EB_MEMSET(picture_control_set_ptr->ois_distortion_histogram, 0, NUMBER_OF_INTRA_SAD_INTERVALS*sizeof(uint16_t));
727         }
728         picture_control_set_ptr->full_sb_count                    = 0;
729 
730         if (sequence_control_set_ptr->static_config.use_qp_file == 1) {
731             picture_control_set_ptr->qp_on_the_fly = EB_TRUE;
732             if (picture_control_set_ptr->eb_input_ptr->qp > MAX_QP_VALUE) {
733                 SVT_LOG("SVT [WARNING]: INPUT QP OUTSIDE OF RANGE\n");
734                 picture_control_set_ptr->qp_on_the_fly = EB_FALSE;
735                 picture_control_set_ptr->picture_qp = (uint8_t)sequence_control_set_ptr->qp;
736             }
737             picture_control_set_ptr->picture_qp = (uint8_t)picture_control_set_ptr->eb_input_ptr->qp;
738         }
739         else {
740             picture_control_set_ptr->qp_on_the_fly = EB_FALSE;
741             picture_control_set_ptr->picture_qp = (uint8_t)sequence_control_set_ptr->qp;
742         }
743 
744         // Picture Stats
745         picture_control_set_ptr->picture_number                   = context_ptr->picture_number_array[instance_index]++;
746 
747         // Set the picture structure: 0: progressive, 1: top, 2: bottom
748         picture_control_set_ptr->pict_struct = PROGRESSIVE_PIC_STRUCT;
749 
750         sequence_control_set_ptr->encode_context_ptr->initial_picture = EB_FALSE;
751 
752         // Get Empty Reference Picture Object
753         eb_vp9_get_empty_object(
754             sequence_control_set_ptr->encode_context_ptr->pa_reference_picture_pool_fifo_ptr,
755             &reference_picture_wrapper_ptr);
756 
757         picture_control_set_ptr->pareference_picture_wrapper_ptr = reference_picture_wrapper_ptr;
758 
759         // Give the new Reference a nominal live_count of 1
760         eb_vp9_object_inc_live_count(
761             picture_control_set_ptr->pareference_picture_wrapper_ptr,
762             2);
763 
764         eb_vp9_object_inc_live_count(
765             picture_control_set_wrapper_ptr,
766             2);
767 
768         ((EbPaReferenceObject*)picture_control_set_ptr->pareference_picture_wrapper_ptr->object_ptr)->input_padded_picture_ptr->buffer_y = picture_control_set_ptr->enhanced_picture_ptr->buffer_y;
769         // Get Empty Output Results Object
770         if (picture_control_set_ptr->picture_number > 0 && prev_picture_control_set_wrapper_ptr != NULL)
771         {
772             ((PictureParentControlSet*)prev_picture_control_set_wrapper_ptr->object_ptr)->end_of_sequence_flag = end_of_sequence_flag;
773             eb_vp9_get_empty_object(
774                 context_ptr->resource_coordination_results_output_fifo_ptr,
775                 &output_wrapper_ptr);
776             output_results_ptr = (ResourceCoordinationResults*)output_wrapper_ptr->object_ptr;
777             output_results_ptr->picture_control_set_wrapper_ptr = prev_picture_control_set_wrapper_ptr;
778 
779             // Post the finished Results Object
780             eb_vp9_post_full_object(output_wrapper_ptr);
781         }
782         prev_picture_control_set_wrapper_ptr = picture_control_set_wrapper_ptr;
783 
784     }
785 
786     return EB_NULL;
787 }
788