Coverage Report

Created: 2025-07-11 06:39

/src/libavc/common/ih264_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
21
/**
22
*******************************************************************************
23
* @file
24
*  ih264_dpb_mgr.c
25
*
26
* @brief
27
*  Function definitions used for decoded picture buffer management
28
*
29
* @author
30
*  ittiam
31
*
32
* @par List of Functions:
33
*  - ih264_dpb_mgr_init
34
*  - ih264_dpb_mgr_sort_short_term_fields_by_frame_num
35
*  - ih264_dpb_mgr_sort_short_term_fields_by_poc_l0
36
*  - ih264_dpb_mgr_sort_short_term_fields_by_poc_l1
37
*  - ih264_dpb_mgr_sort_long_term_fields_by_frame_idx
38
*  - ih264_dpb_mgr_alternate_ref_fields
39
*  - ih264_dpb_mgr_insert_ref_field
40
*  - ih264_dpb_mgr_insert_ref_frame
41
*  - ih264_dpb_mgr_count_ref_frames
42
*  - ih264_dpb_mgr_delete_ref_frame
43
*  - ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx
44
*  - ih264_dpb_mgr_delete_short_ref_frame
45
*  - ih264_dpb_mgr_delete_all_ref_frames
46
*  - ih264_dpb_mgr_reset
47
*  - ih264_dpb_mgr_release_pics
48
*
49
* @remarks
50
*  none
51
*
52
*******************************************************************************
53
*/
54
55
/*****************************************************************************/
56
/* File Includes                                                             */
57
/*****************************************************************************/
58
59
/* System Include Files */
60
#include <stdio.h>
61
#include <stdlib.h>
62
#include <assert.h>
63
64
/* User Include Files */
65
#include "ih264_typedefs.h"
66
#include "ih264_debug.h"
67
#include "ih264_macros.h"
68
#include "ih264_error.h"
69
#include "ih264_defs.h"
70
#include "ih264_structs.h"
71
#include "ih264_buf_mgr.h"
72
#include "ih264_dpb_mgr.h"
73
74
75
/*****************************************************************************/
76
/* Function Definitions                                                      */
77
/*****************************************************************************/
78
79
/**
80
*******************************************************************************
81
*
82
* @brief DPB manager initializer
83
*
84
* @par Description Initialises the DPB manager structure
85
*
86
* @param[in] ps_dpb_mgr
87
*  Pointer to the DPB manager structure
88
*
89
* @returns
90
*
91
* @remarks
92
*
93
*******************************************************************************
94
*/
95
void ih264_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr)
96
9.90k
{
97
9.90k
    UWORD32 i;
98
9.90k
    dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
99
100
643k
    for(i = 0; i < MAX_DPB_BUFS; i++)
101
633k
    {
102
633k
        ps_dpb_info[i].ps_prev_dpb = NULL;
103
633k
        ps_dpb_info[i].ps_pic_buf = NULL;
104
633k
        ps_dpb_mgr->as_top_field_pics[i].i4_used_as_ref = INVALID;
105
633k
        ps_dpb_mgr->as_bottom_field_pics[i].i4_used_as_ref = INVALID;
106
633k
        ps_dpb_mgr->as_top_field_pics[i].i1_field_type = INVALID;
107
633k
        ps_dpb_mgr->as_bottom_field_pics[i].i1_field_type = INVALID;
108
633k
        ps_dpb_mgr->as_top_field_pics[i].i4_long_term_frame_idx = -1;
109
633k
        ps_dpb_mgr->as_bottom_field_pics[i].i4_long_term_frame_idx = -1;
110
633k
    }
111
9.90k
    ps_dpb_mgr->u1_num_short_term_ref_bufs = 0;
112
9.90k
    ps_dpb_mgr->u1_num_long_term_ref_bufs = 0;
113
9.90k
    ps_dpb_mgr->ps_dpb_short_term_head = NULL;
114
9.90k
    ps_dpb_mgr->ps_dpb_long_term_head = NULL;
115
9.90k
}
116
117
/**
118
*******************************************************************************
119
*
120
* @brief
121
*  Function to sort short term pics by frame_num.
122
*
123
* @par Description:
124
*  Sorts short term fields by frame_num. For 2 fields having same frame_num,
125
*  orders them based on requested first field type.
126
*
127
* @param[in] ps_dpb_mgr
128
*  Pointer to the DPB manager structure
129
*
130
* @param[in] curr_frame_num
131
*  frame_num of the current pic
132
*
133
* @param[in] first_field_type
134
*  For complementary fields, required first field
135
*
136
* @param[in] max_frame_num
137
*  Maximum frame_num allowed
138
*
139
* @returns
140
*
141
* @remarks
142
*
143
*
144
*******************************************************************************
145
*/
146
WORD32 ih264_dpb_mgr_sort_short_term_fields_by_frame_num(dpb_mgr_t *ps_dpb_mgr,
147
                                                         WORD32 curr_frame_num,
148
                                                         WORD32 first_field_type,
149
                                                         WORD32 max_frame_num)
150
0
{
151
0
    dpb_info_t *ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
152
0
    dpb_info_t *ps_dpb_node2;
153
0
    WORD32 frame_num_node1;
154
0
    WORD32 frame_num_node2;
155
0
    pic_buf_t *ps_pic_buf;
156
157
0
    if(ps_dpb_node1 == NULL)
158
0
        return -1;
159
160
0
    for (; ps_dpb_node1 != NULL; ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb)
161
0
    {
162
0
        for (ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb; ps_dpb_node2 != NULL; ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb)
163
0
        {
164
0
            frame_num_node1 = ps_dpb_node1->ps_pic_buf->i4_frame_num;
165
0
            frame_num_node2 = ps_dpb_node2->ps_pic_buf->i4_frame_num;
166
167
0
            if(frame_num_node1 > curr_frame_num)
168
0
                frame_num_node1 = frame_num_node1 - max_frame_num;
169
0
            if(frame_num_node2 > curr_frame_num)
170
0
                frame_num_node2 = frame_num_node2 - max_frame_num;
171
172
0
            if(frame_num_node1 < frame_num_node2)
173
0
            {
174
0
                ps_pic_buf = ps_dpb_node1->ps_pic_buf;
175
0
                ps_dpb_node1->ps_pic_buf = ps_dpb_node2->ps_pic_buf;
176
0
                ps_dpb_node2->ps_pic_buf = ps_pic_buf;
177
0
            }
178
0
        }
179
0
    }
180
181
    /**
182
     * For frames and complementary field pairs,
183
     * ensure first_field_type appears first in the list
184
     */
185
0
    ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
186
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
187
0
    while(ps_dpb_node2 != NULL)
188
0
    {
189
0
        pic_buf_t *ps_pic_node1 = ps_dpb_node1->ps_pic_buf;
190
0
        pic_buf_t *ps_pic_node2 = ps_dpb_node2->ps_pic_buf;
191
0
        frame_num_node1 = ps_pic_node1->i4_frame_num;
192
0
        frame_num_node2 = ps_pic_node2->i4_frame_num;
193
0
        if(frame_num_node1 == frame_num_node2)
194
0
        {
195
0
            ASSERT(ps_pic_node1->i1_field_type != ps_pic_node2->i1_field_type);
196
0
            if(ps_pic_node1->i1_field_type != first_field_type)
197
0
            {
198
0
                ps_dpb_node1->ps_pic_buf = ps_pic_node2;
199
0
                ps_dpb_node2->ps_pic_buf = ps_pic_node1;
200
0
            }
201
0
        }
202
0
        ps_dpb_node1 = ps_dpb_node2;
203
0
        ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb;
204
0
    }
205
0
    return 0;
206
0
}
207
208
/**
209
*******************************************************************************
210
*
211
* @brief
212
*  Function to sort sort term pics by poc for list 0.
213
*
214
* @par Description:
215
*  Orders all the pocs less than current poc in the descending order.
216
*  Then orders all the pocs greater than current poc in the ascending order.
217
*
218
* @param[in] ps_dpb_mgr
219
*  Pointer to the DPB manager structure
220
*
221
* @param[in] curr_poc
222
*  Poc of the current pic
223
*
224
* @param[in] first_field_type
225
*  For complementary fields, required first field
226
*
227
* @returns
228
*
229
* @remarks
230
*
231
*******************************************************************************
232
*/
233
WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l0(dpb_mgr_t *ps_dpb_mgr,
234
                                                      WORD32 curr_poc,
235
                                                      WORD32 first_field_type)
236
0
{
237
0
    dpb_info_t *ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
238
0
    dpb_info_t *ps_dpb_node2;
239
0
    WORD32 poc_node1;
240
0
    WORD32 poc_node2;
241
0
    WORD32 frame_num_node1;
242
0
    WORD32 frame_num_node2;
243
0
    pic_buf_t *ps_pic_buf;
244
245
0
    if(ps_dpb_node1 == NULL)
246
0
        return -1;
247
248
    /**
249
     * Sort the fields by poc.
250
     * All POCs less than current poc are first placed in the descending order.
251
     * Then all POCs greater than current poc are placed in the ascending order.
252
     */
253
0
    for (; ps_dpb_node1 != NULL; ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb)
254
0
    {
255
0
        for (ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb; ps_dpb_node2 != NULL; ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb)
256
0
        {
257
0
            poc_node1 = ps_dpb_node1->ps_pic_buf->i4_abs_poc;
258
0
            poc_node2 = ps_dpb_node2->ps_pic_buf->i4_abs_poc;
259
0
            ASSERT(poc_node1 != curr_poc);
260
0
            ASSERT(poc_node2 != curr_poc);
261
0
            if(((poc_node1 < curr_poc) && (poc_node2 > curr_poc)) ||
262
0
                    ((poc_node1 < curr_poc) && (poc_node2 < curr_poc) && (poc_node1 > poc_node2)) ||
263
0
                    ((poc_node1 > curr_poc) && (poc_node2 > curr_poc) && (poc_node1 < poc_node2)))
264
0
                    continue;
265
266
0
            ps_pic_buf = ps_dpb_node1->ps_pic_buf;
267
0
            ps_dpb_node1->ps_pic_buf = ps_dpb_node2->ps_pic_buf;
268
0
            ps_dpb_node2->ps_pic_buf = ps_pic_buf;
269
0
        }
270
0
    }
271
272
0
    ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
273
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
274
0
    while(ps_dpb_node2 != NULL)
275
0
    {
276
0
        pic_buf_t *ps_pic_node1 = ps_dpb_node1->ps_pic_buf;
277
0
        pic_buf_t *ps_pic_node2 = ps_dpb_node2->ps_pic_buf;
278
0
        frame_num_node1 = ps_pic_node1->i4_frame_num;
279
0
        frame_num_node2 = ps_pic_node2->i4_frame_num;
280
0
        if(frame_num_node1 == frame_num_node2)
281
0
        {
282
0
            ASSERT(ps_pic_node1->i1_field_type != ps_pic_node2->i1_field_type);
283
0
            if(ps_pic_node1->i1_field_type != first_field_type)
284
0
            {
285
0
                ps_dpb_node1->ps_pic_buf = ps_pic_node2;
286
0
                ps_dpb_node2->ps_pic_buf = ps_pic_node1;
287
0
            }
288
0
        }
289
0
        ps_dpb_node1 = ps_dpb_node2;
290
0
        ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb;
291
0
    }
292
0
    return 0;
293
0
}
294
295
/**
296
*******************************************************************************
297
*
298
* @brief
299
*  Function to sort sort term pics by poc for list 1.
300
*
301
* @par Description:
302
*  Orders all the pocs greater than current poc in the ascending order.
303
*  Then rrders all the pocs less than current poc in the descending order.
304
*
305
* @param[in] ps_dpb_mgr
306
*  Pointer to the DPB manager structure
307
*
308
* @param[in] curr_poc
309
*  Poc of the current pic
310
*
311
* @param[in] first_field_type
312
*  For complementary fields, required first field
313
*
314
* @returns
315
*
316
* @remarks
317
*
318
*
319
*******************************************************************************
320
*/
321
WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l1(dpb_mgr_t *ps_dpb_mgr,
322
                                                      WORD32 curr_poc,
323
                                                      WORD32 first_field_type)
324
0
{
325
0
    dpb_info_t *ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
326
0
    dpb_info_t *ps_dpb_node2;
327
0
    WORD32 poc_node1;
328
0
    WORD32 poc_node2;
329
0
    WORD32 frame_num_node1;
330
0
    WORD32 frame_num_node2;
331
0
    pic_buf_t *ps_pic_buf;
332
333
0
    if(ps_dpb_node1 == NULL)
334
0
        return -1;
335
336
    /**
337
     * Sort the fields by poc.
338
     * All POCs greater than current poc are first placed in the ascending order.
339
     * Then all POCs less than current poc are placed in the decending order.
340
     */
341
0
    for (; ps_dpb_node1 != NULL; ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb)
342
0
    {
343
0
        for (ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb; ps_dpb_node2 != NULL; ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb)
344
0
        {
345
0
            poc_node1 = ps_dpb_node1->ps_pic_buf->i4_abs_poc;
346
0
            poc_node2 = ps_dpb_node2->ps_pic_buf->i4_abs_poc;
347
0
            ASSERT(poc_node1 != curr_poc);
348
0
            ASSERT(poc_node2 != curr_poc);
349
0
            if(((poc_node1 > curr_poc) && (poc_node2 < curr_poc)) ||
350
0
                    ((poc_node1 < curr_poc) && (poc_node2 < curr_poc) && (poc_node1 > poc_node2)) ||
351
0
                    ((poc_node1 > curr_poc) && (poc_node2 > curr_poc) && (poc_node1 < poc_node2)))
352
0
                    continue;
353
354
0
            ps_pic_buf = ps_dpb_node1->ps_pic_buf;
355
0
            ps_dpb_node1->ps_pic_buf = ps_dpb_node2->ps_pic_buf;
356
0
            ps_dpb_node2->ps_pic_buf = ps_pic_buf;
357
0
        }
358
0
    }
359
360
0
    ps_dpb_node1 = ps_dpb_mgr->ps_dpb_short_term_head;
361
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
362
0
    while(ps_dpb_node2 != NULL)
363
0
    {
364
0
        pic_buf_t *ps_pic_node1 = ps_dpb_node1->ps_pic_buf;
365
0
        pic_buf_t *ps_pic_node2 = ps_dpb_node2->ps_pic_buf;
366
0
        frame_num_node1 = ps_pic_node1->i4_frame_num;
367
0
        frame_num_node2 = ps_pic_node2->i4_frame_num;
368
0
        if(frame_num_node1 == frame_num_node2)
369
0
        {
370
0
            ASSERT(ps_pic_node1->i1_field_type != ps_pic_node2->i1_field_type);
371
0
            if(ps_pic_node1->i1_field_type != first_field_type)
372
0
            {
373
0
                ps_dpb_node1->ps_pic_buf = ps_pic_node2;
374
0
                ps_dpb_node2->ps_pic_buf = ps_pic_node1;
375
0
            }
376
0
        }
377
0
        ps_dpb_node1 = ps_dpb_node2;
378
0
        ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb;
379
0
    }
380
0
    return 0;
381
0
}
382
383
/**
384
*******************************************************************************
385
*
386
* @brief
387
*  Function to sort long term pics by long term frame idx.
388
*
389
* @par Description:
390
*  Sorts long term fields by long term frame idx. For 2 fields
391
*  having same frame_num, orders them based on requested first field type.
392
*
393
* @param[in] ps_dpb_mgr
394
*  Pointer to the DPB manager structure
395
*
396
* @param[in] first_field_type
397
*  For complementary fields, required first field
398
*
399
* @returns
400
*
401
* @remarks
402
*
403
*******************************************************************************
404
*/
405
WORD32 ih264_dpb_mgr_sort_long_term_fields_by_frame_idx(dpb_mgr_t *ps_dpb_mgr,
406
                                                        WORD32 first_field_type)
407
0
{
408
0
    dpb_info_t *ps_dpb_node1 = ps_dpb_mgr->ps_dpb_long_term_head;
409
0
    dpb_info_t *ps_dpb_node2;
410
0
    WORD32 frame_idx_node1;
411
0
    WORD32 frame_idx_node2;
412
0
    pic_buf_t *ps_pic_buf;
413
414
0
    if(ps_dpb_node1 == NULL)
415
0
        return -1;
416
417
    /* Sort the fields by frame idx */
418
0
    for (; ps_dpb_node1 != NULL; ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb)
419
0
    {
420
0
        for (ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb; ps_dpb_node2 != NULL; ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb)
421
0
        {
422
0
            frame_idx_node1 = ps_dpb_node1->ps_pic_buf->i4_long_term_frame_idx;
423
0
            frame_idx_node2 = ps_dpb_node2->ps_pic_buf->i4_long_term_frame_idx;
424
425
0
            if(frame_idx_node1 > frame_idx_node2)
426
0
            {
427
0
                ps_pic_buf = ps_dpb_node1->ps_pic_buf;
428
0
                ps_dpb_node1->ps_pic_buf = ps_dpb_node2->ps_pic_buf;
429
0
                ps_dpb_node2->ps_pic_buf = ps_pic_buf;
430
0
            }
431
0
        }
432
0
    }
433
434
    /**
435
     * For frames and complementary field pairs,
436
     * ensure first_field_type appears first in the list
437
     */
438
0
    ps_dpb_node1 = ps_dpb_mgr->ps_dpb_long_term_head;
439
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
440
0
    while(ps_dpb_node2 != NULL)
441
0
    {
442
0
        pic_buf_t *ps_pic_node1 = ps_dpb_node1->ps_pic_buf;
443
0
        pic_buf_t *ps_pic_node2 = ps_dpb_node2->ps_pic_buf;
444
0
        frame_idx_node1 = ps_pic_node1->i4_long_term_frame_idx;
445
0
        frame_idx_node2 = ps_pic_node2->i4_long_term_frame_idx;
446
0
        if(frame_idx_node1 == frame_idx_node2)
447
0
        {
448
0
            ASSERT(ps_pic_node1->i1_field_type != ps_pic_node2->i1_field_type);
449
0
            if(ps_pic_node1->i1_field_type != first_field_type)
450
0
            {
451
0
                ps_dpb_node1->ps_pic_buf = ps_pic_node2;
452
0
                ps_dpb_node2->ps_pic_buf = ps_pic_node1;
453
0
            }
454
0
        }
455
0
        ps_dpb_node1 = ps_dpb_node2;
456
0
        ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb;
457
0
    }
458
0
    return 0;
459
0
}
460
461
/**
462
*******************************************************************************
463
*
464
* @brief
465
*  Function to alternate fields.
466
*
467
* @par Description:
468
*  In the ordered list of fields, alternate fields starting with
469
*  first_field_type
470
*
471
* @param[in] ps_dpb_mgr
472
*  Pointer to the DPB manager structure
473
*
474
* @param[in] reference_type
475
*  This is used to select between short-term and long-term linked list.
476
*
477
* @param[in] first_field_type
478
*  For complementary fields, required first field
479
*
480
* @returns
481
*
482
* @remarks
483
*
484
*******************************************************************************
485
*/
486
WORD32 ih264_dpb_mgr_alternate_ref_fields(dpb_mgr_t *ps_dpb_mgr,
487
                                          WORD32 reference_type,
488
                                          WORD32 first_field_type)
489
0
{
490
0
    dpb_info_t s_dpb_head;
491
0
    dpb_info_t *ps_dpb_head;
492
0
    dpb_info_t *ps_dpb_node1;
493
0
    dpb_info_t *ps_dpb_node2;
494
0
    dpb_info_t *ps_dpb_node3;
495
0
    dpb_info_t *ps_dpb_node4;
496
0
    WORD32 expected_field;
497
498
0
    expected_field = first_field_type;
499
500
0
    ps_dpb_head = &s_dpb_head;
501
502
0
    ps_dpb_head->ps_prev_dpb = (reference_type == SHORT_TERM_REF) ?
503
0
            ps_dpb_mgr->ps_dpb_short_term_head:
504
0
            ps_dpb_mgr->ps_dpb_long_term_head;
505
506
0
    ps_dpb_node1 = ps_dpb_head;
507
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
508
0
    while(ps_dpb_node2 != NULL)
509
0
    {
510
0
        pic_buf_t *ps_pic_node2 = ps_dpb_node2->ps_pic_buf;
511
0
        if(ps_pic_node2->i1_field_type != expected_field)
512
0
        {
513
            /*
514
             * If it is not expected field, loop over the node till
515
             * the expected field.
516
             */
517
0
            ps_dpb_node3 = ps_dpb_node2;
518
0
            ps_dpb_node4 = ps_dpb_node2->ps_prev_dpb;
519
0
            while((ps_dpb_node4 != NULL) &&
520
0
                    (ps_dpb_node4->ps_pic_buf->i1_field_type != expected_field))
521
0
            {
522
0
                ps_dpb_node3 = ps_dpb_node4;
523
0
                ps_dpb_node4 = ps_dpb_node4->ps_prev_dpb;
524
0
            }
525
0
            if(ps_dpb_node4 != NULL)
526
0
            {
527
0
                ps_dpb_node1->ps_prev_dpb = ps_dpb_node4;
528
0
                ps_dpb_node3->ps_prev_dpb = ps_dpb_node4->ps_prev_dpb;
529
0
                ps_dpb_node4->ps_prev_dpb = ps_dpb_node2;
530
0
            }
531
0
            else
532
0
            {
533
                /* node4 null means we have reached the end */
534
0
                break;
535
0
            }
536
0
        }
537
0
        ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb;
538
0
        ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
539
0
        expected_field = (ps_dpb_node1->ps_pic_buf->i1_field_type == TOP_FIELD)?
540
0
                            BOTTOM_FIELD:TOP_FIELD;
541
0
    }
542
543
0
    if(reference_type == SHORT_TERM_REF)
544
0
    {
545
0
        ps_dpb_mgr->ps_dpb_short_term_head = ps_dpb_head->ps_prev_dpb;
546
0
    }
547
0
    else
548
0
    {
549
0
        ps_dpb_mgr->ps_dpb_long_term_head = ps_dpb_head->ps_prev_dpb;
550
0
    }
551
552
0
    return 0;
553
0
}
554
555
/**
556
*******************************************************************************
557
*
558
* @brief
559
*  Add a ref field to short-term or long-term linked list.
560
*
561
* @par Description:
562
*  This function adds a ref field to either short-term or long-term linked
563
*  list. It picks up memory for the link from the array of dpb_info in
564
*  dpb_mgr. The field is added to the beginning of the linked list and the
565
*  head is set the the field.
566
*
567
* @param[in] ps_dpb_mgr
568
*  Pointer to the DPB manager structure
569
*
570
* @param[in] ps_pic_buf
571
*  Pic buf structure for the field being added.
572
*
573
* @param[in] reference_type
574
*  This is used to select between short-term and long-term linked list.
575
*
576
* @param[in] frame_num
577
*  frame_num for the field.
578
*
579
* @param[in] long_term_frame_idx
580
*  If the ref being added is long-term, long_term_frame_idx of the field.
581
*  Otherwise invalid.
582
*
583
* @returns
584
*
585
* @remarks
586
*
587
*******************************************************************************
588
*/
589
WORD32 ih264_dpb_mgr_insert_ref_field(dpb_mgr_t *ps_dpb_mgr,
590
                                    pic_buf_t *ps_pic_buf,
591
                                    WORD32 reference_type,
592
                                    UWORD32 frame_num,
593
                                    WORD32 long_term_frame_idx)
594
0
{
595
0
    WORD32 i;
596
0
    dpb_info_t *ps_dpb_info;
597
0
    dpb_info_t *ps_dpb_head;
598
599
0
    ps_dpb_info = ps_dpb_mgr->as_dpb_info;
600
601
    /* Return error if buffer is already present in the DPB */
602
0
    for(i = 0; i < MAX_DPB_BUFS; i++)
603
0
    {
604
0
        if( (ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
605
0
                        && (ps_dpb_info[i].ps_pic_buf->i4_used_as_ref == reference_type) )
606
0
        {
607
0
            return (-1);
608
0
        }
609
0
    }
610
611
    /* Find an unused DPB location */
612
0
    for(i = 0; i < MAX_DPB_BUFS; i++)
613
0
    {
614
0
        if(NULL == ps_dpb_info[i].ps_pic_buf)
615
0
        {
616
0
            break;
617
0
        }
618
0
    }
619
0
    if(i == MAX_DPB_BUFS)
620
0
    {
621
0
        return (-1);
622
0
    }
623
624
0
    ps_dpb_head = (reference_type == SHORT_TERM_REF)
625
0
                    ?ps_dpb_mgr->ps_dpb_short_term_head
626
0
                    :ps_dpb_mgr->ps_dpb_long_term_head;
627
628
0
    if(reference_type == SHORT_TERM_REF)
629
0
        long_term_frame_idx = -1;
630
631
    /* Create DPB info */
632
0
    ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
633
0
    ps_dpb_info[i].ps_prev_dpb = ps_dpb_head;
634
0
    ps_dpb_info[i].ps_pic_buf->i4_used_as_ref = reference_type;
635
0
    ps_dpb_info[i].ps_pic_buf->i4_frame_num = frame_num;
636
0
    ps_dpb_info[i].ps_pic_buf->i4_long_term_frame_idx = long_term_frame_idx;
637
638
    /* update the head node of linked list to point to the current picture */
639
0
    if(reference_type == SHORT_TERM_REF)
640
0
    {
641
0
        ps_dpb_mgr->ps_dpb_short_term_head = ps_dpb_info + i;
642
643
        /* Increment Short term buffer count */
644
0
        ps_dpb_mgr->u1_num_short_term_ref_bufs++;
645
646
0
    }
647
0
    else
648
0
    {
649
0
        ps_dpb_mgr->ps_dpb_long_term_head = ps_dpb_info + i;
650
651
        /* Increment Long term buffer count */
652
0
        ps_dpb_mgr->u1_num_long_term_ref_bufs++;
653
0
    }
654
655
0
    return 0;
656
0
}
657
658
/**
659
*******************************************************************************
660
*
661
* @brief
662
*  Add a ref frame to short-term or long-term linked list.
663
*
664
* @par Description:
665
*  This function adds a ref frame to either short-term or long-term linked
666
*  list. Internally it calls add ref field twice to add top and bottom field.
667
*
668
* @param[in] ps_dpb_mgr
669
*  Pointer to the DPB manager structure
670
*
671
* @param[in] ps_pic_buf
672
*  Pic buf structure for the field being added.
673
*
674
* @param[in] reference_type
675
*  This is used to select between short-term and long-term linked list.
676
*
677
* @param[in] frame_num
678
*  frame_num for the field.
679
*
680
* @param[in] long_term_frame_idx
681
*  If the ref being added is long-term, long_term_frame_idx of the field.
682
*  Otherwise invalid.
683
*
684
* @returns
685
*
686
* @remarks
687
*
688
*******************************************************************************
689
*/
690
WORD32 ih264_dpb_mgr_insert_ref_frame(dpb_mgr_t *ps_dpb_mgr,
691
                                      pic_buf_t *ps_pic_buf,
692
                                      WORD32 reference_type,
693
                                      UWORD32 frame_num,
694
                                      WORD32 long_term_frame_idx)
695
0
{
696
0
    WORD32 buf_id;
697
0
    pic_buf_t *ps_pic_top;
698
0
    pic_buf_t *ps_pic_bottom;
699
0
    WORD32 ret;
700
701
    /*
702
     * For a frame, since the ps_pic_buf passed to this function is that of top field
703
     * obtain bottom field using buf_id.
704
     */
705
0
    ps_pic_top = ps_pic_buf;
706
0
    buf_id = ps_pic_top->i4_buf_id;
707
0
    ps_pic_bottom = &ps_dpb_mgr->as_bottom_field_pics[buf_id];
708
709
    /* Insert top field */
710
0
    ret = ih264_dpb_mgr_insert_ref_field(ps_dpb_mgr,
711
0
                                       ps_pic_top,
712
0
                                       reference_type,
713
0
                                       frame_num,
714
0
                                       long_term_frame_idx);
715
716
0
    if(ret != 0)
717
0
        return ret;
718
719
    /* Insert bottom field */
720
0
    ret = ih264_dpb_mgr_insert_ref_field(ps_dpb_mgr,
721
0
                                       ps_pic_bottom,
722
0
                                       reference_type,
723
0
                                       frame_num,
724
0
                                       long_term_frame_idx);
725
726
0
    if(ret != 0)
727
0
        return ret;
728
729
0
    return ret;
730
0
}
731
732
/**
733
*******************************************************************************
734
*
735
* @brief
736
*  Returns the number of ref frames in both the linked list.
737
*
738
* @par Description:
739
*  Returns the count of number of frames, number of complementary field pairs
740
*  and number of unpaired fields.
741
*
742
* @param[in] ps_dpb_mgr
743
*  Pointer to the DPB manager structure
744
*
745
* @param[in] curr_frame_num
746
*  frame_num for the field.
747
*
748
* @param[in] max_frame_num
749
*  Maximum frame_num allowed
750
*
751
* @returns
752
*
753
* @remarks
754
*
755
*******************************************************************************
756
*/
757
WORD32 ih264_dpb_mgr_count_ref_frames(dpb_mgr_t *ps_dpb_mgr,
758
                                      WORD32 curr_frame_num,
759
                                      WORD32 max_frame_num)
760
0
{
761
0
    WORD32 numShortTerm = 0;
762
0
    WORD32 numLongTerm = 0;
763
0
    dpb_info_t *ps_dpb_node;
764
0
    WORD32 frame_num;
765
0
    WORD32 prev_frame_num;
766
767
    /*
768
     * Compute the number of short-term frames/complementary field pairs/
769
     * unpaired fields
770
     */
771
0
    if(ps_dpb_mgr->ps_dpb_short_term_head != NULL)
772
0
    {
773
        /* Sort the short-term list by frame_num */
774
0
        ih264_dpb_mgr_sort_short_term_fields_by_frame_num(ps_dpb_mgr,
775
0
                                                        curr_frame_num,
776
0
                                                        TOP_FIELD,
777
0
                                                        max_frame_num);
778
779
0
        ps_dpb_node = ps_dpb_mgr->ps_dpb_short_term_head;
780
0
        if(ps_dpb_node != NULL)
781
0
        {
782
0
            numShortTerm++;
783
0
            prev_frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
784
0
            ps_dpb_node = ps_dpb_node->ps_prev_dpb;
785
0
        }
786
787
0
        while(ps_dpb_node != NULL)
788
0
        {
789
0
            frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
790
0
            if(frame_num != prev_frame_num)
791
0
                numShortTerm++;
792
0
            prev_frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
793
0
            ps_dpb_node = ps_dpb_node->ps_prev_dpb;
794
0
        }
795
0
    }
796
797
    /*
798
     * Compute the number of long-term frames/complementary field pairs/
799
     * unpaired fields
800
     */
801
0
    if(ps_dpb_mgr->ps_dpb_long_term_head != NULL)
802
0
    {
803
0
        ih264_dpb_mgr_sort_long_term_fields_by_frame_idx(ps_dpb_mgr,
804
0
                                                        TOP_FIELD);
805
806
0
        ps_dpb_node = ps_dpb_mgr->ps_dpb_long_term_head;
807
0
        if(ps_dpb_node != NULL)
808
0
        {
809
0
            numLongTerm++;
810
0
            prev_frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
811
0
            ps_dpb_node = ps_dpb_node->ps_prev_dpb;
812
0
        }
813
814
0
        while(ps_dpb_node != NULL)
815
0
        {
816
0
            frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
817
0
            if(frame_num != prev_frame_num)
818
0
                numLongTerm++;
819
0
            prev_frame_num = ps_dpb_node->ps_pic_buf->i4_frame_num;
820
0
            ps_dpb_node = ps_dpb_node->ps_prev_dpb;
821
0
        }
822
0
    }
823
0
    return (numShortTerm + numLongTerm);
824
0
}
825
826
/**
827
*******************************************************************************
828
*
829
* @brief
830
*  Deletes the ref frame at the end of the linked list.
831
*
832
* @par Description:
833
*  Deletes the ref frame at the end of the linked list. For unpaired fields,
834
*  it deletes just the last node. For frame or complementary field pair, it
835
*  deletes the last two nodes.
836
*
837
* @param[in] ps_dpb_mgr
838
*  Pointer to the DPB manager structure
839
*
840
* @param[in] reference_type
841
*  This is used to select between short-term and long-term linked list.
842
*
843
* @returns
844
*
845
* @remarks
846
*
847
*******************************************************************************
848
*/
849
WORD32 ih264_dpb_mgr_delete_ref_frame(dpb_mgr_t *ps_dpb_mgr,
850
                                      WORD32 reference_type)
851
0
{
852
0
    dpb_info_t *ps_dpb_node1;
853
0
    dpb_info_t *ps_dpb_node2;
854
0
    dpb_info_t *ps_dpb_node3;
855
856
    /*
857
     * Assumption: The nodes sorted for frame num.
858
     */
859
    /* Select bw short-term and long-term list. */
860
0
    ps_dpb_node1 = (reference_type == SHORT_TERM_REF)
861
0
                    ?ps_dpb_mgr->ps_dpb_short_term_head
862
0
                    :ps_dpb_mgr->ps_dpb_long_term_head;
863
    /* If null, no entries in the list. Hence return. */
864
0
    if(ps_dpb_node1 == NULL)
865
0
        return 0;
866
867
    /* If only one node in the list, set as unsed for refer and return. */
868
0
    if(ps_dpb_node1->ps_prev_dpb == NULL)
869
0
    {
870
        /* Set the picture as unused for reference */
871
0
        ps_dpb_node1->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
872
0
        ps_dpb_node1->ps_pic_buf = NULL;
873
874
0
        if(reference_type == SHORT_TERM_REF)
875
0
        {
876
0
            ps_dpb_mgr->ps_dpb_short_term_head = NULL;
877
878
            /* Increment Short term buffer count */
879
0
            ps_dpb_mgr->u1_num_short_term_ref_bufs = 0;
880
881
0
        }
882
0
        else
883
0
        {
884
0
            ps_dpb_mgr->ps_dpb_long_term_head = NULL;
885
886
            /* Increment Long term buffer count */
887
0
            ps_dpb_mgr->u1_num_long_term_ref_bufs = 0;
888
889
0
        }
890
0
        return 0;
891
0
    }
892
893
    /**
894
     * If there are only 2 nodes in the list, set second node as unused for reference.
895
     * If the frame_num of second node and first node is same, set first node also as
896
     * unused for reference and set the corresponding head to NULL.
897
     */
898
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
899
0
    if(ps_dpb_node2->ps_prev_dpb == NULL)
900
0
    {
901
        /* Set the picture as unused for reference */
902
0
        if(ps_dpb_node2->ps_pic_buf->i4_frame_num == ps_dpb_node1->ps_pic_buf->i4_frame_num)
903
0
        {
904
            /* Set the picture as unused for reference */
905
0
            ps_dpb_node1->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
906
0
            ps_dpb_node1->ps_pic_buf = NULL;
907
0
            if(reference_type == SHORT_TERM_REF)
908
0
            {
909
0
                ps_dpb_mgr->ps_dpb_short_term_head = NULL;
910
911
                /* Increment Short term buffer count */
912
0
                ps_dpb_mgr->u1_num_short_term_ref_bufs = 0;
913
914
0
            }
915
0
            else
916
0
            {
917
0
                ps_dpb_mgr->ps_dpb_long_term_head = NULL;
918
919
                /* Increment Long term buffer count */
920
0
                ps_dpb_mgr->u1_num_long_term_ref_bufs = 0;
921
922
0
            }
923
924
0
        }
925
0
        ps_dpb_node2->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
926
0
        ps_dpb_node2->ps_pic_buf = NULL;
927
0
        ps_dpb_node1->ps_prev_dpb = NULL;
928
0
        return 0;
929
0
    }
930
    /*
931
     * If there are more than 2 nodes, run a loop to get the last 3 nodes.
932
     */
933
0
    ps_dpb_node3 = ps_dpb_node2->ps_prev_dpb;
934
0
    while(ps_dpb_node3->ps_prev_dpb != NULL)
935
0
    {
936
0
        ps_dpb_node1 = ps_dpb_node2;
937
0
        ps_dpb_node2 = ps_dpb_node3;
938
0
        ps_dpb_node3 = ps_dpb_node3->ps_prev_dpb;
939
0
    }
940
    /*
941
     * If node 2 and node 3 frame_nums are same, set node 2 also as unsed for
942
     * reference and del reference from node1.
943
     */
944
0
    if(ps_dpb_node2->ps_pic_buf->i4_frame_num == ps_dpb_node3->ps_pic_buf->i4_frame_num)
945
0
    {
946
0
        ps_dpb_node2->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
947
0
        ps_dpb_node2->ps_pic_buf = NULL;
948
0
        ps_dpb_node1->ps_prev_dpb = NULL;
949
950
0
    }
951
    /* Set the third node as unused for reference */
952
0
    ps_dpb_node3->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
953
0
    ps_dpb_node3->ps_pic_buf = NULL;
954
0
    ps_dpb_node2->ps_prev_dpb = NULL;
955
956
0
    return 0;
957
0
}
958
959
/**
960
*******************************************************************************
961
*
962
* @brief
963
*  Delete long-term ref fields above max frame idx.
964
*
965
* @par Description:
966
*  Deletes all the long-term ref fields having idx greater than max_frame_idx
967
*
968
* @param[in] ps_dpb_mgr
969
*  Pointer to the DPB manager structure
970
*
971
* @param[in] max_frame_idx
972
*  Max long-term frame idx allowed.
973
*
974
* @returns
975
*
976
* @remarks
977
*
978
*******************************************************************************
979
*/
980
WORD32 ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx(dpb_mgr_t *ps_dpb_mgr,
981
                                                          WORD32 max_frame_idx)
982
0
{
983
0
    dpb_info_t *ps_dpb_node1;
984
0
    dpb_info_t *ps_dpb_node2;
985
986
    /*
987
     * Loop until there is node which isn't to be deleted is encountered.
988
     */
989
0
    while(ps_dpb_mgr->ps_dpb_long_term_head != NULL)
990
0
    {
991
0
        if(ps_dpb_mgr->ps_dpb_long_term_head->ps_pic_buf->i4_long_term_frame_idx
992
0
                        <= max_frame_idx)
993
0
        {
994
0
            break;
995
0
        }
996
0
        ps_dpb_mgr->ps_dpb_long_term_head->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
997
0
        ps_dpb_mgr->ps_dpb_long_term_head->ps_pic_buf = NULL;
998
0
        ps_dpb_mgr->ps_dpb_long_term_head = ps_dpb_mgr->ps_dpb_long_term_head->ps_prev_dpb;
999
0
    }
1000
1001
0
    ps_dpb_node1 = ps_dpb_mgr->ps_dpb_long_term_head;
1002
0
    if(ps_dpb_node1 == NULL)
1003
0
        return 0;
1004
    /*
1005
     * With the node that isn't to be deleted as head, loop until the end.
1006
     */
1007
0
    ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
1008
0
    while(ps_dpb_node2 != NULL)
1009
0
    {
1010
0
        if(ps_dpb_node2->ps_pic_buf->i4_long_term_frame_idx > max_frame_idx)
1011
0
        {
1012
0
            ps_dpb_node2->ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
1013
0
            ps_dpb_node2->ps_pic_buf = NULL;
1014
0
            ps_dpb_node1->ps_prev_dpb = ps_dpb_node2->ps_prev_dpb;
1015
0
        }
1016
0
        ps_dpb_node1 = ps_dpb_node1->ps_prev_dpb;
1017
0
        if(ps_dpb_node1 == NULL)
1018
0
            break;
1019
0
        ps_dpb_node2 = ps_dpb_node1->ps_prev_dpb;
1020
0
    }
1021
0
    return 0;
1022
0
}
1023
1024
/**
1025
*******************************************************************************
1026
*
1027
* @brief
1028
*  Deletes the short-term with least frame_num
1029
*
1030
* @par Description:
1031
*  Deletes the short-term with least frame_num. It sorts the function the
1032
*  short-term linked list by frame-num and the function that deletes the last
1033
*  frame in the linked list.
1034
*
1035
* @param[in] ps_dpb_mgr
1036
*  Pointer to the DPB manager structure
1037
*
1038
* @param[in] curr_frame_num
1039
*  frame_num of the current pic
1040
*
1041
* @param[in] max_frame_num
1042
*  Maximum frame_num allowed
1043
*
1044
* @returns
1045
*
1046
* @remarks
1047
*
1048
*******************************************************************************
1049
*/
1050
WORD32 ih264_dpb_mgr_delete_short_ref_frame(dpb_mgr_t *ps_dpb_mgr,
1051
                                            WORD32 curr_frame_num,
1052
                                            WORD32 max_frame_num)
1053
0
{
1054
0
    WORD32 ret;
1055
1056
    /* Sort the short-term list by frame_num */
1057
0
    ret = ih264_dpb_mgr_sort_short_term_fields_by_frame_num(ps_dpb_mgr,
1058
0
                                                          curr_frame_num,
1059
0
                                                          TOP_FIELD,
1060
0
                                                          max_frame_num);
1061
1062
    /* Delete the last reference frame or field */
1063
0
    ret = ih264_dpb_mgr_delete_ref_frame(ps_dpb_mgr,SHORT_TERM_REF);
1064
1065
0
    if(ret != 0)
1066
0
    {
1067
0
        ASSERT(0);
1068
0
    }
1069
1070
0
    return ret;
1071
0
}
1072
1073
/**
1074
*******************************************************************************
1075
*
1076
* @brief
1077
*  Deletes all the ref frames.
1078
*
1079
* @par Description:
1080
*  Deletes all of the ref frames/fields in the short-term and long-term linked
1081
*  list.
1082
*
1083
* @param[in] ps_dpb_mgr
1084
*  Pointer to the DPB manager structure
1085
*
1086
* @returns
1087
*
1088
* @remarks
1089
*
1090
*******************************************************************************
1091
*/
1092
WORD32 ih264_dpb_mgr_delete_all_ref_frames(dpb_mgr_t *ps_dpb_mgr)
1093
0
{
1094
    /* Loop over short-term linked list. */
1095
0
    while(ps_dpb_mgr->ps_dpb_short_term_head != NULL)
1096
0
    {
1097
0
        ih264_dpb_mgr_delete_ref_frame(ps_dpb_mgr,SHORT_TERM_REF);
1098
0
    }
1099
1100
    /* Loop over long-term linked list. */
1101
0
    while(ps_dpb_mgr->ps_dpb_long_term_head != NULL)
1102
0
    {
1103
0
        ih264_dpb_mgr_delete_ref_frame(ps_dpb_mgr,LONG_TERM_REF);
1104
0
    }
1105
0
    return 0;
1106
0
}
1107
1108
/**
1109
*******************************************************************************
1110
*
1111
* @brief
1112
*  deletes all pictures from DPB and reset dpb
1113
*
1114
* @par Description:
1115
*  deletes all pictures from DPB and reset dpb
1116
*
1117
* @param[in] ps_dpb_mgr
1118
*  Pointer to the DPB manager structure
1119
*
1120
* @param[in] ps_buf_mgr
1121
*  Pointer to buffer manager structure
1122
*
1123
* @returns
1124
*
1125
* @remarks
1126
*
1127
*******************************************************************************
1128
*/
1129
void ih264_dpb_mgr_reset(dpb_mgr_t *ps_dpb_mgr, buf_mgr_t *ps_buf_mgr)
1130
0
{
1131
0
    WORD32 i;
1132
0
    dpb_info_t *ps_dpb_info;
1133
1134
0
    ASSERT(0);
1135
0
    ps_dpb_info = ps_dpb_mgr->as_dpb_info;
1136
0
    for(i = 0; i < MAX_DPB_BUFS; i++)
1137
0
    {
1138
0
        if(ps_dpb_info[i].ps_pic_buf->i4_used_as_ref)
1139
0
        {
1140
0
            ps_dpb_info[i].ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF;
1141
0
            ps_dpb_info[i].ps_prev_dpb = NULL;
1142
            // Release physical buffer
1143
0
            ih264_buf_mgr_release(ps_buf_mgr, ps_dpb_info[i].ps_pic_buf->i4_buf_id,
1144
0
                                  BUF_MGR_REF);
1145
1146
0
            ps_dpb_info[i].ps_pic_buf = NULL;
1147
0
        }
1148
0
    }
1149
0
    ps_dpb_mgr->u1_num_short_term_ref_bufs = 0;
1150
0
    ps_dpb_mgr->u1_num_long_term_ref_bufs  = 0;
1151
0
    ps_dpb_mgr->ps_dpb_short_term_head = NULL;
1152
0
    ps_dpb_mgr->ps_dpb_long_term_head  = NULL;
1153
0
}
1154
1155
/**
1156
*******************************************************************************
1157
*
1158
* @brief
1159
*  deletes all pictures from DPB
1160
*
1161
* @par Description:
1162
*  Deletes all pictures present in the DPB manager
1163
*
1164
* @param[in] ps_buf_mgr
1165
*  Pointer to buffer manager structure
1166
*
1167
* @param[in] u1_disp_bufs
1168
*  Number of buffers to be deleted
1169
*
1170
* @returns
1171
*
1172
* @remarks
1173
*
1174
*******************************************************************************
1175
*/
1176
void ih264_dpb_mgr_release_pics(buf_mgr_t *ps_buf_mgr, UWORD8 u1_disp_bufs)
1177
0
{
1178
0
    WORD8 i;
1179
0
    UWORD32 buf_status;
1180
1181
0
    ASSERT(0);
1182
0
    for(i = 0; i < u1_disp_bufs; i++)
1183
0
    {
1184
0
        buf_status = ih264_buf_mgr_get_status(ps_buf_mgr, i);
1185
0
        if(0 != buf_status)
1186
0
        {
1187
0
            ih264_buf_mgr_release((buf_mgr_t *)ps_buf_mgr, i, BUF_MGR_REF);
1188
0
        }
1189
0
    }
1190
0
}