Coverage Report

Created: 2026-09-28 08:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavc/decoder/ih264d_dpb_mgr.c
Line
Count
Source
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__)
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
 */
80
void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr)
81
2.38k
{
82
2.38k
    UWORD32 i;
83
2.38k
    struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
84
78.6k
    for(i = 0; i < MAX_REF_BUFS; i++)
85
76.2k
    {
86
76.2k
        ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
87
76.2k
        ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
88
76.2k
        ps_dpb_info[i].ps_prev_short = NULL;
89
76.2k
        ps_dpb_info[i].ps_prev_long = NULL;
90
76.2k
        ps_dpb_info[i].ps_pic_buf = NULL;
91
76.2k
        ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
92
76.2k
        ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
93
76.2k
        ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
94
76.2k
        ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
95
96
76.2k
    }
97
2.38k
    ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
98
2.38k
    ps_dpb_mgr->ps_dpb_st_head = NULL;
99
2.38k
    ps_dpb_mgr->ps_dpb_ht_head = NULL;
100
2.38k
    ps_dpb_mgr->i1_gaps_deleted = 0;
101
2.38k
    ps_dpb_mgr->i1_poc_buf_id_entries = 0;
102
2.38k
    ps_dpb_mgr->u1_mmco_error_in_seq = 0;
103
104
2.38k
    ps_dpb_mgr->u1_num_gaps = 0;
105
40.4k
    for(i = 0; i < MAX_FRAMES; i++)
106
38.1k
    {
107
38.1k
        ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
108
38.1k
        ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
109
38.1k
        ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
110
38.1k
        ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1;
111
38.1k
        ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff;
112
38.1k
        ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0;
113
38.1k
    }
114
115
2.38k
}
116
117
void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id)
118
2.68k
{
119
2.68k
    dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
120
121
2.68k
    if((pic_buf_id == ps_dec->u1_pic_buf_id) &&
122
578
                    ps_dec->ps_cur_slice->u1_field_pic_flag &&
123
293
                    (ps_dec->u1_top_bottom_decoded == 0))
124
43
    {
125
43
        return;
126
43
    }
127
128
2.64k
    ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
129
2.64k
                          pic_buf_id,
130
2.64k
                          BUF_MGR_REF);
131
2.64k
    ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
132
2.64k
                          ps_dec->as_buf_id_info_map[pic_buf_id].mv_buf_id,
133
2.64k
                          BUF_MGR_REF);
134
2.64k
}
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
 */
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
857
{
152
857
    *pi4_status = 0;
153
857
    if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
154
290
    {
155
290
        WORD32 i;
156
290
        struct dpb_info_t *ps_next_dpb;
157
        /* ps_unmark_node points to the node to be removed */
158
        /* from long term list.                            */
159
290
        struct dpb_info_t *ps_unmark_node;
160
        //Find the node with matching LTIndex
161
290
        ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
162
290
        if(ps_next_dpb->u1_lt_idx == u4_lt_idx)
163
56
        {
164
56
            ps_unmark_node = ps_next_dpb;
165
56
        }
166
234
        else
167
234
        {
168
235
            for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
169
68
            {
170
68
                if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx)
171
67
                    break;
172
1
                ps_next_dpb = ps_next_dpb->ps_prev_long;
173
1
            }
174
234
            if(i == ps_dpb_mgr->u1_num_lt_ref_bufs)
175
167
                *pi4_status = 1;
176
67
            else
177
67
                ps_unmark_node = ps_next_dpb->ps_prev_long;
178
234
        }
179
180
290
        if(*pi4_status == 0)
181
123
        {
182
123
            if(u1_fld_pic_flag)
183
45
            {
184
45
                if(ps_lt_node_to_insert != ps_unmark_node)
185
45
                {
186
45
                    UWORD8 u1_deleted = 0;
187
                    /* for the ps_unmark_node mark the corresponding field */
188
                    /* field as unused for reference                       */
189
190
45
                    if(ps_unmark_node->s_top_field.u1_long_term_frame_idx
191
45
                                    == u4_lt_idx)
192
37
                    {
193
37
                        ps_unmark_node->s_top_field.u1_reference_info =
194
37
                                        UNUSED_FOR_REF;
195
37
                        ps_unmark_node->s_top_field.u1_long_term_frame_idx =
196
37
                        MAX_REF_BUFS + 1;
197
37
                        u1_deleted = 1;
198
37
                    }
199
45
                    if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx
200
45
                                    == u4_lt_idx)
201
27
                    {
202
27
                        ps_unmark_node->s_bot_field.u1_reference_info =
203
27
                                        UNUSED_FOR_REF;
204
27
                        ps_unmark_node->s_bot_field.u1_long_term_frame_idx =
205
27
                        MAX_REF_BUFS + 1;
206
27
                        u1_deleted = 1;
207
27
                    }
208
209
45
                    if(!u1_deleted)
210
8
                    {
211
212
8
                        UWORD32 i4_error_code;
213
8
                        i4_error_code = ERROR_DBP_MANAGER_T;
214
215
8
                        return i4_error_code;
216
8
                    }
217
45
                }
218
219
37
                ps_unmark_node->u1_used_as_ref =
220
37
                                ps_unmark_node->s_top_field.u1_reference_info
221
37
                                                | ps_unmark_node->s_bot_field.u1_reference_info;
222
37
            }
223
78
            else
224
78
                ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
225
226
115
            if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref)
227
105
            {
228
105
                if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head)
229
38
                    ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long;
230
231
105
                ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1;
232
105
                ps_unmark_node->s_top_field.u1_reference_info =
233
105
                UNUSED_FOR_REF;
234
105
                ps_unmark_node->s_bot_field.u1_reference_info =
235
105
                UNUSED_FOR_REF;
236
                // Release the physical buffer
237
105
                ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
238
105
                                            ps_unmark_node->u1_buf_id);
239
105
                ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link
240
105
                ps_unmark_node->ps_prev_long = NULL;
241
105
                ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count
242
105
            }
243
115
        }
244
290
    }
245
849
    return OK;
246
857
}
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
 */
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
573
{
264
573
    UWORD8 u1_mark_top_field_long_term = 0;
265
573
    UWORD8 u1_mark_bot_field_long_term = 0;
266
267
573
    {
268
573
        if(u1_fld_pic_flag)
269
22
        {
270
            /* Assign corresponding field (top or bottom) long_term_frame_idx */
271
272
22
            if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
273
20
                            && (ps_mov_node->s_bot_field.u1_reference_info
274
20
                                            == IS_LONG_TERM))
275
0
            {
276
0
                if(ps_mov_node->u1_lt_idx == u4_lt_idx)
277
0
                    u1_mark_bot_field_long_term = 1;
278
0
                else
279
0
                {
280
281
0
                    UWORD32 i4_error_code;
282
0
                    i4_error_code = ERROR_DBP_MANAGER_T;
283
284
0
                    return i4_error_code;
285
286
0
                }
287
0
            }
288
22
            else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
289
20
            {
290
20
                u1_mark_top_field_long_term = 1;
291
20
            }
292
293
22
            if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term))
294
2
            {
295
2
                UWORD32 i4_error_code;
296
2
                i4_error_code = ERROR_DBP_MANAGER_T;
297
2
                return i4_error_code;
298
2
            }
299
22
        }
300
551
        else
301
551
        {
302
551
            ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM;
303
551
            ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
304
551
            ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
305
551
            ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
306
551
            u1_mark_bot_field_long_term = 1;
307
551
            u1_mark_top_field_long_term = 1;
308
551
        }
309
310
571
        ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node
311
571
        ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx;
312
571
        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
571
        if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
317
186
        {
318
186
            struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
319
186
            if(u4_lt_idx < ps_next_dpb->u1_lt_idx)
320
20
            {
321
                //LTIndex to be inserted is the smallest LT index
322
                //Update head and point prev to the next higher index
323
20
                ps_mov_node->ps_prev_long = ps_next_dpb;
324
20
                ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
325
20
            }
326
166
            else
327
166
            {
328
166
                WORD32 i;
329
166
                struct dpb_info_t *ps_nxtDPB = ps_next_dpb;
330
166
                ps_next_dpb = ps_next_dpb->ps_prev_long;
331
166
                for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
332
1
                {
333
1
                    if(ps_next_dpb->u1_lt_idx > u4_lt_idx)
334
1
                        break;
335
0
                    ps_nxtDPB = ps_next_dpb;
336
0
                    ps_next_dpb = ps_next_dpb->ps_prev_long;
337
0
                }
338
339
166
                ps_nxtDPB->ps_prev_long = ps_mov_node;
340
166
                ps_mov_node->ps_prev_long = ps_next_dpb;
341
166
            }
342
186
        }
343
385
        else
344
385
        {
345
385
            ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
346
385
            ps_mov_node->ps_prev_long = NULL;
347
385
        }
348
        /* Identify the picture buffer as a long term picture buffer */
349
571
        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
571
        if(u1_mark_bot_field_long_term)
355
551
            ps_dpb_mgr->u1_num_lt_ref_bufs++;
356
357
571
    }
358
571
    return OK;
359
573
}
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
 */
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
3.23k
{
380
3.23k
    WORD32 i;
381
3.23k
    struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
382
3.23k
    UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype;
383
    /* Find an unused dpb location */
384
4.38k
    for(i = 0; i < MAX_REF_BUFS; i++)
385
4.38k
    {
386
4.38k
        if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
387
207
                        && ps_dpb_info[i].u1_used_as_ref)
388
119
        {
389
            /*signal an error in the case of frame pic*/
390
119
            if(ps_dpb_info[i].ps_pic_buf->u1_pic_type == FRM_PIC)
391
41
            {
392
41
                return ERROR_DBP_MANAGER_T;
393
41
            }
394
78
            else
395
78
            {
396
                /* Can occur only for field bottom pictures */
397
78
                ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
398
78
                return OK;
399
78
            }
400
119
        }
401
402
4.26k
        if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF)
403
3.11k
                        && (ps_dpb_info[i].s_top_field.u1_reference_info
404
3.11k
                                        == UNUSED_FOR_REF)
405
3.11k
                        && (ps_dpb_info[i].s_bot_field.u1_reference_info
406
3.11k
                                        == UNUSED_FOR_REF))
407
3.11k
            break;
408
4.26k
    }
409
3.11k
    if(i == MAX_REF_BUFS)
410
0
    {
411
0
        UWORD32 i4_error_code;
412
0
        i4_error_code = ERROR_DBP_MANAGER_T;
413
0
        return i4_error_code;
414
0
    }
415
416
    /* Create dpb info */
417
3.11k
    ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
418
3.11k
    ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
419
3.11k
    ps_dpb_info[i].u1_buf_id = u1_buf_id;
420
3.11k
    ps_dpb_info[i].u1_used_as_ref = TRUE;
421
3.11k
    ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
422
3.11k
    ps_dpb_info[i].i4_frame_num = u4_cur_pic_num;
423
3.11k
    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
3.11k
    ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
427
428
    // Increment Short term bufCount
429
3.11k
    ps_dpb_mgr->u1_num_st_ref_bufs++;
430
    /* Identify the picture as a short term picture buffer */
431
3.11k
    ps_pic_buf->u1_is_short = IS_SHORT_TERM;
432
433
3.11k
    if((u1_picture_type & 0x03) == FRM_PIC)
434
2.38k
    {
435
2.38k
        ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM;
436
2.38k
        ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
437
2.38k
        ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
438
2.38k
    }
439
440
3.11k
    if((u1_picture_type & 0x03) == TOP_FLD)
441
141
        ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
442
443
3.11k
    if((u1_picture_type & 0x03) == BOT_FLD)
444
0
        ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
445
446
3.11k
    return OK;
447
3.11k
}
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
 */
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
915
{
469
915
    WORD32 i;
470
915
    struct dpb_info_t *ps_next_dpb;
471
915
    WORD32 i4_frame_num = i4_pic_num;
472
915
    struct dpb_info_t *ps_unmark_node = NULL;
473
915
    UWORD8 u1_del_node = 0, u1_del_st = 0;
474
915
    UWORD8 u1_reference_type = UNUSED_FOR_REF;
475
915
    WORD32 ret;
476
477
915
    if(u1_fld_pic_flag)
478
338
    {
479
338
        i4_frame_num = i4_frame_num >> 1;
480
481
338
        if(u4_lt_idx == (MAX_REF_BUFS + 1))
482
296
            u1_reference_type = UNUSED_FOR_REF;
483
42
        else
484
42
            u1_reference_type = IS_LONG_TERM;
485
338
    }
486
487
    //Find the node with matching picNum
488
915
    ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
489
915
    if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num)
490
579
    {
491
579
        ps_unmark_node = ps_next_dpb;
492
579
    }
493
336
    else
494
336
    {
495
365
        for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
496
58
        {
497
58
            if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num)
498
29
                break;
499
29
            ps_next_dpb = ps_next_dpb->ps_prev_short;
500
29
        }
501
502
336
        if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
503
307
        {
504
307
            if(ps_dpb_mgr->u1_num_gaps)
505
263
            {
506
263
                ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st);
507
263
                if(ret != OK)
508
127
                    return ret;
509
263
            }
510
44
            else
511
44
            {
512
44
                UWORD32 i4_error_code;
513
44
                i4_error_code = ERROR_DBP_MANAGER_T;
514
515
44
                return i4_error_code;
516
44
            }
517
518
136
            if(u1_del_st)
519
0
            {
520
0
                UWORD32 i4_error_code;
521
0
                i4_error_code = ERROR_DBP_MANAGER_T;
522
0
                return i4_error_code;
523
0
            }
524
136
            else
525
136
            {
526
136
                return 0;
527
136
            }
528
136
        }
529
29
        else
530
29
            ps_unmark_node = ps_next_dpb->ps_prev_short;
531
336
    }
532
533
608
    if(u1_fld_pic_flag)
534
37
    {
535
        /* Mark the corresponding field ( top or bot) as  */
536
        /* UNUSED_FOR_REF or IS_LONG_TERM depending on    */
537
        /* u1_reference_type.                             */
538
37
        if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num)
539
28
        {
540
28
            ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type;
541
28
            ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
542
28
            {
543
28
                UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
544
28
                WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
545
28
                                * ps_dpb_mgr->u2_pic_ht) >> 5);
546
                /* memset the colocated zero u4_flag buffer */
547
28
                memset(pu1_src, 0, i4_size);
548
28
            }
549
28
        }
550
551
9
        else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num)
552
7
        {
553
554
7
            ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type;
555
7
            ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
556
7
            {
557
7
                UWORD8 *pu1_src =
558
7
                                ps_unmark_node->ps_pic_buf->pu1_col_zero_flag
559
7
                                                + ((ps_dpb_mgr->u2_pic_wd
560
7
                                                                * ps_dpb_mgr->u2_pic_ht)
561
7
                                                                >> 5);
562
7
                WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
563
7
                                * ps_dpb_mgr->u2_pic_ht) >> 5);
564
                /* memset the colocated zero u4_flag buffer */
565
7
                memset(pu1_src, 0, i4_size);
566
7
            }
567
7
        }
568
37
        ps_unmark_node->u1_used_as_ref =
569
37
                        ps_unmark_node->s_top_field.u1_reference_info
570
37
                                        | ps_unmark_node->s_bot_field.u1_reference_info;
571
37
    }
572
571
    else
573
571
    {
574
571
        ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
575
571
        ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
576
571
        ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
577
578
571
        {
579
571
            UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
580
581
571
            WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
582
571
                            * ps_dpb_mgr->u2_pic_ht) >> 4);
583
            /* memset the colocated zero u4_flag buffer */
584
571
            memset(pu1_src, 0, i4_size);
585
571
        }
586
571
    }
587
588
608
    if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM))
589
592
    {
590
592
        if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
591
573
            ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
592
19
        else
593
19
            ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link
594
592
        ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count
595
592
        u1_del_node = 1;
596
592
    }
597
598
608
    if(u4_lt_idx == MAX_REF_BUFS + 1)
599
27
    {
600
27
        if(u1_del_node)
601
21
        {
602
            // Release the physical buffer
603
21
            ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
604
21
                                        ps_unmark_node->u1_buf_id);
605
21
            ps_unmark_node->ps_prev_short = NULL;
606
21
        }
607
27
    }
608
581
    else
609
581
    {
610
581
        WORD32 i4_status;
611
        //If another node has the same LT index, delete that node
612
581
        ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx,
613
581
                              u1_fld_pic_flag, ps_unmark_node, &i4_status);
614
581
        if(ret != OK)
615
8
            return ret;
616
        // Now insert the short term node as a long term node
617
573
        ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx,
618
573
                              u1_fld_pic_flag);
619
573
        if(ret != OK)
620
2
            return ret;
621
573
    }
622
598
    return OK;
623
608
}
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
 */
635
void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr)
636
5.26k
{
637
5.26k
    WORD32 i;
638
5.26k
    struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
639
640
173k
    for(i = 0; i < MAX_REF_BUFS; i++)
641
168k
    {
642
168k
        if(ps_dpb_info[i].u1_used_as_ref)
643
1.91k
        {
644
1.91k
            ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
645
1.91k
            ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
646
1.91k
            ps_dpb_info[i].ps_prev_short = NULL;
647
1.91k
            ps_dpb_info[i].ps_prev_long = NULL;
648
1.91k
            ps_dpb_info[i].ps_pic_buf = NULL;
649
1.91k
            ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
650
1.91k
            ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
651
1.91k
            ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
652
1.91k
            ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
653
654
            //Release physical buffer
655
1.91k
            ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
656
1.91k
                                        ps_dpb_info[i].u1_buf_id);
657
1.91k
        }
658
168k
    }
659
5.26k
    ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
660
5.26k
    ps_dpb_mgr->ps_dpb_st_head = NULL;
661
5.26k
    ps_dpb_mgr->ps_dpb_ht_head = NULL;
662
5.26k
    ps_dpb_mgr->u1_mmco_error_in_seq = 0;
663
664
    /* release all gaps */
665
5.26k
    ps_dpb_mgr->u1_num_gaps = 0;
666
89.4k
    for(i = 0; i < MAX_FRAMES; i++)
667
84.1k
    {
668
84.1k
        ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
669
84.1k
        ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
670
84.1k
        ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
671
84.1k
    }
672
5.26k
}
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
 */
686
WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr)
687
4.68k
{
688
4.68k
    WORD32 i;
689
4.68k
    struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
690
691
10.8k
    for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
692
6.18k
    {
693
6.18k
        ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
694
6.18k
        ps_next_dpb = ps_next_dpb->ps_prev_short;
695
6.18k
    }
696
697
4.68k
    ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
698
5.39k
    for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
699
717
    {
700
717
        ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
701
717
        ps_next_dpb = ps_next_dpb->ps_prev_long;
702
717
    }
703
4.68k
    return 0;
704
4.68k
}
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
 */
728
WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx)
729
3.27k
{
730
3.27k
    dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr;
731
3.27k
    UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num;
732
    /*< Maximum Picture Number Minus 1 */
733
3.27k
    UWORD32 ui_max_frame_num =
734
3.27k
                    ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
735
736
3.27k
    WORD32 i, count = 0;
737
3.27k
    UWORD32 ui_remapIdc, ui_nextUev;
738
3.27k
    WORD16 u2_pred_frame_num = u4_cur_pic_num;
739
3.27k
    WORD32 i_temp;
740
3.27k
    UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */
741
3.27k
    UWORD8 modCount = 0;
742
3.27k
    UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
743
3.27k
    UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
744
3.27k
    dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
745
3.27k
    UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
746
747
3.27k
    if(u1_field_pic_flag)
748
800
    {
749
800
        u4_cur_pic_num = u4_cur_pic_num * 2 + 1;
750
800
        ui_max_frame_num = ui_max_frame_num * 2;
751
800
    }
752
753
3.27k
    u2_pred_frame_num = u4_cur_pic_num;
754
755
3.27k
    ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
756
757
4.75k
    while((ui_remapIdc != 3)
758
4.32k
                    && (count < ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]))
759
4.21k
    {
760
4.21k
        ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
761
4.21k
        if(ui_remapIdc != 2)
762
3.83k
        {
763
3.83k
            if(ui_nextUev > ui_max_frame_num)
764
26
                return ERROR_DBP_MANAGER_T;
765
766
3.81k
            ui_nextUev = ui_nextUev + 1;
767
768
3.81k
            if(ui_remapIdc == 0)
769
2.92k
            {
770
                // diffPicNum is -ve
771
2.92k
                i_temp = (WORD32)u2_pred_frame_num - (WORD32)ui_nextUev;
772
2.92k
                if(i_temp < 0)
773
589
                    i_temp += ui_max_frame_num;
774
2.92k
            }
775
886
            else
776
886
            {
777
                // diffPicNum is +ve
778
886
                i_temp = (WORD32)u2_pred_frame_num + (WORD32)ui_nextUev;
779
886
                if(i_temp >= (WORD32)ui_max_frame_num)
780
53
                    i_temp -= ui_max_frame_num;
781
886
            }
782
            /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */
783
784
3.81k
            if(i_temp > u4_cur_pic_num)
785
922
                i_temp = i_temp - ui_max_frame_num;
786
787
7.96k
            for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
788
5.58k
            {
789
5.58k
                if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp)
790
1.42k
                    break;
791
5.58k
            }
792
3.81k
            if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
793
2.38k
            {
794
2.38k
                UWORD32 i4_error_code;
795
2.38k
                i4_error_code = ERROR_DBP_MANAGER_T;
796
2.38k
                return i4_error_code;
797
2.38k
            }
798
799
1.42k
            u2_def_mod_flag |= (1 << i);
800
1.42k
            ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
801
1.42k
                            ps_dpb_mgr->ps_init_dpb[uc_lx][i];
802
1.42k
            u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained
803
1.42k
        }
804
374
        else //2
805
374
        {
806
374
            UWORD8 u1_lt_idx;
807
808
374
            if(ui_nextUev > (MAX_REF_BUFS + 1))
809
0
                return ERROR_DBP_MANAGER_T;
810
811
374
            u1_lt_idx = (UWORD8)ui_nextUev;
812
813
970
            for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
814
651
            {
815
651
                if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short)
816
66
                {
817
66
                    if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num
818
66
                                    == u1_lt_idx)
819
55
                        break;
820
66
                }
821
651
            }
822
374
            if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
823
319
            {
824
319
                UWORD32 i4_error_code;
825
319
                i4_error_code = ERROR_DBP_MANAGER_T;
826
319
                return i4_error_code;
827
319
            }
828
829
55
            u2_def_mod_flag |= (1 << i);
830
55
            ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
831
55
                            ps_dpb_mgr->ps_init_dpb[uc_lx][i];
832
55
        }
833
834
1.48k
        ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
835
        /* Get the remapping_idc - 0/1/2/3 */
836
1.48k
        count++;
837
1.48k
    }
838
839
    //Handle the ref indices that were not remapped
840
2.19k
    for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++)
841
1.65k
    {
842
1.65k
        if(!(u2_def_mod_flag & (1 << i)))
843
800
            ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
844
800
                            ps_dpb_mgr->ps_init_dpb[uc_lx][i];
845
1.65k
    }
846
543
    return OK;
847
3.27k
}
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
 */
865
WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
866
81.1k
{
867
81.1k
    dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
868
81.1k
    dec_seq_params_t *ps_sps = ps_pps->ps_sps;
869
81.1k
    dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
870
81.1k
    dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch);
871
81.1k
    dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
872
81.1k
    WORD32 j;
873
81.1k
    UWORD8 u1_buf_mode;
874
81.1k
    struct MMCParams *ps_mmc_params;
875
81.1k
    UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
876
81.1k
    UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
877
81.1k
    UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst;
878
879
81.1k
    ps_slice->u1_mmco_equalto5 = 0;
880
81.1k
    {
881
81.1k
        if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL)
882
22.9k
        {
883
22.9k
            ps_slice->u1_no_output_of_prior_pics_flag =
884
22.9k
                            ih264d_get_bit_h264(ps_bitstrm);
885
22.9k
            COPYTHECONTEXT("SH: no_output_of_prior_pics_flag",
886
22.9k
                            ps_slice->u1_no_output_of_prior_pics_flag);
887
22.9k
            ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264(
888
22.9k
                            ps_bitstrm);
889
22.9k
            COPYTHECONTEXT("SH: long_term_reference_flag",
890
22.9k
                            ps_slice->u1_long_term_reference_flag);
891
22.9k
            ps_dpb_cmds->u1_idr_pic = 1;
892
22.9k
            ps_dpb_cmds->u1_no_output_of_prior_pics_flag =
893
22.9k
                            ps_slice->u1_no_output_of_prior_pics_flag;
894
22.9k
            ps_dpb_cmds->u1_long_term_reference_flag =
895
22.9k
                            ps_slice->u1_long_term_reference_flag;
896
22.9k
        }
897
58.2k
        else
898
58.2k
        {
899
58.2k
            u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary
900
58.2k
            COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode);
901
58.2k
            ps_dpb_cmds->u1_buf_mode = u1_buf_mode;
902
58.2k
            j = 0;
903
904
58.2k
            if(u1_buf_mode == 1)
905
21.8k
            {
906
21.8k
                UWORD32 u4_mmco;
907
21.8k
                UWORD32 u4_diff_pic_num;
908
21.8k
                UWORD32 u4_lt_idx, u4_max_lt_idx_plus1;
909
910
21.8k
                u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
911
21.8k
                                     pu4_bitstrm_buf);
912
72.5k
                while(u4_mmco != END_OF_MMCO)
913
50.7k
                {
914
50.7k
                    if (j >= MAX_REF_BUFS)
915
62
                    {
916
#ifdef __ANDROID__
917
                        ALOGE("b/25818142");
918
                        android_errorWriteLog(0x534e4554, "25818142");
919
#endif
920
62
                        ps_dpb_cmds->u1_num_of_commands = 0;
921
62
                        return -1;
922
62
                    }
923
50.6k
                    ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
924
50.6k
                    ps_mmc_params->u4_mmco = u4_mmco;
925
50.6k
                    switch(u4_mmco)
926
50.6k
                    {
927
9.33k
                        case MARK_ST_PICNUM_AS_NONREF:
928
9.33k
                            u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
929
9.33k
                                                         pu4_bitstrm_buf);
930
                            //Get absDiffPicnumMinus1
931
9.33k
                            ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
932
9.33k
                            break;
933
934
9.15k
                        case MARK_LT_INDEX_AS_NONREF:
935
9.15k
                            u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
936
9.15k
                                                   pu4_bitstrm_buf);
937
9.15k
                            ps_mmc_params->u4_lt_idx = u4_lt_idx;
938
9.15k
                            break;
939
940
5.15k
                        case MARK_ST_PICNUM_AS_LT_INDEX:
941
5.15k
                            u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
942
5.15k
                                                         pu4_bitstrm_buf);
943
5.15k
                            ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
944
5.15k
                            u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
945
5.15k
                                                   pu4_bitstrm_buf);
946
5.15k
                            ps_mmc_params->u4_lt_idx = u4_lt_idx;
947
5.15k
                            break;
948
949
7.73k
                        case SET_MAX_LT_INDEX:
950
7.73k
                        {
951
7.73k
                            u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst,
952
7.73k
                                                             pu4_bitstrm_buf);
953
7.73k
                            if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames)
954
4
                            {
955
                                /* Invalid max LT ref index */
956
4
                                return -1;
957
4
                            }
958
7.73k
                            ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1;
959
7.73k
                            break;
960
7.73k
                        }
961
5.03k
                        case RESET_REF_PICTURES:
962
5.03k
                        {
963
5.03k
                            ps_slice->u1_mmco_equalto5 = 1;
964
5.03k
                            break;
965
7.73k
                        }
966
967
7.80k
                        case SET_LT_INDEX:
968
7.80k
                            u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
969
7.80k
                                                   pu4_bitstrm_buf);
970
7.80k
                            ps_mmc_params->u4_lt_idx = u4_lt_idx;
971
7.80k
                            break;
972
973
6.47k
                        default:
974
6.47k
                            break;
975
50.6k
                    }
976
50.6k
                    u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
977
50.6k
                                         pu4_bitstrm_buf);
978
979
50.6k
                    j++;
980
50.6k
                }
981
21.8k
                ps_dpb_cmds->u1_num_of_commands = j;
982
21.8k
            }
983
58.2k
        }
984
81.0k
        ps_dpb_cmds->u1_dpb_commands_read = 1;
985
81.0k
        ps_dpb_cmds->u1_dpb_commands_read_slc = 1;
986
987
81.0k
    }
988
0
    u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst;
989
81.0k
    return u4_bit_ofst;
990
81.1k
}
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
 */
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
1.46k
{
1018
1.46k
    WORD32 i;
1019
1.46k
    UWORD8 u1_buf_mode, u1_marked_lt;
1020
1.46k
    struct dpb_info_t *ps_next_dpb;
1021
1.46k
    UWORD8 u1_num_gaps;
1022
1.46k
    UWORD8 u1_del_node = 1;
1023
1.46k
    UWORD8 u1_insert_st_pic = 1;
1024
1.46k
    WORD32 ret;
1025
1.46k
    UNUSED(u1_nal_unit_type);
1026
1.46k
    UNUSED(u2_u4_max_pic_num_minus1);
1027
1.46k
    u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive
1028
1.46k
    u1_marked_lt = 0;
1029
1.46k
    u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1030
1031
1.46k
    if(!u1_buf_mode)
1032
908
    {
1033
        //Sliding window - implements 8.2.5.3
1034
908
        if((ps_dpb_mgr->u1_num_st_ref_bufs
1035
908
                        + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps)
1036
908
                        == u1_numRef_frames_for_seq)
1037
517
        {
1038
517
            UWORD8 u1_new_node_flag = 1;
1039
517
            if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1040
45
            {
1041
45
                UWORD32 i4_error_code;
1042
45
                i4_error_code = ERROR_DBP_MANAGER_T;
1043
45
                return i4_error_code;
1044
45
            }
1045
1046
            // Chase the links to reach the last but one picNum, if available
1047
472
            ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1048
1049
472
            if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1050
25
            {
1051
25
                if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1052
15
                {
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
15
                    u1_new_node_flag = 0;
1058
15
                }
1059
1060
90
                for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1061
65
                {
1062
65
                    if(ps_next_dpb == NULL)
1063
0
                    {
1064
0
                        UWORD32 i4_error_code;
1065
0
                        i4_error_code = ERROR_DBP_MANAGER_T;
1066
0
                        return i4_error_code;
1067
0
                    }
1068
65
                    if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1069
34
                    {
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
34
                        u1_new_node_flag = 0;
1075
34
                    }
1076
65
                    ps_next_dpb = ps_next_dpb->ps_prev_short;
1077
65
                }
1078
1079
25
                if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1080
0
                {
1081
0
                    UWORD32 i4_error_code;
1082
0
                    i4_error_code = ERROR_DBP_MANAGER_T;
1083
0
                    return i4_error_code;
1084
0
                }
1085
1086
25
                if(u1_new_node_flag)
1087
8
                {
1088
8
                    if(u1_num_gaps)
1089
0
                    {
1090
0
                        ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1091
0
                                                            ps_next_dpb->ps_prev_short->i4_frame_num,
1092
0
                                                            &u1_del_node);
1093
0
                        if(ret != OK)
1094
0
                            return ret;
1095
0
                    }
1096
1097
8
                    if(u1_del_node)
1098
8
                    {
1099
8
                        ps_dpb_mgr->u1_num_st_ref_bufs--;
1100
8
                        ps_next_dpb->ps_prev_short->u1_used_as_ref =
1101
8
                                        UNUSED_FOR_REF;
1102
8
                        ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1103
8
                                        UNUSED_FOR_REF;
1104
8
                        ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1105
8
                                        UNUSED_FOR_REF;
1106
8
                        ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1107
8
                                                    ps_next_dpb->ps_prev_short->u1_buf_id);
1108
8
                        ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1109
8
                        ps_next_dpb->ps_prev_short = NULL;
1110
8
                    }
1111
8
                }
1112
25
            }
1113
447
            else
1114
447
            {
1115
447
                if(ps_dpb_mgr->u1_num_st_ref_bufs)
1116
396
                {
1117
396
                    ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1118
396
                                                       ps_next_dpb->i4_frame_num,
1119
396
                                                       &u1_del_node);
1120
396
                    if(ret != OK)
1121
0
                        return ret;
1122
396
                    if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1123
26
                                    && u1_del_node)
1124
26
                    {
1125
26
                        ps_dpb_mgr->u1_num_st_ref_bufs--;
1126
26
                        ps_next_dpb->u1_used_as_ref = FALSE;
1127
26
                        ps_next_dpb->s_top_field.u1_reference_info =
1128
26
                                        UNUSED_FOR_REF;
1129
26
                        ps_next_dpb->s_bot_field.u1_reference_info =
1130
26
                                        UNUSED_FOR_REF;
1131
26
                        ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1132
26
                                                    ps_next_dpb->u1_buf_id);
1133
26
                        ps_next_dpb->ps_pic_buf = NULL;
1134
26
                        ps_next_dpb->ps_prev_short = NULL;
1135
26
                        ps_dpb_mgr->ps_dpb_st_head = NULL;
1136
26
                        ps_next_dpb = NULL;
1137
26
                    }
1138
370
                    else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1139
370
                    {
1140
370
                        if(u1_curr_pic_in_err)
1141
0
                        {
1142
0
                            u1_insert_st_pic = 0;
1143
0
                        }
1144
370
                        else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1145
370
                        {
1146
370
                            ps_dpb_mgr->u1_num_st_ref_bufs--;
1147
370
                            ps_next_dpb->u1_used_as_ref = FALSE;
1148
370
                            ps_next_dpb->s_top_field.u1_reference_info =
1149
370
                                            UNUSED_FOR_REF;
1150
370
                            ps_next_dpb->s_bot_field.u1_reference_info =
1151
370
                                            UNUSED_FOR_REF;
1152
370
                            ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1153
370
                                                        ps_next_dpb->u1_buf_id);
1154
370
                            ps_next_dpb->ps_pic_buf = NULL;
1155
370
                            ps_next_dpb = NULL;
1156
370
                        }
1157
370
                    }
1158
396
                }
1159
51
                else
1160
51
                {
1161
51
                    ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1162
51
                                                        INVALID_FRAME_NUM,
1163
51
                                                        &u1_del_node);
1164
51
                    if(ret != OK)
1165
0
                        return ret;
1166
51
                    if(u1_del_node)
1167
3
                    {
1168
3
                        UWORD32 i4_error_code;
1169
3
                        i4_error_code = ERROR_DBP_MANAGER_T;
1170
3
                        return i4_error_code;
1171
3
                    }
1172
51
                }
1173
447
            }
1174
472
        }
1175
908
    }
1176
561
    else
1177
561
    {
1178
        //Adaptive memory control - implements 8.2.5.4
1179
561
        UWORD32 u4_mmco;
1180
561
        UWORD32 u4_diff_pic_num;
1181
561
        WORD32 i4_pic_num;
1182
561
        UWORD32 u4_lt_idx;
1183
561
        WORD32 j;
1184
561
        struct MMCParams *ps_mmc_params;
1185
1186
2.70k
        for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
1187
2.32k
        {
1188
2.32k
            ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
1189
2.32k
            u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO
1190
1191
2.32k
            switch(u4_mmco)
1192
2.32k
            {
1193
380
                case MARK_ST_PICNUM_AS_NONREF:
1194
380
                {
1195
1196
380
                    {
1197
380
                        UWORD32 i4_cur_pic_num = u4_cur_pic_num;
1198
380
                        WORD64 i8_pic_num;
1199
380
                        u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1200
380
                        if(u1_fld_pic_flag)
1201
343
                            i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
1202
380
                        i8_pic_num = ((WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1));
1203
380
                        if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1204
1
                        {
1205
1
                            return ERROR_DBP_MANAGER_T;
1206
1
                        }
1207
379
                        i4_pic_num = i8_pic_num;
1208
379
                    }
1209
1210
379
                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1211
322
                    {
1212
322
                        ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1213
322
                                                               i4_pic_num,
1214
322
                                                               MAX_REF_BUFS + 1,
1215
322
                                                               u1_fld_pic_flag);
1216
322
                        if(ret != OK)
1217
159
                            return ret;
1218
322
                    }
1219
57
                    else
1220
57
                    {
1221
57
                        UWORD8 u1_dummy;
1222
57
                        ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy);
1223
57
                        if(ret != OK)
1224
2
                            return ret;
1225
57
                    }
1226
218
                    break;
1227
379
                }
1228
276
                case MARK_LT_INDEX_AS_NONREF:
1229
276
                {
1230
276
                    WORD32 i4_status;
1231
276
                    u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1232
276
                    ret = ih264d_delete_lt_node(ps_dpb_mgr,
1233
276
                                                u4_lt_idx,
1234
276
                                                u1_fld_pic_flag,
1235
276
                                                0, &i4_status);
1236
276
                    if(ret != OK)
1237
0
                        return ret;
1238
276
                    if(i4_status)
1239
0
                    {
1240
0
                        UWORD32 i4_error_code;
1241
0
                        i4_error_code = ERROR_DBP_MANAGER_T;
1242
0
                        return i4_error_code;
1243
0
                    }
1244
276
                    break;
1245
276
                }
1246
1247
276
                case MARK_ST_PICNUM_AS_LT_INDEX:
1248
132
                {
1249
132
                    {
1250
132
                        UWORD32 i4_cur_pic_num = u4_cur_pic_num;
1251
132
                        WORD64 i8_pic_num;
1252
132
                        u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
1253
132
                        if(u1_fld_pic_flag)
1254
130
                            i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
1255
1256
132
                        i8_pic_num = (WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1);
1257
132
                        if(IS_OUT_OF_RANGE_S32(i8_pic_num))
1258
0
                        {
1259
0
                            return ERROR_DBP_MANAGER_T;
1260
0
                        }
1261
132
                        i4_pic_num = i8_pic_num;
1262
132
                    }
1263
1264
0
                    u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1265
1266
132
                    if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1267
132
                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1268
5
                    {
1269
5
                        return ERROR_DBP_MANAGER_T;
1270
5
                    }
1271
1272
127
                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1273
0
                    {
1274
0
                        ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1275
0
                                                               i4_pic_num, u4_lt_idx,
1276
0
                                                               u1_fld_pic_flag);
1277
0
                        if(ret != OK)
1278
0
                            return ret;
1279
0
                    }
1280
127
                    break;
1281
127
                }
1282
255
                case SET_MAX_LT_INDEX:
1283
255
                {
1284
255
                    UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
1285
255
                    u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
1286
255
                    if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx
1287
47
                                    && uc_numLT > 0)
1288
23
                    {
1289
23
                        struct dpb_info_t *ps_nxtDPB;
1290
                        //Set all LT buffers with index >= u4_lt_idx to nonreference
1291
23
                        ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head;
1292
23
                        ps_next_dpb = ps_nxtDPB->ps_prev_long;
1293
23
                        if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx)
1294
0
                        {
1295
0
                            i = 0;
1296
0
                            ps_dpb_mgr->ps_dpb_ht_head = NULL;
1297
0
                        }
1298
23
                        else
1299
23
                        {
1300
23
                            for(i = 1; i < uc_numLT; i++)
1301
23
                            {
1302
23
                                if(ps_next_dpb->u1_lt_idx >= u4_lt_idx)
1303
23
                                    break;
1304
0
                                ps_nxtDPB = ps_next_dpb;
1305
0
                                ps_next_dpb = ps_next_dpb->ps_prev_long;
1306
0
                            }
1307
23
                            ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max
1308
23
                        }
1309
23
                        ps_dpb_mgr->u1_num_lt_ref_bufs = i;
1310
23
                        if(i == 0)
1311
0
                            ps_next_dpb = ps_nxtDPB;
1312
1313
46
                        for(; i < uc_numLT; i++)
1314
23
                        {
1315
23
                            ps_nxtDPB = ps_next_dpb;
1316
23
                            ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1;
1317
23
                            ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF;
1318
23
                            ps_nxtDPB->s_top_field.u1_reference_info =
1319
23
                                            UNUSED_FOR_REF;
1320
23
                            ps_nxtDPB->s_bot_field.u1_reference_info =
1321
23
                                            UNUSED_FOR_REF;
1322
1323
23
                            ps_nxtDPB->ps_pic_buf = NULL;
1324
                            //Release buffer
1325
23
                            ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1326
23
                                                        ps_nxtDPB->u1_buf_id);
1327
23
                            ps_next_dpb = ps_nxtDPB->ps_prev_long;
1328
23
                            ps_nxtDPB->ps_prev_long = NULL;
1329
23
                        }
1330
23
                    }
1331
255
                    if(u4_lt_idx == 0)
1332
5
                    {
1333
5
                        ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
1334
5
                    }
1335
250
                    else
1336
250
                    {
1337
250
                        ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
1338
250
                    }
1339
1340
255
                    break;
1341
127
                }
1342
297
                case SET_LT_INDEX:
1343
297
                {
1344
297
                    u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
1345
297
                    if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
1346
293
                        (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
1347
4
                    {
1348
4
                        return ERROR_DBP_MANAGER_T;
1349
4
                    }
1350
293
                    ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1351
293
                                          u4_cur_pic_num);
1352
293
                    if(ret != OK)
1353
0
                        return ret;
1354
1355
293
                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
1356
1357
293
                    {
1358
293
                        ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
1359
293
                                                               u4_cur_pic_num,
1360
293
                                                               u4_lt_idx,
1361
293
                                                               u1_fld_pic_flag);
1362
293
                        if(ret != OK)
1363
12
                            return ret;
1364
293
                    }
1365
0
                    else
1366
0
                    {
1367
0
                        return ERROR_DBP_MANAGER_T;
1368
0
                    }
1369
1370
281
                    u1_marked_lt = 1;
1371
281
                    break;
1372
293
                }
1373
1374
982
                default:
1375
982
                    break;
1376
2.32k
            }
1377
2.13k
            if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES)
1378
415
            {
1379
415
                ih264d_reset_ref_bufs(ps_dpb_mgr);
1380
415
                u4_cur_pic_num = 0;
1381
415
            }
1382
2.13k
        }
1383
561
    }
1384
1.23k
    if(!u1_marked_lt && u1_insert_st_pic)
1385
1.09k
    {
1386
1.09k
        ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
1387
1.09k
                              u4_cur_pic_num);
1388
1.09k
        if(ret != OK)
1389
41
            return ret;
1390
1.09k
    }
1391
1.19k
    return OK;
1392
1.23k
}
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
/*****************************************************************************/
1415
void ih264d_release_pics_in_dpb(void *pv_dec,
1416
                                UWORD8 u1_disp_bufs)
1417
0
{
1418
0
    WORD8 i;
1419
0
    dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
1420
1421
0
    for(i = 0; i < u1_disp_bufs; i++)
1422
0
    {
1423
0
        ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
1424
0
                              i,
1425
0
                              BUF_MGR_REF);
1426
0
        ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
1427
0
                              ps_dec->as_buf_id_info_map[i].mv_buf_id,
1428
0
                              BUF_MGR_REF);
1429
0
    }
1430
0
}
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
/*****************************************************************************/
1457
WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr,
1458
                                    WORD32 i4_frame_num,
1459
                                    UWORD8 *pu1_del_node)
1460
4.46M
{
1461
4.46M
    WORD8 i1_gap_idx, i, j, j_min;
1462
4.46M
    WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
1463
4.46M
    WORD32 i4_start_frm_num, i4_end_frm_num;
1464
4.46M
    WORD32 i4_max_frm_num;
1465
4.46M
    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
4.46M
    *pu1_del_node = 1;
1470
4.46M
    if(0 == ps_dpb_mgr->u1_num_gaps)
1471
354
        return OK;
1472
4.46M
    pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
1473
4.46M
    pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
1474
4.46M
    i4_gap_frame_num = INVALID_FRAME_NUM;
1475
4.46M
    i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1476
1477
4.46M
    i1_gap_idx = -1;
1478
4.46M
    if(INVALID_FRAME_NUM != i4_frame_num)
1479
1.72k
    {
1480
1.72k
        i4_gap_frame_num = i4_frame_num;
1481
29.2k
        for(i = 0; i < MAX_FRAMES; i++)
1482
27.5k
        {
1483
27.5k
            i4_start_frm_num = pi4_gaps_start_frm_num[i];
1484
27.5k
            if(INVALID_FRAME_NUM != i4_start_frm_num)
1485
3.52k
            {
1486
3.52k
                i4_end_frm_num = pi4_gaps_end_frm_num[i];
1487
3.52k
                if(i4_end_frm_num < i4_max_frm_num)
1488
3.52k
                {
1489
3.52k
                    if(i4_start_frm_num <= i4_gap_frame_num)
1490
3.20k
                    {
1491
3.20k
                        i4_gap_frame_num = i4_start_frm_num;
1492
3.20k
                        i1_gap_idx = i;
1493
3.20k
                    }
1494
3.52k
                }
1495
0
                else
1496
0
                {
1497
0
                    if(((i4_start_frm_num <= i4_gap_frame_num)
1498
0
                                    && (i4_gap_frame_num <= i4_max_frm_num))
1499
0
                                    || ((i4_start_frm_num >= i4_gap_frame_num)
1500
0
                                                    && ((i4_gap_frame_num
1501
0
                                                                    + i4_max_frm_num)
1502
0
                                                                    >= i4_end_frm_num)))
1503
0
                    {
1504
0
                        i4_gap_frame_num = i4_start_frm_num;
1505
0
                        i1_gap_idx = i;
1506
0
                    }
1507
0
                }
1508
3.52k
            }
1509
27.5k
        }
1510
1.72k
    }
1511
4.46M
    else
1512
4.46M
    {
1513
        /* no valid short term buffers, delete one gap from the least start */
1514
        /* of gap sequence                                                  */
1515
4.46M
        i4_gap_frame_num = pi4_gaps_start_frm_num[0];
1516
4.46M
        i1_gap_idx = 0;
1517
71.4M
        for(i = 1; i < MAX_FRAMES; i++)
1518
66.9M
        {
1519
66.9M
            if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
1520
2.23M
            {
1521
2.23M
                if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
1522
2.22M
                {
1523
2.22M
                    i4_gap_frame_num = pi4_gaps_start_frm_num[i];
1524
2.22M
                    i1_gap_idx = i;
1525
2.22M
                }
1526
2.23M
            }
1527
66.9M
        }
1528
4.46M
        if(INVALID_FRAME_NUM == i4_gap_frame_num)
1529
31
        {
1530
31
            UWORD32 i4_error_code;
1531
31
            i4_error_code = ERROR_DBP_MANAGER_T;
1532
31
            return i4_error_code;
1533
31
        }
1534
4.46M
    }
1535
1536
4.46M
    if(-1 != i1_gap_idx)
1537
4.46M
    {
1538
        /* find least frame_num in the poc_map, which is in this range */
1539
4.46M
        i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
1540
4.46M
        if(i4_start_frm_num < 0)
1541
1.05k
            i4_start_frm_num += i4_max_frm_num;
1542
4.46M
        i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
1543
4.46M
        if(i4_end_frm_num < 0)
1544
4.43M
            i4_end_frm_num += i4_max_frm_num;
1545
1546
4.46M
        i4_gap_frm_num_min = 0xfffffff;
1547
4.46M
        j_min = MAX_FRAMES;
1548
75.9M
        for(j = 0; j < MAX_FRAMES; j++)
1549
71.4M
        {
1550
71.4M
            i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2];
1551
71.4M
            if((i4_start_frm_num <= i4_frm_num)
1552
66.9M
                            && (i4_end_frm_num >= i4_frm_num))
1553
66.7M
            {
1554
66.7M
                if(i4_frm_num < i4_gap_frm_num_min)
1555
5.57M
                {
1556
5.57M
                    j_min = j;
1557
5.57M
                    i4_gap_frm_num_min = i4_frm_num;
1558
5.57M
                }
1559
66.7M
            }
1560
71.4M
        }
1561
1562
4.46M
        if(j_min != MAX_FRAMES)
1563
4.46M
        {
1564
1565
4.46M
            ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1;
1566
4.46M
            ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff;
1567
4.46M
            ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM;
1568
4.46M
            ps_dpb_mgr->i1_gaps_deleted++;
1569
1570
4.46M
            ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
1571
4.46M
            ps_dpb_mgr->u1_num_gaps--;
1572
4.46M
            *pu1_del_node = 0;
1573
4.46M
            if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
1574
296
            {
1575
296
                ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] =
1576
296
                INVALID_FRAME_NUM;
1577
296
                ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
1578
296
            }
1579
4.46M
        }
1580
4.46M
    }
1581
1582
4.46M
    return OK;
1583
4.46M
}
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
/*****************************************************************************/
1611
WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr,
1612
                                  WORD32 i4_frame_num,
1613
                                  UWORD8 *pu1_del_node)
1614
320
{
1615
320
    WORD8 i, j;
1616
320
    WORD32 *pi4_start, *pi4_end;
1617
320
    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
320
    *pu1_del_node = 1;
1622
320
    pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
1623
320
    pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
1624
320
    i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
1625
1626
320
    if(0 == ps_dpb_mgr->u1_num_gaps)
1627
55
        return OK;
1628
1629
265
    if(i4_frame_num < 0)
1630
0
        i4_frame_num += i4_max_frm_num;
1631
395
    for(i = 0; i < MAX_FRAMES; i++)
1632
394
    {
1633
394
        i4_start_frm_num = pi4_start[i];
1634
394
        if(i4_start_frm_num < 0)
1635
1
            i4_start_frm_num += i4_max_frm_num;
1636
394
        if(INVALID_FRAME_NUM != i4_start_frm_num)
1637
385
        {
1638
385
            i4_end_frm_num = pi4_end[i];
1639
385
            if(i4_end_frm_num < 0)
1640
8
                i4_end_frm_num += i4_max_frm_num;
1641
1642
385
            if((i4_frame_num >= i4_start_frm_num)
1643
385
                            && (i4_frame_num <= i4_end_frm_num))
1644
264
            {
1645
264
                break;
1646
264
            }
1647
121
            else
1648
121
            {
1649
121
                if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num)
1650
121
                                && ((i4_frame_num + i4_max_frm_num)
1651
121
                                                <= i4_end_frm_num))
1652
0
                {
1653
0
                    UWORD32 i4_error_code;
1654
0
                    i4_error_code = ERROR_DBP_MANAGER_T;
1655
0
                    return i4_error_code;
1656
0
                }
1657
121
            }
1658
385
        }
1659
394
    }
1660
1661
    /* find frame_num index, in the poc_map which needs to be deleted */
1662
3.89k
    for(j = 0; j < MAX_FRAMES; j++)
1663
3.76k
    {
1664
3.76k
        if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2])
1665
136
            break;
1666
3.76k
    }
1667
1668
265
    if(MAX_FRAMES != i)
1669
264
    {
1670
264
        if(j == MAX_FRAMES)
1671
128
        {
1672
128
            UWORD32 i4_error_code;
1673
128
            i4_error_code = ERROR_DBP_MANAGER_T;
1674
128
            return i4_error_code;
1675
128
        }
1676
1677
136
        ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1;
1678
136
        ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff;
1679
136
        ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM;
1680
136
        ps_dpb_mgr->i1_gaps_deleted++;
1681
1682
136
        ps_dpb_mgr->ai1_gaps_per_seq[i]--;
1683
136
        ps_dpb_mgr->u1_num_gaps--;
1684
136
        *pu1_del_node = 0;
1685
136
        if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
1686
9
        {
1687
9
            ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
1688
9
            ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
1689
9
        }
1690
136
    }
1691
1
    else
1692
1
    {
1693
1
        UWORD32 i4_error_code;
1694
1
        i4_error_code = ERROR_DBP_MANAGER_T;
1695
1
        return i4_error_code;
1696
1
    }
1697
1698
136
    return OK;
1699
265
}
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
 */
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
4.47M
{
1720
4.47M
    struct dpb_info_t *ps_next_dpb;
1721
4.47M
    UWORD8 u1_num_gaps;
1722
4.47M
    UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node;
1723
4.47M
    WORD8 i;
1724
4.47M
    WORD32 i4_frame_gaps = 1;
1725
4.47M
    WORD32 ret;
1726
1727
    //Sliding window - implements 8.2.5.3, flush out buffers
1728
4.47M
    u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
1729
4.47M
    u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
1730
1731
8.94M
    while(1)
1732
8.94M
    {
1733
8.94M
        u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1734
8.94M
        if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps)
1735
8.94M
                        > u1_num_ref_frames)
1736
4.46M
        {
1737
4.46M
            if(0 == (u1_st_ref_bufs + u1_num_gaps))
1738
1.44k
            {
1739
1.44k
                i4_frame_gaps = 0;
1740
1.44k
                ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames
1741
1.44k
                                - u1_lt_ref_bufs);
1742
1.44k
            }
1743
4.46M
            else
1744
4.46M
            {
1745
4.46M
                u1_del_node = 1;
1746
4.46M
                ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1747
1748
4.46M
                if(u1_st_ref_bufs > 1)
1749
176
                {
1750
197
                    for(i = 1; i < (u1_st_ref_bufs - 1); i++)
1751
21
                    {
1752
21
                        if(ps_next_dpb == NULL)
1753
0
                        {
1754
0
                            UWORD32 i4_error_code;
1755
0
                            i4_error_code = ERROR_DBP_MANAGER_T;
1756
0
                            return i4_error_code;
1757
0
                        }
1758
21
                        ps_next_dpb = ps_next_dpb->ps_prev_short;
1759
21
                    }
1760
1761
176
                    if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1762
133
                    {
1763
133
                        return ERROR_DBP_MANAGER_T;
1764
133
                    }
1765
1766
43
                    if(u1_num_gaps)
1767
40
                    {
1768
40
                        ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1769
40
                                                            ps_next_dpb->ps_prev_short->i4_frame_num,
1770
40
                                                            &u1_del_node);
1771
40
                        if(ret != OK)
1772
0
                            return ret;
1773
40
                    }
1774
1775
43
                    if(u1_del_node)
1776
17
                    {
1777
17
                        u1_st_ref_bufs--;
1778
17
                        ps_next_dpb->ps_prev_short->u1_used_as_ref =
1779
17
                                        UNUSED_FOR_REF;
1780
17
                        ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1781
17
                                        UNUSED_FOR_REF;
1782
17
                        ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1783
17
                                        UNUSED_FOR_REF;
1784
17
                        ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1785
17
                                                    ps_next_dpb->ps_prev_short->u1_buf_id);
1786
17
                        ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1787
17
                        ps_next_dpb->ps_prev_short = NULL;
1788
17
                    }
1789
43
                }
1790
4.46M
                else
1791
4.46M
                {
1792
4.46M
                    if(u1_st_ref_bufs)
1793
1.79k
                    {
1794
1.79k
                        if(u1_num_gaps)
1795
1.63k
                        {
1796
1.63k
                            ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1797
1.63k
                                                                ps_next_dpb->i4_frame_num,
1798
1.63k
                                                                &u1_del_node);
1799
1.63k
                            if(ret != OK)
1800
0
                                return ret;
1801
1.63k
                        }
1802
1803
1.79k
                        if(u1_del_node)
1804
201
                        {
1805
201
                            u1_st_ref_bufs--;
1806
201
                            ps_next_dpb->u1_used_as_ref = FALSE;
1807
201
                            ps_next_dpb->s_top_field.u1_reference_info =
1808
201
                                            UNUSED_FOR_REF;
1809
201
                            ps_next_dpb->s_bot_field.u1_reference_info =
1810
201
                                            UNUSED_FOR_REF;
1811
201
                            ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1812
201
                                                        ps_next_dpb->u1_buf_id);
1813
201
                            ps_next_dpb->ps_pic_buf = NULL;
1814
201
                            ps_next_dpb = NULL;
1815
201
                            ps_dpb_mgr->ps_dpb_st_head = NULL;
1816
201
                            ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1817
201
                        }
1818
1.79k
                    }
1819
4.46M
                    else
1820
4.46M
                    {
1821
4.46M
                        ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1822
4.46M
                                                            INVALID_FRAME_NUM,
1823
4.46M
                                                            &u1_del_node);
1824
4.46M
                        if(ret != OK)
1825
31
                            return ret;
1826
4.46M
                        if(u1_del_node)
1827
39
                        {
1828
39
                            return ERROR_DBP_MANAGER_T;
1829
39
                        }
1830
4.46M
                    }
1831
4.46M
                }
1832
4.46M
            }
1833
4.46M
        }
1834
4.47M
        else
1835
4.47M
        {
1836
4.47M
            ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
1837
4.47M
            break;
1838
4.47M
        }
1839
8.94M
    }
1840
1841
4.47M
    ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
1842
1843
4.47M
    return OK;
1844
4.47M
}
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 *****/
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
0
{
1873
0
    WORD32 i;
1874
0
    UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
1875
0
    struct dpb_info_t *ps_next_dpb;
1876
0
    UWORD8 u1_del_node = 1;
1877
0
    WORD32 ret;
1878
1879
    //Sliding window - implements 8.2.5.3
1880
0
    if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs
1881
0
                    + u1_num_gaps) == u1_numRef_frames_for_seq)
1882
0
    {
1883
0
        UWORD8 u1_new_node_flag = 1;
1884
0
        if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
1885
0
        {
1886
0
            return ERROR_DBP_MANAGER_T;
1887
0
        }
1888
1889
        // Chase the links to reach the last but one picNum, if available
1890
0
        ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
1891
1892
0
        if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
1893
0
        {
1894
0
            if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1895
0
            {
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
0
                u1_new_node_flag = 0;
1901
0
            }
1902
1903
0
            for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
1904
0
            {
1905
0
                if(ps_next_dpb == NULL)
1906
0
                    return ERROR_DBP_MANAGER_T;
1907
1908
0
                if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
1909
0
                {
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
0
                    u1_new_node_flag = 0;
1915
0
                }
1916
0
                ps_next_dpb = ps_next_dpb->ps_prev_short;
1917
0
            }
1918
1919
0
            if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
1920
0
                return ERROR_DBP_MANAGER_T;
1921
1922
0
            if(u1_new_node_flag)
1923
0
            {
1924
0
                if(u1_num_gaps)
1925
0
                {
1926
0
                    ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1927
0
                                                        ps_next_dpb->ps_prev_short->i4_frame_num,
1928
0
                                                        &u1_del_node);
1929
0
                    if(ret != OK)
1930
0
                        return ret;
1931
0
                }
1932
1933
0
                if(u1_del_node)
1934
0
                {
1935
0
                    ps_dpb_mgr->u1_num_st_ref_bufs--;
1936
0
                    ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF;
1937
0
                    ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
1938
0
                                    UNUSED_FOR_REF;
1939
0
                    ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
1940
0
                                    UNUSED_FOR_REF;
1941
0
                    ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1942
0
                                                ps_next_dpb->ps_prev_short->u1_buf_id);
1943
0
                    ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
1944
0
                    ps_next_dpb->ps_prev_short = NULL;
1945
0
                }
1946
0
            }
1947
0
        }
1948
0
        else
1949
0
        {
1950
0
            if(ps_dpb_mgr->u1_num_st_ref_bufs)
1951
0
            {
1952
0
                ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
1953
0
                                                    ps_next_dpb->i4_frame_num,
1954
0
                                                    &u1_del_node);
1955
0
                if(ret != OK)
1956
0
                    return ret;
1957
0
                if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
1958
0
                                && u1_del_node)
1959
0
                {
1960
0
                    ps_dpb_mgr->u1_num_st_ref_bufs--;
1961
0
                    ps_next_dpb->u1_used_as_ref = FALSE;
1962
0
                    ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
1963
0
                    ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
1964
0
                    ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
1965
0
                                                ps_next_dpb->u1_buf_id);
1966
0
                    ps_next_dpb->ps_pic_buf = NULL;
1967
0
                    ps_next_dpb = NULL;
1968
0
                }
1969
0
            }
1970
0
            else
1971
0
            {
1972
0
                ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
1973
0
                if(ret != OK)
1974
0
                    return ret;
1975
0
                if(u1_del_node)
1976
0
                    return ERROR_DBP_MANAGER_T;
1977
0
            }
1978
0
        }
1979
0
    }
1980
0
    return OK;
1981
0
}
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
2005
void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr)
2006
8.95M
{
2007
8.95M
    WORD8 i;
2008
8.95M
    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
21.0M
    for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
2012
12.1M
    {
2013
12.1M
        if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
2014
4.46M
        {
2015
4.46M
            ps_dpb_mgr->i1_gaps_deleted--;
2016
4.46M
            ps_dpb_mgr->i1_poc_buf_id_entries--;
2017
4.46M
            i4_poc_buf_id_map[i][0] = -1;
2018
4.46M
            i4_poc_buf_id_map[i][1] = 0x7fffffff;
2019
4.46M
            i4_poc_buf_id_map[i][2] = 0;
2020
4.46M
        }
2021
12.1M
    }
2022
8.95M
}
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
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
4.48M
{
2051
4.48M
    WORD8 i;
2052
4.48M
    WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
2053
2054
12.2M
    for(i = 0; i < MAX_FRAMES; i++)
2055
12.2M
    {
2056
        /* Find an empty slot */
2057
12.2M
        if(i4_poc_buf_id_map[i][0] == -1)
2058
4.48M
        {
2059
4.48M
            if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
2060
0
                ps_dpb_mgr->i1_gaps_deleted--;
2061
4.48M
            else
2062
4.48M
                ps_dpb_mgr->i1_poc_buf_id_entries++;
2063
2064
4.48M
            i4_poc_buf_id_map[i][0] = u1_buf_id;
2065
4.48M
            i4_poc_buf_id_map[i][1] = i4_display_poc;
2066
4.48M
            i4_poc_buf_id_map[i][2] = u4_frame_num;
2067
2068
4.48M
            break;
2069
4.48M
        }
2070
12.2M
    }
2071
2072
4.48M
    if(MAX_FRAMES == i)
2073
63
    {
2074
2075
63
        UWORD32 i4_error_code;
2076
63
        i4_error_code = ERROR_GAPS_IN_FRM_NUM;
2077
63
        return i4_error_code;
2078
63
    }
2079
4.48M
    return OK;
2080
4.48M
}
2081