Coverage Report

Created: 2025-07-09 06:41

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