Coverage Report

Created: 2025-07-11 06:43

/src/libhevc/encoder/ihevce_buffer_que.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2018 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
*  ihevce_buffer_que.c
25
*
26
* @brief
27
*  This file contains all the functions related to Buffer Queue manager
28
*
29
* @author
30
*  ittiam
31
*
32
* @par List of Functions:
33
*  ihevce_buff_que_get_mem_recs
34
*  ihevce_buff_que_get_num_mem_recs
35
*  ihevce_buff_que_init
36
*  ihevce_buff_que_get_free_buf
37
*  ihevce_buff_que_get_next_buf
38
*  ihevce_buff_que_get_next_reorder_buf
39
*  ihevce_buff_que_set_buf_prod
40
*  ihevce_buff_que_rel_buf
41
*  ihevce_buff_que_get_active_bufs
42
*  ihevce_buff_que_set_reorder_buf
43
*
44
******************************************************************************
45
*/
46
47
/*****************************************************************************/
48
/* File Includes                                                             */
49
/*****************************************************************************/
50
51
/* System Include Files */
52
#include <stdio.h>
53
#include <string.h>
54
#include <stdlib.h>
55
#include <stdint.h>
56
#include <assert.h>
57
58
/* User Include Files */
59
#include "ihevc_typedefs.h"
60
#include "itt_video_api.h"
61
#include "ihevce_buffer_que_interface.h"
62
#include "ihevce_buffer_que_private.h"
63
64
/*****************************************************************************/
65
/* Function Definitions                                                      */
66
/*****************************************************************************/
67
68
/*!
69
************************************************************************
70
* \brief
71
*    return number of records used by Buffer Que manager.
72
************************************************************************
73
*/
74
WORD32 ihevce_buff_que_get_num_mem_recs(void)
75
142k
{
76
142k
    return (NUM_BUFFER_QUE_MEM_RECS);
77
142k
}
78
79
/*!
80
************************************************************************
81
* \brief
82
*    return each record attributes of Buffer Que manager
83
************************************************************************
84
*/
85
WORD32 ihevce_buff_que_get_mem_recs(
86
    iv_mem_rec_t *ps_mem_tab, WORD32 max_num_bufs_in_que, WORD32 i4_mem_space)
87
71.3k
{
88
    /* Que manager state structure */
89
71.3k
    ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_size = sizeof(buf_que_t);
90
71.3k
    ps_mem_tab[BUFFER_QUE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
91
71.3k
    ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_alignment = 8;
92
93
    /* number of users memory */
94
71.3k
    ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
95
71.3k
    ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
96
71.3k
    ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_alignment = 8;
97
98
    /* Produced status memory */
99
71.3k
    ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
100
71.3k
    ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
101
71.3k
    ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_alignment = 8;
102
103
    /* Encode sequence memory */
104
71.3k
    ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
105
71.3k
    ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
106
71.3k
    ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_alignment = 8;
107
108
    /* Queued sequence memory */
109
71.3k
    ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
110
71.3k
    ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
111
71.3k
    ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_alignment = 8;
112
113
71.3k
    return (NUM_BUFFER_QUE_MEM_RECS);
114
71.3k
}
115
116
/*!
117
************************************************************************
118
* \brief
119
*    Intialization for Buffer Que manager state structure
120
************************************************************************
121
*/
122
void *ihevce_buff_que_init(iv_mem_rec_t *ps_mem_tab, WORD32 num_bufs_in_que, void **ppv_buff_ptrs)
123
71.3k
{
124
71.3k
    buf_que_t *ps_buf_que;
125
71.3k
    WORD32 i;
126
127
    /* que manager state structure */
128
71.3k
    ps_buf_que = (buf_que_t *)ps_mem_tab[BUFFER_QUE_CTXT].pv_base;
129
130
    /* buffer status memory init */
131
71.3k
    ps_buf_que->pi4_num_users = (WORD32 *)ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].pv_base;
132
133
71.3k
    ps_buf_que->pi4_produced_sts = (WORD32 *)ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].pv_base;
134
135
71.3k
    ps_buf_que->pu4_enc_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].pv_base;
136
137
71.3k
    ps_buf_que->pu4_que_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].pv_base;
138
139
    /* reset the state structure variables */
140
71.3k
    ps_buf_que->i4_num_bufs = num_bufs_in_que;
141
71.3k
    ps_buf_que->i4_num_active_bufs = 0;
142
71.3k
    ps_buf_que->u4_last_prod = 0;
143
71.3k
    ps_buf_que->u4_last_cons = 0;
144
71.3k
    ps_buf_que->u4_next_disp_seq = 0;
145
71.3k
    ps_buf_que->u4_last_disp_seq = 0;
146
71.3k
    ps_buf_que->ppv_buff_ptrs = ppv_buff_ptrs;
147
148
    /* init all the buffer status to default values */
149
237k
    for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
150
166k
    {
151
166k
        ps_buf_que->pi4_num_users[i] = 0;
152
166k
        ps_buf_que->pi4_produced_sts[i] = 0;
153
166k
        ps_buf_que->pu4_enc_seq[i] = UINT32_MAX;
154
166k
        ps_buf_que->pu4_que_seq[i] = UINT32_MAX;
155
166k
    }
156
157
71.3k
    return ((void *)ps_buf_que);
158
71.3k
}
159
160
/*!
161
**************************************************************************
162
* \brief
163
*    This function gets the next free buffer. This function is called by the
164
*    Producer to get a free buffer
165
**************************************************************************
166
*/
167
void *ihevce_buff_que_get_free_buf(void *pv_buf_que, WORD32 *pi4_id)
168
1.23M
{
169
1.23M
    buf_que_t *ps_buf_que;
170
1.23M
    WORD32 i;
171
1.23M
    WORD32 num_bufs;
172
173
1.23M
    ps_buf_que = (buf_que_t *)pv_buf_que;
174
1.23M
    num_bufs = ps_buf_que->i4_num_bufs;
175
176
    /* loop unitl a free buffer is found */
177
1.47M
    for(i = 0; i < num_bufs; i++)
178
1.37M
    {
179
1.37M
        if((ps_buf_que->pi4_num_users[i] == 0) && (ps_buf_que->pi4_produced_sts[i] == 0))
180
1.13M
        {
181
1.13M
            *(pi4_id) = i;
182
1.13M
            ps_buf_que->pi4_num_users[i] = 1;
183
1.13M
            ps_buf_que->pu4_que_seq[i] = ps_buf_que->u4_last_prod;
184
1.13M
            ps_buf_que->u4_last_prod += 1;
185
186
1.13M
            return (ps_buf_que->ppv_buff_ptrs[i]);
187
1.13M
        }
188
1.37M
    }
189
96.3k
    return (NULL);
190
1.23M
}
191
192
/*!
193
**************************************************************************
194
* \brief
195
*    This function gets the next buffer in Que . This function will be called by
196
*    consumer to get the next buffer in Queued order.
197
**************************************************************************
198
*/
199
void *ihevce_buff_que_get_next_buf(void *pv_buf_que, WORD32 *pi4_id)
200
2.81M
{
201
2.81M
    buf_que_t *ps_buf_que;
202
2.81M
    WORD32 i;
203
2.81M
    UWORD32 next_qued_seq;
204
205
2.81M
    ps_buf_que = (buf_que_t *)pv_buf_que;
206
207
    /* get the next queued buffer to be sent */
208
2.81M
    next_qued_seq = ps_buf_que->u4_last_cons;
209
210
    /* check for matching index */
211
6.43M
    for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
212
4.77M
    {
213
4.77M
        if(next_qued_seq == ps_buf_que->pu4_que_seq[i])
214
1.16M
        {
215
1.16M
            if(1 == ps_buf_que->pi4_produced_sts[i])
216
1.13M
            {
217
1.13M
                *(pi4_id) = i;
218
1.13M
                ps_buf_que->u4_last_cons += 1;
219
220
1.13M
                return (ps_buf_que->ppv_buff_ptrs[i]);
221
1.13M
            }
222
27.5k
            else
223
27.5k
            {
224
27.5k
                break;
225
27.5k
            }
226
1.16M
        }
227
4.77M
    }
228
229
    /* Buffer not ready for Consumption */
230
1.68M
    return (NULL);
231
2.81M
}
232
233
/*!
234
**************************************************************************
235
* \brief
236
*    This function gives the buffer curresponding to the id passed
237
**************************************************************************
238
*/
239
void *ihevce_buff_que_get_buf(void *pv_buf_que, WORD32 i4_id)
240
0
{
241
0
    buf_que_t *ps_buf_que;
242
243
0
    ps_buf_que = (buf_que_t *)pv_buf_que;
244
245
0
    if(i4_id >= ps_buf_que->i4_num_bufs)
246
0
        return (NULL);
247
248
0
    return (ps_buf_que->ppv_buff_ptrs[i4_id]);
249
0
}
250
251
/*!
252
**************************************************************************
253
* \brief
254
*    This function gets the next buffer for in reordered order. This function
255
*    will be called by consumer to get the next buffer in reordered order
256
**************************************************************************
257
*/
258
void *ihevce_buff_que_get_next_reorder_buf(void *pv_buf_que, WORD32 *pi4_id)
259
0
{
260
0
    buf_que_t *ps_buf_que;
261
0
    WORD32 i;
262
0
    UWORD32 next_disp_seq;
263
264
0
    ps_buf_que = (buf_que_t *)pv_buf_que;
265
266
    /* get the next reordered buffer to be sent */
267
0
    next_disp_seq = ps_buf_que->u4_last_disp_seq;
268
269
    /* check for matching index */
270
0
    for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
271
0
    {
272
0
        if(next_disp_seq == ps_buf_que->pu4_enc_seq[i])
273
0
        {
274
0
            *(pi4_id) = i;
275
0
            ps_buf_que->u4_last_disp_seq += 1;
276
277
0
            return (ps_buf_que->ppv_buff_ptrs[i]);
278
0
        }
279
0
    }
280
281
    /* Buffer not ready for Consumption */
282
0
    return (NULL);
283
0
}
284
285
/*!
286
**************************************************************************
287
* \brief
288
*    This function sets the buffer as produced. This function will be called
289
*    by Producer to say that buffer is ready for consumption.
290
**************************************************************************
291
*/
292
WORD32 ihevce_buff_que_set_buf_prod(void *pv_buf_que, WORD32 buf_id, WORD32 num_users)
293
1.13M
{
294
1.13M
    buf_que_t *ps_buf_que;
295
296
1.13M
    ps_buf_que = (buf_que_t *)pv_buf_que;
297
298
1.13M
    if(buf_id < ps_buf_que->i4_num_bufs)
299
1.13M
    {
300
1.13M
        if(ps_buf_que->pi4_produced_sts[buf_id] == 0)
301
1.13M
        {
302
1.13M
            ps_buf_que->pi4_num_users[buf_id] += num_users;
303
1.13M
            ps_buf_que->i4_num_active_bufs += 1;
304
1.13M
            ps_buf_que->pi4_produced_sts[buf_id] = 1;
305
306
1.13M
            return 0;
307
1.13M
        }
308
0
        else
309
0
        {
310
            /* Buffer is already marked as Produced */
311
0
            return (-1);
312
0
        }
313
1.13M
    }
314
0
    else
315
0
    {
316
        /* Unable to recognize the Buffer ID */
317
0
        return (-1);
318
0
    }
319
320
0
    return (-1);
321
1.13M
}
322
323
/*!
324
**************************************************************************
325
* \brief
326
*    This function decrements number of users. If Number of users are Zero,
327
*    then active Buffers in list gets decremented and this buffer is marked
328
*    unused.
329
**************************************************************************
330
*/
331
WORD32 ihevce_buff_que_rel_buf(void *pv_buf_que, WORD32 buf_id)
332
1.14M
{
333
1.14M
    buf_que_t *ps_buf_que;
334
1.14M
    WORD32 i;
335
336
1.14M
    ps_buf_que = (buf_que_t *)pv_buf_que;
337
1.14M
    i = buf_id;
338
339
    /* check if the buf id is less than max num buffers */
340
1.14M
    if(i < ps_buf_que->i4_num_bufs)
341
1.14M
    {
342
1.14M
        if(ps_buf_que->pi4_produced_sts[i] > 0)
343
1.13M
        {
344
            /* decrease the number of users */
345
1.13M
            ps_buf_que->pi4_num_users[i] -= 1;
346
347
1.13M
            if(ps_buf_que->pi4_num_users[i] == 0)
348
1.13M
            {
349
1.13M
                if(0 == ps_buf_que->i4_num_active_bufs)
350
0
                {
351
0
                    return (-1);
352
0
                }
353
354
1.13M
                ps_buf_que->i4_num_active_bufs -= 1;
355
1.13M
                ps_buf_que->pi4_produced_sts[i] = 0;
356
1.13M
            }
357
1.13M
            return 0;
358
1.13M
        }
359
8.92k
        else
360
8.92k
        {
361
            /* Illeagal release of Buffer, No one is using it */
362
8.92k
            return (-1);
363
8.92k
        }
364
1.14M
    }
365
366
    /* Unable to recognize the Buffer ID */
367
0
    return (-1);
368
1.14M
}
369
370
/*!
371
**************************************************************************
372
* \brief
373
*    This function gets number of active buffers.
374
**************************************************************************
375
*/
376
WORD32 ihevce_buff_que_get_active_bufs(void *pv_buf_que)
377
0
{
378
0
    buf_que_t *ps_buf_que;
379
380
0
    ps_buf_que = (buf_que_t *)pv_buf_que;
381
0
    return (ps_buf_que->i4_num_active_bufs);
382
0
}
383
384
/*!
385
**************************************************************************
386
* \brief
387
*    This function sets the reorder number for given buffer.
388
*    this will set the order for the consumer who is consuming in reorder order
389
**************************************************************************
390
*/
391
WORD32 ihevce_buff_que_set_reorder_buf(void *pv_buf_que, WORD32 buf_id)
392
0
{
393
0
    buf_que_t *ps_buf_que;
394
395
0
    ps_buf_que = (buf_que_t *)pv_buf_que;
396
397
0
    if(buf_id < ps_buf_que->i4_num_bufs)
398
0
    {
399
0
        WORD32 next_disp_seq = ps_buf_que->u4_next_disp_seq;
400
401
        /* increment the seq number */
402
0
        ps_buf_que->u4_next_disp_seq++;
403
404
        /* set the reorder number to the corresponding id */
405
0
        ps_buf_que->pu4_enc_seq[buf_id] = next_disp_seq;
406
407
0
        return 0;
408
0
    }
409
0
    else
410
0
    {
411
        /* invalid buffer id */
412
0
        return (-1);
413
0
    }
414
415
0
    return (-1);
416
0
}