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