xref: /rockchip-linux_mpp/mpp/codec/rc/rc_base.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2016 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG "rc_base"
7 
8 #include <math.h>
9 #include <memory.h>
10 
11 #include "mpp_env.h"
12 #include "mpp_mem.h"
13 #include "mpp_debug.h"
14 #include "mpp_common.h"
15 
16 #include "rc_base.h"
17 
18 #define MPP_RC_DBG_FUNCTION          (0x00000001)
19 #define MPP_RC_DBG_BPS               (0x00000010)
20 #define MPP_RC_DBG_RC                (0x00000020)
21 #define MPP_RC_DBG_CFG               (0x00000100)
22 #define MPP_RC_DBG_RECORD            (0x00001000)
23 #define MPP_RC_DBG_VBV               (0x00002000)
24 
25 #define mpp_rc_dbg(flag, fmt, ...)   _mpp_dbg(mpp_rc_debug, flag, fmt, ## __VA_ARGS__)
26 #define mpp_rc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_rc_debug, flag, fmt, ## __VA_ARGS__)
27 
28 #define mpp_rc_dbg_func(fmt, ...)    mpp_rc_dbg_f(MPP_RC_DBG_FUNCTION, fmt, ## __VA_ARGS__)
29 #define mpp_rc_dbg_bps(fmt, ...)     mpp_rc_dbg(MPP_RC_DBG_BPS, fmt, ## __VA_ARGS__)
30 #define mpp_rc_dbg_rc(fmt, ...)      mpp_rc_dbg(MPP_RC_DBG_RC, fmt, ## __VA_ARGS__)
31 #define mpp_rc_dbg_cfg(fmt, ...)     mpp_rc_dbg(MPP_RC_DBG_CFG, fmt, ## __VA_ARGS__)
32 #define mpp_rc_dbg_vbv(fmt, ...)     mpp_rc_dbg(MPP_RC_DBG_VBV, fmt, ## __VA_ARGS__)
33 
34 #define SIGN(a)         ((a) < (0) ? (-1) : (1))
35 #define DIV(a, b)       (((a) + (SIGN(a) * (b)) / 2) / (b))
36 
mpp_data_init_v2(MppDataV2 ** data,RK_S32 size,RK_S32 value)37 MPP_RET mpp_data_init_v2(MppDataV2 **data, RK_S32 size, RK_S32 value)
38 {
39     MppDataV2 *p;
40 
41     if (!data || size <= 0) {
42         mpp_err_f("invalid data %p size %d\n", data, size);
43         return MPP_ERR_NULL_PTR;
44     }
45 
46     *data = NULL;
47     p = mpp_malloc_size(MppDataV2, sizeof(MppDataV2) + sizeof(RK_S32) * size);
48     if (!p) {
49         mpp_err_f("malloc size %d failed\n", size);
50         return MPP_ERR_MALLOC;
51     }
52     p->size = size;
53     p->pos_r = 0;
54     p->pos_pw = 0;
55     p->pos_w = 0;
56     p->pos_ahead = 0;
57     p->sum = 0;
58     *data = p;
59 
60     mpp_data_reset_v2(p, value);
61     return MPP_OK;
62 }
63 
mpp_data_deinit_v2(MppDataV2 * p)64 void mpp_data_deinit_v2(MppDataV2 *p)
65 {
66     MPP_FREE(p);
67 }
68 
mpp_data_reset_v2(MppDataV2 * p,RK_S32 val)69 void mpp_data_reset_v2(MppDataV2 *p, RK_S32 val)
70 {
71     RK_S32 *data = p->val;
72     RK_S32 i;
73 
74     p->pos_pw = 0;
75     p->pos_w = 0;
76     p->pos_r = p->size;
77     p->sum = val * p->size;
78 
79     for (i = 0; i < p->size; i++)
80         *data++ = val;
81 }
82 
mpp_data_preset_v2(MppDataV2 * p,RK_S32 val)83 void mpp_data_preset_v2(MppDataV2 *p, RK_S32 val)
84 {
85     mpp_assert(p);
86     if (p->pos_r == p->size) {
87         p->pos_r--;
88         p->sum -= p->val[p->pos_pw];
89     }
90     mpp_assert(p->pos_r < p->size);
91     p->val[p->pos_pw] = val;
92     p->sum += p->val[p->pos_pw];
93     p->pos_pw++;
94     p->pos_r++;
95     if (p->pos_pw >= p->size) {
96         p->pos_pw = 0;
97     }
98     p->pos_ahead++;
99 }
100 
mpp_data_update_v2(MppDataV2 * p,RK_S32 val)101 void mpp_data_update_v2(MppDataV2 *p, RK_S32 val)
102 {
103     if (p->pos_ahead) {
104         p->sum += val - p->val[p->pos_w];
105         p->val[p->pos_w] = val;
106         p->pos_w++;
107         if (p->pos_w >= p->size)
108             p->pos_w = 0;
109 
110         p->pos_ahead--;
111 
112         return;
113     }
114 
115     mpp_assert(p);
116     if (p->pos_r == p->size) {
117         p->pos_r--;
118         p->sum -= p->val[p->pos_w];
119     }
120     mpp_assert(p->pos_r < p->size);
121     p->val[p->pos_w] = val;
122     p->sum += p->val[p->pos_w];
123     p->pos_w++;
124     p->pos_r++;
125     if (p->pos_w >= p->size)
126         p->pos_w = 0;
127 }
128 
mpp_data_get_pre_val_v2(MppDataV2 * p,RK_S32 idx)129 RK_S32 mpp_data_get_pre_val_v2(MppDataV2 *p, RK_S32 idx)
130 {
131     RK_S32 pos = 0;
132 
133     if (idx < 0) {
134         idx = p->size + idx;
135     }
136     mpp_assert(p->pos_w < p->size);
137     mpp_assert(idx < p->size);
138 
139     pos = p->pos_w - 1;
140     if (pos - idx < 0) {
141         RK_S32 pos1 = idx - pos;
142 
143         mpp_assert(p->pos_r == p->size);
144         pos = p->size - pos1;
145     } else {
146         pos = pos - idx;
147     }
148     mpp_assert(pos < p->size);
149     return p->val[pos];
150 }
151 
mpp_data_sum_v2(MppDataV2 * p)152 RK_S32 mpp_data_sum_v2(MppDataV2 *p)
153 {
154     return (RK_S32)p->sum;
155 }
mpp_data_mean_v2(MppDataV2 * p)156 RK_S32 mpp_data_mean_v2(MppDataV2 *p)
157 {
158     RK_S32 mean = (RK_S32)p->sum / p->size;
159 
160     return mean;
161 }
162 
mpp_data_sum_with_ratio_v2(MppDataV2 * p,RK_S32 len,RK_S32 num,RK_S32 denom)163 RK_S32 mpp_data_sum_with_ratio_v2(MppDataV2 *p, RK_S32 len, RK_S32 num, RK_S32 denom)
164 {
165     RK_S32 i;
166     RK_S64 sum = 0;
167     RK_S32 *data = p->val;
168 
169     mpp_assert(len <= p->size);
170 
171     if (num == denom) {
172         for (i = 0; i < len; i++)
173             sum += *data++;
174     } else {
175         // NOTE: use 64bit to avoid 0 in 32bit
176         RK_S64 acc_num = 1;
177         RK_S64 acc_denom = 1;
178 
179         for (i = 0; i < len; i++) {
180             sum += p->val[i] * acc_num / acc_denom;
181             acc_num *= num;
182             acc_denom *= denom;
183         }
184     }
185 
186     return DIV(sum, len);
187 }
188