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