Line data Source code
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 "EbSystemResourceManager.h"
12 : #include "EbPictureControlSet.h"
13 : #include "EbSequenceControlSet.h"
14 :
15 : #include "EbPictureManagerProcess.h"
16 : #include "EbReferenceObject.h"
17 :
18 : #include "EbPictureDemuxResults.h"
19 : #include "EbPictureManagerQueue.h"
20 : #include "EbPredictionStructure.h"
21 : #include "EbRateControlTasks.h"
22 : #include "EbSvtAv1ErrorCodes.h"
23 : #include "EbEntropyCoding.h"
24 :
25 : void set_tile_info(PictureParentControlSet * pcs_ptr);
26 : extern MvReferenceFrame svt_get_ref_frame_type(uint8_t list, uint8_t ref_idx);
27 : /************************************************
28 : * Defines
29 : ************************************************/
30 : #define POC_CIRCULAR_ADD(base, offset) (((base) + (offset)))
31 :
32 : /************************************************
33 : * Configure Picture edges
34 : ************************************************/
35 120 : static void ConfigurePictureEdges(
36 : SequenceControlSet *scs_ptr,
37 : PictureControlSet *ppsPtr)
38 : {
39 : // Tiles Initialisation
40 120 : const uint16_t picture_width_in_sb = (scs_ptr->seq_header.max_frame_width + scs_ptr->sb_size_pix - 1) / scs_ptr->sb_size_pix;
41 120 : const uint16_t picture_height_in_sb = (scs_ptr->seq_header.max_frame_height + scs_ptr->sb_size_pix - 1) / scs_ptr->sb_size_pix;
42 : unsigned x_lcu_index, y_lcu_index, sb_index;
43 :
44 : // LCU-loops
45 840 : for (y_lcu_index = 0; y_lcu_index < picture_height_in_sb; ++y_lcu_index) {
46 7920 : for (x_lcu_index = 0; x_lcu_index < picture_width_in_sb; ++x_lcu_index) {
47 7200 : sb_index = (uint16_t)(x_lcu_index + y_lcu_index * picture_width_in_sb);
48 7200 : ppsPtr->sb_ptr_array[sb_index]->picture_left_edge_flag = (x_lcu_index == 0) ? EB_TRUE : EB_FALSE;
49 7200 : ppsPtr->sb_ptr_array[sb_index]->picture_top_edge_flag = (y_lcu_index == 0) ? EB_TRUE : EB_FALSE;
50 7200 : ppsPtr->sb_ptr_array[sb_index]->picture_right_edge_flag = (x_lcu_index == (unsigned)(picture_width_in_sb - 1)) ? EB_TRUE : EB_FALSE;
51 : }
52 : }
53 :
54 120 : return;
55 : }
56 : #if TWO_PASS
57 : void write_stat_to_file(
58 : SequenceControlSet *sequence_control_set_ptr,
59 : stat_struct_t stat_struct,
60 : uint64_t ref_poc);
61 : #endif
62 : /************************************************
63 : * Picture Manager Context Constructor
64 : ************************************************/
65 2 : EbErrorType picture_manager_context_ctor(
66 : PictureManagerContext *context_ptr,
67 : EbFifo *picture_input_fifo_ptr,
68 : EbFifo *picture_manager_output_fifo_ptr,
69 : EbFifo **picture_control_set_fifo_ptr_array)
70 : {
71 2 : context_ptr->picture_input_fifo_ptr = picture_input_fifo_ptr;
72 2 : context_ptr->picture_manager_output_fifo_ptr = picture_manager_output_fifo_ptr;
73 2 : context_ptr->picture_control_set_fifo_ptr_array = picture_control_set_fifo_ptr_array;
74 :
75 2 : return EB_ErrorNone;
76 : }
77 :
78 : /***************************************************************************************************
79 : * Picture Manager Kernel
80 : *
81 : * Notes on the Picture Manager:
82 : *
83 : * The Picture Manager Process performs the function of managing both the Input Picture buffers and
84 : * the Reference Picture buffers and subdividing the Input Picture into Tiles. Both the Input Picture
85 : * and Reference Picture buffers particular management depends on the GoP structure already implemented in
86 : * the Picture decision. Also note that the Picture Manager sets up the RPS for Entropy Coding as well.
87 : *
88 : * Inputs:
89 : * Input Picture
90 : * -Input Picture Data
91 : *
92 : * Reference Picture
93 : * -Reference Picture Data
94 : *
95 : * Outputs:
96 : * -Picture Control Set with fully available Reference List
97 : *
98 : ***************************************************************************************************/
99 2 : void* picture_manager_kernel(void *input_ptr)
100 : {
101 2 : PictureManagerContext *context_ptr = (PictureManagerContext*)input_ptr;
102 :
103 : EbObjectWrapper *ChildPictureControlSetWrapperPtr;
104 : PictureControlSet *ChildPictureControlSetPtr;
105 : PictureParentControlSet *picture_control_set_ptr;
106 : SequenceControlSet *sequence_control_set_ptr;
107 : EncodeContext *encode_context_ptr;
108 :
109 : EbObjectWrapper *inputPictureDemuxWrapperPtr;
110 : PictureDemuxResults *inputPictureDemuxPtr;
111 :
112 : EbObjectWrapper *outputWrapperPtr;
113 : RateControlTasks *rateControlTasksPtr;
114 :
115 : EbBool availabilityFlag;
116 :
117 : PredictionStructureEntry *predPositionPtr;
118 : InputQueueEntry *inputEntryPtr;
119 : uint32_t inputQueueIndex;
120 : uint64_t current_input_poc;
121 : ReferenceQueueEntry *referenceEntryPtr;
122 : uint32_t referenceQueueIndex;
123 : uint64_t ref_poc;
124 : uint32_t depIdx;
125 : uint64_t depPoc;
126 : uint32_t depListCount;
127 : PictureParentControlSet *entryPictureControlSetPtr;
128 : SequenceControlSet *entrySequenceControlSetPtr;
129 :
130 : // Initialization
131 : uint8_t picture_width_in_sb;
132 : uint8_t picture_height_in_sb;
133 : PictureManagerReorderEntry *queueEntryPtr;
134 : int32_t queueEntryIndex;
135 :
136 : // Debug
137 2 : uint32_t loopCount = 0;
138 :
139 : for (;;) {
140 : // Get Input Full Object
141 228 : eb_get_full_object(
142 : context_ptr->picture_input_fifo_ptr,
143 : &inputPictureDemuxWrapperPtr);
144 :
145 226 : inputPictureDemuxPtr = (PictureDemuxResults*)inputPictureDemuxWrapperPtr->object_ptr;
146 :
147 : // *Note - This should be overhauled and/or replaced when we
148 : // need hierarchical support.
149 226 : loopCount++;
150 :
151 226 : switch (inputPictureDemuxPtr->picture_type) {
152 120 : case EB_PIC_INPUT:
153 :
154 120 : picture_control_set_ptr = (PictureParentControlSet*)inputPictureDemuxPtr->picture_control_set_wrapper_ptr->object_ptr;
155 120 : sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
156 120 : encode_context_ptr = sequence_control_set_ptr->encode_context_ptr;
157 :
158 : //printf("\nPicture Manager Process @ %d \n ", picture_control_set_ptr->picture_number);
159 :
160 120 : queueEntryIndex = (int32_t)(picture_control_set_ptr->picture_number_alt - encode_context_ptr->picture_manager_reorder_queue[encode_context_ptr->picture_manager_reorder_queue_head_index]->picture_number);
161 120 : queueEntryIndex += encode_context_ptr->picture_manager_reorder_queue_head_index;
162 120 : queueEntryIndex = (queueEntryIndex > PICTURE_MANAGER_REORDER_QUEUE_MAX_DEPTH - 1) ? queueEntryIndex - PICTURE_MANAGER_REORDER_QUEUE_MAX_DEPTH : queueEntryIndex;
163 120 : queueEntryPtr = encode_context_ptr->picture_manager_reorder_queue[queueEntryIndex];
164 120 : if (queueEntryPtr->parent_pcs_wrapper_ptr != NULL) {
165 0 : CHECK_REPORT_ERROR_NC(
166 : encode_context_ptr->app_callback_ptr,
167 : EB_ENC_PD_ERROR8);
168 : }
169 : else {
170 120 : queueEntryPtr->parent_pcs_wrapper_ptr = inputPictureDemuxPtr->picture_control_set_wrapper_ptr;
171 120 : queueEntryPtr->picture_number = picture_control_set_ptr->picture_number_alt;
172 : }
173 : // Process the head of the Picture Manager Reorder Queue
174 120 : queueEntryPtr = encode_context_ptr->picture_manager_reorder_queue[encode_context_ptr->picture_manager_reorder_queue_head_index];
175 :
176 240 : while (queueEntryPtr->parent_pcs_wrapper_ptr != EB_NULL) {
177 120 : picture_control_set_ptr = (PictureParentControlSet*)queueEntryPtr->parent_pcs_wrapper_ptr->object_ptr;
178 :
179 120 : predPositionPtr = picture_control_set_ptr->pred_struct_ptr->pred_struct_entry_ptr_array[picture_control_set_ptr->pred_struct_index];
180 : // If there was a change in the number of temporal layers, then cleanup the Reference Queue's Dependent Counts
181 120 : if (picture_control_set_ptr->hierarchical_layers_diff != 0) {
182 : // Dynamic GOP
183 : PredictionStructure *next_pred_struct_ptr;
184 : PredictionStructureEntry *next_base_layer_pred_position_ptr;
185 :
186 : uint32_t dependant_list_positive_entries;
187 : uint32_t dependant_list_removed_entries;
188 :
189 2 : referenceQueueIndex = encode_context_ptr->reference_picture_queue_head_index;
190 :
191 84 : while (referenceQueueIndex != encode_context_ptr->reference_picture_queue_tail_index) {
192 82 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
193 :
194 82 : if (referenceEntryPtr->picture_number == (picture_control_set_ptr->picture_number - 1)) { // Picture where the change happened
195 :
196 : // Get the prediction struct entry of the next GOP structure
197 2 : next_pred_struct_ptr = get_prediction_structure(
198 : encode_context_ptr->prediction_structure_group_ptr,
199 2 : picture_control_set_ptr->pred_structure,
200 : sequence_control_set_ptr->reference_count,
201 2 : picture_control_set_ptr->hierarchical_levels);
202 :
203 : // Get the prediction struct of a picture in temporal layer 0 (from the new GOP structure)
204 2 : next_base_layer_pred_position_ptr = next_pred_struct_ptr->pred_struct_entry_ptr_array[next_pred_struct_ptr->pred_struct_entry_count - 1];
205 :
206 : // Remove all positive entries from the dependant lists
207 2 : dependant_list_positive_entries = 0;
208 28 : for (depIdx = 0; depIdx < referenceEntryPtr->list0.list_count; ++depIdx) {
209 26 : if (referenceEntryPtr->list0.list[depIdx] >= 0)
210 26 : dependant_list_positive_entries++;
211 : }
212 2 : referenceEntryPtr->list0.list_count = referenceEntryPtr->list0.list_count - dependant_list_positive_entries;
213 :
214 2 : dependant_list_positive_entries = 0;
215 24 : for (depIdx = 0; depIdx < referenceEntryPtr->list1.list_count; ++depIdx) {
216 22 : if (referenceEntryPtr->list1.list[depIdx] >= 0)
217 4 : dependant_list_positive_entries++;
218 : }
219 2 : referenceEntryPtr->list1.list_count = referenceEntryPtr->list1.list_count - dependant_list_positive_entries;
220 :
221 15 : for (depIdx = 0; depIdx < next_base_layer_pred_position_ptr->dep_list0.list_count; ++depIdx) {
222 13 : if (next_base_layer_pred_position_ptr->dep_list0.list[depIdx] >= 0)
223 13 : referenceEntryPtr->list0.list[referenceEntryPtr->list0.list_count++] = next_base_layer_pred_position_ptr->dep_list0.list[depIdx];
224 : }
225 :
226 14 : for (depIdx = 0; depIdx < next_base_layer_pred_position_ptr->dep_list1.list_count; ++depIdx) {
227 12 : if (next_base_layer_pred_position_ptr->dep_list1.list[depIdx] >= 0)
228 2 : referenceEntryPtr->list1.list[referenceEntryPtr->list1.list_count++] = next_base_layer_pred_position_ptr->dep_list1.list[depIdx];
229 : }
230 :
231 : // Update the dependant count update
232 2 : dependant_list_removed_entries = referenceEntryPtr->dep_list0_count + referenceEntryPtr->dep_list1_count - referenceEntryPtr->dependent_count;
233 2 : referenceEntryPtr->dep_list0_count = (referenceEntryPtr->is_alt_ref) ? referenceEntryPtr->list0.list_count + 1 : referenceEntryPtr->list0.list_count;
234 2 : referenceEntryPtr->dep_list1_count = referenceEntryPtr->list1.list_count;
235 2 : referenceEntryPtr->dependent_count = referenceEntryPtr->dep_list0_count + referenceEntryPtr->dep_list1_count - dependant_list_removed_entries;
236 : }
237 : else {
238 : // Modify Dependent List0
239 80 : depListCount = referenceEntryPtr->list0.list_count;
240 294 : for (depIdx = 0; depIdx < depListCount; ++depIdx) {
241 : // Adjust the latest currentInputPoc in case we're in a POC rollover scenario
242 : // currentInputPoc += (currentInputPoc < referenceEntryPtr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
243 :
244 214 : depPoc = POC_CIRCULAR_ADD(
245 : referenceEntryPtr->picture_number, // can't use a value that gets reset
246 : referenceEntryPtr->list0.list[depIdx]/*,
247 : sequence_control_set_ptr->bitsForPictureOrderCount*/);
248 :
249 : // If Dependent POC is greater or equal to the IDR POC
250 214 : if (depPoc >= picture_control_set_ptr->picture_number && referenceEntryPtr->list0.list[depIdx]) {
251 18 : referenceEntryPtr->list0.list[depIdx] = 0;
252 :
253 : // Decrement the Reference's referenceCount
254 18 : --referenceEntryPtr->dependent_count;
255 :
256 18 : CHECK_REPORT_ERROR(
257 : (referenceEntryPtr->dependent_count != ~0u),
258 : encode_context_ptr->app_callback_ptr,
259 : EB_ENC_PD_ERROR3);
260 : }
261 : }
262 :
263 : // Modify Dependent List1
264 80 : depListCount = referenceEntryPtr->list1.list_count;
265 199 : for (depIdx = 0; depIdx < depListCount; ++depIdx) {
266 : // Adjust the latest currentInputPoc in case we're in a POC rollover scenario
267 : // currentInputPoc += (currentInputPoc < referenceEntryPtr->pocNumber) ? (1 << sequence_control_set_ptr->bitsForPictureOrderCount) : 0;
268 :
269 119 : depPoc = POC_CIRCULAR_ADD(
270 : referenceEntryPtr->picture_number,
271 : referenceEntryPtr->list1.list[depIdx]/*,
272 : sequence_control_set_ptr->bitsForPictureOrderCount*/);
273 :
274 : // If Dependent POC is greater or equal to the IDR POC
275 119 : if ((depPoc >= picture_control_set_ptr->picture_number) && referenceEntryPtr->list1.list[depIdx]) {
276 2 : referenceEntryPtr->list1.list[depIdx] = 0;
277 :
278 : // Decrement the Reference's referenceCount
279 2 : --referenceEntryPtr->dependent_count;
280 :
281 2 : CHECK_REPORT_ERROR(
282 : (referenceEntryPtr->dependent_count != ~0u),
283 : encode_context_ptr->app_callback_ptr,
284 : EB_ENC_PD_ERROR3);
285 : }
286 : }
287 : }
288 :
289 : // Increment the referenceQueueIndex Iterator
290 82 : referenceQueueIndex = (referenceQueueIndex == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : referenceQueueIndex + 1;
291 : }
292 : }
293 : // If there was an I-frame or Scene Change, then cleanup the Reference Queue's Dependent Counts
294 120 : if (picture_control_set_ptr->slice_type == I_SLICE)
295 : {
296 4 : referenceQueueIndex = encode_context_ptr->reference_picture_queue_head_index;
297 68 : while (referenceQueueIndex != encode_context_ptr->reference_picture_queue_tail_index) {
298 64 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
299 :
300 : // Modify Dependent List0
301 64 : depListCount = referenceEntryPtr->list0.list_count;
302 218 : for (depIdx = 0; depIdx < depListCount; ++depIdx) {
303 154 : current_input_poc = picture_control_set_ptr->picture_number;
304 :
305 : // Adjust the latest current_input_poc in case we're in a POC rollover scenario
306 : // current_input_poc += (current_input_poc < referenceEntryPtr->picture_number) ? (1 << sequence_control_set_ptr->bits_for_picture_order_count) : 0;
307 :
308 154 : depPoc = POC_CIRCULAR_ADD(
309 : referenceEntryPtr->picture_number, // can't use a value that gets reset
310 : referenceEntryPtr->list0.list[depIdx]/*,
311 : sequence_control_set_ptr->bits_for_picture_order_count*/);
312 :
313 : // If Dependent POC is greater or equal to the IDR POC
314 154 : if (depPoc >= current_input_poc && referenceEntryPtr->list0.list[depIdx]) {
315 22 : referenceEntryPtr->list0.list[depIdx] = 0;
316 :
317 : // Decrement the Reference's referenceCount
318 22 : --referenceEntryPtr->dependent_count;
319 22 : CHECK_REPORT_ERROR(
320 : (referenceEntryPtr->dependent_count != ~0u),
321 : encode_context_ptr->app_callback_ptr,
322 : EB_ENC_PM_ERROR3);
323 : }
324 : }
325 :
326 : // Modify Dependent List1
327 64 : depListCount = referenceEntryPtr->list1.list_count;
328 146 : for (depIdx = 0; depIdx < depListCount; ++depIdx) {
329 82 : current_input_poc = picture_control_set_ptr->picture_number;
330 :
331 : // Adjust the latest current_input_poc in case we're in a POC rollover scenario
332 : // current_input_poc += (current_input_poc < referenceEntryPtr->picture_number) ? (1 << sequence_control_set_ptr->bits_for_picture_order_count) : 0;
333 :
334 82 : depPoc = POC_CIRCULAR_ADD(
335 : referenceEntryPtr->picture_number,
336 : referenceEntryPtr->list1.list[depIdx]/*,
337 : sequence_control_set_ptr->bits_for_picture_order_count*/);
338 :
339 : // If Dependent POC is greater or equal to the IDR POC or if we inserted trailing Ps
340 82 : if (((depPoc >= current_input_poc) || (((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)) && (depPoc > (current_input_poc - picture_control_set_ptr->pre_assignment_buffer_count)))) && referenceEntryPtr->list1.list[depIdx]) {
341 6 : referenceEntryPtr->list1.list[depIdx] = 0;
342 :
343 : // Decrement the Reference's referenceCount
344 6 : --referenceEntryPtr->dependent_count;
345 6 : CHECK_REPORT_ERROR(
346 : (referenceEntryPtr->dependent_count != ~0u),
347 : encode_context_ptr->app_callback_ptr,
348 : EB_ENC_PM_ERROR3);
349 : }
350 : }
351 :
352 : // Increment the referenceQueueIndex Iterator
353 64 : referenceQueueIndex = (referenceQueueIndex == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : referenceQueueIndex + 1;
354 : }
355 : }
356 116 : else if (picture_control_set_ptr->idr_flag == EB_TRUE) {
357 : // Set Reference Entry pointer
358 0 : referenceEntryPtr = (ReferenceQueueEntry*)EB_NULL;
359 : }
360 :
361 : // Check if the EnhancedPictureQueue is full.
362 : // *Note - Having the number of Enhanced Pictures less than the InputQueueSize should ensure this never gets hit
363 :
364 120 : CHECK_REPORT_ERROR(
365 : (((encode_context_ptr->input_picture_queue_head_index != encode_context_ptr->input_picture_queue_tail_index) || (encode_context_ptr->input_picture_queue[encode_context_ptr->input_picture_queue_head_index]->input_object_ptr == EB_NULL))),
366 : encode_context_ptr->app_callback_ptr,
367 : EB_ENC_PM_ERROR4);
368 :
369 : // Place Picture in input queue
370 120 : inputEntryPtr = encode_context_ptr->input_picture_queue[encode_context_ptr->input_picture_queue_tail_index];
371 120 : inputEntryPtr->input_object_ptr = queueEntryPtr->parent_pcs_wrapper_ptr;
372 : // Since the overlay picture is not added to the reference queue, reference_entry_index points to the previous picture which is the alt ref
373 120 : inputEntryPtr->reference_entry_index = (!picture_control_set_ptr->is_overlay) ? encode_context_ptr->reference_picture_queue_tail_index :
374 0 : (encode_context_ptr->reference_picture_queue_tail_index == 0) ? REFERENCE_QUEUE_MAX_DEPTH - 1 : encode_context_ptr->reference_picture_queue_tail_index - 1;
375 120 : encode_context_ptr->input_picture_queue_tail_index =
376 120 : (encode_context_ptr->input_picture_queue_tail_index == INPUT_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->input_picture_queue_tail_index + 1;
377 :
378 : // Copy the reference lists into the inputEntry and
379 : // set the Reference Counts Based on Temporal Layer and how many frames are active
380 120 : inputEntryPtr->list0_ptr = &predPositionPtr->ref_list0;
381 120 : inputEntryPtr->list1_ptr = &predPositionPtr->ref_list1;
382 120 : if (!picture_control_set_ptr->is_overlay) {
383 : // Check if the ReferencePictureQueue is full.
384 120 : CHECK_REPORT_ERROR(
385 : (((encode_context_ptr->reference_picture_queue_head_index != encode_context_ptr->reference_picture_queue_tail_index) || (encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_head_index]->reference_object_ptr == EB_NULL))),
386 : encode_context_ptr->app_callback_ptr,
387 : EB_ENC_PM_ERROR5);
388 :
389 : // Create Reference Queue Entry even if picture will not be referenced
390 120 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_tail_index];
391 120 : referenceEntryPtr->picture_number = picture_control_set_ptr->picture_number;
392 120 : referenceEntryPtr->reference_object_ptr = (EbObjectWrapper*)EB_NULL;
393 120 : referenceEntryPtr->release_enable = EB_TRUE;
394 120 : referenceEntryPtr->reference_available = EB_FALSE;
395 120 : referenceEntryPtr->slice_type = picture_control_set_ptr->slice_type;
396 120 : referenceEntryPtr->temporal_layer_index = picture_control_set_ptr->temporal_layer_index;
397 120 : referenceEntryPtr->frame_context_updated = EB_FALSE;
398 120 : referenceEntryPtr->is_alt_ref = picture_control_set_ptr->is_alt_ref;
399 120 : referenceEntryPtr->feedback_arrived = EB_FALSE;
400 120 : referenceEntryPtr->is_used_as_reference_flag = picture_control_set_ptr->is_used_as_reference_flag;
401 120 : encode_context_ptr->reference_picture_queue_tail_index =
402 120 : (encode_context_ptr->reference_picture_queue_tail_index == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->reference_picture_queue_tail_index + 1;
403 :
404 : // Copy the Dependent Lists
405 : // *Note - we are removing any leading picture dependencies for now
406 120 : referenceEntryPtr->list0.list_count = 0;
407 440 : for (depIdx = 0; depIdx < predPositionPtr->dep_list0.list_count; ++depIdx) {
408 320 : if (predPositionPtr->dep_list0.list[depIdx] >= 0)
409 302 : referenceEntryPtr->list0.list[referenceEntryPtr->list0.list_count++] = predPositionPtr->dep_list0.list[depIdx];
410 : }
411 :
412 120 : referenceEntryPtr->list1.list_count = predPositionPtr->dep_list1.list_count;
413 295 : for (depIdx = 0; depIdx < predPositionPtr->dep_list1.list_count; ++depIdx)
414 175 : referenceEntryPtr->list1.list[depIdx] = predPositionPtr->dep_list1.list[depIdx];
415 120 : referenceEntryPtr->dep_list0_count = (picture_control_set_ptr->is_alt_ref) ? referenceEntryPtr->list0.list_count + 1 : referenceEntryPtr->list0.list_count;
416 :
417 120 : referenceEntryPtr->dep_list1_count = referenceEntryPtr->list1.list_count;
418 120 : referenceEntryPtr->dependent_count = referenceEntryPtr->dep_list0_count + referenceEntryPtr->dep_list1_count;
419 :
420 120 : CHECK_REPORT_ERROR(
421 : (picture_control_set_ptr->pred_struct_ptr->pred_struct_period * REF_LIST_MAX_DEPTH < MAX_ELAPSED_IDR_COUNT),
422 : encode_context_ptr->app_callback_ptr,
423 : EB_ENC_PM_ERROR6);
424 : }
425 : // Release the Reference Buffer once we know it is not a reference
426 120 : if (picture_control_set_ptr->is_used_as_reference_flag == EB_FALSE) {
427 : // Release the nominal live_count value
428 52 : eb_release_object(picture_control_set_ptr->reference_picture_wrapper_ptr);
429 52 : picture_control_set_ptr->reference_picture_wrapper_ptr = (EbObjectWrapper*)EB_NULL;
430 : }
431 :
432 : // Release the Picture Manager Reorder Queue
433 120 : queueEntryPtr->parent_pcs_wrapper_ptr = (EbObjectWrapper*)EB_NULL;
434 120 : queueEntryPtr->picture_number += PICTURE_MANAGER_REORDER_QUEUE_MAX_DEPTH;
435 :
436 : // Increment the Picture Manager Reorder Queue
437 120 : encode_context_ptr->picture_manager_reorder_queue_head_index = (encode_context_ptr->picture_manager_reorder_queue_head_index == PICTURE_MANAGER_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->picture_manager_reorder_queue_head_index + 1;
438 :
439 : // Get the next entry from the Picture Manager Reorder Queue (Entry N+1)
440 120 : queueEntryPtr = encode_context_ptr->picture_manager_reorder_queue[encode_context_ptr->picture_manager_reorder_queue_head_index];
441 : }
442 :
443 120 : break;
444 :
445 68 : case EB_PIC_REFERENCE:
446 :
447 68 : sequence_control_set_ptr = (SequenceControlSet*)inputPictureDemuxPtr->sequence_control_set_wrapper_ptr->object_ptr;
448 68 : encode_context_ptr = sequence_control_set_ptr->encode_context_ptr;
449 :
450 : // Check if Reference Queue is full
451 68 : CHECK_REPORT_ERROR(
452 : (encode_context_ptr->reference_picture_queue_head_index != encode_context_ptr->reference_picture_queue_tail_index),
453 : encode_context_ptr->app_callback_ptr,
454 : EB_ENC_PM_ERROR7);
455 :
456 68 : referenceQueueIndex = encode_context_ptr->reference_picture_queue_head_index;
457 : // Find the Reference in the Reference Queue
458 : do {
459 1296 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
460 :
461 1296 : if (referenceEntryPtr->picture_number == inputPictureDemuxPtr->picture_number) {
462 : // Assign the reference object if there is a match
463 68 : referenceEntryPtr->reference_object_ptr = inputPictureDemuxPtr->reference_picture_wrapper_ptr;
464 :
465 : // Set the reference availability
466 68 : referenceEntryPtr->reference_available = EB_TRUE;
467 : }
468 :
469 : // Increment the referenceQueueIndex Iterator
470 1296 : referenceQueueIndex = (referenceQueueIndex == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : referenceQueueIndex + 1;
471 1296 : } while ((referenceQueueIndex != encode_context_ptr->reference_picture_queue_tail_index) && (referenceEntryPtr->picture_number != inputPictureDemuxPtr->picture_number));
472 :
473 68 : CHECK_REPORT_ERROR(
474 : (referenceEntryPtr->picture_number == inputPictureDemuxPtr->picture_number),
475 : encode_context_ptr->app_callback_ptr,
476 : EB_ENC_PM_ERROR8);
477 :
478 : //keep the relase of SCS here because we still need the encodeContext strucutre here
479 : // Release the Reference's SequenceControlSet
480 68 : eb_release_object(inputPictureDemuxPtr->sequence_control_set_wrapper_ptr);
481 :
482 68 : break;
483 38 : case EB_PIC_FEEDBACK:
484 38 : sequence_control_set_ptr = (SequenceControlSet*)inputPictureDemuxPtr->sequence_control_set_wrapper_ptr->object_ptr;
485 38 : encode_context_ptr = sequence_control_set_ptr->encode_context_ptr;
486 38 : referenceQueueIndex = encode_context_ptr->reference_picture_queue_head_index;
487 : // Find the Reference in the Reference Queue
488 : do {
489 988 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
490 988 : if (referenceEntryPtr->picture_number == inputPictureDemuxPtr->picture_number)
491 : // Set the feedback arrived
492 38 : referenceEntryPtr->frame_context_updated = EB_TRUE;
493 : // Increment the referenceQueueIndex Iterator
494 988 : referenceQueueIndex = (referenceQueueIndex == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : referenceQueueIndex + 1;
495 :
496 988 : } while ((referenceQueueIndex != encode_context_ptr->reference_picture_queue_tail_index) && (referenceEntryPtr->picture_number != inputPictureDemuxPtr->picture_number));
497 :
498 : //keep the release of SCS here because we still need the encodeContext structure here
499 : // Release the Reference's SequenceControlSet
500 38 : eb_release_object(inputPictureDemuxPtr->sequence_control_set_wrapper_ptr);
501 :
502 38 : break;
503 0 : default:
504 :
505 0 : sequence_control_set_ptr = (SequenceControlSet*)inputPictureDemuxPtr->sequence_control_set_wrapper_ptr->object_ptr;
506 0 : encode_context_ptr = sequence_control_set_ptr->encode_context_ptr;
507 :
508 0 : CHECK_REPORT_ERROR_NC(
509 : encode_context_ptr->app_callback_ptr,
510 : EB_ENC_PM_ERROR9);
511 :
512 : picture_control_set_ptr = (PictureParentControlSet*)EB_NULL;
513 : encode_context_ptr = (EncodeContext*)EB_NULL;
514 :
515 : break;
516 : }
517 :
518 : // ***********************************
519 : // Common Code
520 : // *************************************
521 :
522 : // Walk the input queue and start all ready pictures. Mark entry as null after started. Increment the head as you go.
523 226 : if (encode_context_ptr != (EncodeContext*)EB_NULL) {
524 226 : inputQueueIndex = encode_context_ptr->input_picture_queue_head_index;
525 7349 : while (inputQueueIndex != encode_context_ptr->input_picture_queue_tail_index) {
526 7123 : inputEntryPtr = encode_context_ptr->input_picture_queue[inputQueueIndex];
527 :
528 7123 : if (inputEntryPtr->input_object_ptr != EB_NULL) {
529 5626 : entryPictureControlSetPtr = (PictureParentControlSet*)inputEntryPtr->input_object_ptr->object_ptr;
530 5626 : entrySequenceControlSetPtr = (SequenceControlSet*)entryPictureControlSetPtr->sequence_control_set_wrapper_ptr->object_ptr;
531 :
532 5626 : availabilityFlag = EB_TRUE;
533 :
534 : // Check RefList0 Availability
535 : uint8_t refIdx;
536 20094 : for (refIdx = 0; refIdx < entryPictureControlSetPtr->ref_list0_count; ++refIdx) {
537 : //if (entryPictureControlSetPtr->ref_list0_count) // NM: to double check.
538 : {
539 : // hardcode the reference for the overlay frame
540 14468 : if (entryPictureControlSetPtr->is_overlay) {
541 0 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
542 : ((int32_t)inputEntryPtr->reference_entry_index),
543 : REFERENCE_QUEUE_MAX_DEPTH);
544 :
545 0 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
546 :
547 0 : CHECK_REPORT_ERROR(
548 : (referenceEntryPtr),
549 : encode_context_ptr->app_callback_ptr,
550 : EB_ENC_PM_ERROR10);
551 :
552 0 : ref_poc = POC_CIRCULAR_ADD(
553 : entryPictureControlSetPtr->picture_number,
554 : 0);
555 : }
556 : else {
557 14468 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
558 : ((int32_t)inputEntryPtr->reference_entry_index) - // Base
559 : inputEntryPtr->list0_ptr->reference_list[refIdx], // Offset
560 : REFERENCE_QUEUE_MAX_DEPTH); // Max
561 :
562 14468 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
563 :
564 14468 : CHECK_REPORT_ERROR(
565 : (referenceEntryPtr),
566 : encode_context_ptr->app_callback_ptr,
567 : EB_ENC_PM_ERROR10);
568 :
569 14468 : ref_poc = POC_CIRCULAR_ADD(
570 : entryPictureControlSetPtr->picture_number,
571 : -inputEntryPtr->list0_ptr->reference_list[refIdx]/*,
572 : entrySequenceControlSetPtr->bits_for_picture_order_count*/);
573 : }
574 : // Increment the current_input_poc is the case of POC rollover
575 14468 : current_input_poc = encode_context_ptr->current_input_poc;
576 : //current_input_poc += ((current_input_poc < ref_poc) && (inputEntryPtr->list0_ptr->reference_list[refIdx] > 0)) ?
577 : // (1 << entrySequenceControlSetPtr->bits_for_picture_order_count) :
578 : // 0;
579 :
580 14468 : availabilityFlag =
581 21294 : (availabilityFlag == EB_FALSE) ? EB_FALSE : // Don't update if already False
582 6826 : (ref_poc > current_input_poc) ? EB_FALSE : // The Reference has not been received as an Input Picture yet, then its availability is false
583 6826 : (!encode_context_ptr->terminating_sequence_flag_received &&
584 391 : (sequence_control_set_ptr->static_config.rate_control_mode && entryPictureControlSetPtr->slice_type != I_SLICE
585 0 : && entryPictureControlSetPtr->temporal_layer_index == 0 && !referenceEntryPtr->feedback_arrived)) ? EB_FALSE :
586 6826 : (entryPictureControlSetPtr->frame_end_cdf_update_mode && !referenceEntryPtr->frame_context_updated) ? EB_FALSE :
587 3363 : (referenceEntryPtr->reference_available) ? EB_TRUE : // The Reference has been completed
588 : EB_FALSE; // The Reference has not been completed
589 : }
590 : }
591 : // Check RefList1 Availability
592 5626 : if (entryPictureControlSetPtr->slice_type == B_SLICE) {
593 : uint8_t refIdx;
594 14861 : for (refIdx = 0; refIdx < entryPictureControlSetPtr->ref_list1_count; ++refIdx) {
595 : // if (entryPictureControlSetPtr->ref_list1_count) // NM: To double check
596 : {
597 : // If Reference is valid (non-zero), update the availability
598 9446 : if (inputEntryPtr->list1_ptr->reference_list[refIdx] != (int32_t)INVALID_POC) {
599 9446 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
600 : ((int32_t)inputEntryPtr->reference_entry_index) - // Base
601 : inputEntryPtr->list1_ptr->reference_list[refIdx], // Offset
602 : REFERENCE_QUEUE_MAX_DEPTH); // Max
603 :
604 9446 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
605 :
606 9446 : CHECK_REPORT_ERROR(
607 : (referenceEntryPtr),
608 : encode_context_ptr->app_callback_ptr,
609 : EB_ENC_PM_ERROR10);
610 :
611 9446 : ref_poc = POC_CIRCULAR_ADD(
612 : entryPictureControlSetPtr->picture_number,
613 : -inputEntryPtr->list1_ptr->reference_list[refIdx]/*,
614 : entrySequenceControlSetPtr->bits_for_picture_order_count*/);
615 :
616 : // Increment the current_input_poc is the case of POC rollover
617 9446 : current_input_poc = encode_context_ptr->current_input_poc;
618 : //current_input_poc += ((current_input_poc < ref_poc && inputEntryPtr->list1_ptr->reference_list[refIdx] > 0)) ?
619 : // (1 << entrySequenceControlSetPtr->bits_for_picture_order_count) :
620 : // 0;
621 :
622 9446 : availabilityFlag =
623 10440 : (availabilityFlag == EB_FALSE) ? EB_FALSE : // Don't update if already False
624 994 : (ref_poc > current_input_poc) ? EB_FALSE : // The Reference has not been received as an Input Picture yet, then its availability is false
625 994 : (!encode_context_ptr->terminating_sequence_flag_received &&
626 110 : (sequence_control_set_ptr->static_config.rate_control_mode && entryPictureControlSetPtr->slice_type != I_SLICE
627 0 : && entryPictureControlSetPtr->temporal_layer_index == 0 && !referenceEntryPtr->feedback_arrived)) ? EB_FALSE :
628 994 : (entryPictureControlSetPtr->frame_end_cdf_update_mode && !referenceEntryPtr->frame_context_updated) ? EB_FALSE :
629 562 : (referenceEntryPtr->reference_available) ? EB_TRUE : // The Reference has been completed
630 : EB_FALSE; // The Reference has not been completed
631 : }
632 : }
633 : }
634 : }
635 :
636 5626 : if (availabilityFlag == EB_TRUE) {
637 : // Get New Empty Child PCS from PCS Pool
638 120 : eb_get_empty_object(
639 120 : context_ptr->picture_control_set_fifo_ptr_array[0],
640 : &ChildPictureControlSetWrapperPtr);
641 :
642 : // Child PCS is released by Packetization
643 120 : eb_object_inc_live_count(
644 : ChildPictureControlSetWrapperPtr,
645 : 1);
646 :
647 120 : ChildPictureControlSetPtr = (PictureControlSet*)ChildPictureControlSetWrapperPtr->object_ptr;
648 :
649 : //1.Link The Child PCS to its Parent
650 120 : ChildPictureControlSetPtr->picture_parent_control_set_wrapper_ptr = inputEntryPtr->input_object_ptr;
651 120 : ChildPictureControlSetPtr->parent_pcs_ptr = entryPictureControlSetPtr;
652 :
653 120 : ChildPictureControlSetPtr->parent_pcs_ptr->childPcs = ChildPictureControlSetPtr;
654 :
655 : //2. Have some common information between ChildPCS and ParentPCS.
656 120 : ChildPictureControlSetPtr->sequence_control_set_wrapper_ptr = entryPictureControlSetPtr->sequence_control_set_wrapper_ptr;
657 120 : ChildPictureControlSetPtr->picture_qp = entryPictureControlSetPtr->picture_qp;
658 120 : ChildPictureControlSetPtr->picture_number = entryPictureControlSetPtr->picture_number;
659 120 : ChildPictureControlSetPtr->slice_type = entryPictureControlSetPtr->slice_type;
660 120 : ChildPictureControlSetPtr->temporal_layer_index = entryPictureControlSetPtr->temporal_layer_index;
661 :
662 120 : ChildPictureControlSetPtr->parent_pcs_ptr->total_num_bits = 0;
663 120 : ChildPictureControlSetPtr->parent_pcs_ptr->picture_qp = entryPictureControlSetPtr->picture_qp;
664 120 : ChildPictureControlSetPtr->parent_pcs_ptr->sad_me = 0;
665 120 : ChildPictureControlSetPtr->parent_pcs_ptr->quantized_coeff_num_bits = 0;
666 120 : ChildPictureControlSetPtr->enc_mode = entryPictureControlSetPtr->enc_mode;
667 :
668 : //3.make all init for ChildPCS
669 120 : picture_width_in_sb = (uint8_t)((entrySequenceControlSetPtr->seq_header.max_frame_width + entrySequenceControlSetPtr->sb_size_pix - 1) / entrySequenceControlSetPtr->sb_size_pix);
670 120 : picture_height_in_sb = (uint8_t)((entrySequenceControlSetPtr->seq_header.max_frame_height + entrySequenceControlSetPtr->sb_size_pix - 1) / entrySequenceControlSetPtr->sb_size_pix);
671 :
672 : // EncDec Segments
673 120 : enc_dec_segments_init(
674 : ChildPictureControlSetPtr->enc_dec_segment_ctrl,
675 120 : entrySequenceControlSetPtr->enc_dec_segment_col_count_array[entryPictureControlSetPtr->temporal_layer_index],
676 120 : entrySequenceControlSetPtr->enc_dec_segment_row_count_array[entryPictureControlSetPtr->temporal_layer_index],
677 : picture_width_in_sb,
678 : picture_height_in_sb);
679 :
680 : // Entropy Coding Rows
681 : {
682 : unsigned row_index;
683 :
684 120 : ChildPictureControlSetPtr->entropy_coding_current_row = 0;
685 120 : ChildPictureControlSetPtr->entropy_coding_current_available_row = 0;
686 120 : ChildPictureControlSetPtr->entropy_coding_row_count = picture_height_in_sb;
687 120 : ChildPictureControlSetPtr->entropy_coding_in_progress = EB_FALSE;
688 :
689 4920 : for (row_index = 0; row_index < MAX_LCU_ROWS; ++row_index)
690 4800 : ChildPictureControlSetPtr->entropy_coding_row_array[row_index] = EB_FALSE;
691 : }
692 :
693 120 : ChildPictureControlSetPtr->parent_pcs_ptr->av1_cm->pcs_ptr = ChildPictureControlSetPtr;
694 :
695 120 : struct PictureParentControlSet *ppcs_ptr = ChildPictureControlSetPtr->parent_pcs_ptr;
696 120 : Av1Common *const cm = ppcs_ptr->av1_cm;
697 : int tile_row, tile_col;
698 : uint32_t x_lcu_index, y_lcu_index;
699 120 : const int tile_cols = ppcs_ptr->av1_cm->tiles_info.tile_cols;
700 120 : const int tile_rows = ppcs_ptr->av1_cm->tiles_info.tile_rows;
701 : TileInfo tile_info;
702 120 : int sb_size_log2 = sequence_control_set_ptr->seq_header.sb_size_log2;
703 : //Tile Loop
704 240 : for (tile_row = 0; tile_row < tile_rows; tile_row++)
705 : {
706 120 : eb_av1_tile_set_row(&tile_info, &cm->tiles_info, cm->mi_rows, tile_row);
707 :
708 240 : for (tile_col = 0; tile_col < tile_cols; tile_col++)
709 : {
710 120 : eb_av1_tile_set_col(&tile_info, &cm->tiles_info, cm->mi_cols, tile_col);
711 :
712 120 : for ((y_lcu_index = cm->tiles_info.tile_row_start_mi[tile_row] >> sb_size_log2);
713 840 : (y_lcu_index < (uint32_t)cm->tiles_info.tile_row_start_mi[tile_row + 1] >> sb_size_log2);
714 720 : y_lcu_index++)
715 : {
716 720 : for ((x_lcu_index = cm->tiles_info.tile_col_start_mi[tile_col] >> sb_size_log2);
717 7920 : (x_lcu_index < (uint32_t)cm->tiles_info.tile_col_start_mi[tile_col + 1] >> sb_size_log2);
718 7200 : x_lcu_index++)
719 : {
720 7200 : int sb_index = (uint16_t)(x_lcu_index + y_lcu_index * picture_width_in_sb);
721 7200 : ChildPictureControlSetPtr->sb_ptr_array[sb_index]->tile_info = tile_info;
722 : }
723 : }
724 : }
725 : }
726 120 : cm->mi_stride = ChildPictureControlSetPtr->mi_stride;
727 : // Picture edges
728 120 : ConfigurePictureEdges(entrySequenceControlSetPtr, ChildPictureControlSetPtr);
729 :
730 : // Reset the qp array for DLF
731 120 : EB_MEMSET(ChildPictureControlSetPtr->qp_array, 0, sizeof(uint8_t)*ChildPictureControlSetPtr->qp_array_size);
732 :
733 : // Error resilience related
734 120 : ChildPictureControlSetPtr->colocated_pu_ref_list = REF_LIST_0; // to be modified
735 :
736 120 : ChildPictureControlSetPtr->is_low_delay = (EbBool)(
737 120 : ChildPictureControlSetPtr->parent_pcs_ptr->pred_struct_ptr->pred_struct_entry_ptr_array[ChildPictureControlSetPtr->parent_pcs_ptr->pred_struct_index]->positive_ref_pics_total_count == 0);
738 :
739 : // Rate Control
740 120 : ChildPictureControlSetPtr->dif_cu_delta_qp_depth = (uint8_t)entrySequenceControlSetPtr->input_resolution == INPUT_SIZE_4K_RANGE ? 3 : 2;
741 :
742 : // Reset the Reference Lists
743 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_0], 0, REF_LIST_MAX_DEPTH * sizeof(EbObjectWrapper*));
744 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_1], 0, REF_LIST_MAX_DEPTH * sizeof(EbObjectWrapper*));
745 :
746 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_qp_array[REF_LIST_0], 0, REF_LIST_MAX_DEPTH * sizeof(uint8_t));
747 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_qp_array[REF_LIST_1], 0, REF_LIST_MAX_DEPTH * sizeof(uint8_t));
748 :
749 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_slice_type_array[REF_LIST_0], 0, REF_LIST_MAX_DEPTH * sizeof(EB_SLICE));
750 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_slice_type_array[REF_LIST_1], 0, REF_LIST_MAX_DEPTH * sizeof(EB_SLICE));
751 : #if TWO_PASS
752 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_referenced_area_avg_array[REF_LIST_0], 0, REF_LIST_MAX_DEPTH * sizeof(uint64_t));
753 120 : EB_MEMSET(ChildPictureControlSetPtr->ref_pic_referenced_area_avg_array[REF_LIST_1], 0, REF_LIST_MAX_DEPTH * sizeof(uint64_t));
754 : #endif
755 120 : int8_t max_temporal_index = -1, ref_index = 0;
756 : // Configure List0
757 120 : if ((entryPictureControlSetPtr->slice_type == P_SLICE) || (entryPictureControlSetPtr->slice_type == B_SLICE)) {
758 : uint8_t refIdx;
759 348 : for (refIdx = 0; refIdx < entryPictureControlSetPtr->ref_list0_count; ++refIdx) {
760 232 : if (entryPictureControlSetPtr->ref_list0_count) {
761 : // hardcode the reference for the overlay frame
762 232 : if (entryPictureControlSetPtr->is_overlay)
763 0 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
764 : ((int32_t)inputEntryPtr->reference_entry_index),
765 : REFERENCE_QUEUE_MAX_DEPTH);
766 : else
767 232 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
768 : ((int32_t)inputEntryPtr->reference_entry_index) - inputEntryPtr->list0_ptr->reference_list[refIdx],
769 : REFERENCE_QUEUE_MAX_DEPTH); // Max
770 :
771 232 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
772 232 : if (entryPictureControlSetPtr->frame_end_cdf_update_mode) {
773 174 : ChildPictureControlSetPtr->ref_frame_context[svt_get_ref_frame_type(REF_LIST_0, refIdx) - LAST_FRAME] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->frame_context;
774 174 : if (max_temporal_index < (int8_t)referenceEntryPtr->temporal_layer_index) {
775 105 : max_temporal_index = (int8_t)referenceEntryPtr->temporal_layer_index;
776 105 : ref_index = svt_get_ref_frame_type(REF_LIST_0, refIdx) - LAST_FRAME;
777 840 : for (int frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame)
778 735 : ChildPictureControlSetPtr->ref_global_motion[frame] =
779 735 : ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->global_motion[frame];
780 : }
781 : }
782 : // Set the Reference Object
783 232 : ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_0][refIdx] = referenceEntryPtr->reference_object_ptr;
784 232 : ChildPictureControlSetPtr->ref_pic_qp_array[REF_LIST_0][refIdx] = (uint8_t)((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->qp;
785 232 : ChildPictureControlSetPtr->ref_slice_type_array[REF_LIST_0][refIdx] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->slice_type;
786 : #if TWO_PASS
787 232 : ChildPictureControlSetPtr->ref_pic_referenced_area_avg_array[REF_LIST_0][refIdx] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->referenced_area_avg;
788 : #endif
789 : // Increment the Reference's liveCount by the number of tiles in the input picture
790 232 : eb_object_inc_live_count(
791 : referenceEntryPtr->reference_object_ptr,
792 : 1);
793 :
794 : // Decrement the Reference's dependent_count Count
795 232 : --referenceEntryPtr->dependent_count;
796 :
797 232 : CHECK_REPORT_ERROR(
798 : (referenceEntryPtr->dependent_count != ~0u),
799 : encode_context_ptr->app_callback_ptr,
800 : EB_ENC_PM_ERROR1);
801 : }
802 : }
803 : //fill the non used spots to be used in MFMV.
804 348 : for (refIdx = entryPictureControlSetPtr->ref_list0_count; refIdx < 4; ++refIdx)
805 232 : ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_0][refIdx] = ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_0][0];
806 :
807 116 : if (entryPictureControlSetPtr->ref_list1_count == 0) {
808 24 : for (refIdx = entryPictureControlSetPtr->ref_list1_count; refIdx < 3; ++refIdx)
809 18 : ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_1][refIdx] = ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_0][0];
810 : }
811 : }
812 :
813 : // Configure List1
814 120 : if (entryPictureControlSetPtr->slice_type == B_SLICE) {
815 : uint8_t refIdx;
816 273 : for (refIdx = 0; refIdx < entryPictureControlSetPtr->ref_list1_count; ++refIdx) {
817 163 : if (entryPictureControlSetPtr->ref_list1_count) {
818 163 : referenceQueueIndex = (uint32_t)CIRCULAR_ADD(
819 : ((int32_t)inputEntryPtr->reference_entry_index) - inputEntryPtr->list1_ptr->reference_list[refIdx],
820 : REFERENCE_QUEUE_MAX_DEPTH); // Max
821 :
822 163 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
823 163 : if (entryPictureControlSetPtr->frame_end_cdf_update_mode) {
824 108 : ChildPictureControlSetPtr->ref_frame_context[svt_get_ref_frame_type(REF_LIST_1, refIdx) - LAST_FRAME] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->frame_context;
825 108 : if (max_temporal_index < (int8_t)referenceEntryPtr->temporal_layer_index && referenceEntryPtr->slice_type != I_SLICE/* && ChildPictureControlSetPtr->temporal_layer_index != 0*/) {
826 8 : max_temporal_index = (int8_t)referenceEntryPtr->temporal_layer_index;
827 8 : ref_index = svt_get_ref_frame_type(REF_LIST_1, refIdx) - LAST_FRAME;
828 64 : for (int frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame)
829 56 : ChildPictureControlSetPtr->ref_global_motion[frame] =
830 56 : ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->global_motion[frame];
831 : }
832 : }
833 : // Set the Reference Object
834 163 : ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_1][refIdx] = referenceEntryPtr->reference_object_ptr;
835 :
836 163 : ChildPictureControlSetPtr->ref_pic_qp_array[REF_LIST_1][refIdx] = (uint8_t)((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->qp;
837 163 : ChildPictureControlSetPtr->ref_slice_type_array[REF_LIST_1][refIdx] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->slice_type;
838 : #if TWO_PASS
839 163 : ChildPictureControlSetPtr->ref_pic_referenced_area_avg_array[REF_LIST_1][refIdx] = ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->referenced_area_avg;
840 : #endif
841 : // Increment the Reference's liveCount by the number of tiles in the input picture
842 163 : eb_object_inc_live_count(
843 : referenceEntryPtr->reference_object_ptr,
844 : 1);
845 :
846 : // Decrement the Reference's dependent_count Count
847 163 : --referenceEntryPtr->dependent_count;
848 :
849 163 : CHECK_REPORT_ERROR(
850 : (referenceEntryPtr->dependent_count != ~0u),
851 : encode_context_ptr->app_callback_ptr,
852 : EB_ENC_PM_ERROR1);
853 : }
854 : }
855 : //fill the non used spots to be used in MFMV.
856 110 : if (entryPictureControlSetPtr->ref_list1_count) {
857 277 : for (refIdx = entryPictureControlSetPtr->ref_list1_count; refIdx < 3; ++refIdx)
858 167 : ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_1][refIdx] = ChildPictureControlSetPtr->ref_pic_ptr_array[REF_LIST_1][0];
859 : }
860 : }
861 :
862 : // Adjust the Slice-type if the Lists are Empty, but don't reset the Prediction Structure
863 120 : entryPictureControlSetPtr->slice_type =
864 120 : (entryPictureControlSetPtr->ref_list1_count > 0) ? B_SLICE :
865 10 : (entryPictureControlSetPtr->ref_list0_count > 0) ? P_SLICE :
866 : I_SLICE;
867 120 : if (entryPictureControlSetPtr->frame_end_cdf_update_mode) {
868 60 : if (entryPictureControlSetPtr->slice_type != I_SLICE)
869 58 : ChildPictureControlSetPtr->parent_pcs_ptr->frm_hdr.primary_ref_frame = ref_index;
870 : else
871 2 : ChildPictureControlSetPtr->parent_pcs_ptr->frm_hdr.primary_ref_frame = PRIMARY_REF_NONE;
872 60 : ChildPictureControlSetPtr->parent_pcs_ptr->refresh_frame_context = REFRESH_FRAME_CONTEXT_BACKWARD;
873 :
874 : }
875 : else {
876 60 : ChildPictureControlSetPtr->parent_pcs_ptr->frm_hdr.primary_ref_frame = PRIMARY_REF_NONE;
877 60 : ChildPictureControlSetPtr->parent_pcs_ptr->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
878 : }
879 : // Increment the sequenceControlSet Wrapper's live count by 1 for only the pictures which are used as reference
880 120 : if (ChildPictureControlSetPtr->parent_pcs_ptr->is_used_as_reference_flag) {
881 68 : eb_object_inc_live_count(
882 68 : ChildPictureControlSetPtr->parent_pcs_ptr->sequence_control_set_wrapper_ptr,
883 : 1);
884 : }
885 :
886 : // Get Empty Results Object
887 120 : eb_get_empty_object(
888 : context_ptr->picture_manager_output_fifo_ptr,
889 : &outputWrapperPtr);
890 :
891 120 : rateControlTasksPtr = (RateControlTasks*)outputWrapperPtr->object_ptr;
892 120 : rateControlTasksPtr->picture_control_set_wrapper_ptr = ChildPictureControlSetWrapperPtr;
893 120 : rateControlTasksPtr->task_type = RC_PICTURE_MANAGER_RESULT;
894 :
895 : // Post the Full Results Object
896 120 : eb_post_full_object(outputWrapperPtr);
897 :
898 : // Remove the Input Entry from the Input Queue
899 120 : inputEntryPtr->input_object_ptr = (EbObjectWrapper*)EB_NULL;
900 : }
901 : }
902 :
903 : // Increment the head_index if the head is null
904 7123 : encode_context_ptr->input_picture_queue_head_index =
905 7243 : (encode_context_ptr->input_picture_queue[encode_context_ptr->input_picture_queue_head_index]->input_object_ptr) ? encode_context_ptr->input_picture_queue_head_index :
906 120 : (encode_context_ptr->input_picture_queue_head_index == INPUT_QUEUE_MAX_DEPTH - 1) ? 0
907 120 : : encode_context_ptr->input_picture_queue_head_index + 1;
908 :
909 : // Increment the inputQueueIndex Iterator
910 7123 : inputQueueIndex = (inputQueueIndex == INPUT_QUEUE_MAX_DEPTH - 1) ? 0 : inputQueueIndex + 1;
911 : }
912 :
913 : // Walk the reference queue and remove entries that have been completely referenced.
914 226 : referenceQueueIndex = encode_context_ptr->reference_picture_queue_head_index;
915 8409 : while (referenceQueueIndex != encode_context_ptr->reference_picture_queue_tail_index) {
916 8183 : referenceEntryPtr = encode_context_ptr->reference_picture_queue[referenceQueueIndex];
917 :
918 : // Remove the entry & release the reference if there are no remaining references
919 8183 : if ((referenceEntryPtr->dependent_count == 0) &&
920 3826 : (referenceEntryPtr->reference_available) &&
921 62 : (referenceEntryPtr->release_enable) &&
922 62 : (referenceEntryPtr->reference_object_ptr))
923 : {
924 : // Release the nominal live_count value
925 : #if TWO_PASS
926 62 : if (sequence_control_set_ptr->use_output_stat_file &&
927 0 : referenceEntryPtr->reference_object_ptr->live_count == 1)
928 0 : write_stat_to_file(
929 : sequence_control_set_ptr,
930 0 : ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->stat_struct,
931 0 : ((EbReferenceObject*)referenceEntryPtr->reference_object_ptr->object_ptr)->ref_poc);
932 : #endif
933 62 : eb_release_object(referenceEntryPtr->reference_object_ptr);
934 62 : referenceEntryPtr->reference_object_ptr = (EbObjectWrapper*)EB_NULL;
935 62 : referenceEntryPtr->reference_available = EB_FALSE;
936 62 : referenceEntryPtr->is_used_as_reference_flag = EB_FALSE;
937 : }
938 :
939 : // Increment the head_index if the head is empty
940 8183 : encode_context_ptr->reference_picture_queue_head_index =
941 16366 : (encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_head_index]->release_enable == EB_FALSE) ? encode_context_ptr->reference_picture_queue_head_index :
942 8351 : (encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_head_index]->reference_available == EB_FALSE &&
943 16302 : encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_head_index]->is_used_as_reference_flag == EB_TRUE) ? encode_context_ptr->reference_picture_queue_head_index :
944 8223 : (encode_context_ptr->reference_picture_queue[encode_context_ptr->reference_picture_queue_head_index]->dependent_count > 0) ? encode_context_ptr->reference_picture_queue_head_index :
945 104 : (encode_context_ptr->reference_picture_queue_head_index == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0
946 104 : : encode_context_ptr->reference_picture_queue_head_index + 1;
947 : // Increment the referenceQueueIndex Iterator
948 8183 : referenceQueueIndex = (referenceQueueIndex == REFERENCE_QUEUE_MAX_DEPTH - 1) ? 0 : referenceQueueIndex + 1;
949 : }
950 : }
951 :
952 : // Release the Input Picture Demux Results
953 226 : eb_release_object(inputPictureDemuxWrapperPtr);
954 : }
955 : return EB_NULL;
956 : }
|