1 /*
2 * Copyright 2016 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "rc_base"
18
19 #include <math.h>
20 #include <memory.h>
21
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_common.h"
25
26 #include "rc_base.h"
27
28 #define MPP_RC_DBG_FUNCTION (0x00000001)
29 #define MPP_RC_DBG_BPS (0x00000010)
30 #define MPP_RC_DBG_RC (0x00000020)
31 #define MPP_RC_DBG_CFG (0x00000100)
32 #define MPP_RC_DBG_RECORD (0x00001000)
33 #define MPP_RC_DBG_VBV (0x00002000)
34
35 #define mpp_rc_dbg(flag, fmt, ...) _mpp_dbg(mpp_rc_debug, flag, fmt, ## __VA_ARGS__)
36 #define mpp_rc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_rc_debug, flag, fmt, ## __VA_ARGS__)
37
38 #define mpp_rc_dbg_func(fmt, ...) mpp_rc_dbg_f(MPP_RC_DBG_FUNCTION, fmt, ## __VA_ARGS__)
39 #define mpp_rc_dbg_bps(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_BPS, fmt, ## __VA_ARGS__)
40 #define mpp_rc_dbg_rc(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_RC, fmt, ## __VA_ARGS__)
41 #define mpp_rc_dbg_cfg(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_CFG, fmt, ## __VA_ARGS__)
42 #define mpp_rc_dbg_vbv(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_VBV, fmt, ## __VA_ARGS__)
43
44 #define SIGN(a) ((a) < (0) ? (-1) : (1))
45 #define DIV(a, b) (((a) + (SIGN(a) * (b)) / 2) / (b))
46
mpp_data_init_v2(MppDataV2 ** data,RK_S32 size,RK_S32 value)47 MPP_RET mpp_data_init_v2(MppDataV2 **data, RK_S32 size, RK_S32 value)
48 {
49 if (NULL == data || size <= 0) {
50 mpp_err_f("invalid data %p size %d\n", data, size);
51 return MPP_ERR_NULL_PTR;
52 }
53
54 *data = NULL;
55 MppDataV2 *p = mpp_malloc_size(MppDataV2, sizeof(MppDataV2) + sizeof(RK_S32) * size);
56 if (NULL == p) {
57 mpp_err_f("malloc size %d failed\n", size);
58 return MPP_ERR_MALLOC;
59 }
60 p->size = size;
61 p->pos_r = 0;
62 p->pos_pw = 0;
63 p->pos_w = 0;
64 p->pos_ahead = 0;
65 p->sum = 0;
66 *data = p;
67
68 mpp_data_reset_v2(p, value);
69 return MPP_OK;
70 }
71
mpp_data_deinit_v2(MppDataV2 * p)72 void mpp_data_deinit_v2(MppDataV2 *p)
73 {
74 MPP_FREE(p);
75 }
76
mpp_data_reset_v2(MppDataV2 * p,RK_S32 val)77 void mpp_data_reset_v2(MppDataV2 *p, RK_S32 val)
78 {
79 RK_S32 i;
80 RK_S32 *data = p->val;
81
82 p->pos_pw = 0;
83 p->pos_w = 0;
84 p->pos_r = p->size;
85 p->sum = val * p->size;
86
87 for (i = 0; i < p->size; i++)
88 *data++ = val;
89 }
90
mpp_data_preset_v2(MppDataV2 * p,RK_S32 val)91 void mpp_data_preset_v2(MppDataV2 *p, RK_S32 val)
92 {
93 mpp_assert(p);
94 if (p->pos_r == p->size) {
95 p->pos_r--;
96 p->sum -= p->val[p->pos_pw];
97 }
98 mpp_assert(p->pos_r < p->size);
99 p->val[p->pos_pw] = val;
100 p->sum += p->val[p->pos_pw];
101 p->pos_pw++;
102 p->pos_r++;
103 if (p->pos_pw >= p->size) {
104 p->pos_pw = 0;
105 }
106 p->pos_ahead++;
107 }
108
mpp_data_update_v2(MppDataV2 * p,RK_S32 val)109 void mpp_data_update_v2(MppDataV2 *p, RK_S32 val)
110 {
111 if (p->pos_ahead) {
112 p->sum += val - p->val[p->pos_w];
113 p->val[p->pos_w] = val;
114 p->pos_w++;
115 if (p->pos_w >= p->size)
116 p->pos_w = 0;
117
118 p->pos_ahead--;
119
120 return;
121 }
122
123 mpp_assert(p);
124 if (p->pos_r == p->size) {
125 p->pos_r--;
126 p->sum -= p->val[p->pos_w];
127 }
128 mpp_assert(p->pos_r < p->size);
129 p->val[p->pos_w] = val;
130 p->sum += p->val[p->pos_w];
131 p->pos_w++;
132 p->pos_r++;
133 if (p->pos_w >= p->size)
134 p->pos_w = 0;
135 }
136
mpp_data_get_pre_val_v2(MppDataV2 * p,RK_S32 idx)137 RK_S32 mpp_data_get_pre_val_v2(MppDataV2 *p, RK_S32 idx)
138 {
139 if (idx < 0) {
140 idx = p->size + idx;
141 }
142 mpp_assert(p->pos_w < p->size);
143 mpp_assert(idx < p->size);
144 RK_S32 pos = 0;
145
146 pos = p->pos_w - 1;
147 if (pos - idx < 0) {
148 mpp_assert(p->pos_r == p->size);
149 RK_S32 pos1 = idx - pos;
150 pos = p->size - pos1;
151 } else {
152 pos = pos - idx;
153 }
154 mpp_assert(pos < p->size);
155 return p->val[pos];
156 }
157
mpp_data_sum_v2(MppDataV2 * p)158 RK_S32 mpp_data_sum_v2(MppDataV2 *p)
159 {
160 return (RK_S32)p->sum;
161 }
mpp_data_mean_v2(MppDataV2 * p)162 RK_S32 mpp_data_mean_v2(MppDataV2 *p)
163 {
164 RK_S32 mean = (RK_S32)p->sum / p->size;
165 return mean;
166 }
167
mpp_data_sum_with_ratio_v2(MppDataV2 * p,RK_S32 len,RK_S32 num,RK_S32 denorm)168 RK_S32 mpp_data_sum_with_ratio_v2(MppDataV2 *p, RK_S32 len, RK_S32 num, RK_S32 denorm)
169 {
170 mpp_assert(p);
171
172 RK_S32 i;
173 RK_S64 sum = 0;
174 RK_S32 *data = p->val;
175
176 mpp_assert(len <= p->size);
177
178 if (num == denorm) {
179 for (i = 0; i < len; i++)
180 sum += *data++;
181 } else {
182 // NOTE: use 64bit to avoid 0 in 32bit
183 RK_S64 acc_num = 1;
184 RK_S64 acc_denorm = 1;
185
186 for (i = 0; i < len; i++) {
187 sum += p->val[i] * acc_num / acc_denorm;
188 acc_num *= num;
189 acc_denorm *= denorm;
190 }
191 }
192
193 return DIV(sum, len);
194 }
195