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