Coverage Report

Created: 2026-10-17 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/common/ihevc_dpb_mgr.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevc_dpb_mgr.c
22
 *
23
 * @brief
24
 *  Function definitions used for decoded picture buffer management
25
 *
26
 * @author
27
 *  Srinivas T
28
 *
29
 * @par List of Functions:
30
 *   - ihevc_dpb_mgr_init()
31
 *   - ihevc_dpb_mgr_del_lt()
32
 *   - ihevc_dpb_mgr_insert_lt()
33
 *   - ihevc_dpb_mgr_del_st_or_make_lt()
34
 *   - ihevc_dpb_mgr_insert_st()
35
 *   - ihevc_dpb_mgr_reset()
36
 *   - ihevc_dpb_mgr_release_pics()
37
 *
38
 * @remarks
39
 *  None
40
 *
41
 *******************************************************************************
42
 */
43
44
#include <stdio.h>
45
#include <stdlib.h>
46
47
#include "ihevc_typedefs.h"
48
#include "ihevc_defs.h"
49
#include "ihevc_macros.h"
50
#include "ihevc_structs.h"
51
#include "ihevc_buf_mgr.h"
52
#include "ihevc_dpb_mgr.h"
53
54
/**
55
 *******************************************************************************
56
 *
57
 * @brief
58
 *  DPB manager initializer
59
 *
60
 * @par Description:
61
 *  Initialises the DPB manager structure
62
 *
63
 * @param[in] ps_dpb_mgr
64
 *  Pointer to the DPB manager structure
65
 *
66
 * @returns
67
 *
68
 * @remarks
69
 *
70
 *
71
 *******************************************************************************
72
 */
73
74
void ihevc_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr)
75
27.6k
{
76
27.6k
    UWORD32 i;
77
27.6k
    dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
78
1.79M
    for(i = 0; i < MAX_DPB_BUFS; i++)
79
1.77M
    {
80
1.77M
        ps_dpb_info[i].ps_prev_dpb = NULL;
81
1.77M
        ps_dpb_info[i].ps_pic_buf = NULL;
82
83
1.77M
    }
84
85
27.6k
    ps_dpb_mgr->u1_num_ref_bufs = 0;
86
27.6k
    ps_dpb_mgr->ps_dpb_head = NULL;
87
88
27.6k
}
89
90
91
/**
92
 *******************************************************************************
93
 *
94
 * @brief
95
 *  Adds a reference picture into the linked  list
96
 *
97
 * @par Description:
98
 *  Adds the reference buffer with the given buffer id into the DPB manager
99
 *
100
 *
101
 * @param[in] ps_dpb_mgr
102
 *  Pointer to the DPB manager structure
103
 *
104
 * @param[in] ps_picBuf
105
 *  Pointer to the picture buffer
106
 *
107
 * @param[in] buf_id
108
 *  buffer id of the picture buffer
109
 *
110
 * @returns  0 if successful, -1 otherwise
111
 *
112
 * @remarks
113
 *
114
 *
115
 *******************************************************************************
116
 */
117
118
WORD32 ihevc_dpb_mgr_insert_ref(dpb_mgr_t *ps_dpb_mgr,
119
                                pic_buf_t *ps_pic_buf,
120
                                WORD32 buf_id)
121
69.8k
{
122
69.8k
    int i;
123
69.8k
    dpb_info_t *ps_dpb_info;
124
125
69.8k
    ps_dpb_info = ps_dpb_mgr->as_dpb_info;
126
127
    /* Return error if buffer is already present in the DPB */
128
4.54M
    for(i = 0; i < MAX_DPB_BUFS; i++)
129
4.47M
    {
130
4.47M
        if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
131
0
                        && (ps_dpb_info[i].ps_pic_buf->u1_used_as_ref))
132
0
        {
133
0
            return (-1);
134
0
        }
135
136
137
4.47M
    }
138
139
    /* Find an unused DPB location */
140
84.5k
    for(i = 0; i < MAX_DPB_BUFS; i++)
141
84.5k
    {
142
84.5k
        if(NULL == ps_dpb_info[i].ps_pic_buf)
143
69.8k
        {
144
69.8k
            break;
145
69.8k
        }
146
84.5k
    }
147
69.8k
    if(i == MAX_DPB_BUFS)
148
0
    {
149
0
        return (-1);
150
0
    }
151
152
    /* Create DPB info */
153
69.8k
    ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
154
69.8k
    ps_dpb_info[i].ps_prev_dpb = ps_dpb_mgr->ps_dpb_head;
155
69.8k
    ps_dpb_info[i].ps_pic_buf->u1_buf_id = buf_id;
156
69.8k
    ps_dpb_info[i].ps_pic_buf->u1_used_as_ref = SHORT_TERM_REF;
157
158
    /* update the head node of linked list to point to the current picture */
159
69.8k
    ps_dpb_mgr->ps_dpb_head = ps_dpb_info + i;
160
161
    /* Increment Short term buffer count */
162
69.8k
    ps_dpb_mgr->u1_num_ref_bufs++;
163
164
69.8k
    return 0;
165
69.8k
}
166
167
/**
168
 *******************************************************************************
169
 *
170
 * @brief
171
 *  Deletes a reference buffer from the dpb manager
172
 *
173
 * @par Description:
174
 *  Delete short term reference with a given POC from the linked
175
 *  list
176
 *
177
 * @param[in] ps_dpb_mgr
178
 *  Pointer to DPB Manager structure
179
 *
180
 * @param[in] ps_buf_mgr
181
 *  Pointer to buffer manager structure
182
 *
183
 * @param[in] u4_abs_poc
184
 *  Node's absolute poc
185
 *
186
 *
187
 * @returns  0 if successful, -1 otherwise
188
 *
189
 * @remarks
190
 *
191
 *
192
 *******************************************************************************
193
 */
194
195
void ihevc_dpb_mgr_del_ref(dpb_mgr_t *ps_dpb_mgr,
196
                           buf_mgr_t *ps_buf_mgr,
197
                           WORD32 i4_abs_poc)
198
46.6k
{
199
46.6k
    int i;
200
46.6k
    dpb_info_t *ps_next_dpb;
201
202
46.6k
    dpb_info_t *ps_unmark_node;
203
46.6k
    UWORD8 u1_del_node;
204
46.6k
    UNUSED(u1_del_node);
205
46.6k
    u1_del_node = 0;
206
207
    /* Find the node with matching absolute POC */
208
46.6k
    ps_next_dpb = ps_dpb_mgr->ps_dpb_head;
209
46.6k
    if(ps_next_dpb->ps_pic_buf->i4_abs_poc == i4_abs_poc)
210
43.6k
    {
211
43.6k
        ps_unmark_node = ps_next_dpb;
212
43.6k
    }
213
3.04k
    else
214
3.04k
    {
215
3.58k
        for(i = 1; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
216
3.58k
        {
217
3.58k
            if(ps_next_dpb->ps_prev_dpb->ps_pic_buf->i4_abs_poc == i4_abs_poc)
218
3.04k
                break;
219
542
            ps_next_dpb = ps_next_dpb->ps_prev_dpb;
220
542
        }
221
222
3.04k
        if(i == ps_dpb_mgr->u1_num_ref_bufs)
223
0
        {
224
0
            return;
225
0
        }
226
3.04k
        else
227
3.04k
            ps_unmark_node = ps_next_dpb->ps_prev_dpb;
228
3.04k
    }
229
230
46.6k
    if(ps_unmark_node == ps_dpb_mgr->ps_dpb_head)
231
43.6k
    {
232
43.6k
        ps_dpb_mgr->ps_dpb_head = ps_unmark_node->ps_prev_dpb;
233
43.6k
    }
234
3.04k
    else
235
3.04k
    {
236
3.04k
        ps_next_dpb->ps_prev_dpb = ps_unmark_node->ps_prev_dpb; //update link
237
3.04k
        ps_unmark_node->ps_prev_dpb = NULL;
238
3.04k
    }
239
46.6k
    ps_dpb_mgr->u1_num_ref_bufs--; //decrement buffer count
240
241
    /* Release the physical buffer */
242
46.6k
    ihevc_buf_mgr_release((buf_mgr_t *)ps_buf_mgr, ps_unmark_node->ps_pic_buf->u1_buf_id,
243
46.6k
                          BUF_MGR_REF);
244
46.6k
    ps_unmark_node->ps_prev_dpb = NULL;
245
46.6k
    ps_unmark_node->ps_pic_buf = NULL;
246
46.6k
}
247
248
249
/**
250
 *******************************************************************************
251
 *
252
 * @brief
253
 *  Gets a buffer with abs_poc closest to the current poc
254
 *
255
 * @par Description:
256
 *  Returns the pointer to the picture buffer whose poc is equal to abs_poc
257
 *
258
 * @param[in] ps_dpb_mgr
259
 *  Pointer to DPB Manager structure
260
 *
261
 * @param[out] ps_pic_buf
262
 *  Pointer to picture buffer
263
264
 * @param[in] abs_poc
265
 *  poc of the buffer to be returned
266
 *
267
 * @returns
268
 *  0 if successful, pic_buf otherwise
269
 * @remarks
270
 *
271
 *
272
 *******************************************************************************
273
 */
274
pic_buf_t* ihevc_dpb_mgr_get_ref_by_nearest_poc(dpb_mgr_t *ps_dpb_mgr, WORD32 cur_abs_poc)
275
131k
{
276
131k
    WORD32 i;
277
131k
    WORD32 min_diff = 0x7FFFFFFF;
278
131k
    pic_buf_t *ps_pic_buf = NULL;
279
280
8.56M
    for(i = 0; i < MAX_DPB_BUFS; i++)
281
8.43M
    {
282
8.43M
        if((ps_dpb_mgr->as_dpb_info[i].ps_pic_buf) &&
283
132k
                        (ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->u1_used_as_ref != UNUSED_FOR_REF))
284
107k
        {
285
107k
            WORD32 poc_diff = cur_abs_poc - ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->i4_abs_poc;
286
107k
            if((poc_diff > 0) && (poc_diff < min_diff))
287
45.5k
            {
288
45.5k
                min_diff = poc_diff;
289
45.5k
                ps_pic_buf = ps_dpb_mgr->as_dpb_info[i].ps_pic_buf;
290
45.5k
            }
291
107k
        }
292
8.43M
    }
293
294
131k
    if(NULL == ps_pic_buf)
295
95.0k
    {
296
95.0k
        min_diff = 0x7FFFFFFF;
297
6.17M
        for(i = 0; i < MAX_DPB_BUFS; i++)
298
6.08M
        {
299
6.08M
            if((ps_dpb_mgr->as_dpb_info[i].ps_pic_buf) &&
300
45.4k
                            (ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->u1_used_as_ref != UNUSED_FOR_REF))
301
32.2k
            {
302
32.2k
                WORD32 poc_diff = cur_abs_poc - ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->i4_abs_poc;
303
32.2k
                if(ABS(poc_diff) < min_diff)
304
27.8k
                {
305
27.8k
                    min_diff = ABS(poc_diff);
306
27.8k
                    ps_pic_buf = ps_dpb_mgr->as_dpb_info[i].ps_pic_buf;
307
27.8k
                }
308
32.2k
            }
309
6.08M
        }
310
95.0k
    }
311
312
131k
    return ps_pic_buf;
313
131k
}
314
315
316
/**
317
 *******************************************************************************
318
 *
319
 * @brief
320
 *  Gets a buffer with abs_poc
321
 *
322
 * @par Description:
323
 *  Returns the pointer to the picture buffer whose poc is equal to abs_poc
324
 *
325
 * @param[in] ps_dpb_mgr
326
 *  Pointer to DPB Manager structure
327
 *
328
 * @param[out] ps_pic_buf
329
 *  Pointer to picture buffer
330
331
 * @param[in] abs_poc
332
 *  poc of the buffer to be returned
333
 *
334
 * @returns
335
 *  0 if successful, pic_buf otherwise
336
 * @remarks
337
 *
338
 *
339
 *******************************************************************************
340
 */
341
pic_buf_t* ihevc_dpb_mgr_get_ref_by_poc(dpb_mgr_t *ps_dpb_mgr, WORD32 abs_poc)
342
99.8k
{
343
99.8k
    UWORD32 i;
344
99.8k
    dpb_info_t *ps_next_ref;
345
99.8k
    pic_buf_t *ps_pic_buf = NULL;
346
347
348
99.8k
    ps_next_ref = ps_dpb_mgr->ps_dpb_head;
349
281k
    for(i = 0; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
350
215k
    {
351
215k
        if(ps_next_ref->ps_pic_buf->i4_abs_poc == abs_poc)
352
33.9k
        {
353
33.9k
            ps_pic_buf = ps_next_ref->ps_pic_buf;
354
33.9k
            break;
355
33.9k
        }
356
357
181k
        ps_next_ref = ps_next_ref->ps_prev_dpb;
358
181k
    }
359
360
99.8k
    if(i == ps_dpb_mgr->u1_num_ref_bufs)
361
65.9k
    {
362
65.9k
        ps_pic_buf = NULL;
363
65.9k
    }
364
365
99.8k
    return ps_pic_buf;
366
99.8k
}
367
368
/**
369
 *******************************************************************************
370
 *
371
 * @brief
372
 *  Gets a buffer with poc_lsb
373
 *
374
 * @par Description:
375
 *  Returns the pointer to the picture buffer whose poc is equal to poc_lsb
376
 *
377
 * @param[in] ps_dpb_mgr
378
 *  Pointer to DPB Manager structure
379
 *
380
 * @param[out] ps_pic_buf
381
 *  Pointer to picture buffer
382
383
 * @param[in] poc_lsb
384
 *  poc_lsb of the buffer to be returned
385
 *
386
 * @returns
387
 *  0 if successful, pic_buf otherwise
388
 * @remarks
389
 *
390
 *
391
 *******************************************************************************
392
 */
393
394
pic_buf_t* ihevc_dpb_mgr_get_ref_by_poc_lsb(dpb_mgr_t *ps_dpb_mgr, WORD32 poc_lsb)
395
11.0k
{
396
11.0k
    pic_buf_t *ps_pic_buf = NULL;
397
11.0k
    UWORD32 i;
398
11.0k
    dpb_info_t *ps_next_ref;
399
400
11.0k
    ps_next_ref = ps_dpb_mgr->ps_dpb_head;
401
20.7k
    for(i = 0; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
402
12.8k
    {
403
12.8k
        if(ps_next_ref->ps_pic_buf->i4_poc_lsb == poc_lsb)
404
3.09k
        {
405
3.09k
            ps_pic_buf = ps_next_ref->ps_pic_buf;
406
3.09k
            break;
407
3.09k
        }
408
409
9.75k
        ps_next_ref = ps_next_ref->ps_prev_dpb;
410
9.75k
    }
411
412
11.0k
    if(i == ps_dpb_mgr->u1_num_ref_bufs)
413
7.91k
    {
414
7.91k
        ps_pic_buf = NULL;
415
7.91k
    }
416
417
11.0k
    return ps_pic_buf;
418
11.0k
}
419
420
421
/**
422
 *******************************************************************************
423
 *
424
 * @brief
425
 *  Resets the DPB manager
426
 *
427
 * @par Description:
428
 *  Re-initialises the DPB manager structure
429
 *
430
 * @param[in] ps_dpb_mgr
431
 *  Pointer to DPB Manager structure
432
 *
433
 * @param[in] ps_buf_mgr
434
 *  Pointer to buffer manager structure
435
 *
436
 * @returns
437
 *
438
 * @remarks
439
 *
440
 *
441
 *******************************************************************************
442
 */
443
444
void ihevc_dpb_mgr_reset(dpb_mgr_t *ps_dpb_mgr, buf_mgr_t *ps_buf_mgr)
445
0
{
446
0
    int i;
447
0
    dpb_info_t *ps_dpb_info;
448
449
0
    ps_dpb_info = ps_dpb_mgr->as_dpb_info;
450
451
0
    for(i = 0; i < MAX_DPB_BUFS; i++)
452
0
    {
453
0
        if(ps_dpb_info[i].ps_pic_buf->u1_used_as_ref)
454
0
        {
455
0
            ps_dpb_info[i].ps_pic_buf->u1_used_as_ref = UNUSED_FOR_REF;
456
0
            ps_dpb_info[i].ps_prev_dpb = NULL;
457
            //Release physical buffer
458
0
            ihevc_buf_mgr_release(ps_buf_mgr, ps_dpb_info[i].ps_pic_buf->u1_buf_id,
459
0
                                  BUF_MGR_REF);
460
461
0
            ps_dpb_info[i].ps_pic_buf = NULL;
462
0
        }
463
0
    }
464
0
    ps_dpb_mgr->u1_num_ref_bufs = 0;
465
0
    ps_dpb_mgr->ps_dpb_head = NULL;
466
467
0
}
468
469
/**
470
 *******************************************************************************
471
 *
472
 * @brief
473
 *  deletes all pictures from DPB
474
 *
475
 * @par Description:
476
 *  Deletes all pictures present in the DPB manager
477
 *
478
 * @param[in] ps_buf_mgr
479
 *  Pointer to buffer manager structure
480
 *
481
 * @param[in] u1_disp_bufs
482
 *  Number of buffers to be deleted
483
 *
484
 * @returns
485
 *
486
 * @remarks
487
 *
488
 *
489
 *******************************************************************************
490
 */
491
492
void ihevc_dpb_mgr_release_pics(buf_mgr_t *ps_buf_mgr, UWORD8 u1_disp_bufs)
493
0
{
494
0
    WORD8 i;
495
0
    UWORD32 buf_status;
496
497
0
    for(i = 0; i < u1_disp_bufs; i++)
498
0
    {
499
0
        buf_status = ihevc_buf_mgr_get_status(ps_buf_mgr, i);
500
0
        if(0 != buf_status)
501
0
        {
502
0
            ihevc_buf_mgr_release((buf_mgr_t *)ps_buf_mgr, i, BUF_MGR_REF);
503
0
        }
504
0
    }
505
0
}