diff --git a/mpp/codec/rc/CMakeLists.txt b/mpp/codec/rc/CMakeLists.txt index dd492bad..0c8cb229 100644 --- a/mpp/codec/rc/CMakeLists.txt +++ b/mpp/codec/rc/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(enc_rc STATIC rc_data_base.cpp rc_data_impl.cpp rc_data.cpp - rc_impl.cpp + rc_api.c rc.cpp rc_base.cpp ) diff --git a/mpp/codec/rc/rc.cpp b/mpp/codec/rc/rc.cpp index 780fc155..75800cfb 100644 --- a/mpp/codec/rc/rc.cpp +++ b/mpp/codec/rc/rc.cpp @@ -26,7 +26,7 @@ #include "rc_debug.h" #include "rc.h" -#include "rc_impl.h" +#include "rc_api.h" #include "rc_base.h" typedef struct MppRcImpl_t { @@ -60,7 +60,7 @@ MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char **request_name) rc_dbg_func("enter type %x name %s\n", type, name); - RcImplApi *api = RcImplApiService::get_instance()->api_get(type, name); + RcImplApi *api = rc_api_get(type, name); mpp_assert(api); diff --git a/mpp/codec/rc/rc_api.c b/mpp/codec/rc/rc_api.c new file mode 100644 index 00000000..7049532f --- /dev/null +++ b/mpp/codec/rc/rc_api.c @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2016 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "rc_api" + +#include + +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_list.h" +#include "mpp_2str.h" +#include "mpp_common.h" +#include "mpp_singleton.h" + +#include "rc_debug.h" +#include "rc_api.h" + +#include "h264e_rc.h" +#include "h265e_rc.h" +#include "jpege_rc.h" +#include "vp8e_rc.h" +#include "rc_model_v2_smt.h" + +#define get_srv_rc_api_srv(caller) \ + ({ \ + MppRcApiSrv *__tmp; \ + if (!rc_api_srv) { \ + rc_api_srv_init(); \ + } \ + if (rc_api_srv) { \ + __tmp = rc_api_srv; \ + } else { \ + mpp_err("mpp rc api srv not init at %s : %s\n", __FUNCTION__, caller); \ + __tmp = NULL; \ + } \ + __tmp; \ + }) + +// use class to register RcImplApi +typedef struct RcImplApiNode_t { + /* list to list in MppRcApiSrv */ + struct list_head list; + char name[64]; + MppCodingType type; + RcApiBrief brief; + RcImplApi api; +} RcImplApiNode; + +typedef struct MppRcApiSrv_t { + MppMutex lock; + RK_U32 api_cnt; + /* list for list in RcImplApiNode */ + struct list_head list; +} MppRcApiSrv; + +static MppRcApiSrv *rc_api_srv = NULL; + +static void rc_api_srv_init() +{ + MppRcApiSrv *srv = rc_api_srv; + + mpp_env_get_u32("rc_debug", &rc_debug, 0); + + if (srv) + return; + + srv = mpp_malloc(MppRcApiSrv, 1); + if (!srv) { + mpp_err_f("failed to create rc api srv\n"); + return; + } + + rc_api_srv = srv; + + mpp_mutex_init(&srv->lock); + INIT_LIST_HEAD(&srv->list); + srv->api_cnt = 0; + + /* add all default rc apis */ + rc_api_add(&default_h264e); + rc_api_add(&default_h265e); + rc_api_add(&default_jpege); + rc_api_add(&default_vp8e); + rc_api_add(&smt_h264e); + rc_api_add(&smt_h265e); +} + +static void rc_api_srv_deinit() +{ + MppRcApiSrv *srv = rc_api_srv; + + if (!srv) + return; + + mpp_mutex_lock(&srv->lock); + + if (srv->api_cnt) { + RcImplApiNode *pos, *n; + + list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) { + rc_dbg_impl("%-5s rc api %s is removed\n", + strof_coding_type(pos->type), pos->name); + + list_del_init(&pos->list); + MPP_FREE(pos); + srv->api_cnt--; + } + + mpp_assert(srv->api_cnt == 0); + } + + mpp_mutex_unlock(&srv->lock); + mpp_mutex_destroy(&srv->lock); + MPP_FREE(srv); + rc_api_srv = NULL; +} + +static RcImplApi *_rc_api_get(MppRcApiSrv *srv, MppCodingType type, const char *name) +{ + if (!srv->api_cnt) + return NULL; + + if (name) { + RcImplApiNode *pos, *n; + + list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) { + if (type == pos->type && + !strncmp(name, pos->name, sizeof(pos->name) - 1)) { + rc_dbg_impl("%-5s rc api %s is selected\n", + strof_coding_type(type), pos->name); + return &pos->api; + } + } + } + + rc_dbg_impl("%-5s rc api %s can not be found\n", strof_coding_type(type), name); + + return NULL; +} + +static void set_node_api(RcImplApiNode *node, const RcImplApi *api) +{ + node->api = *api; + node->type = api->type; + + strncpy(node->name, api->name, sizeof(node->name) - 1); + node->api.name = api->name; + + node->brief.type = api->type; + node->brief.name = api->name; +} + +MPP_RET rc_api_add(const RcImplApi *api) +{ + MppRcApiSrv *srv = get_srv_rc_api_srv(__FUNCTION__); + RcImplApiNode *node = NULL; + RcImplApi *node_api = NULL; + + if (!api) { + mpp_err_f("unable to register NULL api\n"); + return MPP_NOK; + } + + if (!srv) + return MPP_NOK; + + mpp_mutex_lock(&srv->lock); + + /* search for same node for replacement */ + node_api = _rc_api_get(srv, api->type, api->name); + + if (!node_api) { + node = mpp_malloc(RcImplApiNode, 1); + if (!node) { + mpp_err_f("failed to create api node\n"); + mpp_mutex_unlock(&srv->lock); + return MPP_NOK; + } + + INIT_LIST_HEAD(&node->list); + list_add_tail(&node->list, &srv->list); + + srv->api_cnt++; + rc_dbg_impl("%-5s rc api %s is added\n", strof_coding_type(api->type), api->name); + } else { + node = container_of(node_api, RcImplApiNode, api); + rc_dbg_impl("%-5s rc api %s is updated\n", strof_coding_type(api->type), api->name); + } + + set_node_api(node, api); + mpp_mutex_unlock(&srv->lock); + + return MPP_OK; +} + +RcImplApi *rc_api_get(MppCodingType type, const char *name) +{ + MppRcApiSrv *srv = get_srv_rc_api_srv(__FUNCTION__); + + if (!srv) + return NULL; + + return _rc_api_get(srv, type, name); +} + +MPP_RET rc_api_get_all(MppRcApiSrv *srv, RcApiBrief *brief, RK_S32 *count, RK_S32 max_count) +{ + RcImplApiNode *pos, *n; + RK_S32 cnt = 0; + + mpp_mutex_lock(&srv->lock); + + list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) { + if (cnt >= max_count) + break; + + brief[cnt++] = pos->brief; + } + + *count = cnt; + mpp_mutex_unlock(&srv->lock); + + return MPP_OK; +} + +MPP_RET rc_api_get_by_type(MppRcApiSrv *srv, RcApiBrief *brief, RK_S32 *count, + RK_S32 max_count, MppCodingType type) +{ + RcImplApiNode *pos, *n; + RK_S32 cnt = 0; + + mpp_mutex_lock(&srv->lock); + + list_for_each_entry_safe(pos, n, &srv->list, RcImplApiNode, list) { + if (cnt >= max_count) + break; + + if (pos->type != type) + continue; + + brief[cnt++] = pos->brief; + } + + *count = cnt; + mpp_mutex_unlock(&srv->lock); + + return MPP_OK; +} + +MPP_RET rc_brief_get_all(RcApiQueryAll *query) +{ + MppRcApiSrv *srv = rc_api_srv; + RcApiBrief *brief; + RK_S32 *count; + RK_S32 max_count; + + if (!srv) + return MPP_NOK; + + if (!query) { + mpp_err_f("invalide NULL query input\n"); + return MPP_ERR_NULL_PTR; + } + + brief = query->brief; + count = &query->count; + max_count = query->max_count; + + if (!brief || max_count <= 0) { + mpp_err_f("invalide brief buffer %p max count %d\n", brief, max_count); + return MPP_NOK; + } + + return rc_api_get_all(srv, brief, count, max_count); +} + +MPP_RET rc_brief_get_by_type(RcApiQueryType *query) +{ + MppRcApiSrv *srv = rc_api_srv; + RcApiBrief *brief; + RK_S32 *count; + RK_S32 max_count; + MppCodingType type; + + if (!srv) + return MPP_NOK; + + if (!query) { + mpp_err_f("invalide NULL query input\n"); + return MPP_ERR_NULL_PTR; + } + + brief = query->brief; + count = &query->count; + max_count = query->max_count; + type = query->type; + + if (!brief || max_count <= 0) { + mpp_err_f("invalide brief buffer %p max count %d type %x\n", + brief, max_count, type); + return MPP_NOK; + } + + return rc_api_get_by_type(srv, brief, count, max_count, type); +} + +MPP_SINGLETON(MPP_SGLN_ENC_RC_API, rc_api, rc_api_srv_init, rc_api_srv_deinit) diff --git a/mpp/codec/rc/rc_api.h b/mpp/codec/rc/rc_api.h new file mode 100644 index 00000000..aa5e0e3a --- /dev/null +++ b/mpp/codec/rc/rc_api.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2016 Rockchip Electronics Co., Ltd. + */ + +#ifndef __RC_IMPL_H__ +#define __RC_IMPL_H__ + +#include "mpp_rc_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +RcImplApi *rc_api_get(MppCodingType type, const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* __RC_IMPL_H__ */ diff --git a/mpp/codec/rc/rc_debug.h b/mpp/codec/rc/rc_debug.h index 754f5627..1c849baa 100644 --- a/mpp/codec/rc/rc_debug.h +++ b/mpp/codec/rc/rc_debug.h @@ -34,7 +34,7 @@ #define rc_dbg_f(flag, fmt, ...) _mpp_dbg_f(rc_debug, flag, fmt, ## __VA_ARGS__) #define rc_dbg_func(fmt, ...) rc_dbg_f(RC_DBG_FUNCTION, fmt, ## __VA_ARGS__) -#define rc_dbg_impl(fmt, ...) rc_dbg_f(RC_DBG_API_IMPL, fmt, ## __VA_ARGS__) +#define rc_dbg_impl(fmt, ...) rc_dbg(RC_DBG_API_IMPL, fmt, ## __VA_ARGS__) #define rc_dbg_fps(fmt, ...) rc_dbg_f(RC_DBG_FPS, fmt, ## __VA_ARGS__) #define rc_dbg_bps(fmt, ...) rc_dbg_f(RC_DBG_BPS, fmt, ## __VA_ARGS__) #define rc_dbg_rc(fmt, ...) rc_dbg_f(RC_DBG_RC, fmt, ## __VA_ARGS__) diff --git a/mpp/codec/rc/rc_impl.cpp b/mpp/codec/rc/rc_impl.cpp deleted file mode 100644 index c20acd77..00000000 --- a/mpp/codec/rc/rc_impl.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "rc_impl" - -#include - -#include "mpp_env.h" -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "rc_debug.h" -#include "rc_impl.h" - -#include "h264e_rc.h" -#include "h265e_rc.h" -#include "jpege_rc.h" -#include "vp8e_rc.h" -#include "rc_model_v2_smt.h" - -const RcImplApi *rc_apis[] = { - &default_h264e, - &default_h265e, - &default_jpege, - &default_vp8e, - &smt_h264e, - &smt_h265e, -}; - -// use class to register RcImplApi -typedef struct RcImplApiNode_t { - struct list_head list; - char name[32]; - MppCodingType type; - RcApiBrief brief; - RcImplApi api; -} RcImplApiNode; - -static void set_node_api(RcImplApiNode *node, const RcImplApi *api) -{ - node->api = *api; - node->type = api->type; - - strncpy(node->name, api->name, sizeof(node->name) - 1); - node->api.name = api->name; - - node->brief.type = api->type; - node->brief.name = api->name; -} - -RcImplApiService::RcImplApiService() -{ - RK_U32 i; - - mpp_env_get_u32("rc_debug", &rc_debug, 0); - - INIT_LIST_HEAD(&mApis); - mApiCount = 0; - - mpp_mutex_init(&lock); - for (i = 0; i < MPP_ARRAY_ELEMS(rc_apis); i++) - api_add(rc_apis[i]); -} - -RcImplApiService::~RcImplApiService() -{ - RcImplApiNode *pos, *n; - - mpp_mutex_lock(&lock); - - list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) { - MPP_FREE(pos); - mApiCount--; - } - - mpp_assert(mApiCount == 0); - - mpp_mutex_unlock(&lock); - mpp_mutex_destroy(&lock); -} - -MPP_RET RcImplApiService::api_add(const RcImplApi *api) -{ - mpp_mutex_lock(&lock); - - if (NULL == api) { - mpp_err_f("unable to register NULL api\n"); - mpp_mutex_unlock(&lock); - return MPP_NOK; - } - - /* search for same node for replacement */ - RcImplApiNode *node = NULL; - RcImplApi *node_api = api_get(api->type, api->name); - - if (NULL == node_api) { - node = mpp_malloc(RcImplApiNode, 1); - if (NULL == node) { - mpp_err_f("failed to create api node\n"); - mpp_mutex_unlock(&lock); - return MPP_NOK; - } - - INIT_LIST_HEAD(&node->list); - list_add_tail(&node->list, &mApis); - - mApiCount++; - rc_dbg_impl("rc impl %s type %x is added\n", api->name, api->type); - } else { - node = container_of(node_api, RcImplApiNode, api); - rc_dbg_impl("rc impl %s type %x is updated\n", api->name, api->type); - } - - set_node_api(node, api); - mpp_mutex_unlock(&lock); - - return MPP_OK; -} - -RcImplApi *RcImplApiService::api_get(MppCodingType type, const char *name) -{ - mpp_mutex_lock(&lock); - - if (!mApiCount) { - mpp_mutex_unlock(&lock); - return NULL; - } - - if (name) { - RcImplApiNode *pos, *n; - - list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) { - if (type == pos->type && - !strncmp(name, pos->name, sizeof(pos->name) - 1)) { - rc_dbg_impl("rc impl %s is selected\n", pos->name); - mpp_mutex_unlock(&lock); - return &pos->api; - } - } - } - - rc_dbg_impl("failed to find rc impl %s type %x\n", name, type); - mpp_mutex_unlock(&lock); - - return NULL; -} - -MPP_RET RcImplApiService::api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 max_count) -{ - RcImplApiNode *pos, *n; - RK_S32 cnt = 0; - - mpp_mutex_lock(&lock); - - list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) { - if (cnt >= max_count) - break; - - brief[cnt++] = pos->brief; - } - - *count = cnt; - mpp_mutex_unlock(&lock); - - return MPP_OK; -} - -MPP_RET RcImplApiService::api_get_by_type(RcApiBrief *brief, RK_S32 *count, - RK_S32 max_count, MppCodingType type) -{ - RcImplApiNode *pos, *n; - RK_S32 cnt = 0; - - mpp_mutex_lock(&lock); - - list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) { - if (cnt >= max_count) - break; - - if (pos->type != type) - continue; - - brief[cnt++] = pos->brief; - } - - *count = cnt; - mpp_mutex_unlock(&lock); - - return MPP_OK; -} - -MPP_RET rc_api_add(const RcImplApi *api) -{ - return RcImplApiService::get_instance()->api_add(api); -} - -MPP_RET rc_brief_get_all(RcApiQueryAll *query) -{ - RcApiBrief *brief; - RK_S32 *count; - RK_S32 max_count; - - if (NULL == query) { - mpp_err_f("invalide NULL query input\n"); - return MPP_ERR_NULL_PTR; - } - - brief = query->brief; - count = &query->count; - max_count = query->max_count; - - if (NULL == brief || max_count <= 0) { - mpp_err_f("invalide brief buffer %p max count %d\n", brief, max_count); - return MPP_NOK; - } - - return RcImplApiService::get_instance()->api_get_all(brief, count, max_count); -} - -MPP_RET rc_brief_get_by_type(RcApiQueryType *query) -{ - RcApiBrief *brief; - RK_S32 *count; - RK_S32 max_count; - MppCodingType type; - - if (NULL == query) { - mpp_err_f("invalide NULL query input\n"); - return MPP_ERR_NULL_PTR; - } - - brief = query->brief; - count = &query->count; - max_count = query->max_count; - type = query->type; - - if (NULL == brief || max_count <= 0) { - mpp_err_f("invalide brief buffer %p max count %d type %x\n", - brief, max_count, type); - return MPP_NOK; - } - - return RcImplApiService::get_instance()->api_get_by_type(brief, count, max_count, type); -} diff --git a/mpp/codec/rc/rc_impl.h b/mpp/codec/rc/rc_impl.h deleted file mode 100644 index 3675895e..00000000 --- a/mpp/codec/rc/rc_impl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __RC_IMPL_H__ -#define __RC_IMPL_H__ - -#include "mpp_list.h" -#include "mpp_rc_api.h" - -#define MAX_RC_API_COUNT 32 - -#ifdef __cplusplus - -class RcImplApiService -{ -private: - // avoid any unwanted function - RcImplApiService(); - ~RcImplApiService(); - RcImplApiService(const RcImplApiService &); - RcImplApiService &operator=(const RcImplApiService &); - - MppMutex lock; - RK_U32 mApiCount; - - struct list_head mApis; - -public: - static RcImplApiService *get_instance() { - static RcImplApiService instance; - RcImplApiService * ret; - - mpp_mutex_lock(&instance.lock); - ret = &instance; - mpp_mutex_unlock(&instance.lock); - return ret; - } - - MPP_RET api_add(const RcImplApi *api); - RcImplApi *api_get(MppCodingType type, const char *name); - - MPP_RET api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 max_count); - MPP_RET api_get_by_type(RcApiBrief *brief, RK_S32 *count, - RK_S32 max_count, MppCodingType type); - MppMutex *get_lock() {return &lock; }; -}; - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __RC_IMPL_H__ */ diff --git a/osal/inc/mpp_singleton.h b/osal/inc/mpp_singleton.h index aff14c58..ea3436ed 100644 --- a/osal/inc/mpp_singleton.h +++ b/osal/inc/mpp_singleton.h @@ -40,7 +40,7 @@ typedef enum MppSingletonId_e { /* userspace system module */ MPP_SGLN_ENC_CFG, MPP_SGLN_DEC_CFG, - MPP_SGLN_DEC_RC_API, + MPP_SGLN_ENC_RC_API, /* max count for start init process */ MPP_SGLN_MAX_CNT,