blob: ce977d738ef8ab15dbf66eb6fb0d2c9ce57c600b [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
Harish Mahendrakarc59cd5d2016-04-15 10:26:38 +053020#ifdef __ANDROID__
Sasha Smundak51f1a222019-02-01 09:42:34 -080021#include <log/log.h>
Harish Mahendrakarc59cd5d2016-04-15 10:26:38 +053022#endif
Hamsalekha S8d3d3032015-03-13 21:24:58 +053023#include "ih264_typedefs.h"
24#include "ih264_macros.h"
25#include "ih264_platform_macros.h"
26#include "iv.h"
27#include "ih264d_dpb_manager.h"
28#include "ih264d_bitstrm.h"
29#include "ih264d_parse_cavlc.h"
30#include "ih264d_defs.h"
31#include "ih264d_structs.h"
32#include "ih264d_process_bslice.h"
33#include "ih264d_debug.h"
34#include "ih264d_tables.h"
35#include "ih264d_error_handler.h"
36#include "string.h"
37#include "ih264d_defs.h"
38#include "ih264_error.h"
39#include "ih264_buf_mgr.h"
40#include "assert.h"
41
42/*!
43 ***************************************************************************
44 * \file ih264d_dpb_mgr.c
45 *
46 * \brief
47 * Functions for managing the decoded picture buffer
48 *
49 * Detailed_description
50 *
51 * \date
52 * 19-12-2002
53 *
54 * \author Sriram Sethuraman
55 ***************************************************************************
56 */
57
58/*!
59 **************************************************************************
60 * \if Function name : ih264d_init_ref_bufs \endif
61 *
62 * \brief
63 * Called at the start for initialization.
64 *
65 * \return
66 * none
67 **************************************************************************
68 */
69void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr)
70{
71 UWORD32 i;
72 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
73 for(i = 0; i < MAX_REF_BUFS; i++)
74 {
75 ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
76 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
77 ps_dpb_info[i].ps_prev_short = NULL;
78 ps_dpb_info[i].ps_prev_long = NULL;
79 ps_dpb_info[i].ps_pic_buf = NULL;
80 ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
81 ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
82 ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
83 ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
84
85 }
86 ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
87 ps_dpb_mgr->ps_dpb_st_head = NULL;
88 ps_dpb_mgr->ps_dpb_ht_head = NULL;
89 ps_dpb_mgr->i1_gaps_deleted = 0;
90 ps_dpb_mgr->i1_poc_buf_id_entries = 0;
Shivaansh Agrawal2a28c972020-08-27 19:17:35 +053091 ps_dpb_mgr->u1_mmco_error_in_seq = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +053092
93 ps_dpb_mgr->u1_num_gaps = 0;
94 for(i = 0; i < MAX_FRAMES; i++)
95 {
96 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
97 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
98 ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
99 ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1;
100 ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff;
101 ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0;
102 }
103
104}
105
106void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id)
107{
108 dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
109
110 if((pic_buf_id == ps_dec->u1_pic_buf_id) &&
111 ps_dec->ps_cur_slice->u1_field_pic_flag &&
112 (ps_dec->u1_top_bottom_decoded == 0))
113 {
114 return;
115 }
116
117 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
118 pic_buf_id,
119 BUF_MGR_REF);
120 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
121 ps_dec->au1_pic_buf_id_mv_buf_id_map[pic_buf_id],
122 BUF_MGR_REF);
123}
124/*!
125 **************************************************************************
126 * \if Function name : ih264d_delete_lt_node \endif
127 *
128 * \brief
129 * Delete a buffer with a long term index from the LT linked list
130 *
131 * \return
132 * none
133 **************************************************************************
134 */
135WORD32 ih264d_delete_lt_node(dpb_manager_t *ps_dpb_mgr,
136 UWORD32 u4_lt_idx,
137 UWORD8 u1_fld_pic_flag,
138 struct dpb_info_t *ps_lt_node_to_insert,
139 WORD32 *pi4_status)
140{
141 *pi4_status = 0;
142 if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
143 {
144 WORD32 i;
145 struct dpb_info_t *ps_next_dpb;
146 /* ps_unmark_node points to the node to be removed */
147 /* from long term list. */
148 struct dpb_info_t *ps_unmark_node;
149 //Find the node with matching LTIndex
150 ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
151 if(ps_next_dpb->u1_lt_idx == u4_lt_idx)
152 {
153 ps_unmark_node = ps_next_dpb;
154 }
155 else
156 {
157 for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
158 {
159 if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx)
160 break;
161 ps_next_dpb = ps_next_dpb->ps_prev_long;
162 }
163 if(i == ps_dpb_mgr->u1_num_lt_ref_bufs)
164 *pi4_status = 1;
165 else
166 ps_unmark_node = ps_next_dpb->ps_prev_long;
167 }
168
169 if(*pi4_status == 0)
170 {
171 if(u1_fld_pic_flag)
172 {
173 if(ps_lt_node_to_insert != ps_unmark_node)
174 {
175 UWORD8 u1_deleted = 0;
176 /* for the ps_unmark_node mark the corresponding field */
177 /* field as unused for reference */
178
179 if(ps_unmark_node->s_top_field.u1_long_term_frame_idx
180 == u4_lt_idx)
181 {
182 ps_unmark_node->s_top_field.u1_reference_info =
183 UNUSED_FOR_REF;
184 ps_unmark_node->s_top_field.u1_long_term_frame_idx =
185 MAX_REF_BUFS + 1;
186 u1_deleted = 1;
187 }
188 if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx
189 == u4_lt_idx)
190 {
191 ps_unmark_node->s_bot_field.u1_reference_info =
192 UNUSED_FOR_REF;
193 ps_unmark_node->s_bot_field.u1_long_term_frame_idx =
194 MAX_REF_BUFS + 1;
195 u1_deleted = 1;
196 }
197
198 if(!u1_deleted)
199 {
200
201 UWORD32 i4_error_code;
202 i4_error_code = ERROR_DBP_MANAGER_T;
203
204 return i4_error_code;
205 }
206 }
207
208 ps_unmark_node->u1_used_as_ref =
209 ps_unmark_node->s_top_field.u1_reference_info
210 | ps_unmark_node->s_bot_field.u1_reference_info;
211 }
212 else
213 ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
214
215 if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref)
216 {
217 if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head)
218 ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long;
219
220 ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1;
221 ps_unmark_node->s_top_field.u1_reference_info =
222 UNUSED_FOR_REF;
223 ps_unmark_node->s_bot_field.u1_reference_info =
224 UNUSED_FOR_REF;
225 // Release the physical buffer
226 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
227 ps_unmark_node->u1_buf_id);
228 ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link
229 ps_unmark_node->ps_prev_long = NULL;
230 ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count
231 }
232 }
233 }
234 return OK;
235}
236
237/*!
238 **************************************************************************
239 * \if Function name : ih264d_insert_lt_node \endif
240 *
241 * \brief
242 * Insert a buffer into the LT linked list at a given LT index
243 *
244 * \return
245 * none
246 **************************************************************************
247 */
248WORD32 ih264d_insert_lt_node(dpb_manager_t *ps_dpb_mgr,
249 struct dpb_info_t *ps_mov_node,
250 UWORD32 u4_lt_idx,
251 UWORD8 u1_fld_pic_flag)
252{
253 UWORD8 u1_mark_top_field_long_term = 0;
254 UWORD8 u1_mark_bot_field_long_term = 0;
255
256 {
257 if(u1_fld_pic_flag)
258 {
259 /* Assign corresponding field (top or bottom) long_term_frame_idx */
260
261 if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
262 && (ps_mov_node->s_bot_field.u1_reference_info
263 == IS_LONG_TERM))
264 {
265 if(ps_mov_node->u1_lt_idx == u4_lt_idx)
266 u1_mark_bot_field_long_term = 1;
267 else
268 {
269
270 UWORD32 i4_error_code;
271 i4_error_code = ERROR_DBP_MANAGER_T;
272
273 return i4_error_code;
274
275 }
276 }
277 else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
278 {
279 u1_mark_top_field_long_term = 1;
280 }
281
282 if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term))
283 {
284 UWORD32 i4_error_code;
285 i4_error_code = ERROR_DBP_MANAGER_T;
286 return i4_error_code;
287 }
288 }
289 else
290 {
291 ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM;
292 ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
293 ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
294 ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
Hamsalekha S6fa5df82017-02-21 15:47:02 +0530295 u1_mark_bot_field_long_term = 1;
296 u1_mark_top_field_long_term = 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530297 }
298
299 ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node
300 ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx;
301 ps_mov_node->u1_used_as_ref = IS_LONG_TERM;
302
303 /* Insert the new long term in the LT list with u4_lt_idx */
304 /* in ascending order. */
305 if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
306 {
307 struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
308 if(u4_lt_idx < ps_next_dpb->u1_lt_idx)
309 {
310 //LTIndex to be inserted is the smallest LT index
311 //Update head and point prev to the next higher index
312 ps_mov_node->ps_prev_long = ps_next_dpb;
313 ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
314 }
315 else
316 {
317 WORD32 i;
318 struct dpb_info_t *ps_nxtDPB = ps_next_dpb;
319 ps_next_dpb = ps_next_dpb->ps_prev_long;
320 for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
321 {
322 if(ps_next_dpb->u1_lt_idx > u4_lt_idx)
323 break;
324 ps_nxtDPB = ps_next_dpb;
325 ps_next_dpb = ps_next_dpb->ps_prev_long;
326 }
327
328 ps_nxtDPB->ps_prev_long = ps_mov_node;
329 ps_mov_node->ps_prev_long = ps_next_dpb;
330 }
331 }
332 else
333 {
334 ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
335 ps_mov_node->ps_prev_long = NULL;
336 }
337 /* Identify the picture buffer as a long term picture buffer */
338 ps_mov_node->ps_pic_buf->u1_is_short = 0;
339
340 /* Increment LT buf count only if new LT node inserted */
341 /* If Increment during top_field is done, don't increment */
342 /* for bottom field, as both them are part of same pic. */
Hamsalekha S6fa5df82017-02-21 15:47:02 +0530343 if(u1_mark_bot_field_long_term)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530344 ps_dpb_mgr->u1_num_lt_ref_bufs++;
345
346 }
347 return OK;
348}
349
350/*!
351 **************************************************************************
352 * \if Function name : ih264d_insert_st_node \endif
353 *
354 * \brief
355 * Adds a short term reference picture into the ST linked list
356 *
357 * \return
358 * None
359 *
360 * \note
361 * Called only for a new coded picture with nal_ref_idc!=0
362 **************************************************************************
363 */
364WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr,
365 struct pic_buffer_t *ps_pic_buf,
366 UWORD8 u1_buf_id,
367 UWORD32 u4_cur_pic_num)
368{
369 WORD32 i;
370 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
371 UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype;
372 /* Find an unused dpb location */
373 for(i = 0; i < MAX_REF_BUFS; i++)
374 {
375 if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
376 && ps_dpb_info[i].u1_used_as_ref)
377 {
Harish Mahendrakar27b7a142016-04-26 17:23:03 +0530378 /*signal an error in the case of frame pic*/
379 if(ps_dpb_info[i].ps_pic_buf->u1_pic_type == FRM_PIC)
380 {
381 return ERROR_DBP_MANAGER_T;
382 }
383 else
384 {
Ritu Baldwa47cc04b2018-03-09 16:39:07 +0530385 /* Can occur only for field bottom pictures */
386 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
Harish Mahendrakar27b7a142016-04-26 17:23:03 +0530387 return OK;
388 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530389 }
390
391 if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF)
392 && (ps_dpb_info[i].s_top_field.u1_reference_info
393 == UNUSED_FOR_REF)
394 && (ps_dpb_info[i].s_bot_field.u1_reference_info
395 == UNUSED_FOR_REF))
396 break;
397 }
398 if(i == MAX_REF_BUFS)
399 {
400 UWORD32 i4_error_code;
401 i4_error_code = ERROR_DBP_MANAGER_T;
402 return i4_error_code;
403 }
404
405 /* Create dpb info */
406 ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
407 ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
408 ps_dpb_info[i].u1_buf_id = u1_buf_id;
409 ps_dpb_info[i].u1_used_as_ref = TRUE;
410 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
411 ps_dpb_info[i].i4_frame_num = u4_cur_pic_num;
412 ps_dpb_info[i].ps_pic_buf->i4_frame_num = u4_cur_pic_num;
413
414 /* update the head node of linked list to point to the cur Pic */
415 ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
416
417 // Increment Short term bufCount
418 ps_dpb_mgr->u1_num_st_ref_bufs++;
419 /* Identify the picture as a short term picture buffer */
420 ps_pic_buf->u1_is_short = IS_SHORT_TERM;
421
422 if((u1_picture_type & 0x03) == FRM_PIC)
423 {
424 ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM;
425 ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
426 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
427 }
428
429 if((u1_picture_type & 0x03) == TOP_FLD)
430 ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
431
432 if((u1_picture_type & 0x03) == BOT_FLD)
433 ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
434
435 return OK;
436}
437
438/*!
439 **************************************************************************
440 * \if Function name : ih264d_delete_st_node_or_make_lt \endif
441 *
442 * \brief
443 * Delete short term ref with a given picNum from the ST linked list or
444 * make it an LT node
445 *
446 * \return
447 * 0 - if successful; -1 - otherwise
448 *
449 * \note
450 * Common parts to MMCO==1 and MMCO==3 have been combined here
451 **************************************************************************
452 */
453WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr,
454 WORD32 i4_pic_num,
455 UWORD32 u4_lt_idx,
456 UWORD8 u1_fld_pic_flag)
457{
458 WORD32 i;
459 struct dpb_info_t *ps_next_dpb;
460 WORD32 i4_frame_num = i4_pic_num;
461 struct dpb_info_t *ps_unmark_node = NULL;
462 UWORD8 u1_del_node = 0, u1_del_st = 0;
463 UWORD8 u1_reference_type = UNUSED_FOR_REF;
464 WORD32 ret;
465
466 if(u1_fld_pic_flag)
467 {
468 i4_frame_num = i4_frame_num >> 1;
469
470 if(u4_lt_idx == (MAX_REF_BUFS + 1))
471 u1_reference_type = UNUSED_FOR_REF;
472 else
473 u1_reference_type = IS_LONG_TERM;
474 }
475
476 //Find the node with matching picNum
477 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
478 if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num)
479 {
480 ps_unmark_node = ps_next_dpb;
481 }
482 else
483 {
484 for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
485 {
486 if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num)
487 break;
488 ps_next_dpb = ps_next_dpb->ps_prev_short;
489 }
490
491 if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
492 {
493 if(ps_dpb_mgr->u1_num_gaps)
494 {
495 ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st);
496 if(ret != OK)
497 return ret;
498 }
499 else
500 {
501 UWORD32 i4_error_code;
502 i4_error_code = ERROR_DBP_MANAGER_T;
503
504 return i4_error_code;
505 }
506
507 if(u1_del_st)
508 {
509 UWORD32 i4_error_code;
510 i4_error_code = ERROR_DBP_MANAGER_T;
511 return i4_error_code;
512 }
513 else
514 {
515 return 0;
516 }
517 }
518 else
519 ps_unmark_node = ps_next_dpb->ps_prev_short;
520 }
521
522 if(u1_fld_pic_flag)
523 {
524 /* Mark the corresponding field ( top or bot) as */
525 /* UNUSED_FOR_REF or IS_LONG_TERM depending on */
526 /* u1_reference_type. */
527 if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num)
528 {
529 ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type;
530 ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
531 {
532 UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
533 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
534 * ps_dpb_mgr->u2_pic_ht) >> 5);
535 /* memset the colocated zero u4_flag buffer */
536 memset(pu1_src, 0, i4_size);
537 }
538 }
539
540 else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num)
541 {
542
543 ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type;
544 ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
545 {
546 UWORD8 *pu1_src =
547 ps_unmark_node->ps_pic_buf->pu1_col_zero_flag
548 + ((ps_dpb_mgr->u2_pic_wd
549 * ps_dpb_mgr->u2_pic_ht)
550 >> 5);
551 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
552 * ps_dpb_mgr->u2_pic_ht) >> 5);
553 /* memset the colocated zero u4_flag buffer */
554 memset(pu1_src, 0, i4_size);
555 }
556 }
557 ps_unmark_node->u1_used_as_ref =
558 ps_unmark_node->s_top_field.u1_reference_info
559 | ps_unmark_node->s_bot_field.u1_reference_info;
560 }
561 else
562 {
563 ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
564 ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
565 ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
566
567 {
568 UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
569
570 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
571 * ps_dpb_mgr->u2_pic_ht) >> 4);
572 /* memset the colocated zero u4_flag buffer */
573 memset(pu1_src, 0, i4_size);
574 }
575 }
576
577 if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM))
578 {
579 if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
580 ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
581 else
582 ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link
583 ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count
584 u1_del_node = 1;
585 }
586
587 if(u4_lt_idx == MAX_REF_BUFS + 1)
588 {
589 if(u1_del_node)
590 {
591 // Release the physical buffer
592 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
593 ps_unmark_node->u1_buf_id);
594 ps_unmark_node->ps_prev_short = NULL;
595 }
596 }
597 else
598 {
599 WORD32 i4_status;
600 //If another node has the same LT index, delete that node
601 ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx,
602 u1_fld_pic_flag, ps_unmark_node, &i4_status);
603 if(ret != OK)
604 return ret;
605 // Now insert the short term node as a long term node
606 ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx,
607 u1_fld_pic_flag);
608 if(ret != OK)
609 return ret;
610 }
611 return OK;
612}
613/*!
614 **************************************************************************
615 * \if Function name : ih264d_reset_ref_bufs \endif
616 *
617 * \brief
618 * Called if MMCO==5/7 or on the first slice of an IDR picture
619 *
620 * \return
621 * none
622 **************************************************************************
623 */
624void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr)
625{
626 WORD32 i;
627 struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
628
629 for(i = 0; i < MAX_REF_BUFS; i++)
630 {
631 if(ps_dpb_info[i].u1_used_as_ref)
632 {
633 ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
634 ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
635 ps_dpb_info[i].ps_prev_short = NULL;
636 ps_dpb_info[i].ps_prev_long = NULL;
637 ps_dpb_info[i].ps_pic_buf = NULL;
638 ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
639 ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
640 ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
641 ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
642
643 //Release physical buffer
644 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
645 ps_dpb_info[i].u1_buf_id);
646 }
647 }
648 ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
649 ps_dpb_mgr->ps_dpb_st_head = NULL;
650 ps_dpb_mgr->ps_dpb_ht_head = NULL;
Shivaansh Agrawal2a28c972020-08-27 19:17:35 +0530651 ps_dpb_mgr->u1_mmco_error_in_seq = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530652
653 /* release all gaps */
654 ps_dpb_mgr->u1_num_gaps = 0;
655 for(i = 0; i < MAX_FRAMES; i++)
656 {
657 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
658 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
659 ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
660 }
661}
662
663/*!
664 **************************************************************************
665 * \if Function name : Name \endif
666 *
667 * \brief
668 * create the default index list after an MMCO
669 *
670 * \return
671 * 0 - if no_error; -1 - error
672 *
673 **************************************************************************
674 */
675WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr)
676{
677 WORD32 i;
678 struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
679
680 for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
681 {
682 ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
683 ps_next_dpb = ps_next_dpb->ps_prev_short;
684 }
685
686 ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
687 for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
688 {
689 ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
690 ps_next_dpb = ps_next_dpb->ps_prev_long;
691 }
692 return 0;
693}
694
695/*!
696 **************************************************************************
697 * \if Function name : ref_idx_reordering \endif
698 *
699 * \brief
700 * Parse the bitstream and reorder indices for the current slice
701 *
702 * \return
703 * 0 - if no_error; -1 - error
704 *
705 * \note
706 * Called only if ref_idx_reordering_flag_l0 is decoded as 1
707 * Remove error checking for unmatching picNum or LTIndex later (if not needed)
708 * \para
709 * This section implements 7.3.3.1 and 8.2.6.4
710 * Uses the default index list as the starting point and
711 * remaps the picNums sent to the next higher index in the
712 * modified list. The unmodified ones are copied from the
713 * default to modified list retaining their order in the default list.
714 *
715 **************************************************************************
716 */
717WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx)
718{
719 dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr;
720 UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num;
721 /*< Maximum Picture Number Minus 1 */
722 UWORD16 ui_max_frame_num =
723 ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
724
Ritu Baldwa7ea47d52017-11-28 18:38:18 +0530725 WORD32 i, count = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530726 UWORD32 ui_remapIdc, ui_nextUev;
727 WORD16 u2_pred_frame_num = u4_cur_pic_num;
728 WORD32 i_temp;
729 UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */
730 UWORD8 modCount = 0;
731 UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
732 UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
733 dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
734 UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
735
736 if(u1_field_pic_flag)
737 {
738 u4_cur_pic_num = u4_cur_pic_num * 2 + 1;
739 ui_max_frame_num = ui_max_frame_num * 2;
740 }
741
742 u2_pred_frame_num = u4_cur_pic_num;
743
744 ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
745
Ritu Baldwa7ea47d52017-11-28 18:38:18 +0530746 while((ui_remapIdc != 3)
747 && (count < ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]))
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530748 {
749 ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
750 if(ui_remapIdc != 2)
751 {
Isha Kulkarni34769a52019-01-28 17:43:35 +0530752 if(ui_nextUev > ui_max_frame_num)
753 return ERROR_DBP_MANAGER_T;
754
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530755 ui_nextUev = ui_nextUev + 1;
Isha Kulkarni34769a52019-01-28 17:43:35 +0530756
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530757 if(ui_remapIdc == 0)
758 {
759 // diffPicNum is -ve
Isha Kulkarni34769a52019-01-28 17:43:35 +0530760 i_temp = (WORD32)u2_pred_frame_num - (WORD32)ui_nextUev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530761 if(i_temp < 0)
762 i_temp += ui_max_frame_num;
763 }
764 else
765 {
766 // diffPicNum is +ve
Isha Kulkarni34769a52019-01-28 17:43:35 +0530767 i_temp = (WORD32)u2_pred_frame_num + (WORD32)ui_nextUev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530768 if(i_temp >= ui_max_frame_num)
769 i_temp -= ui_max_frame_num;
770 }
771 /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */
772
773 if(i_temp > u4_cur_pic_num)
774 i_temp = i_temp - ui_max_frame_num;
775
776 for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
777 {
778 if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp)
779 break;
780 }
781 if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
782 {
783 UWORD32 i4_error_code;
784 i4_error_code = ERROR_DBP_MANAGER_T;
785 return i4_error_code;
786 }
787
788 u2_def_mod_flag |= (1 << i);
789 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
790 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
791 u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained
792 }
793 else //2
794 {
Isha Kulkarni34769a52019-01-28 17:43:35 +0530795 UWORD8 u1_lt_idx;
796
797 if(ui_nextUev > (MAX_REF_BUFS + 1))
798 return ERROR_DBP_MANAGER_T;
799
800 u1_lt_idx = (UWORD8)ui_nextUev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530801
802 for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
803 {
804 if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short)
805 {
806 if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num
807 == u1_lt_idx)
808 break;
809 }
810 }
811 if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
812 {
813 UWORD32 i4_error_code;
814 i4_error_code = ERROR_DBP_MANAGER_T;
815 return i4_error_code;
816 }
817
818 u2_def_mod_flag |= (1 << i);
819 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
820 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
821 }
822
823 ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
824 /* Get the remapping_idc - 0/1/2/3 */
Ritu Baldwa7ea47d52017-11-28 18:38:18 +0530825 count++;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530826 }
827
828 //Handle the ref indices that were not remapped
829 for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++)
830 {
831 if(!(u2_def_mod_flag & (1 << i)))
832 ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
833 ps_dpb_mgr->ps_init_dpb[uc_lx][i];
834 }
835 return OK;
836}
837/*!
838 **************************************************************************
839 * \if Function name : ih264d_read_mmco_commands \endif
840 *
841 * \brief
842 * Parses MMCO commands and stores them in a structure for later use.
843 *
844 * \return
845 * 0 - No error; -1 - Error
846 *
847 * \note
848 * This function stores MMCO commands in structure only for the first time.
849 * In case of MMCO commands being issued for same Picture Number, they are
850 * just parsed and not stored them in the structure.
851 *
852 **************************************************************************
853 */
854WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
855{
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +0530856 dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
857 dec_seq_params_t *ps_sps = ps_pps->ps_sps;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530858 dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
Ritu Baldwa3c70b9a2017-10-09 13:52:45 +0530859 dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530860 dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
861 WORD32 j;
862 UWORD8 u1_buf_mode;
863 struct MMCParams *ps_mmc_params;
864 UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
865 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
866 UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst;
867
868 ps_slice->u1_mmco_equalto5 = 0;
869 {
870 if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL)
871 {
872 ps_slice->u1_no_output_of_prior_pics_flag =
873 ih264d_get_bit_h264(ps_bitstrm);
874 COPYTHECONTEXT("SH: no_output_of_prior_pics_flag",
875 ps_slice->u1_no_output_of_prior_pics_flag);
876 ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264(
877 ps_bitstrm);
878 COPYTHECONTEXT("SH: long_term_reference_flag",
879 ps_slice->u1_long_term_reference_flag);
880 ps_dpb_cmds->u1_idr_pic = 1;
881 ps_dpb_cmds->u1_no_output_of_prior_pics_flag =
882 ps_slice->u1_no_output_of_prior_pics_flag;
883 ps_dpb_cmds->u1_long_term_reference_flag =
884 ps_slice->u1_long_term_reference_flag;
885 }
886 else
887 {
888 u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary
889 COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode);
890 ps_dpb_cmds->u1_buf_mode = u1_buf_mode;
891 j = 0;
892
893 if(u1_buf_mode == 1)
894 {
895 UWORD32 u4_mmco;
896 UWORD32 u4_diff_pic_num;
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +0530897 UWORD32 u4_lt_idx, u4_max_lt_idx_plus1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530898
899 u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
900 pu4_bitstrm_buf);
901 while(u4_mmco != END_OF_MMCO)
902 {
Naveen Kumar Ponnusamy943323f2015-12-04 16:51:43 +0530903 if (j >= MAX_REF_BUFS)
904 {
Harish Mahendrakarc59cd5d2016-04-15 10:26:38 +0530905#ifdef __ANDROID__
Naveen Kumar Ponnusamy943323f2015-12-04 16:51:43 +0530906 ALOGE("b/25818142");
907 android_errorWriteLog(0x534e4554, "25818142");
Harish Mahendrakarc59cd5d2016-04-15 10:26:38 +0530908#endif
Naveen Kumar Ponnusamy943323f2015-12-04 16:51:43 +0530909 ps_dpb_cmds->u1_num_of_commands = 0;
910 return -1;
911 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530912 ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
913 ps_mmc_params->u4_mmco = u4_mmco;
914 switch(u4_mmco)
915 {
916 case MARK_ST_PICNUM_AS_NONREF:
917 u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
918 pu4_bitstrm_buf);
919 //Get absDiffPicnumMinus1
920 ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
921 break;
922
923 case MARK_LT_INDEX_AS_NONREF:
924 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
925 pu4_bitstrm_buf);
926 ps_mmc_params->u4_lt_idx = u4_lt_idx;
927 break;
928
929 case MARK_ST_PICNUM_AS_LT_INDEX:
930 u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
931 pu4_bitstrm_buf);
932 ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
933 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
934 pu4_bitstrm_buf);
935 ps_mmc_params->u4_lt_idx = u4_lt_idx;
936 break;
937
938 case SET_MAX_LT_INDEX:
939 {
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +0530940 u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst,
941 pu4_bitstrm_buf);
942 if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames)
943 {
944 /* Invalid max LT ref index */
945 return -1;
946 }
947 ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530948 break;
949 }
950 case RESET_REF_PICTURES:
951 {
952 ps_slice->u1_mmco_equalto5 = 1;
953 break;
954 }
955
956 case SET_LT_INDEX:
957 u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
958 pu4_bitstrm_buf);
959 ps_mmc_params->u4_lt_idx = u4_lt_idx;
960 break;
961
962 default:
963 break;
964 }
965 u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
966 pu4_bitstrm_buf);
967
968 j++;
969 }
970 ps_dpb_cmds->u1_num_of_commands = j;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530971 }
972 }
973 ps_dpb_cmds->u1_dpb_commands_read = 1;
974 ps_dpb_cmds->u1_dpb_commands_read_slc = 1;
975
976 }
977 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst;
978 return u4_bit_ofst;
979}
980
981/*!
982 **************************************************************************
983 * \if Function name : ih264d_do_mmco_buffer \endif
984 *
985 * \brief
986 * Perform decoded picture buffer memory management control operations
987 *
988 * \return
989 * 0 - No error; -1 - Error
990 *
991 * \note
992 * Bitstream is also parsed here to get the MMCOs
993 *
994 **************************************************************************
995 */
996WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
997 dpb_manager_t *ps_dpb_mgr,
998 UWORD8 u1_numRef_frames_for_seq, /*!< num_ref_frames from active SeqParSet*/
999 UWORD32 u4_cur_pic_num,
1000 UWORD32 u2_u4_max_pic_num_minus1,
1001 UWORD8 u1_nal_unit_type,
1002 struct pic_buffer_t *ps_pic_buf,
1003 UWORD8 u1_buf_id,
1004 UWORD8 u1_fld_pic_flag,
1005 UWORD8 u1_curr_pic_in_err)
1006{
1007 WORD32 i;
1008 UWORD8 u1_buf_mode, u1_marked_lt;
1009 struct dpb_info_t *ps_next_dpb;
1010 UWORD8 u1_num_gaps;
1011 UWORD8 u1_del_node = 1;
1012 UWORD8 u1_insert_st_pic = 1;
1013 WORD32 ret;
1014 UNUSED(u1_nal_unit_type);
1015 UNUSED(u2_u4_max_pic_num_minus1);
1016 u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive
1017 u1_marked_lt = 0;
1018 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1019
1020 if(!u1_buf_mode)
1021 {
1022 //Sliding window - implements 8.2.5.3
1023 if((ps_dpb_mgr->u1_num_st_ref_bufs
1024 + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps)
1025 == u1_numRef_frames_for_seq)
1026 {
1027 UWORD8 u1_new_node_flag = 1;
1028 if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1029 {
1030 UWORD32 i4_error_code;
1031 i4_error_code = ERROR_DBP_MANAGER_T;
1032 return i4_error_code;
1033 }
1034
1035 // Chase the links to reach the last but one picNum, if available
1036 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1037
1038 if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1039 {
1040 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1041 {
1042 /* Incase of filed pictures top_field has been allocated */
1043 /* picture buffer and complementary bottom field pair comes */
1044 /* then the sliding window mechanism should not allocate a */
1045 /* new node */
1046 u1_new_node_flag = 0;
1047 }
1048
1049 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1050 {
1051 if(ps_next_dpb == NULL)
1052 {
1053 UWORD32 i4_error_code;
1054 i4_error_code = ERROR_DBP_MANAGER_T;
1055 return i4_error_code;
1056 }
1057 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1058 {
1059 /* Incase of field pictures top_field has been allocated */
1060 /* picture buffer and complementary bottom field pair comes */
1061 /* then the sliding window mechanism should not allocate a */
1062 /* new node */
1063 u1_new_node_flag = 0;
1064 }
1065 ps_next_dpb = ps_next_dpb->ps_prev_short;
1066 }
1067
1068 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1069 {
1070 UWORD32 i4_error_code;
1071 i4_error_code = ERROR_DBP_MANAGER_T;
1072 return i4_error_code;
1073 }
1074
1075 if(u1_new_node_flag)
1076 {
1077 if(u1_num_gaps)
1078 {
1079 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1080 ps_next_dpb->ps_prev_short->i4_frame_num,
1081 &u1_del_node);
1082 if(ret != OK)
1083 return ret;
1084 }
1085
1086 if(u1_del_node)
1087 {
1088 ps_dpb_mgr->u1_num_st_ref_bufs--;
1089 ps_next_dpb->ps_prev_short->u1_used_as_ref =
1090 UNUSED_FOR_REF;
1091 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1092 UNUSED_FOR_REF;
1093 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1094 UNUSED_FOR_REF;
1095 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1096 ps_next_dpb->ps_prev_short->u1_buf_id);
1097 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1098 ps_next_dpb->ps_prev_short = NULL;
1099 }
1100 }
1101 }
1102 else
1103 {
1104 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1105 {
1106 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1107 ps_next_dpb->i4_frame_num,
1108 &u1_del_node);
1109 if(ret != OK)
1110 return ret;
1111 if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1112 && u1_del_node)
1113 {
1114 ps_dpb_mgr->u1_num_st_ref_bufs--;
1115 ps_next_dpb->u1_used_as_ref = FALSE;
1116 ps_next_dpb->s_top_field.u1_reference_info =
1117 UNUSED_FOR_REF;
1118 ps_next_dpb->s_bot_field.u1_reference_info =
1119 UNUSED_FOR_REF;
1120 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1121 ps_next_dpb->u1_buf_id);
1122 ps_next_dpb->ps_pic_buf = NULL;
1123 ps_next_dpb->ps_prev_short = NULL;
1124 ps_dpb_mgr->ps_dpb_st_head = NULL;
1125 ps_next_dpb = NULL;
1126 }
1127 else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1128 {
1129 if(u1_curr_pic_in_err)
1130 {
1131 u1_insert_st_pic = 0;
1132 }
1133 else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1134 {
1135 ps_dpb_mgr->u1_num_st_ref_bufs--;
1136 ps_next_dpb->u1_used_as_ref = FALSE;
1137 ps_next_dpb->s_top_field.u1_reference_info =
1138 UNUSED_FOR_REF;
1139 ps_next_dpb->s_bot_field.u1_reference_info =
1140 UNUSED_FOR_REF;
1141 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1142 ps_next_dpb->u1_buf_id);
1143 ps_next_dpb->ps_pic_buf = NULL;
1144 ps_next_dpb = NULL;
1145 }
1146 }
1147 }
1148 else
1149 {
1150 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1151 INVALID_FRAME_NUM,
1152 &u1_del_node);
1153 if(ret != OK)
1154 return ret;
1155 if(u1_del_node)
1156 {
1157 UWORD32 i4_error_code;
1158 i4_error_code = ERROR_DBP_MANAGER_T;
1159 return i4_error_code;
1160 }
1161 }
1162 }
1163 }
1164 }
1165 else
1166 {
1167 //Adaptive memory control - implements 8.2.5.4
1168 UWORD32 u4_mmco;
1169 UWORD32 u4_diff_pic_num;
1170 WORD32 i4_pic_num;
1171 UWORD32 u4_lt_idx;
1172 WORD32 j;
1173 struct MMCParams *ps_mmc_params;
1174
1175 for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
1176 {
1177 ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
1178 u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO
1179
1180 switch(u4_mmco)
1181 {
1182 case MARK_ST_PICNUM_AS_NONREF:
1183 {
1184
1185 {
1186 UWORD32 i4_cur_pic_num = u4_cur_pic_num;
Harish Mahendrakar1d672d22019-07-03 10:12:53 -07001187 WORD64 i8_pic_num;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301188 u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1189 if(u1_fld_pic_flag)
1190 i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
Harish Mahendrakar1d672d22019-07-03 10:12:53 -07001191 i8_pic_num = ((WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1));
1192 if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1193 {
1194 return ERROR_DBP_MANAGER_T;
1195 }
1196 i4_pic_num = i8_pic_num;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301197 }
1198
1199 if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1200 {
1201 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1202 i4_pic_num,
1203 MAX_REF_BUFS + 1,
1204 u1_fld_pic_flag);
1205 if(ret != OK)
1206 return ret;
1207 }
1208 else
1209 {
1210 UWORD8 u1_dummy;
1211 ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy);
1212 if(ret != OK)
1213 return ret;
1214 }
1215 break;
1216 }
1217 case MARK_LT_INDEX_AS_NONREF:
1218 {
1219 WORD32 i4_status;
1220 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1221 ret = ih264d_delete_lt_node(ps_dpb_mgr,
1222 u4_lt_idx,
1223 u1_fld_pic_flag,
1224 0, &i4_status);
1225 if(ret != OK)
1226 return ret;
1227 if(i4_status)
1228 {
1229 UWORD32 i4_error_code;
1230 i4_error_code = ERROR_DBP_MANAGER_T;
1231 return i4_error_code;
1232 }
1233 break;
1234 }
1235
1236 case MARK_ST_PICNUM_AS_LT_INDEX:
1237 {
1238 {
1239 UWORD32 i4_cur_pic_num = u4_cur_pic_num;
Harish Mahendrakar1d672d22019-07-03 10:12:53 -07001240 WORD64 i8_pic_num;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301241 u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1242 if(u1_fld_pic_flag)
1243 i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
1244
Harish Mahendrakar1d672d22019-07-03 10:12:53 -07001245 i8_pic_num = (WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1);
1246 if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1247 {
1248 return ERROR_DBP_MANAGER_T;
1249 }
1250 i4_pic_num = i8_pic_num;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301251 }
1252
1253 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +05301254
1255 if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1256 (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1257 {
1258 return ERROR_DBP_MANAGER_T;
1259 }
1260
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301261 if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1262 {
1263 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1264 i4_pic_num, u4_lt_idx,
1265 u1_fld_pic_flag);
1266 if(ret != OK)
1267 return ret;
1268 }
1269 break;
1270 }
1271 case SET_MAX_LT_INDEX:
1272 {
1273 UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
1274 u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +05301275 if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301276 && uc_numLT > 0)
1277 {
1278 struct dpb_info_t *ps_nxtDPB;
1279 //Set all LT buffers with index >= u4_lt_idx to nonreference
1280 ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head;
1281 ps_next_dpb = ps_nxtDPB->ps_prev_long;
1282 if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx)
1283 {
1284 i = 0;
1285 ps_dpb_mgr->ps_dpb_ht_head = NULL;
1286 }
1287 else
1288 {
1289 for(i = 1; i < uc_numLT; i++)
1290 {
1291 if(ps_next_dpb->u1_lt_idx >= u4_lt_idx)
1292 break;
1293 ps_nxtDPB = ps_next_dpb;
1294 ps_next_dpb = ps_next_dpb->ps_prev_long;
1295 }
1296 ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max
1297 }
1298 ps_dpb_mgr->u1_num_lt_ref_bufs = i;
1299 if(i == 0)
1300 ps_next_dpb = ps_nxtDPB;
1301
1302 for(; i < uc_numLT; i++)
1303 {
1304 ps_nxtDPB = ps_next_dpb;
1305 ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1;
1306 ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF;
1307 ps_nxtDPB->s_top_field.u1_reference_info =
1308 UNUSED_FOR_REF;
1309 ps_nxtDPB->s_bot_field.u1_reference_info =
1310 UNUSED_FOR_REF;
1311
1312 ps_nxtDPB->ps_pic_buf = NULL;
1313 //Release buffer
1314 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1315 ps_nxtDPB->u1_buf_id);
1316 ps_next_dpb = ps_nxtDPB->ps_prev_long;
1317 ps_nxtDPB->ps_prev_long = NULL;
1318 }
1319 }
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +05301320 if(u4_lt_idx == 0)
1321 {
1322 ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
1323 }
1324 else
1325 {
1326 ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
1327 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301328
1329 break;
1330 }
1331 case SET_LT_INDEX:
1332 {
1333 u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
Aasaipriya Chandran083b9fc2020-06-10 13:42:04 +05301334 if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1335 (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1336 {
1337 return ERROR_DBP_MANAGER_T;
1338 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301339 ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1340 u4_cur_pic_num);
1341 if(ret != OK)
1342 return ret;
Hamsalekha S41489f92017-02-10 14:47:11 +05301343
1344 if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1345
1346 {
1347 ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1348 u4_cur_pic_num,
1349 u4_lt_idx,
1350 u1_fld_pic_flag);
1351 if(ret != OK)
1352 return ret;
1353 }
1354 else
1355 {
1356 return ERROR_DBP_MANAGER_T;
1357 }
1358
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301359 u1_marked_lt = 1;
1360 break;
1361 }
1362
1363 default:
1364 break;
1365 }
1366 if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES)
1367 {
1368 ih264d_reset_ref_bufs(ps_dpb_mgr);
1369 u4_cur_pic_num = 0;
1370 }
1371 }
1372 }
1373 if(!u1_marked_lt && u1_insert_st_pic)
1374 {
1375 ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1376 u4_cur_pic_num);
1377 if(ret != OK)
1378 return ret;
1379 }
1380 return OK;
1381}
1382
1383/*****************************************************************************/
1384/* */
1385/* Function Name : ih264d_release_pics_in_dpb */
1386/* */
1387/* Description : This function deletes all pictures from DPB */
1388/* */
1389/* Inputs : h_pic_buf_api: pointer to picture buffer API */
1390/* u1_disp_bufs: number pictures ready for display */
1391/* */
1392/* Globals : None */
1393/* Outputs : None */
1394/* Returns : None */
1395/* */
1396/* Issues : None */
1397/* */
1398/* Revision History: */
1399/* */
1400/* DD MM YYYY Author(s) Changes (Describe the changes made) */
1401/* 22 06 2005 NS Draft */
1402/* */
1403/*****************************************************************************/
1404void ih264d_release_pics_in_dpb(void *pv_dec,
1405 UWORD8 u1_disp_bufs)
1406{
1407 WORD8 i;
1408 dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
1409
1410 for(i = 0; i < u1_disp_bufs; i++)
1411 {
1412 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
1413 i,
1414 BUF_MGR_REF);
1415 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
1416 ps_dec->au1_pic_buf_id_mv_buf_id_map[i],
1417 BUF_MGR_REF);
1418 }
1419}
1420
1421/*****************************************************************************/
1422/* */
1423/* Function Name : ih264d_delete_gap_frm_sliding */
1424/* */
1425/* Description : This function deletes a picture from the list of gaps, */
1426/* if the frame number of gap frame is lesser than the one */
1427/* to be deleted by sliding window */
1428/* Inputs : ps_dpb_mgr: pointer to dpb manager */
1429/* i4_frame_num: frame number of picture that's going to */
1430/* be deleted by sliding window */
1431/* pu1_del_node: holds 0 if a gap is deleted else 1 */
1432/* Globals : None */
1433/* Processing : Function searches for frame number lesser than */
1434/* i4_frame_num in the gaps list */
1435/* Outputs : None */
1436/* Returns : None */
1437/* */
1438/* Issues : None */
1439/* */
1440/* Revision History: */
1441/* */
1442/* DD MM YYYY Author(s) Changes (Describe the changes made) */
1443/* 22 06 2005 NS Draft */
1444/* */
1445/*****************************************************************************/
1446WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr,
1447 WORD32 i4_frame_num,
1448 UWORD8 *pu1_del_node)
1449{
1450 WORD8 i1_gap_idx, i, j, j_min;
1451 WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
1452 WORD32 i4_start_frm_num, i4_end_frm_num;
1453 WORD32 i4_max_frm_num;
1454 WORD32 i4_frm_num, i4_gap_frm_num_min;
1455
1456 /* find the least frame num from gaps and current DPB node */
1457 /* Delete the least one */
1458 *pu1_del_node = 1;
1459 if(0 == ps_dpb_mgr->u1_num_gaps)
1460 return OK;
1461 pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
1462 pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
1463 i4_gap_frame_num = INVALID_FRAME_NUM;
1464 i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1465
1466 i1_gap_idx = -1;
1467 if(INVALID_FRAME_NUM != i4_frame_num)
1468 {
1469 i4_gap_frame_num = i4_frame_num;
1470 for(i = 0; i < MAX_FRAMES; i++)
1471 {
1472 i4_start_frm_num = pi4_gaps_start_frm_num[i];
1473 if(INVALID_FRAME_NUM != i4_start_frm_num)
1474 {
1475 i4_end_frm_num = pi4_gaps_end_frm_num[i];
1476 if(i4_end_frm_num < i4_max_frm_num)
1477 {
1478 if(i4_start_frm_num <= i4_gap_frame_num)
1479 {
1480 i4_gap_frame_num = i4_start_frm_num;
1481 i1_gap_idx = i;
1482 }
1483 }
1484 else
1485 {
1486 if(((i4_start_frm_num <= i4_gap_frame_num)
1487 && (i4_gap_frame_num <= i4_max_frm_num))
1488 || ((i4_start_frm_num >= i4_gap_frame_num)
1489 && ((i4_gap_frame_num
1490 + i4_max_frm_num)
1491 >= i4_end_frm_num)))
1492 {
1493 i4_gap_frame_num = i4_start_frm_num;
1494 i1_gap_idx = i;
1495 }
1496 }
1497 }
1498 }
1499 }
1500 else
1501 {
1502 /* no valid short term buffers, delete one gap from the least start */
1503 /* of gap sequence */
1504 i4_gap_frame_num = pi4_gaps_start_frm_num[0];
1505 i1_gap_idx = 0;
1506 for(i = 1; i < MAX_FRAMES; i++)
1507 {
1508 if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
1509 {
1510 if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
1511 {
1512 i4_gap_frame_num = pi4_gaps_start_frm_num[i];
1513 i1_gap_idx = i;
1514 }
1515 }
1516 }
1517 if(INVALID_FRAME_NUM == i4_gap_frame_num)
1518 {
1519 UWORD32 i4_error_code;
1520 i4_error_code = ERROR_DBP_MANAGER_T;
1521 return i4_error_code;
1522 }
1523 }
1524
1525 if(-1 != i1_gap_idx)
1526 {
1527 /* find least frame_num in the poc_map, which is in this range */
1528 i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
1529 if(i4_start_frm_num < 0)
1530 i4_start_frm_num += i4_max_frm_num;
1531 i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
1532 if(i4_end_frm_num < 0)
1533 i4_end_frm_num += i4_max_frm_num;
1534
1535 i4_gap_frm_num_min = 0xfffffff;
1536 j_min = MAX_FRAMES;
1537 for(j = 0; j < MAX_FRAMES; j++)
1538 {
1539 i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2];
1540 if((i4_start_frm_num <= i4_frm_num)
1541 && (i4_end_frm_num >= i4_frm_num))
1542 {
1543 if(i4_frm_num < i4_gap_frm_num_min)
1544 {
1545 j_min = j;
1546 i4_gap_frm_num_min = i4_frm_num;
1547 }
1548 }
1549 }
1550
1551 if(j_min != MAX_FRAMES)
1552 {
1553
1554 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1;
1555 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff;
1556 ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM;
1557 ps_dpb_mgr->i1_gaps_deleted++;
1558
1559 ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
1560 ps_dpb_mgr->u1_num_gaps--;
1561 *pu1_del_node = 0;
1562 if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
1563 {
1564 ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] =
1565 INVALID_FRAME_NUM;
1566 ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
1567 }
1568 }
1569 }
1570
1571 return OK;
1572}
1573
1574/*****************************************************************************/
1575/* */
1576/* Function Name : ih264d_delete_gap_frm_mmco */
1577/* */
1578/* Description : This function deletes a picture from the list of gaps, */
1579/* if the frame number (specified by mmco commands) to be */
1580/* deleted is in the range by gap sequence. */
1581/* */
1582/* Inputs : ps_dpb_mgr: pointer to dpb manager */
1583/* i4_frame_num: frame number of picture that's going to */
1584/* be deleted by mmco */
1585/* pu1_del_node: holds 0 if a gap is deleted else 1 */
1586/* Globals : None */
1587/* Processing : Function searches for frame number lesser in the range */
1588/* specified by gap sequence */
1589/* Outputs : None */
1590/* Returns : None */
1591/* */
1592/* Issues : None */
1593/* */
1594/* Revision History: */
1595/* */
1596/* DD MM YYYY Author(s) Changes (Describe the changes made) */
1597/* 22 06 2005 NS Draft */
1598/* */
1599/*****************************************************************************/
1600WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr,
1601 WORD32 i4_frame_num,
1602 UWORD8 *pu1_del_node)
1603{
1604 WORD8 i, j;
1605 WORD32 *pi4_start, *pi4_end;
1606 WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_frm_num;
1607
1608 /* find the least frame num from gaps and current DPB node */
1609 /* Delete the gaps */
1610 *pu1_del_node = 1;
1611 pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
1612 pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
1613 i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1614
1615 if(0 == ps_dpb_mgr->u1_num_gaps)
1616 return OK;
1617
1618 if(i4_frame_num < 0)
1619 i4_frame_num += i4_max_frm_num;
1620 for(i = 0; i < MAX_FRAMES; i++)
1621 {
1622 i4_start_frm_num = pi4_start[i];
1623 if(i4_start_frm_num < 0)
1624 i4_start_frm_num += i4_max_frm_num;
1625 if(INVALID_FRAME_NUM != i4_start_frm_num)
1626 {
1627 i4_end_frm_num = pi4_end[i];
1628 if(i4_end_frm_num < 0)
1629 i4_end_frm_num += i4_max_frm_num;
1630
1631 if((i4_frame_num >= i4_start_frm_num)
1632 && (i4_frame_num <= i4_end_frm_num))
1633 {
1634 break;
1635 }
1636 else
1637 {
1638 if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num)
1639 && ((i4_frame_num + i4_max_frm_num)
1640 <= i4_end_frm_num))
1641 {
1642 UWORD32 i4_error_code;
1643 i4_error_code = ERROR_DBP_MANAGER_T;
1644 return i4_error_code;
1645 }
1646 }
1647 }
1648 }
1649
1650 /* find frame_num index, in the poc_map which needs to be deleted */
1651 for(j = 0; j < MAX_FRAMES; j++)
1652 {
1653 if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2])
1654 break;
1655 }
1656
1657 if(MAX_FRAMES != i)
1658 {
1659 if(j == MAX_FRAMES)
1660 {
1661 UWORD32 i4_error_code;
1662 i4_error_code = ERROR_DBP_MANAGER_T;
1663 return i4_error_code;
1664 }
1665
1666 ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1;
1667 ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff;
1668 ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM;
1669 ps_dpb_mgr->i1_gaps_deleted++;
1670
1671 ps_dpb_mgr->ai1_gaps_per_seq[i]--;
1672 ps_dpb_mgr->u1_num_gaps--;
1673 *pu1_del_node = 0;
1674 if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
1675 {
1676 ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
1677 ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
1678 }
1679 }
1680 else
1681 {
1682 UWORD32 i4_error_code;
1683 i4_error_code = ERROR_DBP_MANAGER_T;
1684 return i4_error_code;
1685 }
1686
1687 return OK;
1688}
1689
1690/*!
1691 **************************************************************************
1692 * \if Function name : ih264d_do_mmco_for_gaps \endif
1693 *
1694 * \brief
1695 * Perform decoded picture buffer memory management control operations
1696 *
1697 * \return
1698 * 0 - No error; -1 - Error
1699 *
1700 * \note
1701 * Bitstream is also parsed here to get the MMCOs
1702 *
1703 **************************************************************************
1704 */
1705WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr,
1706 UWORD8 u1_num_ref_frames /*!< num_ref_frames from active SeqParSet*/
1707 )
1708{
1709 struct dpb_info_t *ps_next_dpb;
1710 UWORD8 u1_num_gaps;
1711 UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node;
1712 WORD8 i;
1713 WORD32 i4_frame_gaps = 1;
1714 WORD32 ret;
1715
1716 //Sliding window - implements 8.2.5.3, flush out buffers
1717 u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
1718 u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
1719
1720 while(1)
1721 {
1722 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1723 if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps)
1724 > u1_num_ref_frames)
1725 {
1726 if(0 == (u1_st_ref_bufs + u1_num_gaps))
1727 {
1728 i4_frame_gaps = 0;
1729 ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames
1730 - u1_lt_ref_bufs);
1731 }
1732 else
1733 {
1734 u1_del_node = 1;
1735 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1736
1737 if(u1_st_ref_bufs > 1)
1738 {
1739 for(i = 1; i < (u1_st_ref_bufs - 1); i++)
1740 {
1741 if(ps_next_dpb == NULL)
1742 {
1743 UWORD32 i4_error_code;
1744 i4_error_code = ERROR_DBP_MANAGER_T;
1745 return i4_error_code;
1746 }
1747 ps_next_dpb = ps_next_dpb->ps_prev_short;
1748 }
1749
1750 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1751 {
1752 return ERROR_DBP_MANAGER_T;
1753 }
1754
1755 if(u1_num_gaps)
1756 {
1757 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1758 ps_next_dpb->ps_prev_short->i4_frame_num,
1759 &u1_del_node);
1760 if(ret != OK)
1761 return ret;
1762 }
1763
1764 if(u1_del_node)
1765 {
1766 u1_st_ref_bufs--;
1767 ps_next_dpb->ps_prev_short->u1_used_as_ref =
1768 UNUSED_FOR_REF;
1769 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1770 UNUSED_FOR_REF;
1771 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1772 UNUSED_FOR_REF;
1773 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1774 ps_next_dpb->ps_prev_short->u1_buf_id);
1775 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1776 ps_next_dpb->ps_prev_short = NULL;
1777 }
1778 }
1779 else
1780 {
1781 if(u1_st_ref_bufs)
1782 {
1783 if(u1_num_gaps)
1784 {
1785 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1786 ps_next_dpb->i4_frame_num,
1787 &u1_del_node);
1788 if(ret != OK)
1789 return ret;
1790 }
1791
1792 if(u1_del_node)
1793 {
1794 u1_st_ref_bufs--;
1795 ps_next_dpb->u1_used_as_ref = FALSE;
1796 ps_next_dpb->s_top_field.u1_reference_info =
1797 UNUSED_FOR_REF;
1798 ps_next_dpb->s_bot_field.u1_reference_info =
1799 UNUSED_FOR_REF;
1800 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1801 ps_next_dpb->u1_buf_id);
1802 ps_next_dpb->ps_pic_buf = NULL;
1803 ps_next_dpb = NULL;
1804 ps_dpb_mgr->ps_dpb_st_head = NULL;
1805 ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1806 }
1807 }
1808 else
1809 {
1810 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1811 INVALID_FRAME_NUM,
1812 &u1_del_node);
1813 if(ret != OK)
1814 return ret;
1815 if(u1_del_node)
1816 {
1817 return ERROR_DBP_MANAGER_T;
1818 }
1819 }
1820 }
1821 }
1822 }
1823 else
1824 {
1825 ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
1826 break;
1827 }
1828 }
1829
1830 ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1831
1832 return OK;
1833}
1834/****************************************************************************/
1835/* */
1836/* Function Name : ih264d_free_node_from_dpb */
1837/* */
1838/* Description : */
1839/* */
1840/* Inputs : */
1841/* */
1842/* Globals : */
1843/* */
1844/* Processing : */
1845/* */
1846/* Outputs : */
1847/* */
1848/* Returns : */
1849/* */
1850/* Known Issues : */
1851/* */
1852/* Revision History */
1853/* */
1854/* DD MM YY Author Changes */
1855/* Sarat */
1856/****************************************************************************/
1857/**** Function Added for Error Resilience *****/
1858WORD32 ih264d_free_node_from_dpb(dpb_manager_t *ps_dpb_mgr,
1859 UWORD32 u4_cur_pic_num,
1860 UWORD8 u1_numRef_frames_for_seq)
1861{
1862 WORD32 i;
1863 UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1864 struct dpb_info_t *ps_next_dpb;
1865 UWORD8 u1_del_node = 1;
1866 WORD32 ret;
1867
1868 //Sliding window - implements 8.2.5.3
1869 if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs
1870 + u1_num_gaps) == u1_numRef_frames_for_seq)
1871 {
1872 UWORD8 u1_new_node_flag = 1;
1873 if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1874 {
1875 return ERROR_DBP_MANAGER_T;
1876 }
1877
1878 // Chase the links to reach the last but one picNum, if available
1879 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1880
1881 if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1882 {
1883 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1884 {
1885 /* Incase of filed pictures top_field has been allocated */
1886 /* picture buffer and complementary bottom field pair comes */
1887 /* then the sliding window mechanism should not allocate a */
1888 /* new node */
1889 u1_new_node_flag = 0;
1890 }
1891
1892 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1893 {
1894 if(ps_next_dpb == NULL)
1895 return ERROR_DBP_MANAGER_T;
1896
1897 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1898 {
1899 /* Incase of field pictures top_field has been allocated */
1900 /* picture buffer and complementary bottom field pair comes */
1901 /* then the sliding window mechanism should not allocate a */
1902 /* new node */
1903 u1_new_node_flag = 0;
1904 }
1905 ps_next_dpb = ps_next_dpb->ps_prev_short;
1906 }
1907
1908 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1909 return ERROR_DBP_MANAGER_T;
1910
1911 if(u1_new_node_flag)
1912 {
1913 if(u1_num_gaps)
1914 {
1915 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1916 ps_next_dpb->ps_prev_short->i4_frame_num,
1917 &u1_del_node);
1918 if(ret != OK)
1919 return ret;
1920 }
1921
1922 if(u1_del_node)
1923 {
1924 ps_dpb_mgr->u1_num_st_ref_bufs--;
1925 ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF;
1926 ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1927 UNUSED_FOR_REF;
1928 ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1929 UNUSED_FOR_REF;
1930 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1931 ps_next_dpb->ps_prev_short->u1_buf_id);
1932 ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1933 ps_next_dpb->ps_prev_short = NULL;
1934 }
1935 }
1936 }
1937 else
1938 {
1939 if(ps_dpb_mgr->u1_num_st_ref_bufs)
1940 {
1941 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1942 ps_next_dpb->i4_frame_num,
1943 &u1_del_node);
1944 if(ret != OK)
1945 return ret;
1946 if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1947 && u1_del_node)
1948 {
1949 ps_dpb_mgr->u1_num_st_ref_bufs--;
1950 ps_next_dpb->u1_used_as_ref = FALSE;
1951 ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1952 ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1953 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1954 ps_next_dpb->u1_buf_id);
1955 ps_next_dpb->ps_pic_buf = NULL;
1956 ps_next_dpb = NULL;
1957 }
1958 }
1959 else
1960 {
1961 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
1962 if(ret != OK)
1963 return ret;
1964 if(u1_del_node)
1965 return ERROR_DBP_MANAGER_T;
1966 }
1967 }
1968 }
1969 return OK;
1970}
1971/*****************************************************************************/
1972/* */
1973/* Function Name : ih264d_delete_nonref_nondisplay_pics */
1974/* */
1975/* Description : */
1976/* */
1977/* */
1978/* Inputs : */
1979/* Globals : */
1980/* Processing : */
1981/* */
1982/* Outputs : */
1983/* Returns : */
1984/* */
1985/* Issues : */
1986/* */
1987/* Revision History: */
1988/* */
1989/* DD MM YYYY Author(s) Changes (Describe the changes made) */
1990/* 05 06 2007 Varun Draft */
1991/* */
1992/*****************************************************************************/
1993
1994void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr)
1995{
1996 WORD8 i;
1997 WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
1998
1999 /* remove all gaps marked as unused for ref */
2000 for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
2001 {
2002 if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
2003 {
2004 ps_dpb_mgr->i1_gaps_deleted--;
2005 ps_dpb_mgr->i1_poc_buf_id_entries--;
2006 i4_poc_buf_id_map[i][0] = -1;
2007 i4_poc_buf_id_map[i][1] = 0x7fffffff;
2008 i4_poc_buf_id_map[i][2] = 0;
2009 }
2010 }
2011}
2012/*****************************************************************************/
2013/* */
2014/* Function Name : ih264d_insert_pic_in_display_list */
2015/* */
2016/* Description : */
2017/* */
2018/* */
2019/* Inputs : */
2020/* Globals : */
2021/* Processing : */
2022/* */
2023/* Outputs : */
2024/* Returns : */
2025/* */
2026/* Issues : */
2027/* */
2028/* Revision History: */
2029/* */
2030/* DD MM YYYY Author(s) Changes (Describe the changes made) */
2031/* 05 06 2007 Varun Draft */
2032/* */
2033/*****************************************************************************/
2034
2035WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr,
2036 UWORD8 u1_buf_id,
2037 WORD32 i4_display_poc,
2038 UWORD32 u4_frame_num)
2039{
2040 WORD8 i;
2041 WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
2042
2043 for(i = 0; i < MAX_FRAMES; i++)
2044 {
2045 /* Find an empty slot */
2046 if(i4_poc_buf_id_map[i][0] == -1)
2047 {
2048 if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
2049 ps_dpb_mgr->i1_gaps_deleted--;
2050 else
2051 ps_dpb_mgr->i1_poc_buf_id_entries++;
2052
2053 i4_poc_buf_id_map[i][0] = u1_buf_id;
2054 i4_poc_buf_id_map[i][1] = i4_display_poc;
2055 i4_poc_buf_id_map[i][2] = u4_frame_num;
2056
2057 break;
2058 }
2059 }
2060
2061 if(MAX_FRAMES == i)
2062 {
2063
2064 UWORD32 i4_error_code;
2065 i4_error_code = ERROR_GAPS_IN_FRM_NUM;
2066 return i4_error_code;
2067 }
2068 return OK;
2069}
2070