summaryrefslogtreecommitdiff
authorshihong.zheng <shihong.zheng@amlogic.com>2019-12-10 12:13:25 (GMT)
committer Zhi Zhou <zhi.zhou@amlogic.com>2019-12-19 12:48:39 (GMT)
commit34e98c9877963f77d253d5bdff112d5154a6d671 (patch)
tree23032f4399361c62012f88442105832bd0706638
parenta18da6451372c2a7c62065d9d6d6aabf014080ec (diff)
downloadmedia_modules-34e98c9877963f77d253d5bdff112d5154a6d671.zip
media_modules-34e98c9877963f77d253d5bdff112d5154a6d671.tar.gz
media_modules-34e98c9877963f77d253d5bdff112d5154a6d671.tar.bz2
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 <shihong.zheng@amlogic.com>
Diffstat
-rw-r--r--drivers/frame_provider/decoder/avs2/vavs2.c11
-rw-r--r--drivers/frame_provider/decoder/h264/vh264_mvc.c38
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c65
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c94
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c68
5 files changed, 214 insertions, 62 deletions
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 <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
#include <linux/amlogic/tee.h>
+#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 <linux/amlogic/media/codec_mm/configs.h>
#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 <linux/amlogic/media/codec_mm/configs.h>
#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 <linux/amlogic/media/codec_mm/configs.h>
#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");