summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--[-rwxr-xr-x]Media.mk1
-rw-r--r--drivers/amvdec_ports/Makefile1
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c112
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h5
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c992
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h2
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c122
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_pm.c206
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_pm.h34
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h188
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c34
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h90
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c28
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c81
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c133
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c34
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c178
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c26
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c223
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c194
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c210
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c304
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c209
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c195
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c6
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h21
-rw-r--r--drivers/common/chips/chips.c1
-rw-r--r--drivers/common/chips/decoder_cpu_ver_info.c8
-rw-r--r--drivers/common/chips/decoder_cpu_ver_info.h1
-rw-r--r--drivers/common/firmware/firmware_drv.c9
-rw-r--r--drivers/common/firmware/firmware_type.c1
-rw-r--r--drivers/common/firmware/firmware_type.h1
-rw-r--r--drivers/common/media_clock/clk/clk.c3
-rw-r--r--drivers/common/media_clock/clk/clkg12.c5
-rw-r--r--drivers/frame_provider/decoder/Makefile1
-rw-r--r--drivers/frame_provider/decoder/avs/avs.c60
-rw-r--r--drivers/frame_provider/decoder/avs2/avs2_bufmgr.c12
-rw-r--r--drivers/frame_provider/decoder/avs2/avs2_global.h3
-rw-r--r--drivers/frame_provider/decoder/avs2/vavs2.c115
-rw-r--r--drivers/frame_provider/decoder/avs_multi/Makefile2
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avs_multi.c1633
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c5065
-rw-r--r--drivers/frame_provider/decoder/h264/vh264.c58
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.c50
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.h34
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c1043
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c707
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c60
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c595
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4.c5
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c80
-rw-r--r--drivers/frame_provider/decoder/utils/amvdec.c5
-rw-r--r--drivers/frame_provider/decoder/utils/frame_check.c178
-rw-r--r--drivers/frame_provider/decoder/utils/frame_check.h4
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c530
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.h18
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c12
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.h3
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c92
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h7
-rw-r--r--drivers/frame_provider/decoder/vav1/Makefile2
-rw-r--r--drivers/frame_provider/decoder/vav1/aom_av1_define.h171
-rw-r--r--drivers/frame_provider/decoder/vav1/av1_bufmgr.c3392
-rw-r--r--drivers/frame_provider/decoder/vav1/av1_global.h2310
-rw-r--r--drivers/frame_provider/decoder/vav1/vav1.c9946
-rw-r--r--drivers/frame_provider/decoder/vav1/vav1.h22
-rw-r--r--drivers/frame_provider/decoder/vc1/vvc1.c46
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c449
-rw-r--r--drivers/frame_sink/encoder/h264/encoder.c2
-rw-r--r--drivers/stream_input/Makefile5
-rw-r--r--drivers/stream_input/amports/amstream.c263
-rw-r--r--drivers/stream_input/parser/demux/aml_dvb.h5
-rw-r--r--drivers/stream_input/parser/demux/hw_demux/demod_gt.h62
-rw-r--r--drivers/stream_input/parser/demux/hw_demux/frontend.c293
-rw-r--r--drivers/stream_input/parser/dvb_common.c17
-rw-r--r--drivers/stream_input/parser/dvb_common.h26
-rw-r--r--drivers/stream_input/parser/esparser.c15
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_demod_gt.h87
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dmx.c270
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.c445
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.h32
-rw-r--r--drivers/stream_input/parser/streambuf.c9
-rw-r--r--drivers/stream_input/parser/tsdemux.c14
-rw-r--r--drivers/stream_input/parser/tsdemux.h1
-rw-r--r--drivers/stream_input/tv_frontend/Makefile16
-rw-r--r--drivers/stream_input/tv_frontend/aml_fe.c1372
-rw-r--r--drivers/stream_input/tv_frontend/aml_fe.h213
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_frontend.c791
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.c2163
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.h323
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c725
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/amlfrontend.c1402
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/demod_func.c2996
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c1331
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/dvbt_func.c2188
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/i2c_func.c42
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/acf_filter_coefficient.h414
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che.h77
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che_bit.h266
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front.h70
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front_bit.h331
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync.h53
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync_bit.h110
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top.h90
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top_bit.h178
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/aml_dtv_demod_reg.h28
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/amlfrontend.h86
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/demod_func.h626
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/tuner_func.c189
-rw-r--r--firmware/video_ucode.bin14148
116 files changed, 25845 insertions, 36303 deletions
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index c2e0e91..91d8c1f 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -63,6 +63,9 @@
#include <linux/crc32.h>
#include <media/v4l2-mem2mem.h>
+#define DETECT_WRONG_MULTI_SLICE
+
+
#undef pr_info
#define pr_info printk
#define VDEC_DW
@@ -131,6 +134,8 @@ unsigned int h264_debug_mask = 0xff;
*/
unsigned int h264_debug_cmd;
+static int ref_b_frame_error_max_count = 50;
+
static unsigned int dec_control =
DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE |
DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE;
@@ -267,8 +272,13 @@ static unsigned int i_only_flag;
bit[12] i_only when error happen
bit[13] 0: mark error according to last pic, 1: ignore mark error
bit[14] 0: result done when timeout from ucode. 1: reset bufmgr when timeout.
+ bit[15] 1: dpb_frame_count If the dpb_frame_count difference is large, it moves out of the DPB buffer.
+ bit[16] 1: check slice header number.
+ bit[17] 1: If the decoded Mb count is insufficient but greater than the threshold, it is considered the correct frame.
+ bit[18] 1: time out status, store pic to dpb buffer.
+ bit[19] 1: If a lot b frames are wrong consecutively, the DPB queue reset.
*/
-static unsigned int error_proc_policy = 0x4fb6; /*0x1f14*/
+static unsigned int error_proc_policy = 0xfCfb6; /*0x1f14*/
/*
@@ -306,6 +316,9 @@ static unsigned int frmbase_cont_bitlevel = 0x40;
static unsigned int frmbase_cont_bitlevel2 = 0x1;
+static unsigned int check_slice_num = 30;
+
+static unsigned int mb_count_threshold = 5; /*percentage*/
#define MH264_USERDATA_ENABLE
@@ -633,8 +646,8 @@ struct vdec_h264_hw_s {
#endif
struct StorablePicture *last_dec_picture;
- ulong lmem_addr;
- dma_addr_t lmem_addr_remap;
+ ulong lmem_phy_addr;
+ dma_addr_t lmem_addr;
void *bmmu_box;
#ifdef H264_MMU
@@ -846,10 +859,26 @@ struct vdec_h264_hw_s {
bool first_head_check_flag;
unsigned int height_aspect_ratio;
unsigned int width_aspect_ratio;
- bool new_iframe_flag;
- bool ref_err_flush_dpb_flag;
unsigned int first_i_policy;
u32 reorder_dpb_size_margin;
+ bool wait_reset_done_flag;
+#ifdef DETECT_WRONG_MULTI_SLICE
+ unsigned int multi_slice_pic_check_count;
+ /* multi_slice_pic_flag:
+ 0, unknown;
+ 1, single slice;
+ 2, multi slice
+ */
+ unsigned int multi_slice_pic_flag;
+ unsigned int picture_slice_count;
+ unsigned int cur_picture_slice_count;
+ unsigned char force_slice_as_picture_flag;
+ unsigned int last_picture_slice_count;
+ unsigned int first_pre_frame_num;
+#endif
+ unsigned int res_ch_flag;
+ u32 b_frame_error_count;
+ struct vdec_info gvs;
};
static u32 again_threshold;
@@ -902,13 +931,11 @@ static void h264_clear_dpb(struct vdec_h264_hw_s *hw);
/* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
static u32 mem_map_mode = H265_MEM_MAP_MODE;
-#define MAX_SIZE_8K (8192 * 4608)
#define MAX_SIZE_4K (4096 * 2304)
static int is_oversize(int w, int h)
{
- int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
- MAX_SIZE_8K : MAX_SIZE_4K;
+ int max = MAX_SIZE_4K;
if (w < 0 || h < 0)
return true;
@@ -1669,6 +1696,7 @@ static unsigned char is_buf_spec_in_disp_q(struct vdec_h264_hw_s *hw,
static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i)
{
+ struct vdec_s *vdec = hw_to_vdec(hw);
if (hw->mmu_enable) {
if (hw->buffer_spec[i].alloc_header_addr)
return 0;
@@ -1706,7 +1734,25 @@ static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i)
hw->no_mem_count = 0;
hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM;
}
-
+ if (!vdec_secure(vdec)) {
+ /*init internal buf*/
+ char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr);
+ if (tmpbuf) {
+ memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
+ codec_mm_dma_flush(tmpbuf,
+ PAGE_ALIGN(buf_size),
+ DMA_TO_DEVICE);
+ } else {
+ tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size));
+ if (tmpbuf) {
+ memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
+ codec_mm_dma_flush(tmpbuf,
+ PAGE_ALIGN(buf_size),
+ DMA_TO_DEVICE);
+ codec_mm_unmap_phyaddr(tmpbuf);
+ }
+ }
+ }
hw->buffer_spec[i].buf_adr =
hw->buffer_spec[i].cma_alloc_addr;
addr = hw->buffer_spec[i].buf_adr;
@@ -2513,6 +2559,7 @@ static int check_force_interlace(struct vdec_h264_hw_s *hw,
static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
{
struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
+
if (frame->slice_type == I_SLICE)
vframe_qos->type = 1;
else if (frame->slice_type == P_SLICE)
@@ -2520,7 +2567,10 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
else if (frame->slice_type == B_SLICE)
vframe_qos->type = 3;
- vframe_qos->size = frame->frame_size;
+ if (input_frame_based(hw_to_vdec(hw)))
+ vframe_qos->size = frame->frame_size2;
+ else
+ vframe_qos->size = frame->frame_size;
vframe_qos->pts = frame->pts64;
vframe_qos->max_mv = frame->max_mv;
@@ -2553,8 +2603,6 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
vframe_qos->min_skip);
*/
vframe_qos->num++;
- if (hw->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
}
static int is_iframe(struct FrameStore *frame) {
@@ -2572,6 +2620,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
struct vframe_s *vf = NULL;
int buffer_index = frame->buf_spec_num;
+ struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
+ ulong nv_order = VIDTYPE_VIU_NV21;
int vf_count = 1;
int i;
int bForceInterlace = 0;
@@ -2582,6 +2632,14 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
__func__, buffer_index);
return -1;
}
+
+ /* swap uv */
+ if (hw->is_used_v4l) {
+ if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
+ (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
+ nv_order = VIDTYPE_VIU_NV12;
+ }
+
if (force_disp_bufspec_num & 0x100) {
/*recycle directly*/
if (hw->buffer_spec[frame->buf_spec_num].used != 3 &&
@@ -2631,6 +2689,40 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
hw->last_pts64 = frame->pts64;
hw->last_pts = frame->pts;
}
+
+ /* SWPL-18973 96000/15=6400, less than 15fps check */
+ if ((!hw->duration_from_pts_done) && (hw->frame_dur > 6400ULL)) {
+ if ((check_force_interlace(hw, frame)) &&
+ (frame->slice_type == I_SLICE) &&
+ (hw->pts_outside)) {
+ if ((!hw->h264_pts_count) || (!hw->h264pts1)) {
+ hw->h264pts1 = frame->pts;
+ hw->h264_pts_count = 0;
+ } else if (frame->pts > hw->h264pts1) {
+ u32 calc_dur =
+ PTS2DUR(frame->pts - hw->h264pts1);
+ calc_dur = ((calc_dur/hw->h264_pts_count) << 1);
+ if (hw->frame_dur < (calc_dur + 200) &&
+ hw->frame_dur > (calc_dur - 200)) {
+ hw->frame_dur >>= 1;
+ vdec_schedule_work(&hw->notify_work);
+ dpb_print(DECODE_ID(hw), 0,
+ "correct frame_dur %d, calc_dur %d, count %d\n",
+ hw->frame_dur, (calc_dur >> 1), hw->h264_pts_count);
+ hw->duration_from_pts_done = 1;
+ hw->h264_pts_count = 0;
+ }
+ }
+ }
+ hw->h264_pts_count++;
+ }
+
+ if (frame->data_flag & ERROR_FLAG) {
+ vdec_count_info(&hw->gvs, 1, 0);
+ if (!hw->send_error_frame_flag)
+ hw->gvs.drop_frame_count++;
+ }
+
if ((frame->data_flag & NODISP_FLAG) ||
(frame->data_flag & NULL_FLAG) ||
((!hw->send_error_frame_flag) &&
@@ -2666,6 +2758,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
bForceInterlace = check_force_interlace(hw, frame);
if (bForceInterlace)
vf_count = 2;
+ if (hw->is_used_v4l)
+ vf_count = 1;
hw->buffer_spec[buffer_index].vf_ref = 0;
fill_frame_info(hw, frame);
for (i = 0; i < vf_count; i++) {
@@ -2713,7 +2807,7 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
if (hw->double_write_mode) {
vf->type |= VIDTYPE_PROGRESSIVE
| VIDTYPE_VIU_FIELD;
- vf->type |= VIDTYPE_VIU_NV21;
+ vf->type |= nv_order;
if (hw->double_write_mode == 3)
vf->type |= VIDTYPE_COMPRESS;
@@ -2746,7 +2840,7 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
vf->compHeight = hw->frame_height;
} else {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
- VIDTYPE_VIU_NV21;
+ nv_order;
vf->canvas0Addr = vf->canvas1Addr =
spec2canvas(&hw->buffer_spec[buffer_index]);
@@ -2778,12 +2872,23 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
if (bForceInterlace || is_interlace(frame)) {
vf->type =
VIDTYPE_INTERLACE_FIRST |
- VIDTYPE_VIU_NV21;
+ nv_order;
if (bForceInterlace) {
+ if (frame->frame != NULL && frame->frame->pic_struct == PIC_TOP_BOT) {
vf->type |= (i == 0 ?
VIDTYPE_INTERLACE_TOP :
VIDTYPE_INTERLACE_BOTTOM);
+ } else if (frame->frame != NULL && frame->frame->pic_struct == PIC_BOT_TOP) {
+ vf->type |= (i == 0 ?
+ VIDTYPE_INTERLACE_BOTTOM :
+ VIDTYPE_INTERLACE_TOP);
+ } else {
+ vf->type |= (i == 0 ?
+ VIDTYPE_INTERLACE_TOP :
+ VIDTYPE_INTERLACE_BOTTOM);
+ }
+
if (i == 1) {
vf->pts = 0;
vf->pts_us64 = 0;
@@ -2800,8 +2905,16 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
vf->duration = vf->duration/2;
}
- if (i == 0)
- decoder_do_frame_check(hw_to_vdec(hw), vf);
+ if (i == 0) {
+ struct vdec_s *pvdec;
+ struct vdec_info vs;
+
+ pvdec = hw_to_vdec(hw);
+ memset(&vs, 0, sizeof(struct vdec_info));
+ pvdec->dec_status(pvdec, &vs);
+ decoder_do_frame_check(pvdec, vf);
+ vdec_fill_vdec_frame(pvdec, &hw->vframe_qos, &vs, vf, frame->hw_decode_time);
+ }
/*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
vf->sar_width = hw->width_aspect_ratio;
@@ -3211,7 +3324,7 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
* bit 1:0 -- h264_co_mb_info_wr_ptr
*/
#define H264_CO_MB_RW_CTL VLD_C3D /* 0xc3d */
-
+#define DCAC_DDR_BYTE64_CTL 0x0e1d
unsigned long canvas_adr;
unsigned int ref_reg_val;
unsigned int one_ref_cfg = 0;
@@ -3313,9 +3426,14 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
h264_buffer_info_data_write_count = 0;
//disable this read cache when frame width <= 64 (4MBs)
- //IQIDCT_CONTROL, bit[16] – dcac_dma_read_cache_disable
- if (hw->frame_width <= 64)
+ //IQIDCT_CONTROL, bit[16] dcac_dma_read_cache_disable
+ if (hw->frame_width <= 64) {
SET_VREG_MASK(IQIDCT_CONTROL,(1 << 16));
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A))
+ // Disable DDR_BYTE64_CACHE
+ WRITE_VREG(DCAC_DDR_BYTE64_CTL,
+ (READ_VREG(DCAC_DDR_BYTE64_CTL) & (~0xf)) | 0xa);
+ }
else
CLEAR_VREG_MASK(IQIDCT_CONTROL,(1 << 16));
@@ -3352,6 +3470,24 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
pic->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark1 \n");
}
+
+ if (error_proc_policy & 0x80000) {
+ if (ref_b_frame_error_max_count &&
+ ref->slice_type == B_SLICE) {
+ if (ref->data_flag & ERROR_FLAG)
+ hw->b_frame_error_count++;
+ else
+ hw->b_frame_error_count = 0;
+ if (hw->b_frame_error_count > ref_b_frame_error_max_count) {
+ hw->b_frame_error_count = 0;
+ dpb_print(DECODE_ID(hw), 0,
+ "error %d B frame, reset dpb buffer\n",
+ ref_b_frame_error_max_count);
+ return -1;
+ }
+ }
+ }
+
if (ref->data_flag & NULL_FLAG)
hw->data_flag |= NULL_FLAG;
#endif
@@ -3736,10 +3872,19 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
struct vframe_s *vf;
struct vdec_s *vdec = op_arg;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
+ struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
+ ulong nv_order = VIDTYPE_VIU_NV21;
if (!hw)
return NULL;
+ /* swap uv */
+ if (hw->is_used_v4l) {
+ if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
+ (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
+ nv_order = VIDTYPE_VIU_NV12;
+ }
+
if (force_disp_bufspec_num & 0x100) {
int buffer_index = force_disp_bufspec_num & 0xff;
if (force_disp_bufspec_num & 0x200)
@@ -3770,7 +3915,7 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
if (hw->double_write_mode) {
vf->type |= VIDTYPE_PROGRESSIVE
| VIDTYPE_VIU_FIELD;
- vf->type |= VIDTYPE_VIU_NV21;
+ vf->type |= nv_order;
if (hw->double_write_mode == 3)
vf->type |= VIDTYPE_COMPRESS;
@@ -3808,7 +3953,7 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
}
} else {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
- VIDTYPE_VIU_NV21;
+ nv_order;
vf->canvas0Addr = vf->canvas1Addr =
spec2canvas(&hw->buffer_spec[buffer_index]);
}
@@ -3862,6 +4007,24 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
return NULL;
}
+static bool vf_valid_check(struct vframe_s *vf, struct vdec_h264_hw_s *hw) {
+ int i,j;
+ if (hw->is_used_v4l)
+ return true;
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ for (j = 0; j < VF_POOL_NUM; j ++) {
+ if (vf == &(hw->vfpool[j][i]))
+ return true;
+ }
+ }
+ dpb_print(DECODE_ID(hw), 0, " invalid vf been put, vf = %p\n", vf);
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "dump vf [%d]= %p\n", i, &(hw->vfpool[hw->cur_pool][i]));
+ }
+ return false;
+}
+
static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
{
struct vdec_s *vdec = op_arg;
@@ -3925,7 +4088,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
hw->vf_put_count++;
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
+ if (vf && (vf_valid_check(vf, hw) == true))
+ kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
#define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG
if (hw->buffer_empty_flag)
@@ -4378,55 +4542,55 @@ static void get_picture_qos_info(struct StorablePicture *picture)
#endif
picture->min_mv = mv_lo;
+#ifdef DEBUG_QOS
/* {mvy_L0_max, mvy_L0_min} */
rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
mv_hi = (rdata32>>16)&0xffff;
if (mv_hi & 0x8000)
mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
pr_info(" [Picture %d Quality] MVY_L0 MAX : %d\n",
pic_number, mv_hi);
-#endif
+
mv_lo = (rdata32>>0)&0xffff;
if (mv_lo & 0x8000)
mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
+
pr_info(" [Picture %d Quality] MVY_L0 MIN : %d\n",
pic_number, mv_lo);
-#endif
+
/* {mvx_L1_max, mvx_L1_min} */
rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
mv_hi = (rdata32>>16)&0xffff;
if (mv_hi & 0x8000)
mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
+
pr_info(" [Picture %d Quality] MVX_L1 MAX : %d\n",
pic_number, mv_hi);
-#endif
+
mv_lo = (rdata32>>0)&0xffff;
if (mv_lo & 0x8000)
mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
+
pr_info(" [Picture %d Quality] MVX_L1 MIN : %d\n",
pic_number, mv_lo);
-#endif
+
/* {mvy_L1_max, mvy_L1_min} */
rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
mv_hi = (rdata32>>16)&0xffff;
if (mv_hi & 0x8000)
mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
+
pr_info(" [Picture %d Quality] MVY_L1 MAX : %d\n",
pic_number, mv_hi);
-#endif
+
mv_lo = (rdata32>>0)&0xffff;
if (mv_lo & 0x8000)
mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
+
pr_info(" [Picture %d Quality] MVY_L1 MIN : %d\n",
pic_number, mv_lo);
#endif
@@ -5339,6 +5503,8 @@ static int parse_one_sei_record(struct vdec_h264_hw_s *hw,
/* user data length should be align with 8 bytes,
if not, then padding with zero*/
for (i = 0; i < payload_size; i += 8) {
+ if (hw->sei_itu_data_len + i >= SEI_ITU_DATA_SIZE)
+ break; // Avoid out-of-bound writing
for (j = 0; j < 8; j++) {
int index;
@@ -5356,6 +5522,8 @@ static int parse_one_sei_record(struct vdec_h264_hw_s *hw,
data_len = ((payload_size + 8) >> 3) << 3;
hw->sei_itu_data_len += data_len;
+ if (hw->sei_itu_data_len >= SEI_ITU_DATA_SIZE)
+ hw->sei_itu_data_len = SEI_ITU_DATA_SIZE;
/*
dpb_print(DECODE_ID(hw), 0,
"%s: user data, and len = %d:\n",
@@ -5408,16 +5576,22 @@ static void check_decoded_pic_error(struct vdec_h264_hw_s *hw)
return;
if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME)
mb_total /= 2;
- if (error_proc_policy & 0x100) {
- if (decode_mb_count < mb_total)
- p->data_flag |= ERROR_FLAG;
- }
if ((error_proc_policy & 0x200) &&
READ_VREG(ERROR_STATUS_REG) != 0) {
p->data_flag |= ERROR_FLAG;
}
+ if (error_proc_policy & 0x100) {
+ if (decode_mb_count < mb_total) {
+ p->data_flag |= ERROR_FLAG;
+ if ((error_proc_policy & 0x20000) &&
+ decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100) {
+ p->data_flag &= ~ERROR_FLAG;
+ }
+ }
+ }
+
if (p->data_flag & ERROR_FLAG) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
"%s: decode error, seq_info2 0x%x, mby_mbx 0x%x, mb_total %d decoded mb_count %d ERROR_STATUS_REG 0x%x\n",
@@ -5432,6 +5606,157 @@ static void check_decoded_pic_error(struct vdec_h264_hw_s *hw)
}
}
+static int vh264_pic_done_proc(struct vdec_s *vdec)
+{
+ struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
+ int ret;
+
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+
+ if (input_frame_based(vdec) &&
+ (!(hw->i_only & 0x2)) &&
+ frmbase_cont_bitlevel != 0 &&
+ READ_VREG(VIFF_BIT_CNT) >
+ frmbase_cont_bitlevel) {
+ /*handle the case: multi pictures in one packet*/
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n",
+ __func__,
+ hw->decode_pic_count,
+ READ_VREG(VIFF_BIT_CNT));
+ hw->frmbase_cont_flag = 1;
+ } else
+ hw->frmbase_cont_flag = 0;
+
+ if (p_H264_Dpb->mVideo.dec_picture) {
+ get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture);
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ DEL_EXIST(hw,
+ p_H264_Dpb->mVideo.dec_picture) = 0;
+ if (vdec->master) {
+ struct vdec_h264_hw_s *hw_ba =
+ (struct vdec_h264_hw_s *)
+ vdec->master->private;
+ if (hw_ba->last_dec_picture)
+ DEL_EXIST(hw_ba,
+ hw_ba->last_dec_picture)
+ = 1;
+ }
+#endif
+ mutex_lock(&hw->chunks_mutex);
+ if (hw->chunk) {
+ p_H264_Dpb->mVideo.dec_picture->pts =
+ hw->chunk->pts;
+ p_H264_Dpb->mVideo.dec_picture->pts64 =
+ hw->chunk->pts64;
+ p_H264_Dpb->mVideo.dec_picture->timestamp =
+ hw->chunk->timestamp;
+#ifdef MH264_USERDATA_ENABLE
+ vmh264_udc_fill_vpts(hw,
+ p_H264_Dpb->mSlice.slice_type,
+ hw->chunk->pts, 1);
+#endif
+
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ } else if (vdec->master) {
+ /*dv enhance layer,
+ do not checkout pts*/
+ struct StorablePicture *pic =
+ p_H264_Dpb->mVideo.dec_picture;
+ pic->pts = 0;
+ pic->pts64 = 0;
+#endif
+ } else {
+ struct StorablePicture *pic =
+ p_H264_Dpb->mVideo.dec_picture;
+ u32 offset = pic->offset_delimiter;
+ if (pts_pickout_offset_us64(PTS_TYPE_VIDEO,
+ offset, &pic->pts, 0, &pic->pts64)) {
+ pic->pts = 0;
+ pic->pts64 = 0;
+#ifdef MH264_USERDATA_ENABLE
+ vmh264_udc_fill_vpts(hw,
+ p_H264_Dpb->mSlice.slice_type,
+ pic->pts, 0);
+#endif
+ } else {
+#ifdef MH264_USERDATA_ENABLE
+ vmh264_udc_fill_vpts(hw,
+ p_H264_Dpb->mSlice.slice_type,
+ pic->pts, 1);
+#endif
+ }
+
+ }
+ mutex_unlock(&hw->chunks_mutex);
+
+ check_decoded_pic_error(hw);
+#ifdef ERROR_HANDLE_TEST
+ if ((hw->data_flag & ERROR_FLAG)
+ && (error_proc_policy & 0x80)) {
+ release_cur_decoding_buf(hw);
+ h264_clear_dpb(hw);
+ hw->dec_flag = 0;
+ hw->data_flag = 0;
+ hw->skip_frame_count = 0;
+ hw->has_i_frame = 0;
+ hw->no_error_count = 0xfff;
+ hw->no_error_i_count = 0xf;
+ } else
+#endif
+ ret = store_picture_in_dpb(p_H264_Dpb,
+ p_H264_Dpb->mVideo.dec_picture,
+ hw->data_flag | hw->dec_flag |
+ p_H264_Dpb->mVideo.dec_picture->data_flag);
+
+
+
+ if (ret == -1) {
+ release_cur_decoding_buf(hw);
+ bufmgr_force_recover(p_H264_Dpb);
+ } else {
+ if (hw->data_flag & ERROR_FLAG) {
+ hw->no_error_count = 0;
+ hw->no_error_i_count = 0;
+ } else {
+ hw->no_error_count++;
+ if (hw->data_flag & I_FLAG)
+ hw->no_error_i_count++;
+ }
+ if (hw->mmu_enable)
+ hevc_set_unused_4k_buff_idx(hw,
+ p_H264_Dpb->mVideo.
+ dec_picture->buf_spec_num);
+ bufmgr_post(p_H264_Dpb);
+ hw->last_dec_picture =
+ p_H264_Dpb->mVideo.dec_picture;
+ p_H264_Dpb->mVideo.dec_picture = NULL;
+ /* dump_dpb(&p_H264_Dpb->mDPB); */
+ hw->has_i_frame = 1;
+ if (hw->mmu_enable)
+ hevc_set_frame_done(hw);
+ hw->decode_pic_count++;
+ p_H264_Dpb->decode_pic_count = hw->decode_pic_count;
+ if (hw->skip_frame_count > 0) {
+ /*skip n frame after first I */
+ hw->skip_frame_count--;
+ if (hw->skip_frame_count == 0)
+ hw->dec_flag &= (~NODISP_FLAG);
+ } else if (hw->skip_frame_count < -1) {
+ /*skip n frame after first I until second I */
+ hw->skip_frame_count++;
+ if (hw->skip_frame_count == -1)
+ hw->dec_flag &= (~NODISP_FLAG);
+ }
+ }
+ }
+ return 0;
+}
+
+
static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
{
int i;
@@ -5439,16 +5764,10 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status;
u32 debug_tag;
- int ret;
if (dec_dpb_status == H264_CONFIG_REQUEST) {
#if 1
unsigned short *p = (unsigned short *)hw->lmem_addr;
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->lmem_addr_remap,
- PAGE_SIZE,
- DMA_FROM_DEVICE);
for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
int ii;
for (ii = 0; ii < 4; ii++) {
@@ -5495,6 +5814,20 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
reset_process_time(hw);
hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
hw->dec_result = DEC_RESULT_CONFIG_PARAM;
+#ifdef DETECT_WRONG_MULTI_SLICE
+ /*restart check count and set 'unknown'*/
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
+ "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_CONFIG_REQUEST => restart check\n",
+ __func__,
+ hw->multi_slice_pic_check_count,
+ hw->picture_slice_count,
+ hw->cur_picture_slice_count,
+ hw->multi_slice_pic_flag);
+
+ hw->multi_slice_pic_check_count = 0;
+ hw->multi_slice_pic_flag = 0;
+ hw->picture_slice_count = 0;
+#endif
vdec_schedule_work(&hw->work);
} else if (dec_dpb_status == H264_SLICE_HEAD_DONE) {
u16 data_hight;
@@ -5503,21 +5836,42 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
int slice_header_process_status = 0;
int I_flag;
+ int frame_num_gap = 0;
/*unsigned char is_idr;*/
unsigned short *p = (unsigned short *)hw->lmem_addr;
reset_process_time(hw);
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode && !ctx->v4l_codec_ready) {
- //amvdec_stop();
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
+#ifdef DETECT_WRONG_MULTI_SLICE
+ hw->cur_picture_slice_count++;
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count == 1 &&
+ (error_proc_policy & 0x10000)) {
+ hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num;
+ }
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count > 1 &&
+ (error_proc_policy & 0x10000)) {
+ dpb_print(DECODE_ID(hw), 0,
+ "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n",
+ __func__,
+ hw->multi_slice_pic_check_count,
+ hw->picture_slice_count,
+ hw->cur_picture_slice_count,
+ hw->multi_slice_pic_flag);
+ if (hw->cur_picture_slice_count > hw->last_picture_slice_count)
+ vh264_pic_done_proc(vdec);
+ else {
+ if (p_H264_Dpb->mVideo.dec_picture) {
+ if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) {
+ release_colocate_buf(p_H264_Dpb,
+ p_H264_Dpb->mVideo.dec_picture->colocated_buf_index);
+ p_H264_Dpb->mVideo.dec_picture->colocated_buf_index = -1;
+ }
+ }
+ release_cur_decoding_buf(hw);
}
}
+#endif
hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
@@ -5536,11 +5890,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
goto empty_proc;
}
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->lmem_addr_remap,
- PAGE_SIZE,
- DMA_FROM_DEVICE);
#if 0
if (p_H264_Dpb->mVideo.dec_picture == NULL) {
if (!is_buffer_available(vdec)) {
@@ -5687,7 +6036,7 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
}
slice_header_process_status =
- h264_slice_header_process(p_H264_Dpb);
+ h264_slice_header_process(p_H264_Dpb, &frame_num_gap);
if (hw->mmu_enable)
hevc_sao_set_slice_type(hw,
slice_header_process_status,
@@ -5744,23 +6093,16 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
READ_VREG(MBY_MBX),
decode_mb_count);
p->data_flag |= ERROR_FLAG;
- } else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) {
+ }/* else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) {
p->data_flag |= ERROR_FLAG;
goto pic_done_proc;
- }
+ }*/
}
- if (p_H264_Dpb->mVideo.dec_picture->slice_type == I_SLICE) {
- hw->new_iframe_flag = 1;
- }
- if (hw->new_iframe_flag) {
- if (p_H264_Dpb->mVideo.dec_picture->slice_type == P_SLICE) {
- hw->new_iframe_flag = 0;
- hw->ref_err_flush_dpb_flag = 1;
- }else if (p_H264_Dpb->mVideo.dec_picture->slice_type == B_SLICE) {
- hw->new_iframe_flag = 0;
- hw->ref_err_flush_dpb_flag = 0;
- }
+ if (!I_flag && frame_num_gap) {
+ hw->data_flag |= ERROR_FLAG;
+ p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
+ dpb_print(DECODE_ID(hw), 0, "frame number gap error\n");
}
if (error_proc_policy & 0x400) {
@@ -5774,15 +6116,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
hw->skip_frame_count,
hw->reflist_error_count);
- if (hw->ref_err_flush_dpb_flag) {
- flush_dpb(p_H264_Dpb);
- p_H264_Dpb->colocated_buf_map = 0;
- if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) {
- p_H264_Dpb->colocated_buf_map |= 1 <<
- p_H264_Dpb->mVideo.dec_picture->colocated_buf_index;
- }
- }
-
p_H264_Dpb->mVideo.dec_picture->data_flag = NODISP_FLAG;
if (((error_proc_policy & 0x80)
&& ((hw->dec_flag &
@@ -5844,146 +6177,37 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
start_process_time(hw);
} else if (dec_dpb_status == H264_PIC_DATA_DONE
||((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) {
-pic_done_proc:
- reset_process_time(hw);
-
- if (input_frame_based(vdec) &&
- (!(hw->i_only & 0x2)) &&
- frmbase_cont_bitlevel != 0 &&
- READ_VREG(VIFF_BIT_CNT) >
- frmbase_cont_bitlevel) {
- /*handle the case: multi pictures in one packet*/
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n",
- __func__,
- hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
- hw->frmbase_cont_flag = 1;
- } else
- hw->frmbase_cont_flag = 0;
-
- if (p_H264_Dpb->mVideo.dec_picture) {
- get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- DEL_EXIST(hw,
- p_H264_Dpb->mVideo.dec_picture) = 0;
- if (vdec->master) {
- struct vdec_h264_hw_s *hw_ba =
- (struct vdec_h264_hw_s *)
- vdec->master->private;
- if (hw_ba->last_dec_picture)
- DEL_EXIST(hw_ba,
- hw_ba->last_dec_picture)
- = 1;
- }
-#endif
- mutex_lock(&hw->chunks_mutex);
- if (hw->chunk) {
- p_H264_Dpb->mVideo.dec_picture->pts =
- hw->chunk->pts;
- p_H264_Dpb->mVideo.dec_picture->pts64 =
- hw->chunk->pts64;
- p_H264_Dpb->mVideo.dec_picture->timestamp =
- hw->chunk->timestamp;
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- hw->chunk->pts, 1);
-#endif
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- } else if (vdec->master) {
- /*dv enhance layer,
- do not checkout pts*/
- struct StorablePicture *pic =
- p_H264_Dpb->mVideo.dec_picture;
- pic->pts = 0;
- pic->pts64 = 0;
-#endif
- } else {
- struct StorablePicture *pic =
- p_H264_Dpb->mVideo.dec_picture;
- u32 offset = pic->offset_delimiter;
- if (pts_pickout_offset_us64(PTS_TYPE_VIDEO,
- offset, &pic->pts, 0, &pic->pts64)) {
- pic->pts = 0;
- pic->pts64 = 0;
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- pic->pts, 0);
-#endif
- } else {
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- pic->pts, 1);
-#endif
+#ifdef DETECT_WRONG_MULTI_SLICE
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
+ "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_PIC_DATA_DONE\n",
+ __func__,
+ hw->multi_slice_pic_check_count,
+ hw->picture_slice_count,
+ hw->cur_picture_slice_count,
+ hw->multi_slice_pic_flag);
+
+ if (hw->multi_slice_pic_check_count < check_slice_num) {
+ hw->multi_slice_pic_check_count++;
+ if (hw->cur_picture_slice_count !=
+ hw->picture_slice_count) {
+ /*restart check count and set 'unknown'*/
+ hw->multi_slice_pic_check_count = 0;
+ hw->multi_slice_pic_flag = 0;
+ }
+ hw->picture_slice_count =
+ hw->cur_picture_slice_count;
+ } else if (hw->multi_slice_pic_check_count >= check_slice_num) {
+ if (hw->picture_slice_count > 1)
+ hw->multi_slice_pic_flag = 2;
+ else
+ hw->multi_slice_pic_flag = 1;
}
-
- }
- mutex_unlock(&hw->chunks_mutex);
-
- check_decoded_pic_error(hw);
-#ifdef ERROR_HANDLE_TEST
- if ((hw->data_flag & ERROR_FLAG)
- && (error_proc_policy & 0x80)) {
- release_cur_decoding_buf(hw);
- h264_clear_dpb(hw);
- hw->dec_flag = 0;
- hw->data_flag = 0;
- hw->skip_frame_count = 0;
- hw->has_i_frame = 0;
- hw->no_error_count = 0xfff;
- hw->no_error_i_count = 0xf;
- } else
#endif
- ret = store_picture_in_dpb(p_H264_Dpb,
- p_H264_Dpb->mVideo.dec_picture,
- hw->data_flag | hw->dec_flag |
- p_H264_Dpb->mVideo.dec_picture->data_flag);
-
+pic_done_proc:
+ reset_process_time(hw);
+ vh264_pic_done_proc(vdec);
- if (ret == -1) {
- release_cur_decoding_buf(hw);
- bufmgr_force_recover(p_H264_Dpb);
- } else {
- if (hw->data_flag & ERROR_FLAG) {
- hw->no_error_count = 0;
- hw->no_error_i_count = 0;
- } else {
- hw->no_error_count++;
- if (hw->data_flag & I_FLAG)
- hw->no_error_i_count++;
- }
- if (hw->mmu_enable)
- hevc_set_unused_4k_buff_idx(hw,
- p_H264_Dpb->mVideo.
- dec_picture->buf_spec_num);
- bufmgr_post(p_H264_Dpb);
- hw->last_dec_picture =
- p_H264_Dpb->mVideo.dec_picture;
- p_H264_Dpb->mVideo.dec_picture = NULL;
- /* dump_dpb(&p_H264_Dpb->mDPB); */
- hw->has_i_frame = 1;
- if (hw->mmu_enable)
- hevc_set_frame_done(hw);
- hw->decode_pic_count++;
- p_H264_Dpb->decode_pic_count = hw->decode_pic_count;
- if (hw->skip_frame_count > 0) {
- /*skip n frame after first I */
- hw->skip_frame_count--;
- if (hw->skip_frame_count == 0)
- hw->dec_flag &= (~NODISP_FLAG);
- } else if (hw->skip_frame_count < -1) {
- /*skip n frame after first I until second I */
- hw->skip_frame_count++;
- if (hw->skip_frame_count == -1)
- hw->dec_flag &= (~NODISP_FLAG);
- }
- }
- }
if (hw->frmbase_cont_flag) {
/*do not DEC_RESULT_GET_DATA*/
hw->get_data_count = 0x7fffffff;
@@ -6034,11 +6258,6 @@ pic_done_proc:
} else if (dec_dpb_status == H264_AUX_DATA_READY) {
reset_process_time(hw);
if (READ_VREG(H264_AUX_DATA_SIZE) != 0) {
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->aux_phy_addr,
- hw->prefix_aux_size + hw->suffix_aux_size,
- DMA_FROM_DEVICE);
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DPB_DETAIL))
dump_aux_buf(hw);
@@ -6082,6 +6301,9 @@ pic_done_proc:
(dec_dpb_status == H264_DECODE_TIMEOUT)) {
empty_proc:
reset_process_time(hw);
+ if ((error_proc_policy & 0x40000) &&
+ dec_dpb_status == H264_DECODE_TIMEOUT)
+ goto pic_done_proc;
if (!hw->frmbase_cont_flag)
release_cur_decoding_buf(hw);
@@ -6133,6 +6355,14 @@ empty_proc:
vdec_schedule_work(&hw->work);
} else {
/* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */
+#ifdef DETECT_WRONG_MULTI_SLICE
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count > 1 &&
+ (error_proc_policy & 0x10000)) {
+ p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num;
+ }
+ hw->last_picture_slice_count = hw->cur_picture_slice_count;
+#endif
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s DEC_RESULT_AGAIN\n", __func__);
send_again:
@@ -6182,11 +6412,6 @@ send_again:
u8 *sei_data_buf;
u8 swap_byte;
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->aux_phy_addr,
- hw->prefix_aux_size + hw->suffix_aux_size,
- DMA_FROM_DEVICE);
#if 0
dump_aux_buf(hw);
#endif
@@ -6240,12 +6465,6 @@ send_again:
if (debug_tag & 0x10000) {
unsigned short *p = (unsigned short *)hw->lmem_addr;
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->lmem_addr_remap,
- PAGE_SIZE,
- DMA_FROM_DEVICE);
-
dpb_print(DECODE_ID(hw), 0,
"LMEM<tag %x>:\n", debug_tag);
for (i = 0; i < 0x400; i += 4) {
@@ -6317,9 +6536,11 @@ static irqreturn_t vh264_isr(struct vdec_s *vdec, int irq)
p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG);
dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "%s DPB_STATUS_REG: 0x%x, ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n",
+ "%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n",
__func__,
p_H264_Dpb->dec_dpb_status,
+ run_count[DECODE_ID(hw)],
+ hw->dec_result,
READ_VREG(ERROR_STATUS_REG),
READ_VREG(VLD_MEM_VIFIFO_LEVEL),
READ_VREG(VLD_MEM_VIFIFO_WP),
@@ -6415,7 +6636,7 @@ static void vmh264_dump_state(struct vdec_s *vdec)
);
dpb_print(DECODE_ID(hw), 0,
- "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d\n",
+ "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d error_frame_count = %d, drop_frame_count = %d\n",
input_frame_based(vdec),
hw->eos,
hw->stat,
@@ -6425,9 +6646,21 @@ static void vmh264_dump_state(struct vdec_s *vdec)
run_count[DECODE_ID(hw)],
not_run_ready[DECODE_ID(hw)],
input_empty[DECODE_ID(hw)],
- hw->reset_bufmgr_count
+ hw->reset_bufmgr_count,
+ hw->gvs.error_frame_count,
+ hw->gvs.drop_frame_count
);
+#ifdef DETECT_WRONG_MULTI_SLICE
+ dpb_print(DECODE_ID(hw), 0,
+ "MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d)\n",
+ hw->multi_slice_pic_check_count,
+ hw->picture_slice_count,
+ hw->cur_picture_slice_count,
+ hw->multi_slice_pic_flag);
+#endif
+
+
if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
@@ -6561,7 +6794,8 @@ static void check_timer_func(unsigned long arg)
return;
}
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
+ if (vdec->next_status == VDEC_STATUS_DISCONNECTED &&
+ !hw->is_used_v4l) {
hw->dec_result = DEC_RESULT_FORCE_EXIT;
vdec_schedule_work(&hw->work);
pr_debug("vdec requested to be disconnected\n");
@@ -6578,9 +6812,7 @@ static void check_timer_func(unsigned long arg)
radr = 0;
}
- if ((input_frame_based(vdec) ||
- (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0xb0)) &&
- ((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) &&
+ if (((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) &&
(timeout_val > 0) &&
(hw->start_process_time > 0) &&
((1000 * (jiffies - hw->start_process_time) / HZ)
@@ -6629,7 +6861,7 @@ static void check_timer_func(unsigned long arg)
static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
{
- u32 ar;
+ u32 ar, ar_tmp;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
if (!hw)
@@ -6637,22 +6869,29 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
vstatus->frame_width = hw->frame_width;
vstatus->frame_height = hw->frame_height;
- if (hw->frame_dur != 0)
+ if (hw->frame_dur != 0) {
+ vstatus->frame_dur = hw->frame_dur;
vstatus->frame_rate = 96000 / hw->frame_dur;
+ }
else
vstatus->frame_rate = -1;
- vstatus->error_count = 0;
+ vstatus->error_count = hw->gvs.error_frame_count;
vstatus->status = hw->stat;
if (hw->h264_ar == 0x3ff)
- hw->h264_ar = (0x100 *
+ ar_tmp = (0x100 *
hw->frame_height * hw->height_aspect_ratio) /
(hw->frame_width * hw->width_aspect_ratio);
+ else
+ ar_tmp = hw->h264_ar;
ar = min_t(u32,
- hw->h264_ar,
+ ar_tmp,
DISP_RATIO_ASPECT_RATIO_MAX);
vstatus->ratio_control =
ar << DISP_RATIO_ASPECT_RATIO_BIT;
+ vstatus->error_frame_count = hw->gvs.error_frame_count;
+ vstatus->drop_frame_count = hw->gvs.drop_frame_count;
+ vstatus->frame_count = decode_frame_count[DECODE_ID(hw)];
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s-%02d", DRIVER_NAME, hw->id);
@@ -6731,6 +6970,8 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
&& (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))
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
+ else
+ CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24);
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24);
@@ -6805,7 +7046,7 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
else*/
CLEAR_VREG_MASK(AV_SCRATCH_F, 1 << 6);
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_addr_remap);
+ WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr);
#if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
#endif
@@ -7057,28 +7298,15 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
}
#if 1 /* #ifdef BUFFER_MGR_IN_C */
- hw->lmem_addr = __get_free_page(GFP_KERNEL);
- if (!hw->lmem_addr) {
- pr_info("%s: failed to alloc lmem_addr\n", __func__);
- return -ENOMEM;
- } else {
- hw->lmem_addr_remap = dma_map_single(
- amports_get_dma_device(),
- (void *)hw->lmem_addr,
- PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- hw->lmem_addr_remap)) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s: failed to map lmem_addr\n", __func__);
- free_page(hw->lmem_addr);
- hw->lmem_addr = 0;
- hw->lmem_addr_remap = 0;
- return -ENOMEM;
- }
+ hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(),
+ PAGE_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL);
- pr_debug("%s, vaddr=%lx phy_addr=%p\n",
- __func__, hw->lmem_addr, (void *)hw->lmem_addr_remap);
+ if (hw->lmem_addr == 0) {
+ pr_err("%s: failed to alloc lmem buffer\n", __func__);
+ return -1;
}
+ pr_debug("%s, phy_addr=%lx vaddr=%p\n",
+ __func__, hw->lmem_phy_addr, (void *)hw->lmem_addr);
if (prefix_aux_buf_size > 0 ||
suffix_aux_buf_size > 0) {
@@ -7086,21 +7314,14 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size);
hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size);
aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size;
- hw->aux_addr = kmalloc(aux_buf_size, GFP_KERNEL);
+ hw->aux_addr = dma_alloc_coherent(amports_get_dma_device(),
+ aux_buf_size, &hw->aux_phy_addr,
+ GFP_KERNEL);
if (hw->aux_addr == NULL) {
pr_err("%s: failed to alloc rpm buffer\n", __func__);
return -1;
}
- hw->aux_phy_addr = dma_map_single(amports_get_dma_device(),
- hw->aux_addr, aux_buf_size, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- hw->aux_phy_addr)) {
- pr_err("%s: failed to map rpm buffer\n", __func__);
- kfree(hw->aux_addr);
- hw->aux_addr = NULL;
- return -1;
- }
hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL);
if (hw->sei_data_buf == NULL) {
pr_err("%s: failed to alloc sei itu data buffer\n",
@@ -7111,7 +7332,9 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
if (hw->sei_itu_data_buf == NULL) {
pr_err("%s: failed to alloc sei itu data buffer\n",
__func__);
- kfree(hw->aux_addr);
+ dma_free_coherent(amports_get_dma_device(),
+ hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
+ hw->aux_phy_addr);
hw->aux_addr = NULL;
kfree(hw->sei_data_buf);
hw->sei_data_buf = NULL;
@@ -7125,7 +7348,9 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
if (!hw->sei_user_data_buffer) {
pr_info("%s: Can not allocate sei_data_buffer\n",
__func__);
- kfree(hw->aux_addr);
+ dma_free_coherent(amports_get_dma_device(),
+ hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
+ hw->aux_phy_addr);
hw->aux_addr = NULL;
kfree(hw->sei_data_buf);
hw->sei_data_buf = NULL;
@@ -7183,22 +7408,17 @@ static int vh264_stop(struct vdec_h264_hw_s *hw)
vdec_free_irq(VDEC_IRQ_1, (void *)hw);
hw->stat &= ~STAT_ISR_REG;
}
- if (hw->lmem_addr_remap) {
- dma_unmap_single(amports_get_dma_device(),
- hw->lmem_addr_remap,
- PAGE_SIZE, DMA_FROM_DEVICE);
- hw->lmem_addr_remap = 0;
- }
if (hw->lmem_addr) {
- free_page(hw->lmem_addr);
+ dma_free_coherent(amports_get_dma_device(),
+ PAGE_SIZE, (void *)hw->lmem_addr,
+ hw->lmem_phy_addr);
hw->lmem_addr = 0;
}
+
if (hw->aux_addr) {
- dma_unmap_single(amports_get_dma_device(),
- hw->aux_phy_addr,
- hw->prefix_aux_size + hw->suffix_aux_size,
- DMA_FROM_DEVICE);
- kfree(hw->aux_addr);
+ dma_free_coherent(amports_get_dma_device(),
+ hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
+ hw->aux_phy_addr);
hw->aux_addr = NULL;
}
if (hw->sei_data_buf != NULL) {
@@ -7884,6 +8104,117 @@ static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec)
#endif
+static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw, u32 param1, u32 param4, struct aml_vdec_ps_infos *ps)
+{
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ int mb_width, mb_total;
+ int mb_height = 0;
+ int active_buffer_spec_num;
+ int max_reference_size ,level_idc;
+ unsigned int used_reorder_dpb_size_margin
+ = hw->reorder_dpb_size_margin;
+ int reorder_pic_num;
+
+ level_idc = param4 & 0xff;
+ max_reference_size = (param4 >> 8) & 0xff;
+
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ if (vdec->master || vdec->slave)
+ used_reorder_dpb_size_margin =
+ reorder_dpb_size_margin_dv;
+#endif
+ mb_width = param1 & 0xff;
+ mb_total = (param1 >> 8) & 0xffff;
+ if (!mb_width && mb_total) /*for 4k2k*/
+ mb_width = 256;
+ if (mb_width)
+ mb_height = mb_total/mb_width;
+ if (mb_width <= 0 || mb_height <= 0 ||
+ is_oversize(mb_width << 4, mb_height << 4)) {
+ dpb_print(DECODE_ID(hw), 0,
+ "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
+ param1,
+ mb_width,
+ mb_height);
+ return -1;
+ }
+
+ reorder_pic_num =
+ get_max_dec_frame_buf_size(level_idc,
+ max_reference_size, mb_width, mb_height);
+
+ if ((hw->bitstream_restriction_flag) &&
+ (hw->max_dec_frame_buffering <
+ reorder_pic_num)) {
+ reorder_pic_num = hw->max_dec_frame_buffering;
+ dpb_print(DECODE_ID(hw), 0,
+ "set reorder_pic_num to %d\n",
+ reorder_pic_num);
+ }
+
+ active_buffer_spec_num =
+ reorder_pic_num
+ + used_reorder_dpb_size_margin;
+
+ if (active_buffer_spec_num > MAX_VF_BUF_NUM) {
+ active_buffer_spec_num = MAX_VF_BUF_NUM;
+ reorder_pic_num = active_buffer_spec_num
+ - used_reorder_dpb_size_margin;
+ }
+
+ if (hw->no_poc_reorder_flag)
+ reorder_pic_num = 1;
+
+ ps->profile = level_idc;
+ ps->ref_frames = max_reference_size;
+ ps->mb_width = mb_width;
+ ps->mb_height = mb_height;
+ ps->visible_width = mb_width << 4;
+ ps->visible_height = mb_height << 4;
+ ps->coded_width = ALIGN(mb_width << 4, 64);
+ ps->coded_height = ALIGN(mb_height << 4, 64);
+ ps->reorder_frames = reorder_pic_num;
+ ps->dpb_size = active_buffer_spec_num;
+
+ return 0;
+}
+
+static int v4l_res_change(struct vdec_h264_hw_s *hw, u32 param1, u32 param4)
+{
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
+ int ret = 0;
+
+ if (ctx->param_sets_from_ucode &&
+ hw->res_ch_flag == 0) {
+ if (param1 != 0 &&
+ hw->seq_info2 != (param1 & (~0x80000000)) &&
+ hw->seq_info2 != 0) /*picture size changed*/ {
+ struct aml_vdec_ps_infos ps;
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "h264 res_change\n");
+ if (vmh264_get_ps_info(hw, param1, param4, &ps) < 0) {
+ dpb_print(DECODE_ID(hw), 0, "set parameters error\n");
+ }
+ hw->v4l_params_parsed = false;
+ vdec_v4l_set_ps_infos(ctx, &ps);
+ vdec_v4l_res_ch_event(ctx);
+ hw->res_ch_flag = 1;
+ amvdec_stop();
+ if (hw->mmu_enable)
+ amhevc_stop();
+ hw->eos = 1;
+ flush_dpb(p_H264_Dpb);
+ //del_timer_sync(&hw->check_timer);
+ if (hw->is_used_v4l)
+ notify_v4l_eos(hw_to_vdec(hw));
+ ret = 1;
+ }
+ }
+
+ return ret;
+
+}
static void vh264_work_implement(struct vdec_h264_hw_s *hw,
struct vdec_s *vdec, int from)
@@ -7909,34 +8240,48 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw,
u32 param2 = READ_VREG(AV_SCRATCH_2);
u32 param3 = READ_VREG(AV_SCRATCH_6);
u32 param4 = READ_VREG(AV_SCRATCH_B);
-
- if (vh264_set_params(hw, param1,
- param2, param3, param4) < 0)
- dpb_print(DECODE_ID(hw), 0, "set parameters error\n");
-
- WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
- (hw->dpb.mDPB.size<<16) |
- (hw->dpb.mDPB.size<<8));
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
+ struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
-
- ps.visible_width = hw->frame_width;
- 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 = hw->dpb.mDPB.size;
- hw->v4l_params_parsed = true;
- vdec_v4l_set_ps_infos(ctx, &ps);
+ if (hw->is_used_v4l &&
+ ctx->param_sets_from_ucode) {
+ if (!v4l_res_change(hw, param1, param4)) {
+ if (!hw->v4l_params_parsed) {
+ struct aml_vdec_ps_infos ps;
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "h264 parsered csd data\n");
+ if (vmh264_get_ps_info(hw, param1, param4, &ps) < 0) {
+ dpb_print(DECODE_ID(hw), 0, "set parameters error\n");
+ }
+ hw->v4l_params_parsed = true;
+ vdec_v4l_set_ps_infos(ctx, &ps);
+ amvdec_stop();
+ if (hw->mmu_enable)
+ amhevc_stop();
+ }
+ else {
+ if (vh264_set_params(hw, param1,
+ param2, param3, param4) < 0)
+ dpb_print(DECODE_ID(hw), 0, "set parameters error\n");
+
+ WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
+ (hw->dpb.mDPB.size<<16) |
+ (hw->dpb.mDPB.size<<8));
+ hw->res_ch_flag = 0;
+ start_process_time(hw);
+ return;
+ }
}
- }
+ } else {
+ if (vh264_set_params(hw, param1,
+ param2, param3, param4) < 0)
+ dpb_print(DECODE_ID(hw), 0, "set parameters error\n");
- start_process_time(hw);
- return;
+ WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
+ (hw->dpb.mDPB.size<<16) |
+ (hw->dpb.mDPB.size<<8));
+ start_process_time(hw);
+ return;
+ }
} else
if (((hw->dec_result == DEC_RESULT_GET_DATA) ||
(hw->dec_result == DEC_RESULT_GET_DATA_RETRY))
@@ -8043,6 +8388,22 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw,
/* if (!hw->ctx_valid)
hw->ctx_valid = 1; */
result_done:
+ {
+ if (error_proc_policy & 0x8000) {
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
+ int i;
+ struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
+
+ for (i = 0; i < p_Dpb->used_size; i++) {
+ if (p_Dpb->fs[i]->dpb_frame_count + 500 < p_H264_Dpb->dpb_frame_count) {
+ dpb_print(DECODE_ID(hw),
+ 0,
+ "unmark reference dpb_frame_count diffrence large in dpb\n");
+ unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
+ }
+ }
+ }
+ }
if (hw->mmu_enable
&& hw->frame_busy && hw->frame_done) {
long used_4k_num;
@@ -8127,7 +8488,10 @@ result_done:
WRITE_VREG(ASSIST_MBOX1_MASK, 0);
del_timer_sync(&hw->check_timer);
hw->stat &= ~STAT_TIMER_ARM;
-
+#ifdef DETECT_WRONG_MULTI_SLICE
+ if (hw->dec_result != DEC_RESULT_AGAIN)
+ hw->last_picture_slice_count = 0;
+#endif
wait_vmh264_search_done(hw);
/* mark itself has all HW resource released and input released */
@@ -8297,15 +8661,24 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (ctx->param_sets_from_ucode &&
- !ctx->v4l_codec_ready &&
- hw->v4l_params_parsed) {
- ret = 0; /*the params has parsed.*/
+ if (ctx->param_sets_from_ucode) {
+ if (hw->v4l_params_parsed) {
+ if (!ctx->v4l_codec_dpb_ready &&
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
+ } else {
+ if ((hw->res_ch_flag == 1) &&
+ ((ctx->state <= AML_STATE_INIT) ||
+ (ctx->state >= AML_STATE_FLUSHING)))
+ ret = 0;
+ }
} else if (!ctx->v4l_codec_dpb_ready) {
if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
run_ready_min_buf_num)
ret = 0;
}
+
}
if (ret)
@@ -8358,6 +8731,10 @@ static void run(struct vdec_s *vdec, unsigned long mask,
hw->vdec_cb_arg = arg;
hw->vdec_cb = callback;
+#ifdef DETECT_WRONG_MULTI_SLICE
+ hw->cur_picture_slice_count = 0;
+#endif
+
if (kfifo_len(&hw->display_q) > VF_POOL_SIZE) {
hw->reset_bufmgr_flag = 1;
dpb_print(DECODE_ID(hw), 0,
@@ -8504,7 +8881,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
}
vdec->mc_type = ((1 << 16) | VFORMAT_H264);
}
- vdec->mc_loaded = 1;
+ vdec->mc_loaded = 0;
}
vmh264_reset_udr_mgr(hw);
@@ -8520,6 +8897,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
WRITE_VREG(H264_DECODE_INFO, (1<<13));
WRITE_VREG(H264_DECODE_SIZE, decode_size);
WRITE_VREG(VIFF_BIT_CNT, decode_size * 8);
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = hw->chunk->size;
} else {
if (size <= 0)
size = 0x7fffffff; /*error happen*/
@@ -8553,6 +8932,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
else
CLEAR_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3);
}
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
if (hw->mmu_enable /*&& !hw->frame_busy && !hw->frame_done*/) {
WRITE_VREG(HEVC_ASSIST_SCRATCH_0, 0x0);
@@ -8600,7 +8981,9 @@ static void reset(struct vdec_s *vdec)
cancel_work_sync(&hw->work);
cancel_work_sync(&hw->notify_work);
if (hw->stat & STAT_VDEC_RUN) {
- amhevc_stop();
+ amvdec_stop();
+ if (hw->mmu_enable)
+ amhevc_stop();
hw->stat &= ~STAT_VDEC_RUN;
}
@@ -8715,6 +9098,7 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
{
ulong timeout;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
#if 0
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int actual_dpb_size, max_reference_size;
@@ -8771,6 +9155,8 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
__func__, hw->decode_pic_count+1,
hw->skip_frame_count);
+ flush_dpb(&hw->dpb);
+
timeout = jiffies + HZ;
while (kfifo_len(&hw->display_q) > 0) {
if (time_after(jiffies, timeout))
@@ -8778,8 +9164,6 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
schedule();
}
- vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_RESET, NULL);
-
buf_spec_init(hw);
vh264_local_init(hw, true);
@@ -8797,7 +9181,10 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
if (first_i_policy & 0x01)
hw->first_i_policy = (3 << 8) | first_i_policy;
+ p_H264_Dpb->first_insert_frame = FirstInsertFrm_RESET;
+
hw->init_flag = 1;
+
hw->reset_bufmgr_count++;
#endif
}
@@ -8880,8 +9267,6 @@ static int ammvdec_h264_probe(struct platform_device *pdev)
hw->mmu_enable = 0;
hw->first_head_check_flag = 0;
- hw->new_iframe_flag = 0;
- hw->ref_err_flush_dpb_flag = 0;
if (pdata->sys_info)
hw->vh264_amstream_dec_info = *pdata->sys_info;
@@ -9128,6 +9513,9 @@ static int ammvdec_h264_probe(struct platform_device *pdev)
| CORE_MASK_COMBINE);
atomic_set(&hw->vh264_active, 1);
+ vdec_set_vframe_comm(pdata, DRIVER_NAME);
+ display_frame_count[DECODE_ID(hw)] = 0;
+ decode_frame_count[DECODE_ID(hw)] = 0;
return 0;
}
@@ -9483,6 +9871,11 @@ MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
module_param(without_display_mode, uint, 0664);
MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
+module_param(check_slice_num, uint, 0664);
+MODULE_PARM_DESC(check_slice_num, "\n check_slice_num\n");
+
+module_param(mb_count_threshold, uint, 0664);
+MODULE_PARM_DESC(mb_count_threshold, "\n mb_count_threshold\n");
module_init(ammvdec_h264_driver_init_module);
module_exit(ammvdec_h264_driver_remove_module);