diff --git a/build/android/Android.mk b/build/android/Android.mk index 7dbff1ce..649ea36a 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -1,12 +1,13 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := libmpp_legacy +LOCAL_MODULE := libvpu +LOCAL_MODULE_SRC := libmpp_legacy LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_STEM := $(LOCAL_MODULE) LOCAL_MODULE_SUFFIX := .so -LOCAL_SRC_FILES := $(TOP)/mpp/legacy/$(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_SRC_FILES := $(TOP)/mpp/legacy/$(LOCAL_MODULE_SRC)$(LOCAL_MODULE_SUFFIX) include $(BUILD_PREBUILT) include $(CLEAR_VARS) diff --git a/mpp/codec/dec/h265/h265d_parser.h b/mpp/codec/dec/h265/h265d_parser.h index eb77883c..fc026df7 100644 --- a/mpp/codec/dec/h265/h265d_parser.h +++ b/mpp/codec/dec/h265/h265d_parser.h @@ -605,7 +605,7 @@ typedef struct HEVCContext { enum NALUnitType nal_unit_type; RK_S32 temporal_id; ///< temporal_id_plus1 - 1 HEVCFrame *ref; - HEVCFrame DPB[32]; + HEVCFrame DPB[MAX_DPB_SIZE]; RK_S32 poc; RK_S32 pocTid0; RK_S32 slice_idx; ///< number of the slice being currently decoded diff --git a/mpp/codec/dec/h265/h265d_refs.c b/mpp/codec/dec/h265/h265d_refs.c index a500909d..2f3ea3be 100644 --- a/mpp/codec/dec/h265/h265d_refs.c +++ b/mpp/codec/dec/h265/h265d_refs.c @@ -94,6 +94,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s) mpp_frame_set_hor_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_width, 256) | 256); mpp_frame_set_ver_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_height, 8)); + h265d_dbg(H265D_DBG_GLOBAL,"w_stride %d h_stride %d\n", s->h265dctx->coded_width, s->h265dctx->coded_height); // frame->frame->color_type = s->h265dctx->pix_fmt; // if (!frame->frame->sample_aspect_ratio.num) diff --git a/mpp/legacy/CMakeLists.txt b/mpp/legacy/CMakeLists.txt index 93eefeee..5532818d 100644 --- a/mpp/legacy/CMakeLists.txt +++ b/mpp/legacy/CMakeLists.txt @@ -7,7 +7,13 @@ include_directories(.) add_library(mpp_legacy SHARED vpu_api.cpp vpu_api_legacy.cpp + vpu_mem_legacy.c + rk_list.cpp ) set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy") #set_target_properties(mpp_legacy PROPERTIES OUTPUT_NAME "vpu") +if(ANDROID) + target_link_libraries(mpp_legacy vpu mpp_shared) +else() target_link_libraries(mpp_legacy mpp_shared) +endif() diff --git a/mpp/legacy/rk_list.cpp b/mpp/legacy/rk_list.cpp new file mode 100644 index 00000000..600c1210 --- /dev/null +++ b/mpp/legacy/rk_list.cpp @@ -0,0 +1,428 @@ +#define ALOG_TAG "RK_LIST" +#include "rk_list.h" +#include +#include +#include +//#define _RK_LIST_DEUBG +#define _RK_LIST_ERROR + +#ifdef _RK_LIST_DEUBG +#define LIST_DEBUG(fmt, args...) mpp_log(fmt, ## args) +#else +#define LIST_DEBUG(fmt, args...) /* not debugging: nothing */ +#endif + +#ifdef _RK_LIST_ERROR +#define LIST_ERROR(fmt, args...) mpp_err(fmt, ## args) +#else +#define LIST_ERROR(fmt, args...) +#endif + +typedef struct rk_list_node { + rk_list_node* prev; + rk_list_node* next; + RK_U32 key; + RK_S32 size; +} rk_list_node; + +static inline void list_node_init(rk_list_node *node) +{ + node->prev = node->next = node; +} + +static inline void list_node_init_with_key_and_size(rk_list_node *node, RK_U32 key, RK_S32 size) +{ + list_node_init(node); + node->key = key; + node->size = size; +} + +static rk_list_node* create_list(void *data, RK_S32 size, RK_U32 key) +{ + rk_list_node *node = (rk_list_node*)malloc(sizeof(rk_list_node) + size); + if (node) { + void *dst = (void*)(node + 1); + list_node_init_with_key_and_size(node, key, size); + memcpy(dst, data, size); + } else { + LIST_ERROR("failed to allocate list node"); + } + return node; +} + +static inline void _rk_list_add(rk_list_node * _new, rk_list_node * prev, rk_list_node * next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +static __inline__ void rk_list_add(rk_list_node *_new, rk_list_node *head) +{ + _rk_list_add(_new, head, head->next); +} + +static __inline__ void rk_list_add_tail(rk_list_node *_new, rk_list_node *head) +{ + _rk_list_add(_new, head->prev, head); +} + +RK_S32 rk_list::add_at_head(void *data, RK_S32 size) +{ + RK_S32 ret = -EINVAL; + pthread_mutex_lock(&mutex); + if (head) { + rk_list_node *node = create_list(data, size, 0); + if (node) { + rk_list_add(node, head); + count++; + ret = 0; + } else { + ret = -ENOMEM; + } + } + pthread_mutex_unlock(&mutex); + return ret; +} + +RK_S32 rk_list::add_at_tail(void *data, RK_S32 size) +{ + RK_S32 ret = -EINVAL; + pthread_mutex_lock(&mutex); + if (head) { + rk_list_node *node = create_list(data, size, 0); + if (node) { + rk_list_add_tail(node, head); + count++; + ret = 0; + } else { + ret = -ENOMEM; + } + } + pthread_mutex_unlock(&mutex); + return ret; +} + +static void release_list(rk_list_node*node, void *data, RK_S32 size) +{ + void *src = (void*)(node + 1); + if (node->size == size) { + memcpy(data, src, size); + } else { + LIST_ERROR("node size check failed when release_list"); + size = (size < node->size) ? (size) : (node->size); + memcpy(data, src, size); + } + free(node); +} + +static inline void _rk_list_del(rk_list_node *prev, rk_list_node *next) +{ + next->prev = prev; + prev->next = next; +} + +static __inline__ void rk_list_del_init(rk_list_node *node) +{ + _rk_list_del(node->prev, node->next); + list_node_init(node); +} + +static __inline__ int list_is_last(const rk_list_node *list, const rk_list_node *head) +{ + return list->next == head; +} + +static inline void _list_del_node_no_lock(rk_list_node *node, void *data, RK_S32 size) +{ + rk_list_del_init(node); + release_list(node, data, size); +} + +RK_S32 rk_list::del_at_head(void *data, RK_S32 size) +{ + RK_S32 ret = -EINVAL; + pthread_mutex_lock(&mutex); + if (head && count) { + _list_del_node_no_lock(head->next, data, size); + count--; + ret = 0; + } + pthread_mutex_unlock(&mutex); + return ret; +} + +RK_S32 rk_list::del_at_tail(void *data, RK_S32 size) +{ + RK_S32 ret = -EINVAL; + pthread_mutex_lock(&mutex); + if (head && count) { + _list_del_node_no_lock(head->prev, data, size); + count--; + pthread_mutex_unlock(&mutex); + ret = 0; + } + pthread_mutex_unlock(&mutex); + return ret; +} + +RK_S32 rk_list::list_is_empty() +{ + pthread_mutex_lock(&mutex); + RK_S32 ret = (count == 0); + pthread_mutex_unlock(&mutex); + return ret; +} + +RK_S32 rk_list::list_size() +{ + pthread_mutex_lock(&mutex); + RK_S32 ret = count; + pthread_mutex_unlock(&mutex); + return ret; +} + +RK_S32 rk_list::add_by_key(void *data, RK_S32 size, RK_U32 *key) +{ + RK_S32 ret = 0; + (void)data; + (void)size; + (void)key; + return ret; +} + +RK_S32 rk_list::del_by_key(void *data, RK_S32 size, RK_U32 key) +{ + RK_S32 ret = 0; + (void)data; + (void)size; + (void)key; + return ret; +} + + +RK_S32 rk_list::show_by_key(void *data, RK_U32 key) +{ + RK_S32 ret = 0; + (void)data; + (void)key; + return ret; +} + +RK_S32 rk_list::flush() +{ + pthread_mutex_lock(&mutex); + if (head) { + while (count) { + rk_list_node* node = head->next; + rk_list_del_init(node); + if (destroy) { + destroy((void*)(node + 1)); + } + free(node); + count--; + } + } + pthread_mutex_unlock(&mutex); + return 0; +} + +rk_list::rk_list(node_destructor func) + : destroy(NULL), + head(NULL), + count(0) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex, &attr); + pthread_mutexattr_destroy(&attr); + destroy = func; + head = (rk_list_node*)malloc(sizeof(rk_list_node)); + if (NULL == head) { + LIST_ERROR("failed to allocate list header"); + } else { + list_node_init_with_key_and_size(head, 0, 0); + } +} + +rk_list::~rk_list() +{ + flush(); + if (head) free(head); + head = NULL; + destroy = NULL; + pthread_mutex_destroy(&mutex); +} + +#if BUILD_RK_LIST_TEST +#include "vpu_mem.h" +#include +#include +#include + +#define LOOP_RK_LIST 600 + +#define COUNT_ADD 100 +#define COUNT_DEL 99 + +volatile int err = 0; + +static int rk_list_fifo_test(rk_list *list_0) +{ + int count; + VPUMemLinear_t m; + for (count = 0; count < COUNT_ADD; count++) { + err |= VPUMallocLinear(&m, 100); + if (err) { + printf("VPUMallocLinear in rk_list_fifo_test\n"); + break; + } + err |= list_0->add_at_head(&m, sizeof(m)); + if (err) { + printf("add_at_head in rk_list_fifo_test\n"); + break; + } + } + + if (!err) { + for (count = 0; count < COUNT_DEL; count++) { + err |= list_0->del_at_tail(&m, sizeof(m)); + if (err) { + printf("del_at_tail in rk_list_fifo_test\n"); + break; + } + err |= VPUFreeLinear(&m); + if (err) { + printf("VPUFreeLinear in rk_list_fifo_test\n"); + break; + } + } + } + return err; +} + +static int rk_list_filo_test(rk_list *list_0) +{ + int count; + VPUMemLinear_t m; + for (count = 0; count < COUNT_ADD + COUNT_DEL; count++) { + if (count & 1) { + err |= list_0->del_at_head(&m, sizeof(m)); + if (err) { + printf("del_at_head in rk_list_filo_test\n"); + break; + } + err |= VPUFreeLinear(&m); + if (err) { + printf("VPUFreeLinear in rk_list_fifo_test\n"); + break; + } + } else { + err |= VPUMallocLinear(&m, 100); + if (err) { + printf("VPUMallocLinear in rk_list_filo_test\n"); + break; + } + err |= list_0->add_at_head(&m, sizeof(m)); + if (err) { + printf("add_at_head in rk_list_fifo_test\n"); + break; + } + } + } + + return err; +} + + +void *rk_list_test_loop_0(void *pdata) +{ + int i; + rk_list *list_0 = (rk_list *)pdata; + + printf("rk_list test 0 loop start\n"); + for (i = 0; i < LOOP_RK_LIST; i++) { + err |= rk_list_filo_test(list_0); + if (err) break; + } + + if (err) { + printf("thread: found vpu mem operation err %d\n", err); + } else { + printf("thread: test done and found no err\n"); + } + return NULL; +} + +int rk_list_test_0() +{ + int i, err = 0; + printf("rk_list test 0 FIFO start\n"); + + rk_list *list_0 = new rk_list((node_destructor)VPUFreeLinear); + + pthread_t mThread; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + pthread_create(&mThread, &attr, rk_list_test_loop_0, (void*)list_0); + pthread_attr_destroy(&attr); + + for (i = 0; i < LOOP_RK_LIST; i++) { + err |= rk_list_fifo_test(list_0); + if (err) break; + } + if (err) { + printf("main : found rk_list operation err %d\n", err); + } else { + printf("main : test done and found no err\n"); + } + + void *dummy; + pthread_join(mThread, &dummy); + + printf("rk_list test 0 end size %d\n", list_0->list_size()); + delete list_0; + return err; +} + +#define TOTAL_RK_LIST_TEST_COUNT 1 + +typedef int (*RK_LIST_TEST_FUNC)(void); +RK_LIST_TEST_FUNC test_func[TOTAL_RK_LIST_TEST_COUNT] = { + rk_list_test_0, +}; + +int main(int argc, char *argv[]) +{ + int i, start = 0, end = 0; + if (argc < 2) { + end = TOTAL_RK_LIST_TEST_COUNT; + } else if (argc == 2) { + start = atoi(argv[1]); + end = start + 1; + } else if (argc == 3) { + start = atoi(argv[1]); + end = atoi(argv[2]); + } else { + printf("too many argc %d\n", argc); + return -1; + } + if (start < 0 || start > TOTAL_RK_LIST_TEST_COUNT || end < 0 || end > TOTAL_RK_LIST_TEST_COUNT) { + printf("invalid input: start %d end %d\n", start, end); + return -1; + } + for (i = start; i < end; i++) { + int err = test_func[i](); + if (err) { + printf("test case %d return err %d\n", i, err); + break; + } + } + return 0; +} +#endif + diff --git a/mpp/legacy/rk_list.h b/mpp/legacy/rk_list.h new file mode 100644 index 00000000..2f10479b --- /dev/null +++ b/mpp/legacy/rk_list.h @@ -0,0 +1,49 @@ +#ifndef __RK_LIST_H__ +#define __RK_LIST_H__ + +#include +#include "rk_type.h" +// desctructor of list node +typedef void *(*node_destructor)(void *); + +struct rk_list_node; +class rk_list +{ +public: + rk_list(node_destructor func); + ~rk_list(); + + // for FIFO or FILO implement + // adding functions support simple structure like C struct or C++ class pointer, + // do not support C++ object + RK_S32 add_at_head(void *data, RK_S32 size); + RK_S32 add_at_tail(void *data, RK_S32 size); + // deleting function will copy the stored data to input pointer with size as size + // if NULL is passed to deleting functions, the node will be delete directly + RK_S32 del_at_head(void *data, RK_S32 size); + RK_S32 del_at_tail(void *data, RK_S32 size); + + // for status check + RK_S32 list_is_empty(); + RK_S32 list_size(); + + // for vector implement - not implemented yet + // adding function will return a key + RK_S32 add_by_key(void *data, RK_S32 size, RK_U32 *key); + RK_S32 del_by_key(void *data, RK_S32 size, RK_U32 key); + RK_S32 show_by_key(void *data, RK_U32 key); + + RK_S32 flush(); + +private: + pthread_mutex_t mutex; + node_destructor destroy; + struct rk_list_node *head; + RK_S32 count; + + rk_list(); + rk_list(const rk_list &); + rk_list &operator=(const rk_list &); +}; + +#endif /*__RK_LIST_H__*/ diff --git a/mpp/legacy/vpu_api.cpp b/mpp/legacy/vpu_api.cpp index 0cfd1541..485a3f6c 100644 --- a/mpp/legacy/vpu_api.cpp +++ b/mpp/legacy/vpu_api.cpp @@ -19,20 +19,13 @@ #include #include "mpp_log.h" #include "mpp_mem.h" -#include "mpp_buffer.h" #include "vpu_api_legacy.h" +#include "vpu_mem_legacy.h" #include "vpu_api.h" -#include "vpu.h" - -#ifdef ANDROID -#include -#endif - -typedef struct vpu_display_mem_pool_impl { - vpu_display_mem_pool_FIELDS - MppBufferGroup group; - RK_S32 size; -} vpu_display_mem_pool_impl; +#include +#include +#include +#include "mpp_env.h" static RK_S32 vpu_api_init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) { @@ -196,40 +189,107 @@ static RK_S32 vpu_api_control(VpuCodecContext *ctx, VPU_API_CMD cmdType, void *p return api->control(ctx, cmdType, param); } +#ifdef ANDROID +RK_S32 open_orign_vpu(VpuCodecContext **ctx) +{ + void *rkapi_hdl = NULL; + RK_S32 (*rkvpu_open_cxt)(VpuCodecContext **ctx); + rkapi_hdl = dlopen("/system/lib/librk_vpuapi.so", RTLD_LAZY); + if (rkapi_hdl == NULL) { + mpp_err_f("dlopen librk_vpuapi library fail\n"); + return -1; + } + rkvpu_open_cxt = (RK_S32 (*)(VpuCodecContext **ctx))dlsym(rkapi_hdl, "vpu_open_context"); + dlclose(rkapi_hdl); + if (rkvpu_open_cxt == NULL) { + mpp_err("dlsym rkvpu_open_cxt fail "); + return -1; + } else { + (*rkvpu_open_cxt)(ctx); + return MPP_OK; + } +} + +RK_S32 close_orign_vpu(VpuCodecContext **ctx) +{ + void *rkapi_hdl = NULL; + RK_S32 (*rkvpu_close_cxt)(VpuCodecContext **ctx); + rkapi_hdl = dlopen("/system/lib/librk_vpuapi.so", RTLD_LAZY); + if (rkapi_hdl == NULL) { + mpp_err_f("dlopen librk_vpuapi library fail\n"); + return -1; + } + rkvpu_close_cxt = (RK_S32 (*)(VpuCodecContext **ctx))dlsym(rkapi_hdl, "vpu_close_context"); + if (rkvpu_close_cxt == NULL) { + mpp_err_f("dlsym rkvpu_close_cxt fail"); + return -1; + } else { + (*rkvpu_close_cxt)(ctx); + return MPP_OK; + } + dlclose(rkapi_hdl); +} +#endif RK_S32 vpu_open_context(VpuCodecContext **ctx) { - mpp_log("vpu_open_context in"); VpuCodecContext *s = *ctx; - - if (!s) { - s = mpp_malloc(VpuCodecContext, 1); - if (!s) { - mpp_err("Input context has not been properly allocated"); - return -1; + RK_U32 value; + mpp_env_get_u32("chg_org", &value, 0); +#ifdef ANDROID + if (value || !s) { + if (s) { + free(s); + s = NULL; } - memset(s, 0, sizeof(VpuCodecContext)); - s->enableparsing = 1; - - VpuApi* api = new VpuApi(); - - if (api == NULL) { - mpp_err("Vpu api object has not been properly allocated"); - return -1; - } - - s->vpuApiObj = (void*)api; - s->init = vpu_api_init; - s->decode = vpu_api_decode; - s->encode = vpu_api_encode; - s->flush = vpu_api_flush; - s->control = vpu_api_control; - s->decode_sendstream = vpu_api_sendstream; - s->decode_getframe = vpu_api_getframe; - s->encoder_sendframe = vpu_api_sendframe; - s->encoder_getstream = vpu_api_getstream; - + open_orign_vpu(&s); + s->extra_cfg.reserved[0] = 1; *ctx = s; - return 0; + return MPP_OK; + } +#endif + if (s != NULL) { + mpp_log("s->videoCoding = %d", s->videoCoding); + if (s->videoCoding == OMX_RK_VIDEO_CodingHEVC) { + free(s); + s = NULL; + s = mpp_malloc(VpuCodecContext, 1); + if (!s) { + mpp_err("Input context has not been properly allocated"); + return -1; + } + memset(s, 0, sizeof(VpuCodecContext)); + s->enableparsing = 1; + + VpuApi* api = new VpuApi(); + + if (api == NULL) { + mpp_err("Vpu api object has not been properly allocated"); + return -1; + } + + s->vpuApiObj = (void*)api; + s->init = vpu_api_init; + s->decode = vpu_api_decode; + s->encode = vpu_api_encode; + s->flush = vpu_api_flush; + s->control = vpu_api_control; + s->decode_sendstream = vpu_api_sendstream; + s->decode_getframe = vpu_api_getframe; + s->encoder_sendframe = vpu_api_sendframe; + s->encoder_getstream = vpu_api_getstream; + + *ctx = s; + return 0; + } else { +#ifdef ANDROID + free(s); + s = NULL; + open_orign_vpu(&s); + s->extra_cfg.reserved[0] = 1; + *ctx = s; + return MPP_OK; +#endif + } } if (!s->vpuApiObj) { @@ -243,7 +303,15 @@ RK_S32 vpu_close_context(VpuCodecContext **ctx) { mpp_log("vpu_close_context in"); VpuCodecContext *s = *ctx; - + RK_U32 value; + mpp_env_get_u32("chg_org", &value, 0); +#ifdef ANDROID + if (value || s->extra_cfg.reserved[0]) { + close_orign_vpu(ctx); + mpp_log("org vpu_close_context ok"); + return MPP_OK; + } +#endif if (s) { VpuApi* api = (VpuApi*)(s->vpuApiObj); if (s->vpuApiObj) { @@ -254,216 +322,7 @@ RK_S32 vpu_close_context(VpuCodecContext **ctx) mpp_free(s->private_data); mpp_free(s); *ctx = s = NULL; - mpp_log("vpu_close_context ok"); } return 0; } - -static RK_S32 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size) -{ - MppBufferInfo info; - - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - memset(&info, 0, sizeof(MppBufferInfo)); - info.type = MPP_BUFFER_TYPE_ION; - info.fd = mem_hdl; - info.size = size; - p_mempool->size = size; - mpp_buffer_commit(p_mempool->group, &info); - return info.fd; -} - -static void* get_free_memory_vpumem(vpu_display_mem_pool *p) -{ - MPP_RET ret = MPP_OK; - MppBuffer buffer = NULL; - VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1); - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - if (dmabuf == NULL) { - return NULL; - } - ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size); - if (MPP_OK != ret) { - mpp_free(dmabuf); - return NULL; - } - dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); - dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); - dmabuf->size = p_mempool->size; - dmabuf->offset = (RK_U32*)buffer; - return NULL; - -} - -static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl) -{ - (void)p; - VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; - MppBuffer buffer = (MppBuffer)dmabuf->offset; - if (buffer != NULL) { - mpp_buffer_inc_ref(buffer); - } - return MPP_OK; - -} - -static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl) -{ - (void)p; - VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; - MppBuffer buf = (MppBuffer)dmabuf->offset; - if (buf != NULL) { - mpp_buffer_put(buf); - } - return MPP_OK; -} - -static RK_S32 get_free_memory_num(vpu_display_mem_pool *p) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - if (p_mempool->group != NULL) { - return mpp_buffer_group_unused(p_mempool->group); - } - return 0; -} - -static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - mpp_buffer_group_clear(p_mempool->group); - return 0; - -} - - -vpu_display_mem_pool* open_vpu_memory_pool() -{ - mpp_err("open_vpu_memory_pool in\n"); - vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); - - if (NULL == p_mempool) { - return NULL; - } - mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION); - if (NULL == p_mempool->group) { - return NULL; - } - p_mempool->commit_hdl = commit_memory_handle; - p_mempool->get_free = get_free_memory_vpumem; - p_mempool->put_used = put_used_memory_handle; - p_mempool->inc_used = inc_used_memory_handle_ref; - p_mempool->reset = reset_vpu_mem_pool; - p_mempool->get_unused_num = get_free_memory_num; - p_mempool->version = 1; - p_mempool->buff_size = -1; - return (vpu_display_mem_pool*)p_mempool; -} - -void close_vpu_memory_pool(vpu_display_mem_pool *p) -{ - - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - mpp_buffer_group_put(p_mempool->group); - return; -} - -int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) -{ - (void)ipool; - (void)num; - (void)size; - return 0; -} - -void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) -{ - (void)ipool; -} - -RK_S32 VPUMemJudgeIommu() -{ - int ret = 0; -#ifdef ANDROID - if (VPUClientGetIOMMUStatus() > 0) { - //mpp_err("media.used.iommu"); - ret = 1; - } -#endif - return ret; -} - - -RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) -{ - (void)p; - (void)size; - return 0; -} - -RK_S32 VPUFreeLinear(VPUMemLinear_t *p) -{ - put_used_memory_handle(NULL, p); - return 0; -} - - -RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) -{ - (void)dst; - (void)src; - return 0; -} - -RK_S32 VPUMemLink(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemFlush(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemClean(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - - -RK_S32 VPUMemInvalidate(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemGetFD(VPUMemLinear_t *p) -{ - RK_S32 fd = 0; - MppBuffer buffer = (MppBuffer)p->offset; - fd = mpp_buffer_get_fd(buffer); - //mpp_err("fd = 0x%x",fd); - return fd; - -} - -RK_S32 vpu_mem_judge_used_heaps_type() -{ - // TODO, use property_get -#if 0 //def ANDROID - if (!VPUClientGetIOMMUStatus() > 0) { - return ION_HEAP(ION_CMA_HEAP_ID); - } else { - ALOGV("USE ION_SYSTEM_HEAP"); - return ION_HEAP(ION_VMALLOC_HEAP_ID); - } -#endif - - return 0; -} - - - diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index f484a64d..3c4224c0 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -20,7 +20,7 @@ #include "mpp_frame.h" #include "vpu_api_legacy.h" #include "mpp_mem.h" - +#include "string.h" VpuApi::VpuApi() { @@ -64,8 +64,6 @@ RK_S32 VpuApi::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) vpug.ImgWidth = ctx->width; vpug.ImgHeight = ctx->height; control(ctx, VPU_API_SET_DEFAULT_WIDTH_HEIGH, &vpug); - - mpp_err("mpp_ctx = %p", mpp_ctx); if (extraData != NULL) { mpp_packet_init(&pkt, extraData, extra_size); mpp_packet_set_extra_data(pkt); @@ -118,6 +116,7 @@ RK_S32 VpuApi:: decode_getoutframe(DecoderOut_t *aDecOut) { // mpp_log_f("in\n"); VPU_FRAME *vframe = (VPU_FRAME *)aDecOut->data; + memset(vframe, 0, sizeof(VPU_FRAME)); MppFrame mframe = NULL; if (NULL == mpi) { aDecOut->size = 0; diff --git a/mpp/legacy/vpu_mem_legacy.c b/mpp/legacy/vpu_mem_legacy.c new file mode 100644 index 00000000..255a097f --- /dev/null +++ b/mpp/legacy/vpu_mem_legacy.c @@ -0,0 +1,283 @@ +/* + * Copyright 2010 Rockchip Electronics S.LSI 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. + */ + +#include "mpp_buffer.h" +#include "vpu_mem_legacy.h" +#include "mpp_log.h" +#include "mpp_mem.h" +#include "vpu.h" +#include + +#ifdef ANDROID +#include +#endif + +static RK_S32 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size) +{ + MppBufferInfo info; + + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + memset(&info, 0, sizeof(MppBufferInfo)); + info.type = MPP_BUFFER_TYPE_ION; + info.fd = mem_hdl; + info.size = size; + p_mempool->size = size; + mpp_buffer_commit(p_mempool->group, &info); + return info.fd; +} + +static void* get_free_memory_vpumem(vpu_display_mem_pool *p) +{ + MPP_RET ret = MPP_OK; + MppBuffer buffer = NULL; + VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (dmabuf == NULL) { + return NULL; + } + ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size); + if (MPP_OK != ret) { + mpp_free(dmabuf); + return NULL; + } + dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); + dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); + dmabuf->size = p_mempool->size; + dmabuf->offset = (RK_U32*)buffer; + return dmabuf; + +} + +static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl) +{ + (void)p; + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buffer = (MppBuffer)dmabuf->offset; + if (buffer != NULL) { + mpp_buffer_inc_ref(buffer); + } + return MPP_OK; + +} + +static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl) +{ + (void)p; + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buf = (MppBuffer)dmabuf->offset; + if (buf != NULL) { + mpp_buffer_put(buf); + } + return MPP_OK; +} + +static RK_S32 get_free_memory_num(vpu_display_mem_pool *p) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (p_mempool->group != NULL) { + return mpp_buffer_group_unused(p_mempool->group); + } + return 0; +} + +static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p) +{ + + mpp_err("reset_vpu_mem_pool xxxxxxxxxxxxxxx"); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + mpp_buffer_group_clear(p_mempool->group); + return 0; + +} + + +vpu_display_mem_pool* open_vpu_memory_pool() +{ + mpp_err("open_vpu_memory_pool in\n"); + vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); + + if (NULL == p_mempool) { + return NULL; + } + mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION); + if (NULL == p_mempool->group) { + return NULL; + } + p_mempool->commit_hdl = commit_memory_handle; + p_mempool->get_free = get_free_memory_vpumem; + p_mempool->put_used = put_used_memory_handle; + p_mempool->inc_used = inc_used_memory_handle_ref; + p_mempool->reset = reset_vpu_mem_pool; + p_mempool->get_unused_num = get_free_memory_num; + p_mempool->version = 1; + p_mempool->buff_size = -1; + return (vpu_display_mem_pool*)p_mempool; +} + +void close_vpu_memory_pool(vpu_display_mem_pool *p) +{ + mpp_err("close_vpu_memory_pool in xxxxxxxxxxxxxxx"); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + mpp_buffer_group_put(p_mempool->group); + mpp_free(p_mempool); + return; +} + +int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) +{ + (void)num; + vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); + if (NULL == p_mempool) { + return -1; + } + mpp_buffer_group_get_internal(&p_mempool->group, MPP_BUFFER_TYPE_ION); + if (NULL == p_mempool->group) { + return -1; + } + p_mempool->commit_hdl = commit_memory_handle; + p_mempool->get_free = get_free_memory_vpumem; + p_mempool->put_used = put_used_memory_handle; + p_mempool->inc_used = inc_used_memory_handle_ref; + p_mempool->reset = reset_vpu_mem_pool; + p_mempool->get_unused_num = get_free_memory_num; + p_mempool->version = 0; + p_mempool->buff_size = size; + *ipool = (vpu_display_mem_pool*)p_mempool; + return 0; +} + +void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ipool; + if (p_mempool == NULL) { + return; + } + if (NULL != p_mempool->group) { + mpp_buffer_group_put(p_mempool->group); + } + mpp_free(p_mempool); + return; +} + +RK_S32 VPUMemJudgeIommu() +{ + int ret = 0; +#ifdef ANDROID + if (VPUClientGetIOMMUStatus() > 0) { + //mpp_err("media.used.iommu"); + ret = 1; + } +#endif + return ret; +} + + +RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) +{ + MppBuffer buffer = NULL; + mpp_buffer_get(NULL, &buffer, size); + p->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); + p->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); + p->size = size; + p->offset = (RK_U32*)buffer; + return 0; +} + +RK_S32 VPUMallocLinearFromRender(VPUMemLinear_t *p, RK_U32 size, void *ctx) +{ + VPUMemLinear_t *dma_buf = NULL; + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ctx; + dma_buf = (VPUMemLinear_t *)p_mempool->get_free((vpu_display_mem_pool *)ctx); + if (dma_buf != NULL) { + if (dma_buf->size < size) { + mpp_free(dma_buf); + return -1; + } + memcpy(p, dma_buf, sizeof(VPUMemLinear_t)); + mpp_free(dma_buf); + } + return 0; +} + + +RK_S32 VPUFreeLinear(VPUMemLinear_t *p) +{ + if (p->offset != NULL) { + put_used_memory_handle(NULL, p); + } + return 0; +} + + +RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) +{ + MppBuffer buffer = (MppBuffer)src->offset; + if (buffer != NULL) { + mpp_buffer_inc_ref(buffer); + } + memcpy(dst, src, sizeof(VPUMemLinear_t)); + return 0; +} + +RK_S32 VPUMemLink(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemFlush(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemClean(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + + +RK_S32 VPUMemInvalidate(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemGetFD(VPUMemLinear_t *p) +{ + RK_S32 fd = 0; + MppBuffer buffer = (MppBuffer)p->offset; + fd = mpp_buffer_get_fd(buffer); + return fd; + +} + +RK_S32 vpu_mem_judge_used_heaps_type() +{ + // TODO, use property_get +#if 0//def ANDROID + if (!VPUClientGetIOMMUStatus() > 0) { + return ION_HEAP(ION_CMA_HEAP_ID); + } else { + ALOGV("USE ION_SYSTEM_HEAP"); + return ION_HEAP(ION_VMALLOC_HEAP_ID); + } +#endif + + return 0; +} + diff --git a/mpp/legacy/vpu_mem_legacy.h b/mpp/legacy/vpu_mem_legacy.h new file mode 100644 index 00000000..259e3fa4 --- /dev/null +++ b/mpp/legacy/vpu_mem_legacy.h @@ -0,0 +1,27 @@ +/* + * Copyright 2010 Rockchip Electronics S.LSI 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 _VPU_MEM_H_ +#define _VPU_MEM_H_ + +#include "vpu_api.h" + +typedef struct vpu_display_mem_pool_impl { + vpu_display_mem_pool_FIELDS + MppBufferGroup group; + RK_S32 size; +} vpu_display_mem_pool_impl; + +#endif //_VPU_MEM_H_ \ No newline at end of file diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 95b25164..8df14753 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -128,8 +128,7 @@ void Mpp::clear() if (mType == MPP_CTX_DEC) { mpp_dec_deinit(mDec); mDec = NULL; - } - else { + } else { mpp_enc_deinit(mEnc); mEnc = NULL; }