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