xref: /OK3568_Linux_fs/external/mpp/mpp/codec/rc/rc_base.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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