Coverage Report

Created: 2025-09-17 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/encoder/vbr_storage_vbv.c
Line
Count
Source
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
* \file vbr_storage_vbv.c
23
*
24
* \brief
25
*    This file contain functions related to VBV buffer
26
*
27
* \date
28
*
29
* \author
30
*    ittiam
31
*
32
******************************************************************************
33
*/
34
/*****************************************************************************/
35
/* File Includes                                                             */
36
/*****************************************************************************/
37
/* System include files */
38
#include <stdio.h>
39
40
/* User include files */
41
#include "ittiam_datatypes.h"
42
#include "mem_req_and_acq.h"
43
#include "rc_common.h"
44
#include "rc_cntrl_param.h"
45
#include "var_q_operator.h"
46
#include "fixed_point_error_bits.h"
47
#include "cbr_buffer_control.h"
48
#include "rc_rd_model.h"
49
#include "est_sad.h"
50
#include "cbr_buffer_control.h"
51
#include "picture_type.h"
52
#include "bit_allocation.h"
53
#include "vbr_storage_vbv.h"
54
#include "trace_support.h"
55
56
0
#define MAX(x, y) ((x) > (y) ? (x) : (y))
57
58
typedef struct vbr_storage_vbv_t
59
{
60
    WORD32 i4_max_buf_size;
61
    WORD32 i4_cur_buf_size;
62
    WORD32 i4_max_bits_inflow_per_frm_period;
63
    /* Storing input variables */
64
    WORD32 i4_max_bit_rate;
65
    WORD32 i4_max_frame_rate;
66
    /* Error bits calculation module */
67
    error_bits_handle ps_error_bits;
68
} vbr_storage_vbv_t;
69
70
#if NON_STEADSTATE_CODE
71
72
WORD32 vbr_vbv_num_fill_use_free_memtab(
73
    vbr_storage_vbv_t **pps_vbr_storage_vbv, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
74
49.4k
{
75
49.4k
    WORD32 i4_mem_tab_idx = 0;
76
49.4k
    static vbr_storage_vbv_t s_vbr_storage_vbv_temp;
77
78
    /* Hack for al alloc, during which we dont have any state memory.
79
      Dereferencing can cause issues */
80
49.4k
    if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
81
42.3k
        (*pps_vbr_storage_vbv) = &s_vbr_storage_vbv_temp;
82
83
    /*for src rate control state structure*/
84
49.4k
    if(e_func_type != GET_NUM_MEMTAB)
85
21.1k
    {
86
21.1k
        fill_memtab(
87
21.1k
            &ps_memtab[i4_mem_tab_idx],
88
21.1k
            sizeof(vbr_storage_vbv_t),
89
21.1k
            MEM_TAB_ALIGNMENT,
90
21.1k
            PERSISTENT,
91
21.1k
            DDR);
92
21.1k
        use_or_fill_base(&ps_memtab[0], (void **)pps_vbr_storage_vbv, e_func_type);
93
21.1k
    }
94
49.4k
    i4_mem_tab_idx++;
95
96
49.4k
    i4_mem_tab_idx += error_bits_num_fill_use_free_memtab(
97
49.4k
        &pps_vbr_storage_vbv[0]->ps_error_bits, &ps_memtab[i4_mem_tab_idx], e_func_type);
98
49.4k
    return (i4_mem_tab_idx);
99
49.4k
}
100
/******************************************************************************
101
  Function Name   : init_vbr_vbv
102
  Description     :
103
  Arguments       : ps_vbr_storage_vbv
104
  Return Values   : void
105
  Revision History:
106
                    Creation
107
*****************************************************************************/
108
void init_vbr_vbv(
109
    vbr_storage_vbv_t *ps_vbr_storage_vbv,
110
    WORD32 i4_max_bit_rate,
111
    WORD32 i4_frm_rate,
112
    WORD32 i4_max_vbv_buff_size)
113
0
{
114
0
    ps_vbr_storage_vbv->i4_max_buf_size = i4_max_vbv_buff_size;
115
0
    ps_vbr_storage_vbv->i4_cur_buf_size = i4_max_vbv_buff_size;
116
117
    /* Calculate the max number of bits that flow into the decoder
118
    in the interval of two frames */
119
0
    X_PROD_Y_DIV_Z(
120
0
        i4_max_bit_rate, 1000, i4_frm_rate, ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
121
122
    /* init error bits */
123
0
    init_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate, i4_max_bit_rate);
124
125
    /* Storing the input values */
126
0
    ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate;
127
0
    ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate;
128
0
}
129
#endif /* #if NON_STEADSTATE_CODE */
130
/******************************************************************************
131
  Function Name   : update_vbr_vbv
132
  Description     :
133
  Arguments       : ps_vbr_storage_vbv
134
  Return Values   : void
135
  Revision History:
136
                    Creation
137
*****************************************************************************/
138
void update_vbr_vbv(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_total_bits_decoded)
139
0
{
140
0
    WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
141
    /* In the time interval between two decoded frames the buffer would have been
142
       filled up by the max_bits_inflow_per_frm_period.*/
143
0
    overflow_avoided_summation(
144
0
        &ps_vbr_storage_vbv->i4_cur_buf_size,
145
0
        (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
146
147
0
    if(ps_vbr_storage_vbv->i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
148
0
    {
149
0
        ps_vbr_storage_vbv->i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
150
0
    }
151
152
0
    ps_vbr_storage_vbv->i4_cur_buf_size -= i4_total_bits_decoded;
153
154
    /* Update the error bits state */
155
0
    update_error_bits(ps_vbr_storage_vbv->ps_error_bits);
156
157
0
#define PRINT_UNDERFLOW 0
158
#if PRINT_UNDERFLOW
159
    if(ps_vbr_storage_vbv->i4_cur_buf_size < 0)
160
        printf("The buffer underflows \n");
161
#endif
162
0
}
163
/******************************************************************************
164
  Function Name   : get_max_target_bits
165
  Description     :
166
  Arguments       : ps_vbr_storage_vbv
167
  Return Values   : void
168
  Revision History:
169
                    Creation
170
*****************************************************************************/
171
WORD32 get_max_target_bits(vbr_storage_vbv_t *ps_vbr_storage_vbv)
172
0
{
173
0
    WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size;
174
0
    WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
175
176
    /* The buffer size when the next frame is decoded */
177
0
    overflow_avoided_summation(
178
0
        &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
179
0
    if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
180
0
    {
181
0
        i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
182
0
    }
183
184
    /* Thus for the next frame the maximum number of bits the decoder can consume
185
    without underflow is i4_cur_buf_size */
186
0
    return i4_cur_buf_size;
187
0
}
188
189
/****************************************************************************
190
Function Name : get_buffer_status
191
Description   : Gets the state of VBV buffer
192
Inputs        : Rate control API , header and texture bits
193
Globals       :
194
Processing    :
195
Outputs       : 0 = normal, 1 = underflow, 2= overflow
196
Returns       : vbv_buf_status_e
197
Issues        :
198
Revision History:
199
DD MM YYYY   Author(s)       Changes (Describe the changes made)
200
*****************************************************************************/
201
vbv_buf_status_e get_vbv_buffer_status(
202
    vbr_storage_vbv_t *ps_vbr_storage_vbv,
203
    WORD32 i4_total_frame_bits, /* Total frame bits consumed */
204
    WORD32 *pi4_num_bits_to_prevent_vbv_underflow) /* The curent buffer status after updation */
205
0
{
206
0
    vbv_buf_status_e e_buf_status;
207
0
    WORD32 i4_cur_buf;
208
0
    WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
209
210
    /* error bits due to fixed point computation of drain rate*/
211
0
    i4_cur_buf = ps_vbr_storage_vbv->i4_cur_buf_size;
212
0
    overflow_avoided_summation(
213
0
        &i4_cur_buf, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
214
215
0
    if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size)
216
0
    {
217
0
        i4_cur_buf = ps_vbr_storage_vbv->i4_max_buf_size;
218
0
    }
219
220
0
    pi4_num_bits_to_prevent_vbv_underflow[0] = i4_cur_buf;
221
222
0
    i4_cur_buf -= i4_total_frame_bits;
223
0
    if(i4_cur_buf < 0)
224
0
    {
225
0
        e_buf_status = VBV_UNDERFLOW;
226
0
    }
227
0
    else if(i4_cur_buf > ps_vbr_storage_vbv->i4_max_buf_size)
228
0
    {
229
0
        e_buf_status = VBV_OVERFLOW;
230
0
    }
231
0
    else if(i4_cur_buf < (ps_vbr_storage_vbv->i4_max_buf_size >> 2))
232
0
    {
233
0
        e_buf_status = VBR_CAUTION;
234
0
    }
235
0
    else
236
0
    {
237
0
        e_buf_status = VBV_NORMAL;
238
0
    }
239
240
0
    return e_buf_status;
241
0
}
242
/******************************************************************************
243
  Function Name   : get_max_vbv_buf_size
244
  Description     :
245
  Arguments       : ps_vbr_storage_vbv
246
  Return Values   : void
247
  Revision History:
248
                    Creation
249
*****************************************************************************/
250
WORD32 get_max_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv)
251
0
{
252
0
    return (ps_vbr_storage_vbv->i4_max_buf_size);
253
0
}
254
/******************************************************************************
255
  Function Name   : get_cur_vbv_buf_size
256
  Description     :
257
  Arguments       : ps_vbr_storage_vbv
258
  Return Values   : void
259
  Revision History:
260
                    Creation
261
*****************************************************************************/
262
WORD32 get_cur_vbv_buf_size(vbr_storage_vbv_t *ps_vbr_storage_vbv)
263
0
{
264
0
    return (ps_vbr_storage_vbv->i4_cur_buf_size);
265
0
}
266
/******************************************************************************
267
  Function Name   : get_max_bits_inflow_per_frm_periode
268
  Description     :
269
  Arguments       : ps_vbr_storage_vbv
270
  Return Values   : void
271
  Revision History:
272
                    Creation
273
*****************************************************************************/
274
WORD32 get_max_bits_inflow_per_frm_periode(vbr_storage_vbv_t *ps_vbr_storage_vbv)
275
0
{
276
0
    return (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
277
0
}
278
279
/******************************************************************************
280
  Function Name   : get_vbv_buf_fullness
281
  Description     :
282
  Arguments       : ps_vbr_storage_vbv
283
  Return Values   : void
284
  Revision History:
285
                    Creation
286
*****************************************************************************/
287
WORD32 get_vbv_buf_fullness(vbr_storage_vbv_t *ps_vbr_storage_vbv, UWORD32 u4_bits)
288
0
{
289
0
    WORD32 i4_error_bits = get_error_bits(ps_vbr_storage_vbv->ps_error_bits);
290
0
    WORD32 i4_cur_buf_size = ps_vbr_storage_vbv->i4_cur_buf_size;
291
292
0
    overflow_avoided_summation(
293
0
        &i4_cur_buf_size, (ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period + i4_error_bits));
294
295
0
    if(i4_cur_buf_size > ps_vbr_storage_vbv->i4_max_buf_size)
296
0
    {
297
0
        i4_cur_buf_size = ps_vbr_storage_vbv->i4_max_buf_size;
298
0
    }
299
300
0
    i4_cur_buf_size -= u4_bits;
301
302
#if PRINT_UNDERFLOW
303
    if(i4_cur_buf_size < 0)
304
        printf("The buffer underflows \n");
305
#endif
306
0
    return (i4_cur_buf_size);
307
0
}
308
/******************************************************************************
309
  Function Name   : get_max_tgt_bits_dvd_comp
310
  Description     :
311
  Arguments       : ps_vbr_storage_vbv
312
  Return Values   : void
313
  Revision History:
314
                    Creation
315
*****************************************************************************/
316
WORD32 get_max_tgt_bits_dvd_comp(
317
    vbr_storage_vbv_t *ps_vbr_storage_vbv,
318
    WORD32 i4_rem_bits_in_gop,
319
    WORD32 i4_rem_frms_in_gop,
320
    picture_type_e e_pic_type)
321
0
{
322
0
    WORD32 i4_dbf_max, i4_dbf_min, i4_dbf_prev, i4_vbv_size, i4_dbf_desired;
323
0
    WORD32 i4_max_tgt_bits;
324
325
0
    i4_vbv_size = ps_vbr_storage_vbv->i4_max_buf_size;
326
0
    i4_dbf_max = 95 * i4_vbv_size / 100;
327
0
    i4_dbf_min = 10 * i4_vbv_size / 100;
328
0
    i4_dbf_prev = ps_vbr_storage_vbv->i4_cur_buf_size;
329
330
0
    if(i4_rem_bits_in_gop < 0)
331
0
        i4_rem_bits_in_gop = 0;
332
0
    if(i4_rem_frms_in_gop <= 0)
333
0
        i4_rem_frms_in_gop = 1;
334
335
0
    if(e_pic_type == I_PIC)
336
0
    {
337
0
        i4_dbf_desired = i4_dbf_min;
338
0
    }
339
0
    else
340
0
    {
341
0
        i4_dbf_desired = (i4_dbf_max - i4_rem_bits_in_gop / i4_rem_frms_in_gop - i4_dbf_prev) /
342
0
                         i4_rem_frms_in_gop;
343
0
        i4_dbf_desired += i4_dbf_prev;
344
0
    }
345
346
0
    i4_dbf_prev += ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period;
347
0
    if(i4_dbf_prev > ps_vbr_storage_vbv->i4_max_buf_size)
348
0
    {
349
0
        i4_dbf_prev = ps_vbr_storage_vbv->i4_max_buf_size;
350
0
    }
351
352
0
    i4_max_tgt_bits = MAX(0, (i4_dbf_prev - i4_dbf_desired));
353
0
    return (i4_max_tgt_bits);
354
0
}
355
356
#if NON_STEADSTATE_CODE
357
/******************************************************************************
358
  Function Name   : change_vbr_vbv_frame_rate
359
  Description     :
360
  Arguments       : ps_vbr_storage_vbv
361
  Return Values   : void
362
  Revision History:
363
                    Creation
364
*****************************************************************************/
365
void change_vbr_vbv_frame_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_frm_rate)
366
0
{
367
    /* Calculate the max number of bits that flow into the decoder
368
    in the interval of two frames */
369
0
    X_PROD_Y_DIV_Z(
370
0
        ps_vbr_storage_vbv->i4_max_bit_rate,
371
0
        1000,
372
0
        i4_frm_rate,
373
0
        ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
374
375
    /* update the lower modules */
376
0
    change_frm_rate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_frm_rate);
377
    /* Storing the input values */
378
0
    ps_vbr_storage_vbv->i4_max_frame_rate = i4_frm_rate;
379
0
}
380
/******************************************************************************
381
  Function Name   : change_vbr_vbv_bit_rate
382
  Description     :
383
  Arguments       : ps_vbr_storage_vbv
384
  Return Values   : void
385
  Revision History:
386
                    Creation
387
*****************************************************************************/
388
void change_vbr_vbv_bit_rate(vbr_storage_vbv_t *ps_vbr_storage_vbv, WORD32 i4_max_bit_rate)
389
0
{
390
    /* Calculate the max number of bits that flow into the decoder
391
    in the interval of two frames */
392
0
    X_PROD_Y_DIV_Z(
393
0
        i4_max_bit_rate,
394
0
        1000,
395
0
        ps_vbr_storage_vbv->i4_max_frame_rate,
396
0
        ps_vbr_storage_vbv->i4_max_bits_inflow_per_frm_period);
397
398
    /* update the lower modules */
399
0
    change_bitrate_in_error_bits(ps_vbr_storage_vbv->ps_error_bits, i4_max_bit_rate);
400
401
    /* Storing the input values */
402
0
    ps_vbr_storage_vbv->i4_max_bit_rate = i4_max_bit_rate;
403
0
}
404
#endif /* #if NON_STEADSTATE_CODE */