1 /*
2 * Copyright(c) 2019 Intel Corporation
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10 */
11 
12 #include "EbEncHandle.h"
13 #include "EbPictureControlSet.h"
14 #include "EbSequenceControlSet.h"
15 #include "EbMotionEstimationResults.h"
16 #include "EbInitialRateControlProcess.h"
17 #include "EbInitialRateControlResults.h"
18 #include "EbMotionEstimationContext.h"
19 #include "EbUtility.h"
20 #include "EbReferenceObject.h"
21 #include "EbResize.h"
22 #include "common_dsp_rtcd.h"
23 #include "EbLog.h"
24 #include "EbPictureDecisionProcess.h"
25 /**************************************
26  * Context
27  **************************************/
28 typedef struct LadQueueEntry {
29     EbDctor dctor;
30     PictureParentControlSet *pcs;
31 } LadQueueEntry;
32 
33 typedef struct LadQueue {
34     LadQueueEntry **cir_buf;  //circular buffer holding the entries
35     uint32_t          head;
36     uint32_t          tail;
37 } LadQueue;
38 
39 /* look ahead queue constructor*/
lad_queue_entry_ctor(LadQueueEntry * entry_ptr)40 EbErrorType lad_queue_entry_ctor(LadQueueEntry *entry_ptr) {
41 
42     entry_ptr->pcs = NULL;
43     return EB_ErrorNone;
44 }
45 
46 
47 typedef struct InitialRateControlContext {
48     EbFifo *motion_estimation_results_input_fifo_ptr;
49     EbFifo *initialrate_control_results_output_fifo_ptr;
50     LadQueue         *lad_queue;
51 
52 } InitialRateControlContext;
53 
54 /**************************************
55 * Macros
56 **************************************/
initial_rate_control_context_dctor(EbPtr p)57 static void initial_rate_control_context_dctor(EbPtr p) {
58     EbThreadContext *          thread_context_ptr = (EbThreadContext *)p;
59     InitialRateControlContext *obj = (InitialRateControlContext *)thread_context_ptr->priv;
60 
61     EB_DELETE_PTR_ARRAY(obj->lad_queue->cir_buf, REFERENCE_QUEUE_MAX_DEPTH);
62     EB_FREE(obj->lad_queue);
63     EB_FREE_ARRAY(obj);
64 }
65 
66 /************************************************
67 * Initial Rate Control Context Constructor
68 ************************************************/
initial_rate_control_context_ctor(EbThreadContext * thread_context_ptr,const EbEncHandle * enc_handle_ptr)69 EbErrorType initial_rate_control_context_ctor(EbThreadContext *  thread_context_ptr,
70                                               const EbEncHandle *enc_handle_ptr) {
71     InitialRateControlContext *context_ptr;
72     EB_CALLOC_ARRAY(context_ptr, 1);
73     thread_context_ptr->priv  = context_ptr;
74     thread_context_ptr->dctor = initial_rate_control_context_dctor;
75 
76     context_ptr->motion_estimation_results_input_fifo_ptr = svt_system_resource_get_consumer_fifo(
77         enc_handle_ptr->motion_estimation_results_resource_ptr, 0);
78     context_ptr->initialrate_control_results_output_fifo_ptr =
79         svt_system_resource_get_producer_fifo(
80             enc_handle_ptr->initial_rate_control_results_resource_ptr, 0);
81 
82     EB_MALLOC(context_ptr->lad_queue, sizeof(LadQueue));
83 
84     EB_ALLOC_PTR_ARRAY(context_ptr->lad_queue->cir_buf, REFERENCE_QUEUE_MAX_DEPTH);
85     for (uint32_t picture_index = 0; picture_index < REFERENCE_QUEUE_MAX_DEPTH; ++picture_index) {
86         EB_NEW(context_ptr->lad_queue->cir_buf[picture_index], lad_queue_entry_ctor);
87     }
88     context_ptr->lad_queue->head = 0;
89     context_ptr->lad_queue->tail = 0;
90 
91     return EB_ErrorNone;
92 }
93 
94 /****************************************
95 * Init ZZ Cost array to default values
96 ** Used when no Lookahead is available
97 ****************************************/
init_zz_cost_info(PictureParentControlSet * pcs_ptr)98 void init_zz_cost_info(PictureParentControlSet *pcs_ptr) {
99     uint16_t sb_idx;
100     pcs_ptr->non_moving_index_average = INVALID_ZZ_COST;
101 
102     // SB Loop
103     for (sb_idx = 0; sb_idx < pcs_ptr->sb_total_count; ++sb_idx)
104         pcs_ptr->non_moving_index_array[sb_idx] = INVALID_ZZ_COST;
105     return;
106 }
107 
determine_picture_offset_in_queue(EncodeContext * encode_context_ptr,PictureParentControlSet * pcs_ptr,MotionEstimationResults * in_results_ptr)108 InitialRateControlReorderEntry *determine_picture_offset_in_queue(
109     EncodeContext *encode_context_ptr, PictureParentControlSet *pcs_ptr,
110     MotionEstimationResults *in_results_ptr) {
111     InitialRateControlReorderEntry *queue_entry_ptr;
112     int32_t                         queue_entry_index;
113 
114     queue_entry_index = (int32_t)(
115         pcs_ptr->picture_number -
116         encode_context_ptr
117             ->initial_rate_control_reorder_queue
118                 [encode_context_ptr->initial_rate_control_reorder_queue_head_index]
119             ->picture_number);
120     queue_entry_index += encode_context_ptr->initial_rate_control_reorder_queue_head_index;
121     queue_entry_index = (queue_entry_index > INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1)
122         ? queue_entry_index - INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH
123         : queue_entry_index;
124     queue_entry_ptr   = encode_context_ptr->initial_rate_control_reorder_queue[queue_entry_index];
125     queue_entry_ptr->parent_pcs_wrapper_ptr = in_results_ptr->pcs_wrapper_ptr;
126     queue_entry_ptr->picture_number         = pcs_ptr->picture_number;
127 
128     return queue_entry_ptr;
129 }
130 
131 void svt_av1_build_quantizer(AomBitDepth bit_depth, int32_t y_dc_delta_q, int32_t u_dc_delta_q,
132                              int32_t u_ac_delta_q, int32_t v_dc_delta_q, int32_t v_ac_delta_q,
133                              Quants *const quants, Dequants *const deq);
134 
135 
136 #if LAD_MG_PRINT
137 /*
138  get size  of the  lad queue
139 */
get_lad_q_size(InitialRateControlContext * ctx)140 uint32_t  get_lad_q_size(InitialRateControlContext *ctx)
141 {
142     uint32_t size = 0;
143     uint32_t idx = ctx->lad_queue->head;
144     LadQueueEntry   *queue_entry = ctx->lad_queue->cir_buf[idx];
145     while (queue_entry->pcs != NULL) {
146         queue_entry = ctx->lad_queue->cir_buf[++idx];
147         size++;
148     }
149     return size;
150 }
151 
152 /*
153  dump the content of the  queue for debug purpose
154 */
print_lad_queue(InitialRateControlContext * ctx,uint8_t log)155 void print_lad_queue(InitialRateControlContext *ctx, uint8_t log)
156 {
157     if (log) {
158         LadQueue* queue = ctx->lad_queue;
159         uint32_t idx = queue->head;
160         LadQueueEntry   *queue_entry = queue->cir_buf[idx];
161 
162         SVT_LOG("\n lad_queue size:%i  ", get_lad_q_size(ctx));
163 
164         while (queue_entry->pcs != NULL) {
165             SVT_LOG("%i-%lld ", queue_entry->pcs->ext_mg_id, queue_entry->pcs->picture_number);
166             idx = OUT_Q_ADVANCE(idx);
167             queue_entry = queue->cir_buf[idx];
168         }
169         SVT_LOG("\n");
170     }
171 }
172 #endif
173 /*
174  store pictures in the lad queue
175 */
push_to_lad_queue(PictureParentControlSet * pcs,InitialRateControlContext * ctx)176 void push_to_lad_queue(
177     PictureParentControlSet *pcs,
178     InitialRateControlContext *ctx)
179 {
180     LadQueue *queue = ctx->lad_queue;
181     uint32_t entry_idx = pcs->decode_order % REFERENCE_QUEUE_MAX_DEPTH;
182     LadQueueEntry   *queue_entry  = queue->cir_buf[entry_idx];
183     assert_err(queue_entry->pcs == NULL, "lad queue overflow");
184     if (queue_entry->pcs == NULL)
185        queue_entry->pcs = pcs;
186     else
187         SVT_ERROR("\n lad queue overflow \n");
188 
189 }
190 
191 /* send picture out from irc process */
irc_send_picture_out(InitialRateControlContext * ctx,PictureParentControlSet * pcs)192 void irc_send_picture_out(InitialRateControlContext *ctx, PictureParentControlSet *pcs)
193 {
194     EbObjectWrapper *out_results_wrapper_ptr;
195     // Get Empty Results Object
196     svt_get_empty_object(ctx->initialrate_control_results_output_fifo_ptr,
197            &out_results_wrapper_ptr);
198     InitialRateControlResults *out_results_ptr =
199           (InitialRateControlResults *)out_results_wrapper_ptr->object_ptr;
200     //SVT_LOG("iRC Out:%lld\n",pcs->picture_number);
201     out_results_ptr->pcs_wrapper_ptr = pcs->p_pcs_wrapper_ptr;
202     svt_post_full_object(out_results_wrapper_ptr);
203 }
is_frame_already_exists(PictureParentControlSet * pcs,uint32_t end_index,uint64_t pic_num)204 uint8_t is_frame_already_exists(PictureParentControlSet *pcs, uint32_t end_index, uint64_t pic_num) {
205     for (uint32_t i = 0; i < end_index; i++)
206         if (pcs->tpl_group[i]->picture_number == pic_num)
207             return 1;
208     return 0;
209 }
210 
211 /* decide to inject a frame into the tpl group*/
inj_to_tpl_group(PictureParentControlSet * pcs)212 uint8_t  inj_to_tpl_group( PictureParentControlSet* pcs)
213 {
214     uint8_t inj = 0;
215     if (pcs->hierarchical_levels != 4) {
216         if (pcs->temporal_layer_index < pcs->hierarchical_levels)
217             inj = 1;
218         else
219             inj = 0;
220     }
221     else {
222 
223         if (pcs->scs_ptr->mrp_init_level == 1) {
224 
225             if (pcs->temporal_layer_index < 4)
226                 inj = 1;
227             else if (pcs->is_used_as_reference_flag && (pcs->pic_index == 6 || pcs->pic_index == 10))//TODO: could be removed once TPL r0 adapts dyncamically  to TPL group size
228                 inj = 1;
229             else
230                 inj = 0;
231 
232         }
233         else {
234             if (pcs->temporal_layer_index < 4)
235                 inj = 1;
236             else if (pcs->is_used_as_reference_flag && (pcs->pic_index == 0 || pcs->pic_index == 8))
237                 inj = 1;
238             else
239                 inj = 0;
240 
241         }
242     }
243 
244     return inj;
245 }
246 /*
247  copy the number of pcs entries from the the output queue to extended  buffer
248 */
store_extended_group(PictureParentControlSet * pcs,InitialRateControlContext * ctx,uint32_t start_idx,int64_t end_mg)249 void store_extended_group(
250     PictureParentControlSet    *pcs,
251     InitialRateControlContext  *ctx,
252     uint32_t                    start_idx,
253     int64_t                     end_mg)
254 {
255     LadQueue* queue = ctx->lad_queue;
256     uint32_t pic_i = 0;
257     uint32_t q_idx = start_idx;
258     LadQueueEntry  *entry = queue->cir_buf[q_idx];
259 
260     while (entry->pcs != NULL) {
261 
262         if (entry->pcs->ext_mg_id <= end_mg) {
263 
264             assert_err(pic_i < MAX_TPL_EXT_GROUP_SIZE,"exceeding size of ext group");
265             pcs->ext_group[pic_i++] = queue->cir_buf[q_idx]->pcs;
266         }
267 
268         //Increment the queue_index Iterator
269         q_idx = OUT_Q_ADVANCE(q_idx);
270         //get the next entry
271         entry = queue->cir_buf[q_idx];
272     }
273 
274     pcs->ext_group_size = pic_i;
275 #if LAD_MG_PRINT
276     const uint8_t log = 0;
277     if (log) {
278         SVT_LOG("\n EXT group Pic:%lld  size:%i  \n", pcs->picture_number, pcs->ext_group_size);
279         for (uint32_t i = 0; i < pcs->ext_group_size; i++) {
280             if(pcs->ext_group[i]->temporal_layer_index==0)
281                 SVT_LOG(" | ");
282             SVT_LOG("%lld ", pcs->ext_group[i]->picture_number);
283 
284         }
285         SVT_LOG("\n");
286     }
287 #if 0 //force test
288     if (pcs->tpl_group_size != pcs->ext_group_size)
289         printf("asfafs");
290     for (uint32_t i = 0; i < pcs->ext_group_size; i++)
291         if (pcs->tpl_group[i] != pcs->ext_group[i])
292             printf("asfafs");
293 
294 
295     pcs->tpl_group_size = pcs->ext_group_size;
296 
297     for (uint32_t i = 0; i < pcs->ext_group_size; i++)
298         pcs->tpl_group[i] = pcs->ext_group[i];
299 #endif
300 #endif
301 
302     //new tpl group needs to stop at the second I
303     pcs->ntpl_group_size = 0;
304     uint8_t is_gop_end = 0;
305     int64_t last_intra_mg_id;
306 
307     for (uint32_t i = 0; i < pcs->ext_group_size; i++) {
308 
309         PictureParentControlSet *cur_pcs = pcs->ext_group[i];
310         if (cur_pcs->slice_type == I_SLICE) {
311             if (is_delayed_intra(cur_pcs)) {
312                 if (i == 0) {
313                     pcs->ntpl_group[pcs->ntpl_group_size++] = cur_pcs;
314                 }
315                 else
316                     break;
317             }
318             else {
319                 if (i == 0) {
320                     pcs->ntpl_group[pcs->ntpl_group_size++] = cur_pcs;
321                 }
322                 else{
323                     pcs->ntpl_group[pcs->ntpl_group_size++] = cur_pcs;
324                     last_intra_mg_id = cur_pcs->ext_mg_id;
325                     is_gop_end = 1;
326                 }
327             }
328         }
329         else {
330 
331             if (is_gop_end == 0)
332                 pcs->ntpl_group[pcs->ntpl_group_size++] = cur_pcs;
333             else if (cur_pcs->ext_mg_id == last_intra_mg_id)
334                 pcs->ntpl_group[pcs->ntpl_group_size++] = cur_pcs;
335             else
336                 break;
337         }
338     }
339 
340     SequenceControlSet *scs_ptr = (SequenceControlSet *)pcs->scs_wrapper_ptr->object_ptr;
341     if (scs_ptr->lad_mg) {
342         pcs->tpl_group_size = pcs->ntpl_group_size;
343         memset(pcs->tpl_valid_pic, 0, MAX_TPL_EXT_GROUP_SIZE * sizeof(uint8_t));
344         pcs->tpl_valid_pic[0] = 1;
345         pcs->used_tpl_frame_num = 0;
346         for (uint32_t i = 0; i < pcs->ntpl_group_size; i++) {
347             pcs->tpl_group[i] = pcs->ntpl_group[i];
348             // Check wether the i-th pic already exists in the tpl group
349             if (!is_frame_already_exists(pcs, i, pcs->tpl_group[i]->picture_number)) {
350                 // Discard non-ref pic from the tpl group
351                 uint8_t inject_frame = inj_to_tpl_group(pcs->tpl_group[i]);
352                 if (inject_frame) {
353                     if (pcs->slice_type != I_SLICE) {
354                         // Discard low important pictures from tpl group
355                         if (pcs->tpl_ctrls.tpl_opt_flag && pcs->tpl_ctrls.reduced_tpl_group) {
356                             if (pcs->tpl_group[i]->temporal_layer_index <= pcs->tpl_ctrls.reduced_tpl_group + (pcs->hierarchical_levels == 5 ? 1 : 0)) {
357                                 pcs->tpl_valid_pic[i] = 1;
358                                 pcs->used_tpl_frame_num++;
359                             }
360                         }
361                         else {
362                             pcs->tpl_valid_pic[i] = 1;
363                             pcs->used_tpl_frame_num++;
364                         }
365                     }
366                     else {
367                         pcs->tpl_valid_pic[i] = 1;
368                         pcs->used_tpl_frame_num++;
369                     }
370                 }
371             }
372         }
373     }
374 
375 #if LAD_MG_PRINT
376     if (log) {
377         SVT_LOG("\n NEW TPL group Pic:%lld  size:%i  \n", pcs->picture_number, pcs->ntpl_group_size);
378         for (uint32_t i = 0; i < pcs->ntpl_group_size; i++) {
379             if (pcs->ext_group[i]->temporal_layer_index == 0)
380                 SVT_LOG(" | ");
381             SVT_LOG("%lld ", pcs->ntpl_group[i]->picture_number);
382         }
383         SVT_LOG("\n");
384     }
385 #endif
386 
387 }
388 
389 /*
390  scan the queue and determine if pictures can go outside
391  pictures are stored in dec order.
392  only base pictures are hold. the rest including LDP ones are pass-thru
393 */
process_lad_queue(InitialRateControlContext * ctx,uint8_t pass_thru)394 void process_lad_queue(
395     InitialRateControlContext *ctx, uint8_t pass_thru)
396 {
397     LadQueue *queue = ctx->lad_queue;
398     LadQueueEntry  *head_entry = queue->cir_buf[queue->head];
399 
400     while (head_entry->pcs != NULL) {
401 
402         PictureParentControlSet *head_pcs = head_entry->pcs;
403 
404 
405         uint8_t send_out;
406         if (!pass_thru) {
407             if (head_pcs->temporal_layer_index == 0) {
408 
409                 //delayed Intra can use the whole window relative to the next Base
410                 uint8_t target_mgs = is_delayed_intra(head_pcs) ? head_pcs->scs_ptr->lad_mg + 1 : head_pcs->scs_ptr->lad_mg;
411                 target_mgs++;//add one for the MG including the head
412                 {
413 
414                     uint8_t num_mgs = 0;//number of MGs accumulated so far in the queue including the MG where the head belongs
415                     int64_t cur_mg = head_pcs->ext_mg_id;
416 
417                     uint32_t  tmp_idx = queue->head;
418                     LadQueueEntry  *tmp_entry = queue->cir_buf[tmp_idx];
419                     uint32_t tot_acc_frames_in_cur_mg = 0;
420                     send_out = 0;
421                     while (tmp_entry->pcs != NULL) {
422                         PictureParentControlSet *tmp_pcs = tmp_entry->pcs;
423 
424                         assert_err(tmp_pcs->ext_mg_id >= head_pcs->ext_mg_id, "err in mg id");
425                         //adjust the lad if we hit an EOS
426                         if (tmp_pcs->end_of_sequence_flag)
427                             target_mgs = MIN(target_mgs, (uint8_t)(tmp_pcs->ext_mg_id - head_pcs->ext_mg_id + 1));//+1: to include the MG where the head belongs
428 
429                         if (tmp_pcs->ext_mg_id >= cur_mg) {
430 
431                             if (tmp_pcs->ext_mg_id > cur_mg)
432                                assert_err(tmp_pcs->ext_mg_id == cur_mg+1, "err continuity in mg id");
433 
434                             tot_acc_frames_in_cur_mg++;
435 
436                             if (tot_acc_frames_in_cur_mg == tmp_pcs->ext_mg_size) {
437                                 num_mgs++;
438                                 cur_mg = tmp_pcs->ext_mg_id;
439                                 tot_acc_frames_in_cur_mg = 0;
440                             }
441 
442                             if (num_mgs == target_mgs) {
443                                 store_extended_group(head_pcs, ctx, queue->head, tmp_pcs->ext_mg_id);
444                                 send_out = 1;
445                                 break;
446                             }
447                         }
448 
449                         tmp_idx = OUT_Q_ADVANCE(tmp_idx);
450                         tmp_entry = queue->cir_buf[tmp_idx];
451                     }
452                 }
453 
454             }
455             else {
456                 send_out = 1;
457             }
458         }
459         else {
460             send_out = 1;
461         }
462 
463         if (send_out) {
464             //take the picture out from iRc process
465             irc_send_picture_out(ctx, head_pcs);
466             //advance the head
467             head_entry->pcs = NULL;
468             queue->head = OUT_Q_ADVANCE(queue->head);
469             head_entry = queue->cir_buf[queue->head];
470         }
471         else {
472             break;
473         }
474     }
475 
476 }
477 
478 
479 /* Initial Rate Control Kernel */
480 
481 /*********************************************************************************
482 *
483 * @brief
484 *  The Initial Rate Control process determines the initial bit budget for each picture
485 *  depending on the data gathered in the Picture Analysis and Motion Estimation processes
486 *  as well as the settings determined in the Picture Decision process.
487 *
488 * @par Description:
489 *  The Initial Rate Control process employs a sliding window buffer to analyze
490 *  multiple pictures if a delay is allowed. Note that no reference picture data is
491 *  used in this process.
492 *
493 * @param[in] Picture
494 *  The Initial Rate Control Kernel takes a picture and determines the initial bit budget
495 *  for each picture depending on the data that was gathered in Picture Analysis and
496 *  Motion Estimation processes
497 *
498 * @param[out] Bit Budget
499 *  Bit Budget is the amount of budgetted bits for a picture
500 *
501 * @remarks
502 *  Temporal noise reduction is currently performed in Initial Rate Control Process.
503 *  In the future we might decide to move it to Motion Analysis Process.
504 *
505 ********************************************************************************/
initial_rate_control_kernel(void * input_ptr)506 void *initial_rate_control_kernel(void *input_ptr) {
507     EbThreadContext *          thread_context_ptr = (EbThreadContext *)input_ptr;
508     InitialRateControlContext *context_ptr = (InitialRateControlContext *)thread_context_ptr->priv;
509 
510     EbObjectWrapper *in_results_wrapper_ptr;
511 
512     // Segments
513     for (;;) {
514         // Get Input Full Object
515         EB_GET_FULL_OBJECT(context_ptr->motion_estimation_results_input_fifo_ptr,
516                            &in_results_wrapper_ptr);
517 
518         MotionEstimationResults *in_results_ptr = (MotionEstimationResults *)
519                                                       in_results_wrapper_ptr->object_ptr;
520         PictureParentControlSet *pcs_ptr = (PictureParentControlSet *)
521                                                in_results_ptr->pcs_wrapper_ptr->object_ptr;
522 
523         // Set the segment counter
524         pcs_ptr->me_segments_completion_count++;
525 
526         // If the picture is complete, proceed
527         if (pcs_ptr->me_segments_completion_count == pcs_ptr->me_segments_total_count) {
528             SequenceControlSet *scs_ptr = (SequenceControlSet *)
529                                               pcs_ptr->scs_wrapper_ptr->object_ptr;
530             if (pcs_ptr->picture_number == 0) {
531                 Quants *const   quants_8bit = &scs_ptr->quants_8bit;
532                 Dequants *const deq_8bit    = &scs_ptr->deq_8bit;
533                 svt_av1_build_quantizer(
534                     AOM_BITS_8,
535                     pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_Y],
536                     pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_U],
537                     pcs_ptr->frm_hdr.quantization_params.delta_q_ac[AOM_PLANE_U],
538                     pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_V],
539                     pcs_ptr->frm_hdr.quantization_params.delta_q_ac[AOM_PLANE_V],
540                     quants_8bit,
541                     deq_8bit);
542 
543                 if (scs_ptr->static_config.encoder_bit_depth == AOM_BITS_10) {
544                     Quants *const   quants_bd = &scs_ptr->quants_bd;
545                     Dequants *const deq_bd    = &scs_ptr->deq_bd;
546                     svt_av1_build_quantizer(
547                         AOM_BITS_10,
548                         pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_Y],
549                         pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_U],
550                         pcs_ptr->frm_hdr.quantization_params.delta_q_ac[AOM_PLANE_U],
551                         pcs_ptr->frm_hdr.quantization_params.delta_q_dc[AOM_PLANE_V],
552                         pcs_ptr->frm_hdr.quantization_params.delta_q_ac[AOM_PLANE_V],
553                         quants_bd,
554                         deq_bd);
555                 }
556             }
557             if (scs_ptr->static_config.enable_tpl_la) {
558                 svt_set_cond_var(&pcs_ptr->me_ready, 1);
559             }
560 
561             // Release Pa Ref pictures when not needed
562             // Release Pa ref after when TPL is OFF
563             if (scs_ptr->static_config.enable_tpl_la == 0)
564                 release_pa_reference_objects(scs_ptr, pcs_ptr);
565 
566             /*In case Look-Ahead is zero there is no need to place pictures in the
567               re-order queue. this will cause an artificial delay since pictures come in dec-order*/
568             pcs_ptr->frames_in_sw           = 0;
569             pcs_ptr->end_of_sequence_region = EB_FALSE;
570 
571             init_zz_cost_info(pcs_ptr);
572 
573 
574             push_to_lad_queue(pcs_ptr, context_ptr);
575 #if LAD_MG_PRINT
576             print_lad_queue(context_ptr,0);
577 #endif
578             uint8_t lad_queue_pass_thru = !scs_ptr->static_config.enable_tpl_la;
579             process_lad_queue(context_ptr, lad_queue_pass_thru);
580 
581         }
582         // Release the Input Results
583         svt_release_object(in_results_wrapper_ptr);
584     }
585     return NULL;
586 }
587