From 34e98c9877963f77d253d5bdff112d5154a6d671 Mon Sep 17 00:00:00 2001 From: shihong.zheng Date: Tue, 10 Dec 2019 12:13:25 +0000 Subject: decoder: add dynamic buf margin for mpeg12/mpeg4/mjpeg/avs2/mvc. [1/1] PD#SWPL-18189 Problem: add more buffers control mpeg2/mpeg4/mjpeg/avs2/mvc for multi-instance. Solution: add dynamic_buf_num_margin interface for mpeg2/mpeg4/mjpeg/avs2 decoder driver. Verify: U212 Change-Id: I1e5edccbea1d51e7d85c65fdeb83305cf21d50fc Signed-off-by: shihong.zheng --- diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c index 6258a75..f90fee6 100644 --- a/drivers/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/frame_provider/decoder/avs2/vavs2.c @@ -761,6 +761,7 @@ struct AVS2Decoder_s { #endif int frameinfo_enable; struct vframe_qos_s vframe_qos; + u32 dynamic_buf_margin; }; static int compute_losless_comp_body_size( @@ -3885,7 +3886,7 @@ static int avs2_local_init(struct AVS2Decoder_s *dec) #ifndef AVS2_10B_MMU init_buf_list(dec); #else - dec->used_buf_num = max_buf_num; + dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin; if (dec->used_buf_num > MAX_BUF_NUM) dec->used_buf_num = MAX_BUF_NUM; if (dec->used_buf_num > FRAME_BUFFERS) @@ -7318,6 +7319,13 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->double_write_mode = config_val; else dec->double_write_mode = double_write_mode; + + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + dec->dynamic_buf_margin = config_val; + else + dec->dynamic_buf_margin = 0; + if (get_config_int(pdata->config, "HDRStaticInfo", &vf_dp.present_flag) == 0 && vf_dp.present_flag == 1) { @@ -7363,6 +7371,7 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->vavs2_amstream_dec_info.height = 0; dec->vavs2_amstream_dec_info.rate = 30;*/ dec->double_write_mode = double_write_mode; + dec->dynamic_buf_margin = dynamic_buf_num_margin; } video_signal_type = dec->video_signal_type; diff --git a/drivers/frame_provider/decoder/h264/vh264_mvc.c b/drivers/frame_provider/decoder/h264/vh264_mvc.c index fdb0535..821b3c1 100644 --- a/drivers/frame_provider/decoder/h264/vh264_mvc.c +++ b/drivers/frame_provider/decoder/h264/vh264_mvc.c @@ -46,6 +46,7 @@ #include #include "../utils/firmware.h" #include +#include "../utils/config_parser.h" #define TIME_TASK_PRINT_ENABLE 0x100 #define PUT_PRINT_ENABLE 0x200 @@ -185,9 +186,11 @@ static s32 vh264mvc_init(void); unsigned int DECODE_BUFFER_START = 0x00200000; unsigned int DECODE_BUFFER_END = 0x05000000; +/* #define DISPLAY_BUFFER_NUM 4 */ +static unsigned int dynamic_buf_num_margin = 8; + #define DECODE_BUFFER_NUM_MAX 16 -#define DISPLAY_BUFFER_NUM 4 -#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + DISPLAY_BUFFER_NUM) +#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + dynamic_buf_num_margin) #define TOTAL_BMMU_BUFF_NUM (MAX_BMMU_BUFFER_NUM * 2 + 3) #define VF_BUFFER_IDX(n) (2 + n) @@ -223,8 +226,12 @@ struct buffer_spec_s { unsigned long phy_addr; int alloc_count; }; +/* static struct buffer_spec_s buffer_spec0[MAX_BMMU_BUFFER_NUM]; static struct buffer_spec_s buffer_spec1[MAX_BMMU_BUFFER_NUM]; +*/ +static struct buffer_spec_s *buffer_spec0; +static struct buffer_spec_s *buffer_spec1; static void *mm_blk_handle; /* @@ -741,7 +748,7 @@ static void do_alloc_work(struct work_struct *work) mb_width, mb_height); total_dec_frame_buffering[0] = - max_dec_frame_buffering[0] + DISPLAY_BUFFER_NUM; + max_dec_frame_buffering[0] + dynamic_buf_num_margin; mb_width = (mb_width + 3) & 0xfffffffc; mb_height = (mb_height + 3) & 0xfffffffc; @@ -822,7 +829,7 @@ static void do_alloc_work(struct work_struct *work) } total_dec_frame_buffering[1] = - max_dec_frame_buffering[1] + DISPLAY_BUFFER_NUM; + max_dec_frame_buffering[1] + dynamic_buf_num_margin; mb_width = (mb_width + 3) & 0xfffffffc; mb_height = (mb_height + 3) & 0xfffffffc; @@ -1369,6 +1376,7 @@ static int vh264mvc_local_init(void) max_dec_frame_buffering[1] = -1; fill_ptr = get_ptr = put_ptr = putting_ptr = 0; dirty_frame_num = 0; + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { view0_vfbuf_use[i] = 0; view1_vfbuf_use[i] = 0; @@ -1412,7 +1420,6 @@ static s32 vh264mvc_init(void) { int ret = -1; char *buf = vmalloc(0x1000 * 16); - if (buf == NULL) return -ENOMEM; @@ -1582,6 +1589,7 @@ static void error_do_work(struct work_struct *work) static int amvdec_h264mvc_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + int config_val = 0; pr_info("amvdec_h264mvc probe start.\n"); mutex_lock(&vh264_mvc_mutex); @@ -1603,13 +1611,28 @@ static int amvdec_h264mvc_probe(struct platform_device *pdev) if (pdata->sys_info) vh264mvc_amstream_dec_info = *pdata->sys_info; + if (pdata->config_len) { + pr_info("pdata->config: %s\n", pdata->config); + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + dynamic_buf_num_margin = config_val; + } + pdata->dec_status = vh264mvc_dec_status; /* pdata->set_trickmode = vh264mvc_set_trickmode; */ + buffer_spec0 = (struct buffer_spec_s *)vzalloc( + sizeof(struct buffer_spec_s) * MAX_BMMU_BUFFER_NUM * 2); + if (NULL == buffer_spec0) + return -ENOMEM; + buffer_spec1 = &buffer_spec0[MAX_BMMU_BUFFER_NUM]; + if (vh264mvc_init() < 0) { pr_info("\namvdec_h264mvc init failed.\n"); kfree(gvs); gvs = NULL; + vfree(buffer_spec0); + buffer_spec0 = NULL; mutex_unlock(&vh264_mvc_mutex); return -ENODEV; } @@ -1649,6 +1672,8 @@ static int amvdec_h264mvc_remove(struct platform_device *pdev) #ifdef DEBUG_SKIP pr_info("view_total = %ld, dropped %ld\n", view_total, view_dropped); #endif + vfree(buffer_spec0); + buffer_spec0 = NULL; kfree(gvs); gvs = NULL; @@ -1734,6 +1759,9 @@ MODULE_PARM_DESC(stat, "\n amvdec_h264mvc stat\n"); module_param(dbg_mode, uint, 0664); MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc dbg mode\n"); +module_param(dynamic_buf_num_margin, uint, 0664); +MODULE_PARM_DESC(dynamic_buf_num_margin, "\n amvdec_h264mvc dynamic_buf_num_margin\n"); + module_param(view_mode, uint, 0664); MODULE_PARM_DESC(view_mode, "\n amvdec_h264mvc view mode\n"); diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c index 1ac107f..493231b 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -44,6 +44,7 @@ #include #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" +#include "../utils/config_parser.h" #define MEM_NAME "codec_mmjpeg" @@ -72,8 +73,9 @@ #define PICINFO_INTERLACE_AVI1_BOT 0x0010 #define PICINFO_INTERLACE_FIRST 0x0010 -#define VF_POOL_SIZE 16 -#define DECODE_BUFFER_NUM_MAX 4 +#define VF_POOL_SIZE 64 +#define DECODE_BUFFER_NUM_MAX 16 +#define DECODE_BUFFER_NUM_DEF 4 #define MAX_BMMU_BUFFER_NUM DECODE_BUFFER_NUM_MAX #define DEFAULT_MEM_SIZE (32*SZ_1M) @@ -96,6 +98,7 @@ static void vmjpeg_work(struct work_struct *work); static int pre_decode_buf_level = 0x800; static int start_decode_buf_level = 0x2000; static u32 without_display_mode; +static u32 dynamic_buf_num_margin; #undef pr_info #define pr_info printk unsigned int mmjpeg_debug_mask = 0xff; @@ -112,6 +115,7 @@ unsigned int mmjpeg_debug_mask = 0xff; #define PRINT_FRAMEBASE_DATA 0x0400 #define PRINT_FLAG_TIMEOUT_STATUS 0x1000 #define PRINT_FLAG_V4L_DETAIL 0x8000 +#define IGNORE_PARAM_FROM_CONFIG 0x8000000 int mmjpeg_debug_print(int index, int debug_flag, const char *fmt, ...) { @@ -216,6 +220,8 @@ struct vdec_mjpeg_hw_s { bool is_used_v4l; void *v4l2_ctx; bool v4l_params_parsed; + int buf_num; + int dynamic_buf_num_margin; }; static void reset_process_time(struct vdec_mjpeg_hw_s *hw); @@ -276,7 +282,7 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) reg = READ_VREG(MREG_FROM_AMRISC); index = READ_VREG(AV_SCRATCH_5); - if (index >= DECODE_BUFFER_NUM_MAX) { + if (index >= hw->buf_num) { pr_err("fatal error, invalid buffer index."); return IRQ_HANDLED; } @@ -298,7 +304,7 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) ps.visible_height = hw->frame_height; ps.coded_width = ALIGN(hw->frame_width, 64); ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1; + ps.dpb_size = hw->buf_num; hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } @@ -465,7 +471,7 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) decbuf_uv_size = 0x80000; decbuf_size = 0x300000; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { int canvas; if (hw->is_used_v4l) { @@ -641,9 +647,10 @@ static void vmjpeg_dump_state(struct vdec_s *vdec) mmjpeg_debug_print(DECODE_ID(hw), 0, "====== %s\n", __func__); mmjpeg_debug_print(DECODE_ID(hw), 0, - "width/height (%d/%d)\n", + "width/height (%d/%d) buf_num %d\n", hw->frame_width, - hw->frame_height + hw->frame_height, + hw->buf_num ); mmjpeg_debug_print(DECODE_ID(hw), 0, "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d input_empty %d\n", @@ -937,28 +944,40 @@ static int vmjpeg_v4l_alloc_buff_config_canvas(struct vdec_mjpeg_hw_s *hw, int i return 0; } +static int vmjpeg_get_buf_num(struct vdec_mjpeg_hw_s *hw) +{ + int buf_num = DECODE_BUFFER_NUM_DEF; + + buf_num += hw->dynamic_buf_num_margin; + + if (buf_num > DECODE_BUFFER_NUM_MAX) + buf_num = DECODE_BUFFER_NUM_MAX; + + return buf_num; +} + static bool is_enough_free_buffer(struct vdec_mjpeg_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - return i == DECODE_BUFFER_NUM_MAX ? false : true; + return i == hw->buf_num ? false : true; } static int find_free_buffer(struct vdec_mjpeg_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - if (i == DECODE_BUFFER_NUM_MAX) + if (i == hw->buf_num) return -1; if (hw->is_used_v4l) @@ -971,7 +990,7 @@ static int find_free_buffer(struct vdec_mjpeg_hw_s *hw) static int vmjpeg_hw_ctx_restore(struct vdec_mjpeg_hw_s *hw) { struct buffer_spec_s *buff_spec; - u32 index, i; + int index, i; index = find_free_buffer(hw); if (index < 0) @@ -984,7 +1003,7 @@ static int vmjpeg_hw_ctx_restore(struct vdec_mjpeg_hw_s *hw) vmjpeg_canvas_init(hw); } else { if (!hw->is_used_v4l) { - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { buff_spec = &hw->buffer_spec[i]; canvas_config_config(buff_spec->y_canvas_index, &buff_spec->canvas_config[0]); @@ -1146,12 +1165,12 @@ static void run(struct vdec_s *vdec, unsigned long mask, hw->run_count++; vdec_reset_core(vdec); - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - if (i == DECODE_BUFFER_NUM_MAX) { + if (i == hw->buf_num) { hw->dec_result = DEC_RESULT_AGAIN; vdec_schedule_work(&hw->work); return; @@ -1391,6 +1410,7 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct vdec_mjpeg_hw_s *hw = NULL; + int config_val = 0; if (pdata == NULL) { pr_info("ammvdec_mjpeg memory resource undefined.\n"); @@ -1430,6 +1450,19 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev) snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, PROVIDER_NAME ".%02x", pdev->id & 0xff); + if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { + mmjpeg_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config); + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin = config_val; + else + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } else { + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } + + hw->buf_num = vmjpeg_get_buf_num(hw); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, &vf_provider_ops, pdata); @@ -1555,6 +1588,8 @@ MODULE_PARM_DESC(pre_decode_buf_level, module_param(udebug_flag, uint, 0664); MODULE_PARM_DESC(udebug_flag, "\n amvdec_mmpeg12 udebug_flag\n"); +module_param(dynamic_buf_num_margin, uint, 0664); +MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n"); module_param(decode_timeout_val, uint, 0664); MODULE_PARM_DESC(decode_timeout_val, "\n ammvdec_mjpeg decode_timeout_val\n"); diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 6095f68..2bde5c9 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -48,6 +48,7 @@ #include #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" +#include "../utils/config_parser.h" #define MEM_NAME "codec_mmpeg12" @@ -92,8 +93,11 @@ #define SEQINFO_PROG 0x00010000 #define CCBUF_SIZE (5*1024) -#define VF_POOL_SIZE 32 -#define DECODE_BUFFER_NUM_MAX 8 +#define VF_POOL_SIZE 64 +#define DECODE_BUFFER_NUM_MAX 16 +#define DECODE_BUFFER_NUM_DEF 8 +#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1) + #define PUT_INTERVAL (HZ/100) #define WORKSPACE_SIZE (4*SZ_64K) /*swap&ccbuf&matirx&MV*/ #define CTX_LMEM_SWAP_OFFSET 0 @@ -102,7 +106,6 @@ #define CTX_CO_MV_OFFSET (CTX_QUANT_MATRIX_OFFSET + 1*1024) #define CTX_DECBUF_OFFSET (CTX_CO_MV_OFFSET + 0x11000) -#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1) #define DEFAULT_MEM_SIZE (32*SZ_1M) static u32 buf_size = 32 * 1024 * 1024; static int pre_decode_buf_level = 0x800; @@ -114,6 +117,7 @@ static unsigned int radr; static unsigned int rval; static u32 without_display_mode; +static u32 dynamic_buf_num_margin; #define VMPEG12_DEV_NUM 9 static unsigned int max_decode_instance_num = VMPEG12_DEV_NUM; @@ -237,6 +241,7 @@ struct vdec_mpeg12_hw_s { unsigned long int start_process_time; u32 last_vld_level; u32 eos; + struct pic_info_t pics[DECODE_BUFFER_NUM_MAX]; u32 canvas_spec[DECODE_BUFFER_NUM_MAX]; u64 lastpts64; @@ -300,6 +305,8 @@ struct vdec_mpeg12_hw_s { bool is_used_v4l; void *v4l2_ctx; bool v4l_params_parsed; + u32 buf_num; + u32 dynamic_buf_num_margin; }; static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw); static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw); @@ -329,6 +336,7 @@ unsigned int mpeg12_debug_mask = 0xff; #define PRINT_FLAG_USERDATA_DETAIL 0x2000 #define PRINT_FLAG_TIMEOUT_STATUS 0x4000 #define PRINT_FLAG_V4L_DETAIL 0x8000 +#define IGNORE_PARAM_FROM_CONFIG 0x8000000 @@ -450,28 +458,40 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int } +static unsigned int vmpeg12_get_buf_num(struct vdec_mpeg12_hw_s *hw) +{ + unsigned int buf_num = DECODE_BUFFER_NUM_DEF; + + buf_num += hw->dynamic_buf_num_margin; + + if (buf_num > DECODE_BUFFER_NUM_MAX) + buf_num = DECODE_BUFFER_NUM_MAX; + + return buf_num; +} + static bool is_enough_free_buffer(struct vdec_mpeg12_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - return i == DECODE_BUFFER_NUM_MAX ? false : true; + return (i == hw->buf_num) ? false : true; } static int find_free_buffer(struct vdec_mpeg12_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - if (i == DECODE_BUFFER_NUM_MAX) + if (i == hw->buf_num) return -1; if (hw->is_used_v4l) @@ -484,12 +504,12 @@ static u32 spec_to_index(struct vdec_mpeg12_hw_s *hw, u32 spec) { u32 i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->canvas_spec[i] == spec) return i; } - return DECODE_BUFFER_NUM_MAX; + return hw->buf_num; } static void set_frame_info(struct vdec_mpeg12_hw_s *hw, struct vframe_s *vf) @@ -1514,7 +1534,7 @@ static int update_reference(struct vdec_mpeg12_hw_s *hw, hw->refs[0] = hw->refs[1]; hw->refs[1] = index; /* second pic do not output */ - index = DECODE_BUFFER_NUM_MAX; + index = hw->buf_num; } else { hw->vfbuf_use[hw->refs[0]]--; hw->refs[0] = hw->refs[1]; @@ -1594,7 +1614,7 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) (info & FRAME_PICTURE_MASK) != FRAME_PICTURE) hw->first_i_frame_ready = 1; /* for field struct case*/ - if (index >= DECODE_BUFFER_NUM_MAX) { + if (index >= hw->buf_num) { debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, "mmpeg12: invalid buf index: %d\n", index); hw->dec_result = DEC_RESULT_ERROR; @@ -1633,7 +1653,7 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) ps.visible_height = hw->frame_height; ps.coded_width = ALIGN(hw->frame_width, 64); ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1; + ps.dpb_size = hw->buf_num; hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } @@ -1692,11 +1712,11 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) } else { /* drop b frame before reference pic ready */ if (hw->refs[0] == -1) - index = DECODE_BUFFER_NUM_MAX; + index = hw->buf_num; } vmpeg12_save_hw_context(hw, reg); - if (index >= DECODE_BUFFER_NUM_MAX) { + if (index >= hw->buf_num) { if (hw->dec_num != 2) { debug_print(DECODE_ID(hw), 0, "mmpeg12: drop pic num %d, type %c, index %d, offset %x\n", @@ -1789,7 +1809,7 @@ static void flush_output(struct vdec_mpeg12_hw_s *hw) if (hw->dec_num < 2) return; - if (index >= 0 && index < DECODE_BUFFER_NUM_MAX) + if (index >= 0 && index < hw->buf_num) prepare_display_buf(hw, &hw->pics[index]); } @@ -2072,13 +2092,13 @@ static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw) decbuf_size = 0x300000; } - for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) { + for (i = 0; i < hw->buf_num + 1; i++) { unsigned canvas; - if (i == (MAX_BMMU_BUFFER_NUM - 1)) /* SWAP&CCBUF&MATIRX&MV */ + if (i == hw->buf_num) /* SWAP&CCBUF&MATIRX&MV */ decbuf_size = WORKSPACE_SIZE; - if (hw->is_used_v4l && !(i == (MAX_BMMU_BUFFER_NUM - 1))) { + if (hw->is_used_v4l && !(i == hw->buf_num)) { continue; } else { ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i, @@ -2090,7 +2110,7 @@ static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw) } } - if (i == (MAX_BMMU_BUFFER_NUM - 1)) { + if (i == hw->buf_num) { if (hw->ccbuf_phyAddress_is_remaped_nocache) codec_mm_unmap_phyaddr(hw->ccbuf_phyAddress_virt); hw->ccbuf_phyAddress_virt = NULL; @@ -2170,10 +2190,11 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) debug_print(DECODE_ID(hw), 0, "====== %s\n", __func__); debug_print(DECODE_ID(hw), 0, - "width/height (%d/%d),i_first %d\n", + "width/height (%d/%d),i_first %d, buf_num %d\n", hw->frame_width, hw->frame_height, - hw->first_i_frame_ready + hw->first_i_frame_ready, + hw->buf_num ); debug_print(DECODE_ID(hw), 0, "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d,input_empty %d\n", @@ -2188,7 +2209,7 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) hw->input_empty ); - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { debug_print(DECODE_ID(hw), 0, "index %d, used %d\n", i, hw->vfbuf_use[i]); } @@ -2355,16 +2376,16 @@ static void check_timer_func(unsigned long arg) static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) { - u32 index, i; + int index, i; index = find_free_buffer(hw); - if (index >= DECODE_BUFFER_NUM_MAX) + if (index < 0 || index >= hw->buf_num) return -1; if (!hw->init_flag) vmpeg12_canvas_init(hw); else { if (!hw->is_used_v4l) { WRITE_VREG(MREG_CO_MV_START, hw->buf_start); - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { canvas_config_config(canvas_y(hw->canvas_spec[i]), &hw->canvas_config[i][0]); canvas_config_config(canvas_u(hw->canvas_spec[i]), @@ -2507,6 +2528,7 @@ static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw) hw->start_process_time = 0; hw->init_flag = 0; hw->error_frame_skip_level = error_frame_skip_level; + if (dec_control) hw->dec_control = dec_control; } @@ -2779,6 +2801,7 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct vdec_mpeg12_hw_s *hw = NULL; + int config_val = 0; pr_info("ammvdec_mpeg12 probe start.\n"); @@ -2825,6 +2848,23 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, &vf_provider_ops, pdata); + if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { + debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config); + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin = config_val; + else + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } else { + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } + hw->buf_num = vmpeg12_get_buf_num(hw); + + if (pdata->parallel_dec == 1) { + int i; + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + hw->canvas_spec[i] = 0xffffff; + } platform_set_drvdata(pdev, pdata); hw->canvas_mode = pdata->canvas_mode; hw->platform_dev = pdev; @@ -2990,6 +3030,7 @@ static struct mconfig mmpeg12_configs[] = { MC_PU32("debug_enable", &debug_enable), MC_PU32("udebug_flag", &udebug_flag), MC_PU32("without_display_mode", &without_display_mode), + MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin), #ifdef AGAIN_HAS_THRESHOLD MC_PU32("again_threshold", &again_threshold), #endif @@ -3043,6 +3084,9 @@ MODULE_PARM_DESC(start_decode_buf_level, module_param(decode_timeout_val, uint, 0664); MODULE_PARM_DESC(decode_timeout_val, "\n ammvdec_mpeg12 decode_timeout_val\n"); +module_param(dynamic_buf_num_margin, uint, 0664); +MODULE_PARM_DESC(dynamic_buf_num_margin, "\n ammvdec_mpeg12 dynamic_buf_num_margin\n"); + module_param_array(max_process_time, uint, &max_decode_instance_num, 0664); module_param(udebug_flag, uint, 0664); diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 6847de4..c098a5e 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -46,6 +46,7 @@ #include #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" +#include "../utils/config_parser.h" #define DRIVER_NAME "ammvdec_mpeg4" #define MODULE_NAME "ammvdec_mpeg4" @@ -91,8 +92,9 @@ /* values between 6 and 14 are reserved */ #define PARC_EXTENDED 15 -#define VF_POOL_SIZE 16 -#define DECODE_BUFFER_NUM_MAX 8 +#define VF_POOL_SIZE 64 +#define DECODE_BUFFER_NUM_MAX 16 +#define DECODE_BUFFER_NUM_DEF 8 #define PUT_INTERVAL (HZ/100) #define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1) #define WORKSPACE_SIZE (12*SZ_64K) @@ -141,6 +143,7 @@ static unsigned int radr; static unsigned int rval; /* 0x40bit = 8byte */ static unsigned int frmbase_cont_bitlevel = 0x40; +static unsigned int dynamic_buf_num_margin; #define VMPEG4_DEV_NUM 9 static unsigned int max_decode_instance_num = VMPEG4_DEV_NUM; @@ -168,6 +171,7 @@ unsigned int mpeg4_debug_mask = 0xff; #define PRINT_FLAG_VDEC_STATUS 0x0800 #define PRINT_FLAG_TIMEOUT_STATUS 0x1000 #define PRINT_FLAG_V4L_DETAIL 0x8000 +#define IGNORE_PARAM_FROM_CONFIG 0x8000000 int mmpeg4_debug_print(int index, int debug_flag, const char *fmt, ...) { @@ -299,6 +303,8 @@ struct vdec_mpeg4_hw_s { bool is_used_v4l; void *v4l2_ctx; bool v4l_params_parsed; + u32 buf_num; + u32 dynamic_buf_num_margin; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -332,6 +338,18 @@ static unsigned char aspect_ratio_table[16] = { static void reset_process_time(struct vdec_mpeg4_hw_s *hw); + +static int vmpeg4_get_buf_num(struct vdec_mpeg4_hw_s *hw) +{ + int buf_num = DECODE_BUFFER_NUM_DEF; + + buf_num += hw->dynamic_buf_num_margin; + if (buf_num > DECODE_BUFFER_NUM_MAX) + buf_num = DECODE_BUFFER_NUM_MAX; + + return buf_num; +} + static int vmpeg4_v4l_alloc_buff_config_canvas(struct vdec_mpeg4_hw_s *hw, int i) { int ret; @@ -422,24 +440,24 @@ static bool is_enough_free_buffer(struct vdec_mpeg4_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - return i == DECODE_BUFFER_NUM_MAX ? false : true; + return i == hw->buf_num ? false : true; } static int find_free_buffer(struct vdec_mpeg4_hw_s *hw) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->vfbuf_use[i] == 0) break; } - if (i == DECODE_BUFFER_NUM_MAX) + if (i == hw->buf_num) return -1; if (hw->is_used_v4l) @@ -453,7 +471,7 @@ static int spec_to_index(struct vdec_mpeg4_hw_s *hw, u32 spec) { int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { if (hw->canvas_spec[i] == spec) return i; } @@ -956,7 +974,7 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) ps.visible_height = hw->frame_height; ps.coded_width = ALIGN(hw->frame_width, 64); ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1; + ps.dpb_size = hw->buf_num; hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } @@ -1512,14 +1530,14 @@ static int vmpeg4_canvas_init(struct vdec_mpeg4_hw_s *hw) } } - for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) { + for (i = 0; i < hw->buf_num + 1; i++) { unsigned canvas; - if (i == (MAX_BMMU_BUFFER_NUM - 1)) + if (i == hw->buf_num) decbuf_size = WORKSPACE_SIZE; - if (hw->is_used_v4l && !(i == (MAX_BMMU_BUFFER_NUM - 1))) { + if (hw->is_used_v4l && !(i == hw->buf_num)) { continue; } else { ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i, @@ -1531,7 +1549,7 @@ static int vmpeg4_canvas_init(struct vdec_mpeg4_hw_s *hw) } } - if (i == (MAX_BMMU_BUFFER_NUM - 1)) { + if (i == hw->buf_num) { hw->buf_start = decbuf_start; } else { if (vdec->parallel_dec == 1) { @@ -1591,13 +1609,14 @@ static void vmpeg4_dump_state(struct vdec_s *vdec) mmpeg4_debug_print(DECODE_ID(hw), 0, "====== %s\n", __func__); mmpeg4_debug_print(DECODE_ID(hw), 0, - "width/height (%d/%d), i_fram:%d, buffer_not_ready %d\n", + "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d\n", hw->frame_width, hw->frame_height, hw->first_i_frame_ready, - hw->buffer_not_ready + hw->buffer_not_ready, + hw->buf_num ); - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { mmpeg4_debug_print(DECODE_ID(hw), 0, "index %d, used %d\n", i, hw->vfbuf_use[i]); } @@ -1791,7 +1810,7 @@ static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw) return -1; } else { if (!hw->is_used_v4l) { - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + for (i = 0; i < hw->buf_num; i++) { canvas_config_config(canvas_y(hw->canvas_spec[i]), &hw->canvas_config[i][0]); canvas_config_config(canvas_u(hw->canvas_spec[i]), @@ -2235,6 +2254,7 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct vdec_mpeg4_hw_s *hw = NULL; + int config_val = 0; if (pdata == NULL) { pr_err("%s memory resource undefined.\n", __func__); @@ -2268,6 +2288,19 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, PROVIDER_NAME ".%02x", pdev->id & 0xff); + + if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { + mmpeg4_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config); + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin = config_val; + else + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } else { + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + } + hw->buf_num = vmpeg4_get_buf_num(hw); + if (pdata->parallel_dec == 1) { int i; for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) @@ -2430,6 +2463,9 @@ MODULE_PARM_DESC(debug_enable, module_param(frmbase_cont_bitlevel, uint, 0664); MODULE_PARM_DESC(frmbase_cont_bitlevel, "\nfrmbase_cont_bitlevel\n"); +module_param(dynamic_buf_num_margin, uint, 0664); +MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n"); + module_param(radr, uint, 0664); MODULE_PARM_DESC(radr, "\nradr\n"); -- cgit