From 3c55b55e4624d4a812a018b6631c8ea15716b9c6 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Thu, 22 Oct 2020 11:53:53 +0800 Subject: [PATCH] [mpp_dec]: Add query interface for debug 1. Add query interface. 2. Add query result in mpi_dec_test. Change-Id: Ie0026f155331c0b0f8e1b5409aeb7d41b6a3ecc6 Signed-off-by: Herman Chen --- inc/rk_mpi_cmd.h | 14 +++++++- inc/rk_vdec_cmd.h | 65 ++++++++++++++++++++++++++++++++++++ mpp/codec/inc/mpp_dec_impl.h | 6 ++++ mpp/codec/mpp_dec.cpp | 45 ++++++++++++++++++++++--- mpp/mpp.cpp | 3 +- test/mpi_dec_test.c | 20 ++++++++++- 6 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 inc/rk_vdec_cmd.h diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 15c88a20..4846c981 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -34,8 +34,14 @@ #define CMD_CTX_ID_ENC (0x00020000) #define CMD_CTX_ID_ISP (0x00030000) -/* separate encoder control command to different segment */ +/* separate encoder / decoder control command to different segment */ #define CMD_CFG_ID_MASK (0x0000FF00) + +/* decoder control command */ +#define CMD_DEC_CFG_ALL (0x00000000) +#define CMD_DEC_QUERY (0x00000100) + +/* encoder control command */ #define CMD_ENC_CFG_ALL (0x00000000) #define CMD_ENC_CFG_RC_API (0x00000100) @@ -83,6 +89,11 @@ typedef enum { MPP_DEC_SET_DISABLE_ERROR, /* When set it will disable sw/hw error (H.264 / H.265) */ MPP_DEC_SET_IMMEDIATE_OUT, MPP_DEC_SET_ENABLE_DEINTERLACE, /* MPP enable deinterlace by default. Vpuapi can disable it */ + + MPP_DEC_CMD_QUERY = CMD_MODULE_CODEC | CMD_CTX_ID_DEC | CMD_DEC_QUERY, + /* query decoder runtime information for decode stage */ + MPP_DEC_QUERY, /* set and get MppDecQueryCfg structure */ + MPP_DEC_CMD_END, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, @@ -164,6 +175,7 @@ typedef enum { MPI_CMD_BUTT, } MpiCmd; +#include "rk_vdec_cmd.h" #include "rk_venc_cmd.h" #include "rk_venc_cfg.h" #include "rk_venc_ref.h" diff --git a/inc/rk_vdec_cmd.h b/inc/rk_vdec_cmd.h new file mode 100644 index 00000000..c0f542e5 --- /dev/null +++ b/inc/rk_vdec_cmd.h @@ -0,0 +1,65 @@ +/* + * Copyright 2015 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 __RK_VDEC_CMD_H__ +#define __RK_VDEC_CMD_H__ + +#include "rk_type.h" + +/* + * decoder query interface is only for debug usage + */ +#define MPP_DEC_QUERY_STATUS (0x00000001) +#define MPP_DEC_QUERY_WAIT (0x00000002) +#define MPP_DEC_QUERY_FPS (0x00000004) +#define MPP_DEC_QUERY_BPS (0x00000008) +#define MPP_DEC_QUERY_DEC_IN_PKT (0x00000010) +#define MPP_DEC_QUERY_DEC_WORK (0x00000020) +#define MPP_DEC_QUERY_DEC_OUT_FRM (0x00000040) + +#define MPP_DEC_QUERY_ALL (MPP_DEC_QUERY_STATUS | \ + MPP_DEC_QUERY_WAIT | \ + MPP_DEC_QUERY_FPS | \ + MPP_DEC_QUERY_BPS | \ + MPP_DEC_QUERY_DEC_IN_PKT | \ + MPP_DEC_QUERY_DEC_WORK | \ + MPP_DEC_QUERY_DEC_OUT_FRM) + +typedef struct MppDecQueryCfg_t { + /* + * 32 bit query flag for query data check + * Each bit represent a query data switch. + * bit 0 - for querying decoder runtime status + * bit 1 - for querying decoder runtime waiting status + * bit 2 - for querying decoder realtime decode fps + * bit 3 - for querying decoder realtime input bps + * bit 4 - for querying decoder input packet count + * bit 5 - for querying decoder start hardware times + * bit 6 - for querying decoder output frame count + */ + RK_U32 query_flag; + + /* 64 bit query data output */ + RK_U32 rt_status; + RK_U32 rt_wait; + RK_U32 rt_fps; + RK_U32 rt_bps; + RK_U32 dec_in_pkt_cnt; + RK_U32 dec_hw_run_cnt; + RK_U32 dec_out_frm_cnt; +} MppDecQueryCfg; + +#endif /*__RK_VDEC_CMD_H__*/ diff --git a/mpp/codec/inc/mpp_dec_impl.h b/mpp/codec/inc/mpp_dec_impl.h index 0f713e67..481541b6 100644 --- a/mpp/codec/inc/mpp_dec_impl.h +++ b/mpp/codec/inc/mpp_dec_impl.h @@ -60,6 +60,7 @@ typedef struct MppDecImpl_t { RK_U32 parser_work_count; RK_U32 parser_wait_count; RK_U32 parser_status_flag; + RK_U32 parser_wait_flag; RK_U32 parser_notify_flag; RK_U32 hal_notify_flag; @@ -95,6 +96,11 @@ typedef struct MppDecImpl_t { // statistics data RK_U32 statistics_en; MppClock clocks[DEC_TIMING_BUTT]; + + // query data + RK_U32 dec_in_pkt_count; + RK_U32 dec_hw_run_count; + RK_U32 dec_out_frame_count; } MppDecImpl; #ifdef __cplusplus diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 853dfbed..9f71fbdc 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -128,7 +128,7 @@ static MPP_RET check_task_wait(MppDecImpl *dec, DecTask *task) { MPP_RET ret = MPP_OK; RK_U32 notify = dec->parser_notify_flag; - RK_U32 last_wait = dec->parser_status_flag; + RK_U32 last_wait = dec->parser_wait_flag; RK_U32 curr_wait = task->wait.val; RK_U32 wait_chg = last_wait & (~curr_wait); @@ -147,7 +147,8 @@ static MPP_RET check_task_wait(MppDecImpl *dec, DecTask *task) dec_dbg_status("%p %08x -> %08x [%08x] notify %08x -> %s\n", dec, last_wait, curr_wait, wait_chg, notify, (ret) ? ("wait") : ("work")); - dec->parser_status_flag = task->wait.val; + dec->parser_status_flag = task->status.val; + dec->parser_wait_flag = task->wait.val; dec->parser_notify_flag = 0; if (ret) { @@ -247,6 +248,7 @@ static RK_U32 reset_parser_thread(Mpp *mpp, DecTask *task) task->status.task_parsed_rdy = 0; // IMPORTANT: clear flag in MppDec context dec->parser_status_flag = 0; + dec->parser_wait_flag = 0; } dec_task_init(task); @@ -353,6 +355,8 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags) } } + dec->dec_out_frame_count++; + if (dec->vproc) { HalTaskGroup group = dec->vproc_tasks; HalTaskHnd hnd = NULL; @@ -518,6 +522,7 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) task->wait.dec_pkt_in = 0; packets->del_at_head(&dec->mpp_pkt_in, sizeof(dec->mpp_pkt_in)); mpp->mPacketGetCount++; + dec->dec_in_pkt_count++; if (dec->use_preset_time_order) { MppPacket pkt_in = NULL; @@ -984,6 +989,7 @@ void *mpp_dec_hal_thread(void *data) mpp_clock_start(dec->clocks[DEC_HW_WAIT]); mpp_hal_hw_wait(dec->hal, &task_info); mpp_clock_pause(dec->clocks[DEC_HW_WAIT]); + dec->dec_hw_run_count++; /* * when hardware decoding is done: @@ -1506,6 +1512,10 @@ MPP_RET mpp_dec_reset(MppDec ctx) sem_wait(&dec->parser_reset); } + dec->dec_in_pkt_count = 0; + dec->dec_hw_run_count = 0; + dec->dec_out_frame_count = 0; + dec_dbg_func("%p out\n", dec); return MPP_OK; } @@ -1540,9 +1550,9 @@ MPP_RET mpp_dec_notify(MppDec ctx, RK_U32 flag) dec->parser_notify_flag |= flag; if ((old_flag != dec->parser_notify_flag) && - (dec->parser_notify_flag & dec->parser_status_flag)) { + (dec->parser_notify_flag & dec->parser_wait_flag)) { dec_dbg_notify("%p status %08x notify %08x signal\n", dec, - dec->parser_status_flag, dec->parser_notify_flag); + dec->parser_wait_flag, dec->parser_notify_flag); thd_dec->signal(); } } @@ -1597,6 +1607,33 @@ MPP_RET mpp_dec_control(MppDec ctx, MpiCmd cmd, void *param) dec->enable_deinterlace = (param) ? (*((RK_U32 *)param)) : (1); dec_dbg_func("enable deinterlace %d\n", dec->enable_deinterlace); } break; + case MPP_DEC_QUERY: { + MppDecQueryCfg *query = (MppDecQueryCfg *)param; + RK_U32 flag = query->query_flag; + + dec_dbg_func("query %x\n", flag); + + if (flag & MPP_DEC_QUERY_STATUS) + query->rt_status = dec->parser_status_flag; + + if (flag & MPP_DEC_QUERY_WAIT) + query->rt_wait = dec->parser_wait_flag; + + if (flag & MPP_DEC_QUERY_FPS) + query->rt_fps = 0; + + if (flag & MPP_DEC_QUERY_BPS) + query->rt_bps = 0; + + if (flag & MPP_DEC_QUERY_DEC_IN_PKT) + query->dec_in_pkt_cnt = dec->dec_in_pkt_count; + + if (flag & MPP_DEC_QUERY_DEC_WORK) + query->dec_hw_run_cnt = dec->dec_hw_run_count; + + if (flag & MPP_DEC_QUERY_DEC_OUT_FRM) + query->dec_out_frm_cnt = dec->dec_out_frame_count; + } break; default : { } break; } diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index e5d39263..66fd3748 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -816,7 +816,8 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) case MPP_DEC_SET_OUTPUT_FORMAT: case MPP_DEC_SET_DISABLE_ERROR: case MPP_DEC_SET_PRESENT_TIME_ORDER: - case MPP_DEC_SET_ENABLE_DEINTERLACE: { + case MPP_DEC_SET_ENABLE_DEINTERLACE: + case MPP_DEC_QUERY: { ret = mpp_dec_control(mDec, cmd, param); } default : { diff --git a/test/mpi_dec_test.c b/test/mpi_dec_test.c index 3fb259cd..f8c9557c 100644 --- a/test/mpi_dec_test.c +++ b/test/mpi_dec_test.c @@ -145,7 +145,6 @@ static int decode_simple(MpiDecLoopData *data) read_size = fread(buf, 1, packet_size, data->fp_input); if (!packet_size || read_size != packet_size || feof(data->fp_input)) { - mpp_log("%p get error and check frame_num\n", ctx); if (data->frame_num < 0) { clearerr(data->fp_input); rewind(data->fp_input); @@ -681,6 +680,25 @@ int mpi_dec_test_decode(MpiDecTestCmd *cmd) } cmd->max_usage = data.max_usage; + { + MppDecQueryCfg query; + + memset(&query, 0, sizeof(query)); + query.query_flag = MPP_DEC_QUERY_ALL; + ret = mpi->control(ctx, MPP_DEC_QUERY, &query); + if (ret) { + mpp_err("%p mpi->control query failed\n", ctx); + goto MPP_TEST_OUT; + } + + /* + * NOTE: + * 1. Output frame count included info change frame and empty eos frame. + * 2. Hardware run count is real decoded frame count. + */ + mpp_log("%p input %d pkt output %d frm decode %d frames\n", ctx, + query.dec_in_pkt_cnt, query.dec_out_frm_cnt, query.dec_hw_run_cnt); + } ret = mpi->reset(ctx); if (MPP_OK != ret) {