diff --git a/inc/rk_mpi.h b/inc/rk_mpi.h index 51cfcc47..376f261c 100644 --- a/inc/rk_mpi.h +++ b/inc/rk_mpi.h @@ -78,6 +78,7 @@ typedef enum { MPP_DEC_USE_PRESENT_TIME_ORDER, MPP_DEC_SET_VC1_EXTRA_DATA, MPP_DEC_SET_VP6_ID, + MPP_DEC_USE_FAST_MODE, MPP_ENC_CMD_BASE = 0x50000, MPP_ENC_SETCFG, @@ -169,7 +170,8 @@ extern "C" { /* * mpp interface */ -MPP_RET mpp_init(MppCtx *ctx, MppApi **mpi, MppCtxType type, MppCodingType coding); +MPP_RET mpp_construct(MppCtx *ctx, MppApi **mpi); +MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding); MPP_RET mpp_deinit(MppCtx ctx); #ifdef __cplusplus diff --git a/inc/vpu_api.h b/inc/vpu_api.h index 7d4a688e..8905038b 100644 --- a/inc/vpu_api.h +++ b/inc/vpu_api.h @@ -54,6 +54,7 @@ typedef enum VPU_API_CMD { VPU_API_USE_PRESENT_TIME_ORDER, VPU_API_SET_DEFAULT_WIDTH_HEIGH, VPU_API_SET_INFO_CHANGE, + VPU_API_USE_FAST_MODE, } VPU_API_CMD; typedef struct { diff --git a/mpp/codec/dec/h265/h265d_parser.c b/mpp/codec/dec/h265/h265d_parser.c index 86c80517..7b180e18 100644 --- a/mpp/codec/dec/h265/h265d_parser.c +++ b/mpp/codec/dec/h265/h265d_parser.c @@ -1240,6 +1240,9 @@ static RK_S32 parser_nal_unit(HEVCContext *s, const RK_U8 *nal, int length) s->poc <= s->max_ra) { s->is_decoded = 0; break; + } else if (s->poc < s->max_ra) { //when seek to I slice skip the stream small then I slic poc + s->is_decoded = 0; + break; } else { if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra) s->max_ra = INT_MIN; @@ -1482,6 +1485,9 @@ static RK_S32 split_nal_units(HEVCContext *s, RK_U8 *buf, RK_U32 length) if (!s->is_nalff) extract_length = length; + if (!extract_length) { + return MPP_OK; + } if (s->nals_allocated < 1) { RK_S32 new_size = s->nals_allocated + 10; HEVCNAL *tmp = mpp_malloc(HEVCNAL, new_size); diff --git a/mpp/codec/dec/h265/test/h265d_parser_test.c b/mpp/codec/dec/h265/test/h265d_parser_test.c index 25143cf5..954c3ac9 100644 --- a/mpp/codec/dec/h265/test/h265d_parser_test.c +++ b/mpp/codec/dec/h265/test/h265d_parser_test.c @@ -368,6 +368,7 @@ RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd) parser_cfg.frame_slots = slots; parser_cfg.packet_slots = packet_slots; parser_cfg.need_split = 1; + memset(&hal_cfg, 0, sizeof(hal_cfg)); hal_cfg.frame_slots = slots; hal_cfg.packet_slots = packet_slots; h265d_init(mpp_codex_ctx, &parser_cfg); diff --git a/mpp/codec/inc/mpp_dec.h b/mpp/codec/inc/mpp_dec.h index b652283d..7b1fb7de 100644 --- a/mpp/codec/inc/mpp_dec.h +++ b/mpp/codec/inc/mpp_dec.h @@ -37,6 +37,7 @@ struct MppDec_t { // dec parser thread runtime resource context MppPacket mpp_pkt_in; + RK_U32 fast_mode; }; @@ -53,7 +54,7 @@ void *mpp_dec_hal_thread(void *data); /* * */ -MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding); +MPP_RET mpp_dec_init(MppDec *dec, MppCodingType coding); MPP_RET mpp_dec_deinit(MppDec *dec); MPP_RET mpp_dec_reset(MppDec *dec); diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 5ead737e..eb8ba7ba 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -151,6 +151,7 @@ static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task) MppBufSlots packet_slots = dec->packet_slots; HalDecTask *task_dec = &task->info.dec; + if (!dec->fast_mode) { if (!task->status.prev_task_rdy) { HalTaskHnd task_prev = NULL; hal_task_get_hnd(tasks, TASK_PROC_DONE, &task_prev); @@ -162,6 +163,12 @@ static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task) } else { msleep(5); task->wait.prev_task = 1; + return MPP_NOK; + } + } + } else { + if (hal_task_check_empty(tasks, TASK_PROCESSING)) { + msleep(5); return MPP_NOK; } } @@ -347,6 +354,7 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) task->status.dec_pkt_copy_rdy = 1; } + if (!dec->fast_mode) { // wait previous task done if (!task->status.prev_task_rdy) { HalTaskHnd task_prev = NULL; @@ -361,6 +369,7 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) return MPP_NOK; } } + } if (mpp->mFrameGroup) { task->wait.dec_pic_buf = (mpp_buffer_group_unused(mpp->mFrameGroup) < 1); if (task->wait.dec_pic_buf) @@ -642,7 +651,13 @@ void *mpp_dec_hal_thread(void *data) // TODO: may have risk here hal_task_hnd_set_status(task, TASK_PROC_DONE); task = NULL; - + if (dec->fast_mode) { + + hal_task_get_hnd(tasks, TASK_PROC_DONE, &task); + if (task) { + hal_task_hnd_set_status(task, TASK_IDLE); + } + } mpp->mThreadCodec->signal(); mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); @@ -674,16 +689,19 @@ void *mpp_dec_hal_thread(void *data) return NULL; } -MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding) +MPP_RET mpp_dec_init(MppDec *dec, MppCodingType coding) { MPP_RET ret; MppBufSlots frame_slots = NULL; MppBufSlots packet_slots = NULL; Parser parser = NULL; MppHal hal = NULL; + MppDec *p = dec; + RK_S32 task_count = 2; HalIOInterruptCB cb = {NULL, NULL}; - - MppDec *p = mpp_calloc(MppDec, 1); + if (dec->fast_mode) { + task_count = 3; + } if (NULL == p) { mpp_err_f("failed to malloc context\n"); return MPP_ERR_NULL_PTR; @@ -702,13 +720,13 @@ MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding) break; } - mpp_buf_slot_setup(packet_slots, 2); + mpp_buf_slot_setup(packet_slots, task_count); ParserCfg parser_cfg = { coding, frame_slots, packet_slots, - 2, + task_count, 0, }; @@ -729,6 +747,7 @@ MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding) packet_slots, NULL, parser_cfg.task_count, + dec->fast_mode, cb, }; @@ -744,12 +763,10 @@ MPP_RET mpp_dec_init(MppDec **dec, MppCodingType coding) p->tasks = hal_cfg.tasks; p->frame_slots = frame_slots; p->packet_slots = packet_slots; - *dec = p; return MPP_OK; } while (0); mpp_dec_deinit(p); - *dec = NULL; return MPP_NOK; } diff --git a/mpp/hal/hal_task.cpp b/mpp/hal/hal_task.cpp index 65c5a86b..11944205 100644 --- a/mpp/hal/hal_task.cpp +++ b/mpp/hal/hal_task.cpp @@ -140,6 +140,20 @@ MPP_RET hal_task_get_hnd(HalTaskGroup group, MppTaskStatus status, HalTaskHnd *h return MPP_OK; } +MPP_RET hal_task_check_empty(HalTaskGroup group, MppTaskStatus status) +{ + if (NULL == group || status >= TASK_BUTT) { + mpp_err_f("found invaid input group %p status %d \n", group, status); + return MPP_ERR_UNKNOW; + } + HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; + Mutex::Autolock auto_lock(p->lock); + struct list_head *list = &p->list[status]; + if (list_empty(list)) { + return MPP_OK; + } + return MPP_NOK; +} MPP_RET hal_task_get_count(HalTaskGroup group, MppTaskStatus status, RK_U32 *count) { if (NULL == group || status >= TASK_BUTT || NULL == count) { diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index 7913dbab..433ea92b 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -101,6 +101,7 @@ typedef struct HalDecTask_t { // current task input slot index RK_S32 input; + RK_S32 reg_index; // for test purpose // current tesk output slot index RK_S32 output; @@ -185,6 +186,7 @@ MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, MppTaskStatus status); MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, HalTaskInfo *task); MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, HalTaskInfo *task); MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type); +MPP_RET hal_task_check_empty(HalTaskGroup group, MppTaskStatus status); #ifdef __cplusplus } diff --git a/mpp/hal/inc/mpp_hal.h b/mpp/hal/inc/mpp_hal.h index fcb6ee21..758179e0 100644 --- a/mpp/hal/inc/mpp_hal.h +++ b/mpp/hal/inc/mpp_hal.h @@ -53,6 +53,7 @@ typedef struct MppHalCfg_t { // output HalTaskGroup tasks; RK_S32 task_count; + RK_U32 fast_mode; HalIOInterruptCB hal_int_cb; } MppHalCfg; diff --git a/mpp/hal/rkdec/h265d/hal_h265d_reg.c b/mpp/hal/rkdec/h265d/hal_h265d_reg.c index 471d5bc9..70440c33 100644 --- a/mpp/hal/rkdec/h265d/hal_h265d_reg.c +++ b/mpp/hal/rkdec/h265d/hal_h265d_reg.c @@ -47,7 +47,15 @@ FILE *fp = NULL; #endif +#define MAX_GEN_REG 3 RK_U32 h265h_debug = 0; +typedef struct h265d_reg_buf { + RK_S32 use_flag; + MppBuffer scaling_list_data; + MppBuffer pps_data; + MppBuffer rps_data; + void* hw_regs; +} h265d_reg_buf_t; typedef struct h265d_reg_context { RK_S32 vpu_socket; MppBufSlots slots; @@ -58,6 +66,8 @@ typedef struct h265d_reg_context { MppBuffer pps_data; MppBuffer rps_data; void* hw_regs; + h265d_reg_buf_t g_buf[MAX_GEN_REG]; + RK_U32 fast_mode; HalIOInterruptCB int_cb; } h265d_reg_context_t; @@ -255,6 +265,122 @@ static RK_U32 hevc_ver_align_256_odd(RK_U32 val) { return MPP_ALIGN(val, 256) | 256; } +MPP_RET hal_h265d_alloc_res(void *hal) +{ + RK_S32 i = 0; + RK_S32 ret = 0; + h265d_reg_context_t *reg_cxt = (h265d_reg_context_t *)hal; + if (reg_cxt->fast_mode) { + for (i = 0; i < MAX_GEN_REG; i++) { + reg_cxt->g_buf[i].hw_regs = mpp_calloc_size(void, sizeof(H265d_REGS_t)); + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->g_buf[i].scaling_list_data, SCALING_LIST_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d scaling_list_data get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->g_buf[i].pps_data, PPS_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d pps_data get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->g_buf[i].rps_data, RPS_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d rps_data get buffer failed\n"); + return ret; + } + } + } else { + reg_cxt->hw_regs = mpp_calloc_size(void, sizeof(H265d_REGS_t)); + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->scaling_list_data, SCALING_LIST_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d scaling_list_data get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->pps_data, PPS_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d pps_data get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->rps_data, RPS_SIZE); + if (MPP_OK != ret) { + mpp_err("h265d rps_data get buffer failed\n"); + return ret; + } + + } + return MPP_OK; +} + +MPP_RET hal_h265d_release_res(void *hal) +{ + RK_S32 ret = 0; + h265d_reg_context_t *reg_cxt = ( h265d_reg_context_t *)hal; + RK_S32 i = 0; + if (reg_cxt->fast_mode) { + for (i = 0; i < MAX_GEN_REG; i++) { + if (reg_cxt->g_buf[i].scaling_list_data) { + ret = mpp_buffer_put(reg_cxt->g_buf[i].scaling_list_data); + if (MPP_OK != ret) { + mpp_err("h265d scaling_list_data free buffer failed\n"); + return ret; + } + } + if (reg_cxt->g_buf[i].pps_data) { + ret = mpp_buffer_put(reg_cxt->g_buf[i].pps_data); + if (MPP_OK != ret) { + mpp_err("h265d pps_data free buffer failed\n"); + return ret; + } + } + + if (reg_cxt->g_buf[i].rps_data) { + ret = mpp_buffer_put(reg_cxt->g_buf[i].rps_data); + if (MPP_OK != ret) { + mpp_err("h265d rps_data free buffer failed\n"); + return ret; + } + } + + if (reg_cxt->g_buf[i].hw_regs) { + mpp_free(reg_cxt->g_buf[i].hw_regs); + reg_cxt->g_buf[i].hw_regs = NULL; + } + } + } else { + if (reg_cxt->scaling_list_data) { + ret = mpp_buffer_put(reg_cxt->scaling_list_data); + if (MPP_OK != ret) { + mpp_err("h265d scaling_list_data free buffer failed\n"); + return ret; + } + } + if (reg_cxt->pps_data) { + ret = mpp_buffer_put(reg_cxt->pps_data); + if (MPP_OK != ret) { + mpp_err("h265d pps_data free buffer failed\n"); + return ret; + } + } + + if (reg_cxt->g_buf[i].rps_data) { + ret = mpp_buffer_put(reg_cxt->rps_data); + if (MPP_OK != ret) { + mpp_err("h265d rps_data free buffer failed\n"); + return ret; + } + } + + if (reg_cxt->hw_regs) { + mpp_free(reg_cxt->hw_regs); + reg_cxt->hw_regs = NULL; + } + } + return MPP_OK; +} MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) { @@ -269,6 +395,7 @@ MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) reg_cxt->slots = cfg->frame_slots; reg_cxt->int_cb = cfg->hal_int_cb; + reg_cxt->fast_mode = cfg->fast_mode; mpp_slots_set_prop(reg_cxt->slots, SLOTS_HOR_ALIGN, hevc_ver_align_256_odd); mpp_slots_set_prop(reg_cxt->slots, SLOTS_VER_ALIGN, hevc_ver_align_8); @@ -276,7 +403,11 @@ MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) ///<- VPUClientInit #ifdef ANDROID if (reg_cxt->vpu_socket <= 0) { - reg_cxt->vpu_socket = VPUClientInit(VPU_DEC_RKV); + RK_S32 value = !!access("/dev/rkvdec", F_OK); + if (value) + reg_cxt->vpu_socket = VPUClientInit(VPU_DEC_HEVC); + else + reg_cxt->vpu_socket = VPUClientInit(VPU_DEC_RKV); if (reg_cxt->vpu_socket <= 0) { mpp_err("reg_cxt->vpu_socket <= 0\n"); return MPP_ERR_UNKNOW; @@ -296,8 +427,6 @@ MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) return ret; } } - reg_cxt->hw_regs = mpp_calloc_size(void, sizeof(H265d_REGS_t)); - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->cabac_table_data, sizeof(cabac_table)); if (MPP_OK != ret) { mpp_err("h265d cabac_table get buffer failed\n"); @@ -308,25 +437,12 @@ MPP_RET hal_h265d_init(void *hal, MppHalCfg *cfg) mpp_err("h265d write cabac_table data failed\n"); return ret; } + ret = hal_h265d_alloc_res(hal); - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->scaling_list_data, SCALING_LIST_SIZE); if (MPP_OK != ret) { - mpp_err("h265d scaling_list_data get buffer failed\n"); + mpp_err("hal_h265d_alloc_res failed\n"); return ret; } - - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->pps_data, PPS_SIZE); - if (MPP_OK != ret) { - mpp_err("h265d pps_data get buffer failed\n"); - return ret; - } - - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->rps_data, RPS_SIZE); - if (MPP_OK != ret) { - mpp_err("h265d rps_data get buffer failed\n"); - return ret; - } - mpp_env_get_u32("h265h_debug", &h265h_debug, 0); #ifdef dump @@ -355,24 +471,7 @@ MPP_RET hal_h265d_deinit(void *hal) return ret; } - - ret = mpp_buffer_put(reg_cxt->scaling_list_data); - if (MPP_OK != ret) { - mpp_err("h265d scaling_list_data free buffer failed\n"); - return ret; - } - - ret = mpp_buffer_put(reg_cxt->pps_data); - if (MPP_OK != ret) { - mpp_err("h265d pps_data free buffer failed\n"); - return ret; - } - - ret = mpp_buffer_put(reg_cxt->rps_data); - if (MPP_OK != ret) { - mpp_err("h265d rps_data free buffer failed\n"); - return ret; - } + hal_h265d_release_res(hal); if (reg_cxt->group) { ret = mpp_buffer_group_put(reg_cxt->group); @@ -381,11 +480,6 @@ MPP_RET hal_h265d_deinit(void *hal) return ret; } } - - if (reg_cxt->hw_regs) { - mpp_free(reg_cxt->hw_regs); - reg_cxt->hw_regs = NULL; - } return MPP_OK; } static RK_S32 _count = 0; @@ -1292,6 +1386,7 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) RK_U32 log2_min_cb_size; RK_S32 width, height, numCuInWidth; RK_S32 stride_y, stride_uv, virstrid_y, virstrid_yuv; + RK_S32 i = 0; H265d_REGS_t *hw_regs; RK_S32 ret = MPP_SUCCESS; @@ -1304,7 +1399,25 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) h265d_dxva2_picture_context_t *dxva_cxt = (h265d_dxva2_picture_context_t *)syn->dec.syntax.data; h265d_reg_context_t *reg_cxt = ( h265d_reg_context_t *)hal; - void *rps_ptr = mpp_buffer_get_ptr(reg_cxt->rps_data); + void *rps_ptr = NULL; + if (reg_cxt ->fast_mode) { + for (i = 0; i < MAX_GEN_REG; i++) { + if (!reg_cxt->g_buf[i].use_flag) { + syn->dec.reg_index = i; + reg_cxt->rps_data = reg_cxt->g_buf[i].rps_data; + reg_cxt->scaling_list_data = reg_cxt->g_buf[i].scaling_list_data; + reg_cxt->pps_data = reg_cxt->g_buf[i].pps_data; + reg_cxt->hw_regs = reg_cxt->g_buf[i].hw_regs; + reg_cxt->g_buf[i].use_flag = 1; + break; + } + } + if (i == MAX_GEN_REG) { + mpp_err("hevc rps buf all used"); + return MPP_ERR_NOMEM; + } + } + rps_ptr = mpp_buffer_get_ptr(reg_cxt->rps_data); if (NULL == rps_ptr) { mpp_err("rps_data get ptr error"); @@ -1394,7 +1507,6 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) hw_regs->cabac_error_en = 0xfdfffffd; #ifdef ANDROID - int i = 0; for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(dxva_cxt->pp.RefPicList); i++) { if (dxva_cxt->pp.RefPicList[i].bPicEntry != 0xff && dxva_cxt->pp.RefPicList[i].bPicEntry != 0x7f) { @@ -1429,16 +1541,32 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn) MPP_RET hal_h265d_start(void *hal, HalTaskInfo *task) { MPP_RET ret = MPP_OK; + RK_U8* p = NULL; + H265d_REGS_t *hw_regs = NULL; h265d_reg_context_t *reg_cxt = (h265d_reg_context_t *)hal; - RK_U8* p = (RK_U8*)reg_cxt->hw_regs; + RK_S32 index = task->dec.reg_index; + RK_S32 i; - (void) task; + if (reg_cxt->fast_mode) { + p = (RK_U8*)reg_cxt->g_buf[index].hw_regs; + hw_regs = ( H265d_REGS_t *)reg_cxt->g_buf[index].hw_regs; + } else { + p = (RK_U8*)reg_cxt->hw_regs; + hw_regs = ( H265d_REGS_t *)reg_cxt->hw_regs; + } + + if(hw_regs == NULL){ + mpp_err("hal_h265d_start hw_regs is NULL"); + return MPP_ERR_NULL_PTR; + } for (i = 0; i < 68; i++) { h265h_dbg(H265H_DBG_REG, "RK_HEVC_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + //mpp_log("RK_HEVC_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); p += 4; } #ifdef ANDROID - ret = VPUClientSendReg(reg_cxt->vpu_socket, (RK_U32*)reg_cxt->hw_regs, 68); // 68 is the nb of uint32_t + ret = VPUClientSendReg(reg_cxt->vpu_socket, (RK_U32*)hw_regs, 68); // 68 is the nb of uint32_t + if (ret != 0) { mpp_err("RK_HEVC_DEC: ERROR: VPUClientSendReg Failed!!!\n"); return MPP_ERR_VPUHW; @@ -1455,15 +1583,24 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task) (void)task; (void) hal; #ifdef ANDROID + RK_S32 index = task->dec.reg_index; h265d_reg_context_t *reg_cxt = (h265d_reg_context_t *)hal; - RK_U8* p = (RK_U8*)reg_cxt->hw_regs; - H265d_REGS_t *hw_regs = ( H265d_REGS_t *)reg_cxt->hw_regs; + RK_U8* p = NULL; + H265d_REGS_t *hw_regs = NULL; RK_S32 i; VPU_CMD_TYPE cmd; RK_S32 len; - ret = VPUClientWaitResult(reg_cxt->vpu_socket, (RK_U32*)reg_cxt->hw_regs, 68, &cmd, &len); + if (reg_cxt->fast_mode) { + hw_regs = ( H265d_REGS_t *)reg_cxt->g_buf[index].hw_regs; + } else { + hw_regs = ( H265d_REGS_t *)reg_cxt->hw_regs; + } + p = (RK_U8*)hw_regs; + ret = VPUClientWaitResult(reg_cxt->vpu_socket, (RK_U32*)hw_regs, 68, &cmd, &len); if ((hw_regs->sw_interrupt.sw_dec_error_sta || - hw_regs->sw_interrupt.sw_dec_empty_sta) && reg_cxt->int_cb.callBack) { + hw_regs->sw_interrupt.sw_dec_empty_sta) && + reg_cxt->int_cb.callBack && + !reg_cxt->fast_mode) { reg_cxt->int_cb.callBack(reg_cxt->int_cb.opaque, NULL); } for (i = 0; i < 68; i++) { @@ -1476,6 +1613,9 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task) } p += 4; } + if (reg_cxt->fast_mode) { + reg_cxt->g_buf[index].use_flag = 0; + } #endif return ret; diff --git a/mpp/legacy/vpu_api.cpp b/mpp/legacy/vpu_api.cpp index 7df97f3e..5cfe5c11 100644 --- a/mpp/legacy/vpu_api.cpp +++ b/mpp/legacy/vpu_api.cpp @@ -19,6 +19,7 @@ #include #ifdef ANDROID #include +#include #endif #include "mpp_log.h" @@ -197,10 +198,12 @@ 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_log("dlopen librk_vpuapi library fail\n"); + RK_S32 value = !!access("/dev/rkvdec", F_OK); + if (value) { rkapi_hdl = dlopen("/system/lib/librk_on2.so", RTLD_LAZY); + } + if (rkapi_hdl == NULL) { + rkapi_hdl = dlopen("/system/lib/librk_vpuapi.so", RTLD_LAZY); if (rkapi_hdl == NULL) { return -1; } @@ -220,11 +223,13 @@ RK_S32 open_orign_vpu(VpuCodecContext **ctx) RK_S32 close_orign_vpu(VpuCodecContext **ctx) { void *rkapi_hdl = NULL; + RK_S32 value = !!access("/dev/rkvdec", F_OK); RK_S32 (*rkvpu_close_cxt)(VpuCodecContext **ctx); - rkapi_hdl = dlopen("/system/lib/librk_vpuapi.so", RTLD_LAZY); - if (rkapi_hdl == NULL) { - mpp_log("dlopen librk_vpuapi library fail\n"); + if (value) { rkapi_hdl = dlopen("/system/lib/librk_on2.so", RTLD_LAZY); + } + if (rkapi_hdl == NULL) { + rkapi_hdl = dlopen("/system/lib/librk_vpuapi.so", RTLD_LAZY); if (rkapi_hdl == NULL) { return -1; } @@ -247,6 +252,8 @@ RK_S32 vpu_open_context(VpuCodecContext **ctx) RK_U32 value; mpp_env_get_u32("chg_orig", &value, 0); #ifdef ANDROID + value = value || (!!access("/dev/rkvdec", F_OK)); + value = (value & (s->videoCoding != OMX_RK_VIDEO_CodingHEVC)); if (value || !s) { if (s) { free(s); diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index e279a1fe..d67b7e12 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -30,6 +30,7 @@ VpuApi::VpuApi() #ifdef DUMP_YUV fp = fopen("data/hevcdump.yuv", "wb"); #endif + mpp_construct(&mpp_ctx, &mpi); frame_count = 0; mpp_log_f("ok\n"); @@ -57,7 +58,11 @@ RK_S32 VpuApi::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size) return MPP_ERR_VPU_CODEC_INIT; } - ret = mpp_init(&mpp_ctx, &mpi, type, (MppCodingType)ctx->videoCoding); + if (mpp_ctx == NULL || mpi == NULL) { + mpp_err("found invalid context input"); + return MPP_ERR_NULL_PTR; + } + ret = mpp_init(mpp_ctx, type, (MppCodingType)ctx->videoCoding); VPU_GENERIC vpug; vpug.CodecType = ctx->codecType; @@ -253,6 +258,10 @@ RK_S32 VpuApi::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) mpicmd = MPP_CODEC_SET_INFO_CHANGE_READY; break; } + case VPU_API_USE_FAST_MODE: { + mpicmd = MPP_DEC_USE_FAST_MODE; + break; + } default: { break; } diff --git a/mpp/mpi.cpp b/mpp/mpi.cpp index f5fb8ca5..5b88e9e5 100644 --- a/mpp/mpi.cpp +++ b/mpp/mpi.cpp @@ -128,8 +128,11 @@ static MPP_RET mpi_encode_get_packet(MppCtx ctx, MppPacket *packet) static MPP_RET mpi_flush(MppCtx ctx) { MpiImpl *p = (MpiImpl *)ctx; + MPP_RET ret = MPP_OK; MPI_FUNCTION_ENTER(); - MPP_RET ret = p->ctx->reset(); + if (p->ctx->mInitDone) { + ret = p->ctx->reset(); + } MPI_FUNCTION_LEAVE(); return ret; } @@ -158,16 +161,15 @@ static MppApi mpp_api = { {0}, }; -MPP_RET mpp_init(MppCtx *ctx, MppApi **mpi, MppCtxType type, MppCodingType coding) +MPP_RET mpp_construct(MppCtx *ctx, MppApi **mpi) { + MpiImpl *p; + MPI_FUNCTION_ENTER(); - if (NULL == ctx || NULL == mpi || - type >= MPP_CTX_BUTT || - coding >= MPP_VIDEO_CodingMax) { - mpp_err("mpp_init invalid input ctx %p mpi %p type %d coding %d\n", - ctx, mpi, type, coding); + if (NULL == ctx || NULL == mpi) { + mpp_err("mpp_init invalid input ctx %p mpi %p\n", ctx, mpi); return MPP_ERR_NULL_PTR; } @@ -181,23 +183,39 @@ MPP_RET mpp_init(MppCtx *ctx, MppApi **mpi, MppCtxType type, MppCodingType codin } memset(p, 0, sizeof(*p)); - - p->ctx = new Mpp(type, coding); + p->ctx = new Mpp(); if (NULL == p->ctx) { mpp_free(p); - mpp_err("mpp_init failed to new Mpp\n"); + mpp_err("mpp_construct failed to new Mpp\n"); return MPP_ERR_MALLOC; } - p->api = &mpp_api; p->check = p; - p->type = type; - p->coding = coding; *ctx = p; *mpi = p->api; + MPI_FUNCTION_LEAVE_OK(); + return MPP_OK; +} + + +MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding) +{ + MpiImpl *p = (MpiImpl*)ctx; + MPI_FUNCTION_ENTER(); + + if (NULL == ctx || + type >= MPP_CTX_BUTT || + coding >= MPP_VIDEO_CodingMax) { + mpp_err("mpp_init invalid input ctx %p type %d coding %d\n", + ctx, type, coding); + return MPP_ERR_NULL_PTR; + } + + p->ctx->init(type, coding); + p->type = type; + p->coding = coding; get_mpi_debug(); - MPI_FUNCTION_LEAVE_OK(); return MPP_OK; } diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index fe3dfeb0..ae1246e8 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -33,7 +33,7 @@ #define MPP_TEST_FRAME_SIZE SZ_1M #define MPP_TEST_PACKET_SIZE SZ_512K -Mpp::Mpp(MppCtxType type, MppCodingType coding) +Mpp::Mpp() : mPackets(NULL), mFrames(NULL), mTasks(NULL), @@ -50,26 +50,45 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding) mThreadHal(NULL), mDec(NULL), mEnc(NULL), - mType(type), - mCoding(coding), + mFastMode(0), + mInitDone(0), + mType(MPP_CTX_BUTT), + mCoding(MPP_VIDEO_CodingUnused), mPacketBlock(0), mOutputBlock(0), mMultiFrame(0), mStatus(0) { +} +MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) +{ + + mType = type; + mCoding = coding; switch (mType) { case MPP_CTX_DEC : { + mDec = mpp_calloc(MppDec, 1); + if (NULL == mDec) { + mpp_err_f("failed to malloc context\n"); + return MPP_ERR_NULL_PTR; + } + mPackets = new mpp_list((node_destructor)mpp_packet_deinit); mFrames = new mpp_list((node_destructor)mpp_frame_deinit); mTasks = new mpp_list((node_destructor)NULL); - mpp_dec_init(&mDec, coding); + if (MPP_VIDEO_CodingHEVC == coding) { + mDec->fast_mode = mFastMode; + } + + mpp_dec_init(mDec, coding); + mThreadCodec = new MppThread(mpp_dec_parser_thread, this); mThreadHal = new MppThread(mpp_dec_hal_thread, this); mpp_buffer_group_get_internal(&mInternalGroup, MPP_BUFFER_TYPE_ION); mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_limit_config(mPacketGroup, 0, 2); + mpp_buffer_group_limit_config(mPacketGroup, 0, 3); } break; case MPP_CTX_ENC : { @@ -101,7 +120,9 @@ Mpp::Mpp(MppCtxType type, MppCodingType coding) clear(); } + mInitDone = 1; mpp_env_get_u32("mpp_debug", &mpp_debug, 0); + return MPP_OK; } Mpp::~Mpp () @@ -250,8 +271,8 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param) mpp_log("mpi_control group %p\n", param); mFrameGroup = (MppBufferGroup)param; mpp_buffer_group_set_listener((MppBufferGroupImpl *)param, (void *)mThreadCodec); - mpp_log("signal codec thread\n"); - mThreadCodec->signal(); + mpp_log("signal codec thread\n"); + mThreadCodec->signal(); break; } case MPP_SET_OUTPUT_BLOCK: { @@ -270,6 +291,11 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param) mpp_dec_control(mDec, cmd, param); break; } + case MPP_DEC_USE_FAST_MODE: { + RK_U32 mode = *((RK_U32 *)param); + mFastMode = mode; + break; + } default : { } break; } diff --git a/mpp/mpp.h b/mpp/mpp.h index 5bf42eca..10bc89e2 100644 --- a/mpp/mpp.h +++ b/mpp/mpp.h @@ -59,9 +59,9 @@ class Mpp { public: - Mpp(MppCtxType type, MppCodingType coding); + Mpp(); ~Mpp(); - + MPP_RET init(MppCtxType type, MppCodingType coding); MPP_RET put_packet(MppPacket packet); MPP_RET get_frame(MppFrame *frame); @@ -101,6 +101,9 @@ public: MppDec *mDec; MppEnc *mEnc; + RK_U32 mFastMode; + RK_U32 mInitDone; + private: void clear(); @@ -113,7 +116,6 @@ private: RK_U32 mStatus; - Mpp(); Mpp(const Mpp &); Mpp &operator=(const Mpp &); }; diff --git a/test/mpi_test.c b/test/mpi_test.c index 33ecd92c..84db6fc6 100644 --- a/test/mpi_test.c +++ b/test/mpi_test.c @@ -63,7 +63,13 @@ int mpi_test() mpp_log("mpi_test decoder test start\n"); // decoder demo - ret = mpp_init(&ctx, &mpi, MPP_CTX_DEC, MPP_VIDEO_CodingUnused); + ret = mpp_construct(&ctx, &mpi); + + if (MPP_OK != ret) { + mpp_err("mpp_construct failed\n"); + goto MPP_TEST_FAILED; + } + ret = mpp_init(ctx, MPP_CTX_DEC, MPP_VIDEO_CodingUnused); if (MPP_OK != ret) { mpp_err("mpp_init failed\n"); goto MPP_TEST_FAILED; @@ -172,7 +178,13 @@ int mpi_test() mpp_log("mpi_test encoder test start\n"); // encoder demo - ret = mpp_init(&ctx, &mpi, MPP_CTX_ENC, MPP_VIDEO_CodingUnused); + ret = mpp_construct(&ctx, &mpi); + if (MPP_OK != ret) { + mpp_err("mpp_construct failed\n"); + goto MPP_TEST_FAILED; + } + + ret = mpp_init(ctx, MPP_CTX_ENC, MPP_VIDEO_CodingUnused); if (MPP_OK != ret) { mpp_err("mpp_init failed\n"); goto MPP_TEST_FAILED;