summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--drivers/amvdec_ports/Makefile13
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c22
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h3
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c534
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h39
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c57
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h11
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c18
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h8
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c9
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.h6
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c662
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_h264_parser.h226
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c1274
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_hevc_parser.h137
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c397
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h163
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.c198
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h74
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c1233
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h250
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c299
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_vp9_parser.h279
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.c389
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.h141
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.c111
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.h39
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c357
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c477
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c498
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c490
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c499
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c461
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/vdec_vp9_trigger.h0
-rw-r--r--drivers/amvdec_ports/test/vcodec_m2m_test.c18
-rw-r--r--drivers/amvdec_ports/utils/common.c221
-rw-r--r--drivers/amvdec_ports/utils/common.h72
-rw-r--r--drivers/amvdec_ports/utils/get_bits.h590
-rw-r--r--drivers/amvdec_ports/utils/golomb.c147
-rw-r--r--drivers/amvdec_ports/utils/golomb.h500
-rw-r--r--drivers/amvdec_ports/utils/pixfmt.h470
-rw-r--r--drivers/amvdec_ports/utils/put_bits.h323
-rw-r--r--drivers/amvdec_ports/vdec_drv_base.h11
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c45
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h10
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c219
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c308
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c334
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c233
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c317
-rw-r--r--drivers/frame_provider/decoder/utils/Makefile1
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c19
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c131
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h22
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c388
55 files changed, 11471 insertions, 2282 deletions
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c
index e74aa4f..7e2e258 100644
--- a/drivers/frame_provider/decoder/h265/vh265.c
+++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -46,7 +46,7 @@
#include "../utils/config_parser.h"
#include "../utils/firmware.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../../amvdec_ports/vdec_drv_base.h"
+#include "../utils/vdec_v4l2_buffer_ops.h"
#define CONSTRAIN_MAX_BUF_NUM
@@ -1304,6 +1304,7 @@ struct BUF_s {
unsigned long start_adr;
unsigned int size;
int used_flag;
+ unsigned int y_size;
ulong v4l_ref_buf_addr;
} /*BUF_t */;
@@ -1369,6 +1370,7 @@ struct PIC_s {
u32 pts;
u64 pts64;
+ u64 timestamp;
u32 aspect_ratio_idc;
u32 sar_width;
@@ -1424,6 +1426,7 @@ struct tile_s {
#define DEC_RESULT_GET_DATA_RETRY 8
#define DEC_RESULT_EOS 9
#define DEC_RESULT_FORCE_EXIT 10
+#define DEC_RESULT_FREE_CANVAS 11
static void vh265_work(struct work_struct *work);
static void vh265_timeout_work(struct work_struct *work);
@@ -1721,18 +1724,9 @@ struct hevc_state_s {
struct vframe_qos_s vframe_qos;
bool is_used_v4l;
void *v4l2_ctx;
+ bool v4l_params_parsed;
} /*hevc_stru_t */;
-static int v4l_get_fb(struct aml_vcodec_ctx *ctx, struct vdec_fb **out)
-{
- int ret = 0;
-
- ret = ctx->dec_if->get_param(ctx->drv_handle,
- GET_PARAM_FREE_FRAME_BUFFER, out);
-
- return ret;
-}
-
#ifdef AGAIN_HAS_THRESHOLD
u32 again_threshold;
#endif
@@ -2087,7 +2081,7 @@ static void restore_decode_state(struct hevc_state_s *hevc)
static void hevc_init_stru(struct hevc_state_s *hevc,
struct BuffInfo_s *buf_spec_i)
{
- int i;
+ //int i;
INIT_LIST_HEAD(&hevc->log_list);
hevc->work_space_buf = buf_spec_i;
hevc->prefix_aux_size = 0;
@@ -2144,8 +2138,11 @@ static void hevc_init_stru(struct hevc_state_s *hevc,
else
hevc->ignore_bufmgr_error = 0x0;
- for (i = 0; i < MAX_REF_PIC_NUM; i++)
- hevc->m_PIC[i] = NULL;
+ hevc->dec_result = DEC_RESULT_FREE_CANVAS;
+ vdec_schedule_work(&hevc->work);
+ /*for (i = 0; i < MAX_REF_PIC_NUM; i++)
+ hevc->m_PIC[i] = NULL;*/
+
hevc->pic_num = 0;
hevc->lcu_x_num_pre = 0;
hevc->lcu_y_num_pre = 0;
@@ -2969,7 +2966,9 @@ static int alloc_buf(struct hevc_state_s *hevc)
int i;
int ret = -1;
int buf_size = cal_current_buf_size(hevc, NULL);
- struct vdec_fb *fb = NULL;
+
+ if (hevc->is_used_v4l)
+ return 0;
if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
return ret;
@@ -2983,38 +2982,19 @@ static int alloc_buf(struct hevc_state_s *hevc)
/*get_cma_alloc_ref();*/ /*DEBUG_TMP*/
/*alloc compress header first*/
- if (hevc->is_used_v4l) {
- ret = v4l_get_fb(hevc->v4l2_ctx, &fb);
- if (ret) {
+ ret = decoder_bmmu_box_alloc_buf_phy
+ (hevc->bmmu_box,
+ VF_BUFFER_IDX(i), buf_size,
+ DRIVER_NAME,
+ &hevc->m_BUF[i].start_adr);
+ if (ret < 0) {
+ hevc->m_BUF[i].start_adr = 0;
+ if (i <= 8) {
+ hevc->fatal_error |=
+ DECODER_FATAL_ERROR_NO_MEM;
hevc_print(hevc, PRINT_FLAG_ERROR,
- "[%d] get fb fail.\n",
- ((struct aml_vcodec_ctx *)
- (hevc->v4l2_ctx))->id);
- return ret;
- }
-
- hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
- hevc->m_BUF[i].start_adr =
- virt_to_phys(fb->base_y.va);
- hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l ref buf addr: 0x%x\n",
- ((struct aml_vcodec_ctx *)
- (hevc->v4l2_ctx))->id, __func__, fb);
- } else {
- ret = decoder_bmmu_box_alloc_buf_phy
- (hevc->bmmu_box,
- VF_BUFFER_IDX(i), buf_size,
- DRIVER_NAME,
- &hevc->m_BUF[i].start_adr);
- if (ret < 0) {
- hevc->m_BUF[i].start_adr = 0;
- if (i <= 8) {
- hevc->fatal_error |=
- DECODER_FATAL_ERROR_NO_MEM;
- hevc_print(hevc, PRINT_FLAG_ERROR,
- "%s[%d], size: %d, no mem fatal err\n",
- __func__, i, buf_size);
- }
+ "%s[%d], size: %d, no mem fatal err\n",
+ __func__, i, buf_size);
}
}
@@ -3022,6 +3002,7 @@ static int alloc_buf(struct hevc_state_s *hevc)
hevc->m_BUF[i].size = buf_size;
hevc->m_BUF[i].used_flag = 0;
ret = 0;
+
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
hevc_print(hevc, 0,
"Buffer %d: start_adr %p size %x\n",
@@ -3151,7 +3132,6 @@ static int get_work_pic_num(struct hevc_state_s *hevc)
sps_pic_buf_diff = hevc->param.p.sps_max_dec_pic_buffering_minus1_0
- hevc->sps_num_reorder_pics_0;
-
#ifdef MULTI_INSTANCE_SUPPORT
/*
need one more for multi instance, as
@@ -3207,8 +3187,45 @@ static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
struct buf_stru_s buf_stru;
int buf_size = cal_current_buf_size(hevc, &buf_stru);
int dw_mode = get_double_write_mode(hevc);
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ if (hevc->is_used_v4l)
+ buf_size = 0;
for (i = 0; i < BUF_POOL_SIZE; i++) {
+ if (hevc->is_used_v4l && !hevc->m_BUF[i].start_adr) {
+ ret = vdec_v4l_get_buffer(hevc->v4l2_ctx, &fb);
+ if (ret) {
+ hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
+ "[%d] get fb fail.\n",
+ ((struct aml_vcodec_ctx *)
+ (hevc->v4l2_ctx))->id);
+ return ret;
+ }
+
+ hevc->m_BUF[i].used_flag = 0;
+ hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
+ if (fb->num_planes == 1) {
+ hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
+ hevc->m_BUF[i].size = fb->m.mem[0].size;
+ hevc->m_BUF[i].y_size = fb->m.mem[0].offset;
+ fb->m.mem[0].bytes_used = fb->m.mem[0].size;
+ } else if (fb->num_planes == 2) {
+ hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
+ hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size;
+ hevc->m_BUF[i].y_size = fb->m.mem[0].size;
+ fb->m.mem[0].bytes_used = fb->m.mem[0].size;
+ fb->m.mem[1].bytes_used = fb->m.mem[1].size;
+ }
+
+ pic->BUF_index = i;
+
+ hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
+ "[%d] %s(), v4l ref buf addr: 0x%x\n",
+ ((struct aml_vcodec_ctx *)
+ (hevc->v4l2_ctx))->id, __func__, fb);
+ }
+
if (hevc->m_BUF[i].start_adr != 0 &&
hevc->m_BUF[i].used_flag == 0 &&
buf_size <= hevc->m_BUF[i].size) {
@@ -3216,6 +3233,7 @@ static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
break;
}
}
+
if (i >= BUF_POOL_SIZE)
return -1;
@@ -3231,7 +3249,9 @@ static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
} else
y_adr = hevc->m_BUF[i].start_adr;
- y_adr = ((y_adr + 0xffff) >> 16) << 16; /*64k alignment*/
+ if (!hevc->is_used_v4l)
+ y_adr = ((y_adr + 0xffff) >> 16) << 16; /*64k alignment*/
+
pic->POC = INVALID_POC;
/*ensure get_pic_by_POC()
not get the buffer not decoded*/
@@ -3246,9 +3266,14 @@ static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
pic->mc_canvas_y = pic->index;
pic->mc_canvas_u_v = pic->index;
if (dw_mode & 0x10) {
- pic->mc_y_adr = y_adr;
- pic->mc_u_v_adr = y_adr +
- ((buf_stru.mc_buffer_size_u_v_h << 16) << 1);
+ if (hevc->is_used_v4l) {
+ pic->mc_y_adr = y_adr;
+ pic->mc_u_v_adr = y_adr + hevc->m_BUF[i].y_size;
+ } else {
+ pic->mc_y_adr = y_adr;
+ pic->mc_u_v_adr = y_adr +
+ ((buf_stru.mc_buffer_size_u_v_h << 16) << 1);
+ }
pic->mc_canvas_y = (pic->index << 1);
pic->mc_canvas_u_v = (pic->index << 1) + 1;
@@ -3317,19 +3342,24 @@ static void init_pic_list(struct hevc_state_s *hevc)
pic->y_canvas_index = -1;
pic->uv_canvas_index = -1;
}
- if (config_pic(hevc, pic) < 0) {
- if (get_dbg_flag(hevc))
- hevc_print(hevc, 0,
- "Config_pic %d fail\n", pic->index);
- pic->index = -1;
- i++;
- break;
- }
+
pic->width = hevc->pic_w;
pic->height = hevc->pic_h;
pic->double_write_mode = dw_mode;
- if (pic->double_write_mode)
- set_canvas(hevc, pic);
+
+ if (!hevc->is_used_v4l) {
+ if (config_pic(hevc, pic) < 0) {
+ if (get_dbg_flag(hevc))
+ hevc_print(hevc, 0,
+ "Config_pic %d fail\n", pic->index);
+ pic->index = -1;
+ i++;
+ break;
+ }
+
+ if (pic->double_write_mode)
+ set_canvas(hevc, pic);
+ }
}
for (; i < MAX_REF_PIC_NUM; i++) {
@@ -4956,6 +4986,7 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
hevc->lcu_total * hevc->lcu_size * hevc->lcu_size / 2;
int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
struct PIC_s *cur_pic = hevc->cur_pic;
+ struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
data32 = READ_VREG(HEVC_SAO_CTRL0);
data32 &= (~0xf);
@@ -5143,6 +5174,27 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
"[DBLK DEBUG] HEVC1 CFGB : 0x%x\n", data);
}
+ /* swap uv */
+ if (hevc->is_used_v4l) {
+ if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
+ (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
+ data32 &= ~(1 << 8); /* NV21 */
+ else
+ data32 |= (1 << 8); /* NV12 */
+ }
+
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
WRITE_VREG(HEVC_SAO_CTRL1, data32);
if (get_double_write_mode(hevc) & 0x10) {
/* [23:22] dw_v1_ctrl
@@ -5164,6 +5216,25 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
data32 &= (~0xF);
data32 |= 0xf; /* valid only when double write only */
/*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
+
+ /* swap uv */
+ if (hevc->is_used_v4l) {
+ if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
+ (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
+ data32 |= (1 << 12); /* NV21 */
+ else
+ data32 &= ~(1 << 12); /* NV12 */
+ }
+
+ /*
+ * [3:0] little_endian
+ * [5:4] address_format 00:linear 01:32x32 10:64x32
+ * [7:6] reserved
+ * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
+ * [11:10] reserved
+ * [12] CbCr_byte_swap
+ * [31:13] reserved
+ */
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#endif
data32 = 0;
@@ -8205,6 +8276,13 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
if (hevc->is_used_v4l) {
vf->v4l_mem_handle
= hevc->m_BUF[pic->BUF_index].v4l_ref_buf_addr;
+ if (hevc->mmu_enable) {
+ if (vdec_v4l_binding_fd_and_vf(vf->v4l_mem_handle, vf) < 0) {
+ hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
+ "v4l: binding vf fail.\n");
+ return -1;
+ }
+ }
hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
"[%d] %s(), v4l mem handle: 0x%lx\n",
((struct aml_vcodec_ctx *)(hevc->v4l2_ctx))->id,
@@ -8215,6 +8293,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
if (vdec_frame_based(hw_to_vdec(hevc))) {
vf->pts = pic->pts;
vf->pts_us64 = pic->pts64;
+ vf->timestamp = pic->timestamp;
}
/* if (pts_lookup_offset(PTS_TYPE_VIDEO,
stream_offset, &vf->pts, 0) != 0) { */
@@ -8724,7 +8803,7 @@ static int notify_v4l_eos(struct vdec_s *vdec)
struct hevc_state_s *hw = (struct hevc_state_s *)vdec->private;
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
struct vframe_s *vf = NULL;
- struct vdec_fb *fb = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
if (hw->is_used_v4l && hw->eos) {
if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
@@ -8734,11 +8813,12 @@ static int notify_v4l_eos(struct vdec_s *vdec)
return -1;
}
- if (v4l_get_fb(hw->v4l2_ctx, &fb)) {
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) {
pr_err("[%d] get fb fail.\n", ctx->id);
return -1;
}
+ vf->type |= VIDTYPE_V4L_EOS;
vf->timestamp = ULONG_MAX;
vf->v4l_mem_handle = (unsigned long)fb;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
@@ -9211,6 +9291,7 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data)
&& (hevc->chunk)) {
hevc->cur_pic->pts = hevc->chunk->pts;
hevc->cur_pic->pts64 = hevc->chunk->pts64;
+ hevc->cur_pic->timestamp = hevc->chunk->timestamp;
}
mutex_unlock(&hevc->chunks_mutex);
@@ -9748,6 +9829,27 @@ force_output:
hevc->param.p.vui_time_scale_hi,
hevc->param.p.vui_time_scale_lo);
}
+
+ if (hevc->is_used_v4l) {
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
+
+ if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) {
+ struct aml_vdec_pic_infos info;
+
+ hevc->frame_width = hevc->param.p.pic_width_in_luma_samples;
+ hevc->frame_height = hevc->param.p.pic_height_in_luma_samples;
+ info.visible_width = hevc->frame_width;
+ info.visible_height = hevc->frame_height;
+ info.coded_width = ALIGN(hevc->frame_width, 32);
+ info.coded_height = ALIGN(hevc->frame_height, 32);
+ info.dpb_size = get_work_pic_num(hevc);
+ hevc->v4l_params_parsed = true;
+ /*notice the v4l2 codec.*/
+ vdec_v4l_set_pic_infos(ctx, &info);
+ }
+ }
+
if (
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
vdec->master == NULL &&
@@ -10686,6 +10788,15 @@ static s32 vh265_init(struct hevc_state_s *hevc)
init_timer(&hevc->timer);
hevc->stat |= STAT_TIMER_INIT;
+
+ if (hevc->m_ins_flag) {
+#ifdef USE_UNINIT_SEMA
+ sema_init(&hevc->h265_uninit_done_sema, 0);
+#endif
+ INIT_WORK(&hevc->work, vh265_work);
+ INIT_WORK(&hevc->timeout_work, vh265_timeout_work);
+ }
+
if (vh265_local_init(hevc) < 0)
return -EBUSY;
@@ -10758,17 +10869,6 @@ static s32 vh265_init(struct hevc_state_s *hevc)
hevc->timer.function = vh265_check_timer_func;
hevc->timer.expires = jiffies + PUT_INTERVAL;
-#ifdef USE_UNINIT_SEMA
- sema_init(&hevc->h265_uninit_done_sema, 0);
-#endif
-
- /*add_timer(&hevc->timer);
- *hevc->stat |= STAT_TIMER_ARM;
- */
-
- INIT_WORK(&hevc->work, vh265_work);
- INIT_WORK(&hevc->timeout_work, vh265_timeout_work);
-
hevc->fw = fw;
return 0;
@@ -11199,7 +11299,9 @@ static int vmh265_stop(struct hevc_state_s *hevc)
if (use_cma) {
hevc->uninit_list = 1;
reset_process_time(hevc);
+ hevc->dec_result = DEC_RESULT_FREE_CANVAS;
vdec_schedule_work(&hevc->work);
+ flush_work(&hevc->work);
#ifdef USE_UNINIT_SEMA
if (hevc->init_flag) {
down(&hevc->h265_uninit_done_sema);
@@ -11283,7 +11385,7 @@ static void vh265_notify_work(struct work_struct *work)
static void vh265_work_implement(struct hevc_state_s *hevc,
struct vdec_s *vdec,int from)
{
- if (hevc->uninit_list) {
+ if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) {
/*USE_BUF_BLOCK*/
uninit_pic_list(hevc);
hevc_print(hevc, 0, "uninit list\n");
@@ -11690,6 +11792,15 @@ static void vh265_work_implement(struct hevc_state_s *hevc,
else
vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+ if (hevc->is_used_v4l) {
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
+
+ if (ctx->param_sets_from_ucode &&
+ !hevc->v4l_params_parsed)
+ vdec_v4l_write_frame_sync(ctx);
+ }
+
if (hevc->vdec_cb)
hevc->vdec_cb(hw_to_vdec(hevc), hevc->vdec_cb_arg);
}
@@ -11816,6 +11927,17 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
}
#endif
+ if (hevc->is_used_v4l) {
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
+
+ if (ctx->param_sets_from_ucode &&
+ !ctx->v4l_codec_ready &&
+ hevc->v4l_params_parsed)
+ ret = 0; /*the params has parsed.*/
+ }
+
+
if (ret)
not_run_ready[hevc->index] = 0;
else
@@ -12007,10 +12129,32 @@ static void reset(struct vdec_s *vdec)
struct hevc_state_s *hevc =
(struct hevc_state_s *)vdec->private;
+ int i;
- hevc_print(hevc,
- PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
+ cancel_work_sync(&hevc->work);
+ cancel_work_sync(&hevc->notify_work);
+ if (hevc->stat & STAT_VDEC_RUN) {
+ amhevc_stop();
+ hevc->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (hevc->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&hevc->timer);
+ hevc->stat &= ~STAT_TIMER_ARM;
+ }
+ hevc->dec_result = DEC_RESULT_NONE;
+ reset_process_time(hevc);
+ hevc->init_flag = 0;
+ hevc->pic_list_init_flag = 0;
+ dealloc_mv_bufs(hevc);
+ hevc_local_uninit(hevc);
+ if (vh265_local_init(hevc) < 0)
+ pr_debug(" %s local init fail\n", __func__);
+ for (i = 0; i < BUF_POOL_SIZE; i++) {
+ hevc->m_BUF[i].start_adr = 0;
+ }
+ hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
}
static irqreturn_t vh265_irq_cb(struct vdec_s *vdec, int irq)
@@ -12531,8 +12675,14 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
hevc->is_used_v4l = (((unsigned long)
hevc->vh265_amstream_dec_info.param & 0x80) >> 7);
if (hevc->is_used_v4l) {
- hevc->double_write_mode = 0x10;
- hevc->mmu_enable = 0;
+ hevc->mmu_enable = (((unsigned long) // scatter mem
+ hevc->vh265_amstream_dec_info.param & 0x100) >> 8);
+ if (!hevc->mmu_enable)
+ hevc->double_write_mode = 0x10;
+
+ hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
+ "%s v4: enable mmu %d.\n",
+ __func__, hevc->mmu_enable);
}
if (init_mmu_buffers(hevc) < 0) {