xref: /rockchip-linux_mpp/mpp/codec/rc/rc_api.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2016 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG "rc_api"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka 
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka #include "mpp_mem.h"
12*437bfbebSnyanmisaka #include "mpp_list.h"
13*437bfbebSnyanmisaka #include "mpp_2str.h"
14*437bfbebSnyanmisaka #include "mpp_common.h"
15*437bfbebSnyanmisaka #include "mpp_singleton.h"
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #include "rc_debug.h"
18*437bfbebSnyanmisaka #include "rc_api.h"
19*437bfbebSnyanmisaka 
20*437bfbebSnyanmisaka #include "h264e_rc.h"
21*437bfbebSnyanmisaka #include "h265e_rc.h"
22*437bfbebSnyanmisaka #include "jpege_rc.h"
23*437bfbebSnyanmisaka #include "vp8e_rc.h"
24*437bfbebSnyanmisaka #include "rc_model_v2_smt.h"
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #define get_srv_rc_api_srv(caller) \
27*437bfbebSnyanmisaka     ({ \
28*437bfbebSnyanmisaka         MppRcApiSrv *__tmp; \
29*437bfbebSnyanmisaka         if (!rc_api_srv) { \
30*437bfbebSnyanmisaka             rc_api_srv_init(); \
31*437bfbebSnyanmisaka         } \
32*437bfbebSnyanmisaka         if (rc_api_srv) { \
33*437bfbebSnyanmisaka             __tmp = rc_api_srv; \
34*437bfbebSnyanmisaka         } else { \
35*437bfbebSnyanmisaka             mpp_err("mpp rc api srv not init at %s : %s\n", __FUNCTION__, caller); \
36*437bfbebSnyanmisaka             __tmp = NULL; \
37*437bfbebSnyanmisaka         } \
38*437bfbebSnyanmisaka         __tmp; \
39*437bfbebSnyanmisaka     })
40*437bfbebSnyanmisaka 
41*437bfbebSnyanmisaka // use class to register RcImplApi
42*437bfbebSnyanmisaka typedef struct RcImplApiNode_t {
43*437bfbebSnyanmisaka     /* list to list in MppRcApiSrv */
44*437bfbebSnyanmisaka     struct list_head    list;
45*437bfbebSnyanmisaka     char                name[64];
46*437bfbebSnyanmisaka     MppCodingType       type;
47*437bfbebSnyanmisaka     RcApiBrief          brief;
48*437bfbebSnyanmisaka     RcImplApi           api;
49*437bfbebSnyanmisaka } RcImplApiNode;
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka typedef struct MppRcApiSrv_t {
52*437bfbebSnyanmisaka     MppMutex            lock;
53*437bfbebSnyanmisaka     RK_U32              api_cnt;
54*437bfbebSnyanmisaka     /* list for list in RcImplApiNode */
55*437bfbebSnyanmisaka     struct list_head    list;
56*437bfbebSnyanmisaka } MppRcApiSrv;
57*437bfbebSnyanmisaka 
58*437bfbebSnyanmisaka static MppRcApiSrv *rc_api_srv = NULL;
59*437bfbebSnyanmisaka 
rc_api_srv_init()60*437bfbebSnyanmisaka static void rc_api_srv_init()
61*437bfbebSnyanmisaka {
62*437bfbebSnyanmisaka     MppRcApiSrv *srv = rc_api_srv;
63*437bfbebSnyanmisaka 
64*437bfbebSnyanmisaka     mpp_env_get_u32("rc_debug", &rc_debug, 0);
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     if (srv)
67*437bfbebSnyanmisaka         return;
68*437bfbebSnyanmisaka 
69*437bfbebSnyanmisaka     srv = mpp_malloc(MppRcApiSrv, 1);
70*437bfbebSnyanmisaka     if (!srv) {
71*437bfbebSnyanmisaka         mpp_err_f("failed to create rc api srv\n");
72*437bfbebSnyanmisaka         return;
73*437bfbebSnyanmisaka     }
74*437bfbebSnyanmisaka 
75*437bfbebSnyanmisaka     rc_api_srv = srv;
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka     mpp_mutex_init(&srv->lock);
78*437bfbebSnyanmisaka     INIT_LIST_HEAD(&srv->list);
79*437bfbebSnyanmisaka     srv->api_cnt = 0;
80*437bfbebSnyanmisaka 
81*437bfbebSnyanmisaka     /* add all default rc apis */
82*437bfbebSnyanmisaka     rc_api_add(&default_h264e);
83*437bfbebSnyanmisaka     rc_api_add(&default_h265e);
84*437bfbebSnyanmisaka     rc_api_add(&default_jpege);
85*437bfbebSnyanmisaka     rc_api_add(&default_vp8e);
86*437bfbebSnyanmisaka     rc_api_add(&smt_h264e);
87*437bfbebSnyanmisaka     rc_api_add(&smt_h265e);
88*437bfbebSnyanmisaka }
89*437bfbebSnyanmisaka 
rc_api_srv_deinit()90*437bfbebSnyanmisaka static void rc_api_srv_deinit()
91*437bfbebSnyanmisaka {
92*437bfbebSnyanmisaka     MppRcApiSrv *srv = rc_api_srv;
93*437bfbebSnyanmisaka 
94*437bfbebSnyanmisaka     if (!srv)
95*437bfbebSnyanmisaka         return;
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     mpp_mutex_lock(&srv->lock);
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka     if (srv->api_cnt) {
100*437bfbebSnyanmisaka         RcImplApiNode *pos, *n;
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka         list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) {
103*437bfbebSnyanmisaka             rc_dbg_impl("%-5s rc api %s is removed\n",
104*437bfbebSnyanmisaka                         strof_coding_type(pos->type), pos->name);
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka             list_del_init(&pos->list);
107*437bfbebSnyanmisaka             MPP_FREE(pos);
108*437bfbebSnyanmisaka             srv->api_cnt--;
109*437bfbebSnyanmisaka         }
110*437bfbebSnyanmisaka 
111*437bfbebSnyanmisaka         mpp_assert(srv->api_cnt == 0);
112*437bfbebSnyanmisaka     }
113*437bfbebSnyanmisaka 
114*437bfbebSnyanmisaka     mpp_mutex_unlock(&srv->lock);
115*437bfbebSnyanmisaka     mpp_mutex_destroy(&srv->lock);
116*437bfbebSnyanmisaka     MPP_FREE(srv);
117*437bfbebSnyanmisaka     rc_api_srv = NULL;
118*437bfbebSnyanmisaka }
119*437bfbebSnyanmisaka 
_rc_api_get(MppRcApiSrv * srv,MppCodingType type,const char * name)120*437bfbebSnyanmisaka static RcImplApi *_rc_api_get(MppRcApiSrv *srv, MppCodingType type, const char *name)
121*437bfbebSnyanmisaka {
122*437bfbebSnyanmisaka     if (!srv->api_cnt)
123*437bfbebSnyanmisaka         return NULL;
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     if (name) {
126*437bfbebSnyanmisaka         RcImplApiNode *pos, *n;
127*437bfbebSnyanmisaka 
128*437bfbebSnyanmisaka         list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) {
129*437bfbebSnyanmisaka             if (type == pos->type &&
130*437bfbebSnyanmisaka                 !strncmp(name, pos->name, sizeof(pos->name) - 1)) {
131*437bfbebSnyanmisaka                 rc_dbg_impl("%-5s rc api %s is selected\n",
132*437bfbebSnyanmisaka                             strof_coding_type(type), pos->name);
133*437bfbebSnyanmisaka                 return &pos->api;
134*437bfbebSnyanmisaka             }
135*437bfbebSnyanmisaka         }
136*437bfbebSnyanmisaka     }
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka     rc_dbg_impl("%-5s rc api %s can not be found\n", strof_coding_type(type), name);
139*437bfbebSnyanmisaka 
140*437bfbebSnyanmisaka     return NULL;
141*437bfbebSnyanmisaka }
142*437bfbebSnyanmisaka 
set_node_api(RcImplApiNode * node,const RcImplApi * api)143*437bfbebSnyanmisaka static void set_node_api(RcImplApiNode *node, const RcImplApi *api)
144*437bfbebSnyanmisaka {
145*437bfbebSnyanmisaka     node->api = *api;
146*437bfbebSnyanmisaka     node->type = api->type;
147*437bfbebSnyanmisaka 
148*437bfbebSnyanmisaka     strncpy(node->name, api->name, sizeof(node->name) - 1);
149*437bfbebSnyanmisaka     node->api.name = api->name;
150*437bfbebSnyanmisaka 
151*437bfbebSnyanmisaka     node->brief.type = api->type;
152*437bfbebSnyanmisaka     node->brief.name = api->name;
153*437bfbebSnyanmisaka }
154*437bfbebSnyanmisaka 
rc_api_add(const RcImplApi * api)155*437bfbebSnyanmisaka MPP_RET rc_api_add(const RcImplApi *api)
156*437bfbebSnyanmisaka {
157*437bfbebSnyanmisaka     MppRcApiSrv *srv = get_srv_rc_api_srv(__FUNCTION__);
158*437bfbebSnyanmisaka     RcImplApiNode *node = NULL;
159*437bfbebSnyanmisaka     RcImplApi *node_api = NULL;
160*437bfbebSnyanmisaka 
161*437bfbebSnyanmisaka     if (!api) {
162*437bfbebSnyanmisaka         mpp_err_f("unable to register NULL api\n");
163*437bfbebSnyanmisaka         return MPP_NOK;
164*437bfbebSnyanmisaka     }
165*437bfbebSnyanmisaka 
166*437bfbebSnyanmisaka     if (!srv)
167*437bfbebSnyanmisaka         return MPP_NOK;
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka     mpp_mutex_lock(&srv->lock);
170*437bfbebSnyanmisaka 
171*437bfbebSnyanmisaka     /* search for same node for replacement */
172*437bfbebSnyanmisaka     node_api = _rc_api_get(srv, api->type, api->name);
173*437bfbebSnyanmisaka 
174*437bfbebSnyanmisaka     if (!node_api) {
175*437bfbebSnyanmisaka         node = mpp_malloc(RcImplApiNode, 1);
176*437bfbebSnyanmisaka         if (!node) {
177*437bfbebSnyanmisaka             mpp_err_f("failed to create api node\n");
178*437bfbebSnyanmisaka             mpp_mutex_unlock(&srv->lock);
179*437bfbebSnyanmisaka             return MPP_NOK;
180*437bfbebSnyanmisaka         }
181*437bfbebSnyanmisaka 
182*437bfbebSnyanmisaka         INIT_LIST_HEAD(&node->list);
183*437bfbebSnyanmisaka         list_add_tail(&node->list, &srv->list);
184*437bfbebSnyanmisaka 
185*437bfbebSnyanmisaka         srv->api_cnt++;
186*437bfbebSnyanmisaka         rc_dbg_impl("%-5s rc api %s is added\n", strof_coding_type(api->type), api->name);
187*437bfbebSnyanmisaka     } else {
188*437bfbebSnyanmisaka         node = container_of(node_api, RcImplApiNode, api);
189*437bfbebSnyanmisaka         rc_dbg_impl("%-5s rc api %s is updated\n", strof_coding_type(api->type), api->name);
190*437bfbebSnyanmisaka     }
191*437bfbebSnyanmisaka 
192*437bfbebSnyanmisaka     set_node_api(node, api);
193*437bfbebSnyanmisaka     mpp_mutex_unlock(&srv->lock);
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     return MPP_OK;
196*437bfbebSnyanmisaka }
197*437bfbebSnyanmisaka 
rc_api_get(MppCodingType type,const char * name)198*437bfbebSnyanmisaka RcImplApi *rc_api_get(MppCodingType type, const char *name)
199*437bfbebSnyanmisaka {
200*437bfbebSnyanmisaka     MppRcApiSrv *srv = get_srv_rc_api_srv(__FUNCTION__);
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka     if (!srv)
203*437bfbebSnyanmisaka         return NULL;
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka     return _rc_api_get(srv, type, name);
206*437bfbebSnyanmisaka }
207*437bfbebSnyanmisaka 
rc_api_get_all(MppRcApiSrv * srv,RcApiBrief * brief,RK_S32 * count,RK_S32 max_count)208*437bfbebSnyanmisaka MPP_RET rc_api_get_all(MppRcApiSrv *srv, RcApiBrief *brief, RK_S32 *count, RK_S32 max_count)
209*437bfbebSnyanmisaka {
210*437bfbebSnyanmisaka     RcImplApiNode *pos, *n;
211*437bfbebSnyanmisaka     RK_S32 cnt = 0;
212*437bfbebSnyanmisaka 
213*437bfbebSnyanmisaka     mpp_mutex_lock(&srv->lock);
214*437bfbebSnyanmisaka 
215*437bfbebSnyanmisaka     list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) {
216*437bfbebSnyanmisaka         if (cnt >= max_count)
217*437bfbebSnyanmisaka             break;
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka         brief[cnt++] = pos->brief;
220*437bfbebSnyanmisaka     }
221*437bfbebSnyanmisaka 
222*437bfbebSnyanmisaka     *count = cnt;
223*437bfbebSnyanmisaka     mpp_mutex_unlock(&srv->lock);
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka     return MPP_OK;
226*437bfbebSnyanmisaka }
227*437bfbebSnyanmisaka 
rc_api_get_by_type(MppRcApiSrv * srv,RcApiBrief * brief,RK_S32 * count,RK_S32 max_count,MppCodingType type)228*437bfbebSnyanmisaka MPP_RET rc_api_get_by_type(MppRcApiSrv *srv, RcApiBrief *brief, RK_S32 *count,
229*437bfbebSnyanmisaka                            RK_S32 max_count, MppCodingType type)
230*437bfbebSnyanmisaka {
231*437bfbebSnyanmisaka     RcImplApiNode *pos, *n;
232*437bfbebSnyanmisaka     RK_S32 cnt = 0;
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka     mpp_mutex_lock(&srv->lock);
235*437bfbebSnyanmisaka 
236*437bfbebSnyanmisaka     list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) {
237*437bfbebSnyanmisaka         if (cnt >= max_count)
238*437bfbebSnyanmisaka             break;
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka         if (pos->type != type)
241*437bfbebSnyanmisaka             continue;
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka         brief[cnt++] = pos->brief;
244*437bfbebSnyanmisaka     }
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka     *count = cnt;
247*437bfbebSnyanmisaka     mpp_mutex_unlock(&srv->lock);
248*437bfbebSnyanmisaka 
249*437bfbebSnyanmisaka     return MPP_OK;
250*437bfbebSnyanmisaka }
251*437bfbebSnyanmisaka 
rc_brief_get_all(RcApiQueryAll * query)252*437bfbebSnyanmisaka MPP_RET rc_brief_get_all(RcApiQueryAll *query)
253*437bfbebSnyanmisaka {
254*437bfbebSnyanmisaka     MppRcApiSrv *srv = rc_api_srv;
255*437bfbebSnyanmisaka     RcApiBrief *brief;
256*437bfbebSnyanmisaka     RK_S32 *count;
257*437bfbebSnyanmisaka     RK_S32 max_count;
258*437bfbebSnyanmisaka 
259*437bfbebSnyanmisaka     if (!srv)
260*437bfbebSnyanmisaka         return MPP_NOK;
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka     if (!query) {
263*437bfbebSnyanmisaka         mpp_err_f("invalide NULL query input\n");
264*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
265*437bfbebSnyanmisaka     }
266*437bfbebSnyanmisaka 
267*437bfbebSnyanmisaka     brief = query->brief;
268*437bfbebSnyanmisaka     count = &query->count;
269*437bfbebSnyanmisaka     max_count = query->max_count;
270*437bfbebSnyanmisaka 
271*437bfbebSnyanmisaka     if (!brief || max_count <= 0) {
272*437bfbebSnyanmisaka         mpp_err_f("invalide brief buffer %p max count %d\n", brief, max_count);
273*437bfbebSnyanmisaka         return MPP_NOK;
274*437bfbebSnyanmisaka     }
275*437bfbebSnyanmisaka 
276*437bfbebSnyanmisaka     return rc_api_get_all(srv, brief, count, max_count);
277*437bfbebSnyanmisaka }
278*437bfbebSnyanmisaka 
rc_brief_get_by_type(RcApiQueryType * query)279*437bfbebSnyanmisaka MPP_RET rc_brief_get_by_type(RcApiQueryType *query)
280*437bfbebSnyanmisaka {
281*437bfbebSnyanmisaka     MppRcApiSrv *srv = rc_api_srv;
282*437bfbebSnyanmisaka     RcApiBrief *brief;
283*437bfbebSnyanmisaka     RK_S32 *count;
284*437bfbebSnyanmisaka     RK_S32 max_count;
285*437bfbebSnyanmisaka     MppCodingType type;
286*437bfbebSnyanmisaka 
287*437bfbebSnyanmisaka     if (!srv)
288*437bfbebSnyanmisaka         return MPP_NOK;
289*437bfbebSnyanmisaka 
290*437bfbebSnyanmisaka     if (!query) {
291*437bfbebSnyanmisaka         mpp_err_f("invalide NULL query input\n");
292*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
293*437bfbebSnyanmisaka     }
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka     brief = query->brief;
296*437bfbebSnyanmisaka     count = &query->count;
297*437bfbebSnyanmisaka     max_count = query->max_count;
298*437bfbebSnyanmisaka     type = query->type;
299*437bfbebSnyanmisaka 
300*437bfbebSnyanmisaka     if (!brief || max_count <= 0) {
301*437bfbebSnyanmisaka         mpp_err_f("invalide brief buffer %p max count %d type %x\n",
302*437bfbebSnyanmisaka                   brief, max_count, type);
303*437bfbebSnyanmisaka         return MPP_NOK;
304*437bfbebSnyanmisaka     }
305*437bfbebSnyanmisaka 
306*437bfbebSnyanmisaka     return rc_api_get_by_type(srv, brief, count, max_count, type);
307*437bfbebSnyanmisaka }
308*437bfbebSnyanmisaka 
309*437bfbebSnyanmisaka MPP_SINGLETON(MPP_SGLN_ENC_RC_API, rc_api, rc_api_srv_init, rc_api_srv_deinit)
310