From 09bbdb6639324f25abab4c4381aff1f6c9462e2d Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Fri, 8 Sep 2017 11:28:41 +0800 Subject: [PATCH] media_modules: merged code from 43177e6a on the amlogic-3.14-dev [2/3] PD#150739: merged code from 43177e6a on the amlogic-3.14-dev 1.decoder: vmh264, fix multi pic in one packet 2.decoder: add amvdec_stop when error reset 3.clk: switch vdec clk source when suspend Change-Id: I43b8f5a7a13d880c130505cd21e08c8e1eb4cf38 Signed-off-by: Nanxin Qin --- .../common/media_clock/clk/clkgx.c | 0 .../common/media_clock/switch/amports_gate.c | 0 .../frame_provider/decoder/avs/avs.c | 21 +- .../frame_provider/decoder/h264/vh264.c | 57 ++- .../frame_provider/decoder/h264/vh264_4k2k.c | 5 +- .../frame_provider/decoder/h264/vh264_mvc.c | 82 +-- .../decoder/h264_multi/h264_dpb.c | 385 +++++++++++--- .../decoder/h264_multi/h264_dpb.h | 10 + .../decoder/h264_multi/vmh264.c | 468 ++++++++++++++---- .../frame_provider/decoder/h265/vh265.c | 121 ++++- .../frame_provider/decoder/mjpeg/vmjpeg.c | 23 +- .../frame_provider/decoder/mpeg12/vmpeg12.c | 34 +- .../frame_provider/decoder/mpeg4/vmpeg4.c | 23 +- .../decoder/mpeg4/vmpeg4_multi.c | 1 + .../frame_provider/decoder/real/vreal.c | 19 +- .../frame_provider/decoder/utils/amvdec.c | 78 ++- .../decoder/utils/decoder_bmmu_box.c | 6 +- .../frame_provider/decoder/utils/vdec.c | 69 ++- .../frame_provider/decoder/utils/vdec.h | 7 + .../frame_provider/decoder/utils/vdec_input.c | 40 +- .../frame_provider/decoder/vc1/vvc1.c | 22 +- .../frame_provider/decoder/vp9/vvp9.c | 81 ++- .../stream_input/amports/amstream.c | 44 +- .../stream_input/parser/tsdemux.c | 14 +- firmware/video/video_ucode.bin | Bin 424448 -> 424448 bytes 25 files changed, 1241 insertions(+), 369 deletions(-) mode change 100755 => 100644 drivers/amlogic/media_modules/common/media_clock/clk/clkgx.c mode change 100755 => 100644 drivers/amlogic/media_modules/common/media_clock/switch/amports_gate.c diff --git a/drivers/amlogic/media_modules/common/media_clock/clk/clkgx.c b/drivers/amlogic/media_modules/common/media_clock/clk/clkgx.c old mode 100755 new mode 100644 diff --git a/drivers/amlogic/media_modules/common/media_clock/switch/amports_gate.c b/drivers/amlogic/media_modules/common/media_clock/switch/amports_gate.c old mode 100755 new mode 100644 diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c index 8d05ff9a3cea..da964cc68116 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c @@ -176,6 +176,7 @@ static struct dec_sysinfo vavs_amstream_dec_info; static struct vdec_info *gvs; static u32 fr_hint_status; static struct work_struct notify_work; +static bool is_reset; #ifdef AVSP_LONG_CABAC static struct work_struct long_cabac_wd_work; @@ -778,6 +779,12 @@ int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vavs_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static int vavs_vdec_info_init(void) { gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); @@ -1212,7 +1219,6 @@ static void vavs_fatal_error_handler(struct work_struct *work) static void vavs_notify_work(struct work_struct *work) { - pr_info("frame duration changed %d\n", frame_dur); if (fr_hint_status == VDEC_NEED_HINT) { vf_notify_receiver(PROVIDER_NAME , VFRAME_EVENT_PROVIDER_FR_HINT , @@ -1495,10 +1501,11 @@ static s32 vavs_init(void) #endif if (vavs_amstream_dec_info.rate != 0) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long) - vavs_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long) + vavs_amstream_dec_info.rate)); fr_hint_status = VDEC_HINTED; } else fr_hint_status = VDEC_NEED_HINT; @@ -1554,6 +1561,8 @@ static int amvdec_avs_probe(struct platform_device *pdev) vavs_amstream_dec_info.height, vavs_amstream_dec_info.rate); pdata->dec_status = vavs_dec_status; + pdata->set_isreset = vavs_set_isreset; + is_reset = 0; vavs_vdec_info_init(); @@ -1647,7 +1656,7 @@ static int amvdec_avs_remove(struct platform_device *pdev) } #endif if (stat & STAT_VF_HOOK) { - if (fr_hint_status == VDEC_HINTED) + if (fr_hint_status == VDEC_HINTED && !is_reset) vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); fr_hint_status = VDEC_NO_NEED_HINT; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c index 7e1b1ac23354..ff31b464c49f 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c @@ -52,11 +52,18 @@ #include #include #include "../utils/firmware.h" +#include #define DRIVER_NAME "amvdec_h264" #define MODULE_NAME "amvdec_h264" #define MEM_NAME "codec_264" #define HANDLE_H264_IRQ + +#if 0 +/* currently, only iptv supports this function*/ +#define SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY +#endif + /* #define DEBUG_PTS */ #if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */ #define DROP_B_FRAME_FOR_1080P_50_60FPS @@ -233,6 +240,11 @@ static u32 max_refer_buf = 1; static u32 decoder_force_reset; static unsigned int no_idr_error_count; static unsigned int no_idr_error_max = 60; +#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY +/* 0~128*/ +static u32 bad_block_scale; +#endif + static unsigned int enable_switch_fense = 1; #define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k) #if 0 @@ -245,6 +257,7 @@ static struct vframe_s *p_last_vf; static s32 iponly_early_mode; static void *mm_blk_handle; static int tvp_flag; +static bool is_reset; /*TODO irq*/ #if 1 @@ -2013,10 +2026,7 @@ static void vh264_isr(void) fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; /* this is fatal error, need restart */ pr_info("fatal error happend\n"); - vh264_stream_switching_state = SWITCHING_STATE_ON_CMD3; amvdec_stop(); - pr_info("fatal error switching mode cmd3.\n"); - schedule_work(&stream_switching_work); if (!fatal_error_reset) schedule_work(&error_wd_work); } else if ((cpu_cmd & 0xff) == 7) { @@ -2287,6 +2297,12 @@ int vh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) return 0; } +int vh264_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static void vh264_prot_init(void) { @@ -2332,12 +2348,19 @@ static void vh264_prot_init(void) WRITE_VREG(AV_SCRATCH_0, 0); WRITE_VREG(AV_SCRATCH_1, buf_offset); - WRITE_VREG(AV_SCRATCH_G, mc_dma_handle); + if (!is_secload_get()) + WRITE_VREG(AV_SCRATCH_G, mc_dma_handle); WRITE_VREG(AV_SCRATCH_7, 0); WRITE_VREG(AV_SCRATCH_8, 0); WRITE_VREG(AV_SCRATCH_9, 0); WRITE_VREG(AV_SCRATCH_N, 0); +#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY + if (bad_block_scale > 128) + bad_block_scale = 128; + WRITE_VREG(AV_SCRATCH_A, bad_block_scale); +#endif + error_recovery_mode_use = (error_recovery_mode != 0) ? error_recovery_mode : error_recovery_mode_in; @@ -2542,7 +2565,12 @@ static s32 vh264_init(void) query_video_status(0, &trickmode_fffb); amvdec_enable(); - + if (!firmwareloaded && is_secload_get()) { + if (tee_load_video_fw((u32)VIDEO_DEC_H264) != 0) { + amvdec_disable(); + return -1; + } + } else { /* -- ucode loading (amrisc and swap code) */ mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE, @@ -2652,6 +2680,7 @@ static s32 vh264_init(void) return -EBUSY; } } + } stat |= STAT_MC_LOAD; @@ -2683,9 +2712,10 @@ static s32 vh264_init(void) #endif if (frame_dur != 0) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)frame_dur)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long)frame_dur)); fr_hint_status = VDEC_HINTED; } else fr_hint_status = VDEC_NEED_HINT; @@ -2738,7 +2768,7 @@ static int vh264_stop(int mode) if (stat & STAT_VF_HOOK) { if (mode == MODE_FULL) { - if (fr_hint_status == VDEC_HINTED) + if (fr_hint_status == VDEC_HINTED && !is_reset) vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); @@ -2787,7 +2817,7 @@ static void error_do_work(struct work_struct *work) * free_irq/deltimer/..and some other. */ if (atomic_read(&vh264_active)) { - + amvdec_stop(); do { msleep(20); } while (vh264_stream_switching_state != SWITCHING_STATE_OFF); @@ -3001,6 +3031,8 @@ static int amvdec_h264_probe(struct platform_device *pdev) } pdata->dec_status = vh264_dec_status; pdata->set_trickmode = vh264_set_trickmode; + pdata->set_isreset = vh264_set_isreset; + is_reset = 0; if (vh264_init() < 0) { pr_info("\namvdec_h264 init failed.\n"); @@ -3163,6 +3195,11 @@ module_param(enable_switch_fense, uint, 0664); MODULE_PARM_DESC(enable_switch_fense, "\n enable switch fense\n"); +#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY +module_param(bad_block_scale, uint, 0664); +MODULE_PARM_DESC(bad_block_scale, + "\n print bad_block_scale\n"); +#endif module_init(amvdec_h264_driver_init_module); module_exit(amvdec_h264_driver_remove_module); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c index 38cf2d820a0c..a333da43b71e 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c @@ -1363,8 +1363,9 @@ static s32 vh264_4k2k_init(void) stat |= STAT_TIMER_INIT; - vh264_4k2k_local_init(); - + ret = vh264_4k2k_local_init(); + if (ret < 0) + return ret; amvdec_enable(); /* -- ucode loading (amrisc and swap code) */ diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c index 8e1ed38be447..9d2b85773a50 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c @@ -44,6 +44,7 @@ #include #include #include "../utils/firmware.h" +#include #define TIME_TASK_PRINT_ENABLE 0x100 #define PUT_PRINT_ENABLE 0x200 @@ -1403,45 +1404,52 @@ static s32 vh264mvc_init(void) amvdec_enable(); - /* -- ucode loading (amrisc and swap code) */ - mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL); - if (!mc_cpu_addr) { - amvdec_disable(); + if (is_secload_get()) { + if (tee_load_video_fw((u32)VIDEO_DEC_H264_MVC) != 0) { + amvdec_disable(); + return -1; + } + } else { + /* -- ucode loading (amrisc and swap code) */ + mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL); + if (!mc_cpu_addr) { + amvdec_disable(); + vfree(buf); + pr_err("vh264_mvc init: Can not allocate mc memory.\n"); + return -ENOMEM; + } + + WRITE_VREG(UCODE_START_ADDR, mc_dma_handle); + + size = get_firmware_data(VIDEO_DEC_H264_MVC, buf); + if (size < 0) { + pr_err("get firmware fail."); + vfree(buf); + return -1; + } + + ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf); + + /*header*/ + memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000); + /*mmco*/ + memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000); + /*slice*/ + memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000); + vfree(buf); - pr_err("vh264_mvc init: Can not allocate mc memory.\n"); - return -ENOMEM; + + if (ret < 0) { + amvdec_disable(); + + dma_free_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, + mc_cpu_addr, mc_dma_handle); + mc_cpu_addr = NULL; + return -EBUSY; + } } - - WRITE_VREG(UCODE_START_ADDR, mc_dma_handle); - - size = get_firmware_data(VIDEO_DEC_H264_MVC, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf); - - /*header*/ - memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000); - /*mmco*/ - memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000); - /*slice*/ - memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000); - - vfree(buf); - - if (ret < 0) { - amvdec_disable(); - - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); - mc_cpu_addr = NULL; - return -EBUSY; - } - stat |= STAT_MC_LOAD; /* enable AMRISC side protocol */ diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c index f266d0861f7a..89aa74fe767d 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c @@ -58,6 +58,7 @@ unsigned char dpb_is_debug(int index, int debug_flag) "%s(%d): listXsize[%d] %d is larger than max size\r\n",\ __func__, __LINE__, mark, list_size);\ list_size = 0; \ + p_H264_Dpb->dpb_error_flag = __LINE__;\ } \ } @@ -286,11 +287,12 @@ void ref_pic_list_reordering(struct h264_dpb_stru *p_H264_Dpb, /* set reference index of redundant slices. */ /* - if (currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE)) - { - currSlice->redundant_slice_ref_idx = - currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1; - }*/ + *if(currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE)) + *{ + *currSlice->redundant_slice_ref_idx = + * currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1; + *} + */ } void slice_prepare(struct h264_dpb_stru *p_H264_Dpb, @@ -422,10 +424,14 @@ void slice_prepare(struct h264_dpb_stru *p_H264_Dpb, pSlice->structure, pSlice->picture_structure_mmco); #ifdef ERROR_CHECK - if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE) + if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE) { pSlice->num_ref_idx_active[LIST_0] = MAX_LIST_SIZE - 1; - if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) + p_H264_Dpb->dpb_error_flag = __LINE__; + } + if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) { pSlice->num_ref_idx_active[LIST_1] = MAX_LIST_SIZE - 1; + p_H264_Dpb->dpb_error_flag = __LINE__; + } #endif #if 1 @@ -973,6 +979,49 @@ static void init_picture(struct h264_dpb_stru *p_H264_Dpb, } +void dump_pic(struct h264_dpb_stru *p_H264_Dpb) +{ + int ii; + struct StorablePicture *pic; + for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) { + pic = &(p_H264_Dpb->m_PIC[ii]); + if (pic->is_used) { + dpb_print(p_H264_Dpb->decoder_index, 0, + "pic(%d,%d) poc %d is_used %d bufspec %d colbuf %d for_ref %d long_term %d pre_out %d output %d nonexist %d data_flag 0x%x\n", + ii, pic->index, + pic->poc, + pic->is_used, + pic->buf_spec_num, + pic->colocated_buf_index, + pic->used_for_reference, + pic->is_long_term, + pic->pre_output, + pic->is_output, + pic->non_existing, + pic->data_flag); + } + } +} + +/* +static void is_pic_used_by_dpb(struct h264_dpb_stru *p_H264_Dpb, + struct StorablePicture *pic) +{ + struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; + unsigned i; + for (i = 0; i < p_Dpb->used_size; i++) { + if (p_Dpb->fs[i]->top_field == pic || + p_Dpb->fs[i]->bottom_field == pic || + p_Dpb->fs[i]->frame == pic + ) + break; + } + if (i < p_Dpb->used_size) + return 1; + return 0; +} +*/ + static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb, enum PictureStructure structure, unsigned char is_output) { @@ -1029,24 +1078,27 @@ static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb, s->top_poc = s->bottom_poc = s->poc = 0; s->seiHasTone_mapping = 0; + s->frame_mbs_only_flag = p_Vid->active_sps->frame_mbs_only_flag; if (!p_Vid->active_sps->frame_mbs_only_flag && structure != FRAME) { int i, j; for (j = 0; j < MAX_NUM_SLICES; j++) { for (i = 0; i < 2; i++) { - /* s->listX[j][i] = - calloc(MAX_LIST_SIZE, - sizeof (struct StorablePicture *)); - +1 for reordering ??? - - if (NULL == s->listX[j][i]) - no_mem_exit("alloc_storable_picture: - s->listX[i]"); */ + /* + *s->listX[j][i] = + *calloc(MAX_LIST_SIZE, + *sizeof (struct StorablePicture *)); + *+1 for reordering ??? + * + *if (NULL==s->listX[j][i]) + * no_mem_exit("alloc_storable_picture:s->listX[i]"); + */ } } } - } + } else + p_H264_Dpb->buf_alloc_fail = 1; dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%s %p\n", __func__, s); return s; @@ -1204,16 +1256,16 @@ static void init_dpb(struct h264_dpb_stru *p_H264_Dpb, int type) p_Dpb->fs_ilref[0] = NULL; #endif - /* - for (i = 0; i < 6; i++) - { - currSlice->listX[i] = - calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *)); - +1 for reordering - if (NULL == currSlice->listX[i]) - no_mem_exit("init_dpb: currSlice->listX[i]"); - } - */ +/* + * for (i = 0; i < 6; i++) + * { + * currSlice->listX[i] = + * calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *)); + * +1 for reordering + * if (NULL==currSlice->listX[i]) + * no_mem_exit("init_dpb: currSlice->listX[i]"); + * } + */ /* allocate a dummy storable picture */ if (!p_Vid->no_reference_picture) { p_Vid->no_reference_picture = get_new_pic(p_H264_Dpb, @@ -1453,7 +1505,7 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, /* rain */ /* p->buf_spec_num = fs->index; */ p->data_flag = data_flag; - fs->data_flag = data_flag; + fs->data_flag |= data_flag; fs->buf_spec_num = p->buf_spec_num; fs->colocated_buf_index = p->colocated_buf_index; #endif @@ -1633,13 +1685,13 @@ int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb, return -1; } -static void update_pic_num(struct Slice *currSlice) +static void update_pic_num(struct h264_dpb_stru *p_H264_Dpb) { unsigned int i; + struct Slice *currSlice = &p_H264_Dpb->mSlice; struct VideoParameters *p_Vid = currSlice->p_Vid; struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb; struct SPSParameters *active_sps = p_Vid->active_sps; - int add_top = 0, add_bottom = 0; int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4); @@ -1647,8 +1699,10 @@ static void update_pic_num(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) + p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_used == 3) { if ((p_Dpb->fs_ref[i]->frame-> @@ -1675,8 +1729,10 @@ static void update_pic_num(struct Slice *currSlice) for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { #ifdef ERROR_CHECK if (p_Dpb->fs_ltref[i] == NULL || - p_Dpb->fs_ltref[i]->frame == NULL) + p_Dpb->fs_ltref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ltref[i]->is_used == 3) { if (p_Dpb->fs_ltref[i]->frame->is_long_term) { @@ -1698,8 +1754,10 @@ static void update_pic_num(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference) { if (p_Dpb->fs_ref[i]->frame_num > currSlice-> @@ -1713,8 +1771,12 @@ static void update_pic_num(struct Slice *currSlice) } if (p_Dpb->fs_ref[i]->is_reference & 1) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) + if (p_Dpb->fs_ref[i]->top_field + == NULL) { + p_H264_Dpb->dpb_error_flag = + __LINE__; continue; + } #endif p_Dpb->fs_ref[i]->top_field-> pic_num = (2 * p_Dpb->fs_ref[i]-> @@ -1723,8 +1785,11 @@ static void update_pic_num(struct Slice *currSlice) if (p_Dpb->fs_ref[i]->is_reference & 2) { #ifdef ERROR_CHECK if (p_Dpb->fs_ref[i]->bottom_field - == NULL) + == NULL) { + p_H264_Dpb->dpb_error_flag = + __LINE__; continue; + } #endif p_Dpb->fs_ref[i]->bottom_field-> pic_num = (2 * p_Dpb->fs_ref[i]-> @@ -1735,13 +1800,17 @@ static void update_pic_num(struct Slice *currSlice) /* update long_term_pic_num */ for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i] == NULL) + if (p_Dpb->fs_ltref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ltref[i]->is_long_term & 1) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i]->top_field == NULL) + if (p_Dpb->fs_ltref[i]->top_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif p_Dpb->fs_ltref[i]->top_field-> long_term_pic_num = 2 * @@ -1750,8 +1819,10 @@ static void update_pic_num(struct Slice *currSlice) } if (p_Dpb->fs_ltref[i]->is_long_term & 2) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i]->bottom_field == NULL) + if (p_Dpb->fs_ltref[i]->bottom_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif p_Dpb->fs_ltref[i]->bottom_field-> long_term_pic_num = 2 * @@ -1797,6 +1868,7 @@ static void remove_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb, int pos) dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "invalid frame store type %x", 500); } + fs->data_flag = 0; fs->is_used = 0; fs->is_long_term = 0; fs->is_reference = 0; @@ -2050,7 +2122,15 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag) #endif if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) p_Dpb->fs[pos]->pre_output = 1; - + else { + dpb_print(p_H264_Dpb->decoder_index, 0, + "%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n", + __func__, pos, poc, + p_Dpb->last_output_poc, + p_H264_Dpb->poc_even_odd_flag); + dump_dpb(p_Dpb, 1); + return 0; + } dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n", __func__, pos, poc, @@ -2259,6 +2339,7 @@ static void idr_memory_management(struct h264_dpb_stru *p_H264_Dpb, __func__, p_Dpb->ref_frames_in_buffer, p_Dpb->ltref_frames_in_buffer); + if (p->no_output_of_prior_pics_flag) { #if 0 /*???*/ @@ -2369,13 +2450,16 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) "("); dpb_print_cont(p_H264_Dpb->decoder_index, 0, - "fn=%d ", p_Dpb->fs[i]->frame_num); + "fn=%d is_used %d ", + p_Dpb->fs[i]->frame_num, + p_Dpb->fs[i]->is_used); if (p_Dpb->fs[i]->is_used & 1) { if (p_Dpb->fs[i]->top_field) dpb_print_cont(p_H264_Dpb->decoder_index, 0, - "T: poc=%d ", - p_Dpb->fs[i]->top_field->poc); + "T: poc=%d pic_num=%d ", + p_Dpb->fs[i]->top_field->poc, + p_Dpb->fs[i]->top_field->pic_num); else dpb_print_cont(p_H264_Dpb->decoder_index, 0, @@ -2386,8 +2470,9 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) if (p_Dpb->fs[i]->bottom_field) dpb_print_cont(p_H264_Dpb->decoder_index, 0, - "B: poc=%d ", - p_Dpb->fs[i]->bottom_field->poc); + "B: poc=%d pic_num=%d ", + p_Dpb->fs[i]->bottom_field->poc, + p_Dpb->fs[i]->bottom_field->pic_num); else dpb_print_cont(p_H264_Dpb->decoder_index, 0, @@ -2397,8 +2482,9 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) if (p_Dpb->fs[i]->is_used == 3) dpb_print_cont(p_H264_Dpb->decoder_index, 0, - "F: poc=%d ", - p_Dpb->fs[i]->frame->poc); + "F: poc=%d pic_num=%d ", + p_Dpb->fs[i]->frame->poc, + p_Dpb->fs[i]->frame->pic_num); dpb_print_cont(p_H264_Dpb->decoder_index, 0, "G: poc=%d) ", p_Dpb->fs[i]->poc); @@ -2443,7 +2529,6 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) } } - /*! ************************************************************************ * \brief @@ -2475,6 +2560,8 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer *p_Dpb, struct StorablePicture *p, int difference_of_pic_nums_minus1) { + struct h264_dpb_stru *p_H264_Dpb = + container_of(p_Dpb, struct h264_dpb_stru, mDPB); int picNumX; unsigned int i; @@ -2483,15 +2570,19 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p->structure == FRAME) { if ((p_Dpb->fs_ref[i]->is_reference == 3) && (p_Dpb->fs_ref[i]->is_long_term == 0)) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) + if (p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->frame->pic_num == picNumX) { @@ -2504,8 +2595,10 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer if ((p_Dpb->fs_ref[i]->is_reference & 1) && (!(p_Dpb->fs_ref[i]->is_long_term & 1))) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) + if (p_Dpb->fs_ref[i]->top_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->top_field->pic_num == picNumX) { @@ -2526,8 +2619,10 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer if ((p_Dpb->fs_ref[i]->is_reference & 2) && (!(p_Dpb->fs_ref[i]->is_long_term & 2))) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) + if (p_Dpb->fs_ref[i]->bottom_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNumX) { @@ -2758,13 +2853,17 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb, if (p->structure == FRAME) { for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference == 3) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) + if (p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->frame-> is_long_term) && @@ -2822,13 +2921,17 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb, } for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference & 1) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) + if (p_Dpb->fs_ref[i]->top_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->top_field-> is_long_term) && @@ -2877,8 +2980,10 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb, } if (p_Dpb->fs_ref[i]->is_reference & 2) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) + if (p_Dpb->fs_ref[i]->bottom_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->bottom_field-> is_long_term) && @@ -2956,13 +3061,17 @@ static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb, for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference & 1) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) + if (p_Dpb->fs_ref[i]->top_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->top_field-> pic_num == picNumX) { @@ -2972,8 +3081,10 @@ static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb, } if (p_Dpb->fs_ref[i]->is_reference & 2) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) + if (p_Dpb->fs_ref[i]->bottom_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->bottom_field-> pic_num == picNumX) { @@ -3200,7 +3311,6 @@ void store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, p_Vid->last_has_mmco_5 = 0; p_Vid->last_pic_bottom_field = (p->structure == BOTTOM_FIELD); - if (p->idr_flag) { idr_memory_management(p_H264_Dpb, p); #if 0 @@ -3922,8 +4032,10 @@ static void init_lists_p_slice(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) + p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_used == 3) { if ((p_Dpb->fs_ref[i]->frame-> @@ -3983,8 +4095,10 @@ static void init_lists_p_slice(struct Slice *currSlice) #endif for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference) fs_list0[list0idx++] = p_Dpb->fs_ref[i]; @@ -4090,12 +4204,12 @@ static void init_lists_p_slice(struct Slice *currSlice) * ************************************************************************ */ -static void init_mbaff_lists(struct VideoParameters *p_Vid, +static void init_mbaff_lists(struct h264_dpb_stru *p_H264_Dpb, struct Slice *currSlice) { unsigned j; int i; - + struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; for (i = 2; i < 6; i++) { for (j = 0; j < MAX_LIST_SIZE; j++) currSlice->listX[i][j] = p_Vid->no_reference_picture; @@ -4105,6 +4219,7 @@ static void init_mbaff_lists(struct VideoParameters *p_Vid, for (i = 0; i < currSlice->listXsize[0]; i++) { #ifdef ERROR_CHECK if (currSlice->listX[0][i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; pr_info( "error currSlice->listX[0][%d] is NULL\r\n", i); break; @@ -4125,6 +4240,7 @@ static void init_mbaff_lists(struct VideoParameters *p_Vid, for (i = 0; i < currSlice->listXsize[1]; i++) { #ifdef ERROR_CHECK if (currSlice->listX[1][i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; pr_info( "error currSlice->listX[1][%d] is NULL\r\n", i); break; @@ -4186,8 +4302,10 @@ static void init_lists_b_slice(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) + p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((p_Dpb->fs_ref[i]->is_used == 3) && ((p_Dpb->fs_ref[i]->frame-> @@ -4212,8 +4330,10 @@ static void init_lists_b_slice(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) + p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((p_Dpb->fs_ref[i]->is_used == 3) && ((p_Dpb->fs_ref[i]->frame-> @@ -4344,8 +4464,10 @@ static void init_lists_b_slice(struct Slice *currSlice) for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_used) { if (currSlice->ThisPOC >= @@ -4361,8 +4483,10 @@ static void init_lists_b_slice(struct Slice *currSlice) list0idx_1 = list0idx; for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_used) { if (currSlice->ThisPOC < @@ -4558,17 +4682,22 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice, struct DecodedPictureBuffer *p_Dpb, int picNum) { unsigned i; - + struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, + struct h264_dpb_stru, mDPB); for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { if (currSlice->structure == FRAME) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference == 3) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) + if (p_Dpb->fs_ref[i]->frame == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->frame-> is_long_term) && @@ -4578,13 +4707,17 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice, } } else { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) + if (p_Dpb->fs_ref[i] == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if (p_Dpb->fs_ref[i]->is_reference & 1) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) + if (p_Dpb->fs_ref[i]->top_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->top_field-> is_long_term) && @@ -4594,8 +4727,10 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice, } if (p_Dpb->fs_ref[i]->is_reference & 2) { #ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) + if (p_Dpb->fs_ref[i]->bottom_field == NULL) { + p_H264_Dpb->dpb_error_flag = __LINE__; continue; + } #endif if ((!p_Dpb->fs_ref[i]->bottom_field-> is_long_term) && @@ -4816,7 +4951,6 @@ static void reorder_ref_pic_list(struct Slice *currSlice, int cur_list) (char)(num_ref_idx_lX_active_minus1 + 1); } - static void reorder_lists(struct Slice *currSlice) { struct VideoParameters *p_Vid = currSlice->p_Vid; @@ -4851,11 +4985,11 @@ static void reorder_lists(struct Slice *currSlice) PRINT_FLAG_DPB_DETAIL, "listX[0] reorder (PicNum): "); for (i = 0; i < currSlice->listXsize[0]; i++) { - dpb_print(p_H264_Dpb->decoder_index, + dpb_print_cont(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%d ", currSlice->listX[0][i]->pic_num); } - dpb_print(p_H264_Dpb->decoder_index, + dpb_print_cont(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "\n"); } } @@ -4886,11 +5020,11 @@ static void reorder_lists(struct Slice *currSlice) PRINT_FLAG_DPB_DETAIL, "listX[1] reorder (PicNum): "); for (i = 0; i < currSlice->listXsize[1]; i++) { - dpb_print(p_H264_Dpb->decoder_index, + dpb_print_cont(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%d ", currSlice->listX[1][i]->pic_num); } - dpb_print(p_H264_Dpb->decoder_index, + dpb_print_cont(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "\n"); } } @@ -5013,8 +5147,10 @@ int allocate_colocate_buf(struct h264_dpb_stru *p_H264_Dpb) break; } } - if (i == p_H264_Dpb->colocated_buf_count) + if (i == p_H264_Dpb->colocated_buf_count) { i = -1; + p_H264_Dpb->buf_alloc_fail = 1; + } return i; } @@ -5261,7 +5397,8 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) #else new_pic_flag = (p_H264_Dpb->mVideo.dec_picture == NULL); #endif - + p_H264_Dpb->buf_alloc_fail = 0; + p_H264_Dpb->dpb_error_flag = 0; slice_prepare(p_H264_Dpb, &p_H264_Dpb->mDPB, &p_H264_Dpb->mVideo, &p_H264_Dpb->mSPS, &p_H264_Dpb->mSlice); @@ -5338,7 +5475,7 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) p_H264_Dpb->mVideo.dec_picture->buf_spec_num = -1; p_H264_Dpb->mVideo.dec_picture-> colocated_buf_index = -1; - update_pic_num(&p_H264_Dpb->mSlice); + update_pic_num(p_H264_Dpb); if ((currSlice->structure == TOP_FIELD) || (currSlice->structure == BOTTOM_FIELD)) { @@ -5352,6 +5489,10 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) -1) { p_H264_Dpb->mVideo.dec_picture->buf_spec_num = get_free_buf_idx(p_H264_Dpb->vdec); + if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num + < 0) + p_H264_Dpb->buf_alloc_fail = 1; + if (p_H264_Dpb->mVideo.dec_picture-> used_for_reference) { p_H264_Dpb->mVideo.dec_picture-> @@ -5374,10 +5515,90 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) reorder_lists(&p_H264_Dpb->mSlice); if (p_H264_Dpb->mSlice.structure == FRAME) - init_mbaff_lists(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice); + init_mbaff_lists(p_H264_Dpb, &p_H264_Dpb->mSlice); if (new_pic_flag) return 1; return 0; } + +enum PictureStructure get_cur_slice_picture_struct( + struct h264_dpb_stru *p_H264_Dpb) +{ + struct Slice *currSlice = &p_H264_Dpb->mSlice; + return currSlice->structure; +} + +static unsigned char is_pic_in_dpb(struct h264_dpb_stru *p_H264_Dpb, + struct StorablePicture *pic) +{ + unsigned char ret = 0; + int i; + struct DecodedPictureBuffer *p_Dpb = + &p_H264_Dpb->mDPB; + for (i = 0; i < p_Dpb->used_size; i++) { + if (p_Dpb->fs[i]->top_field == pic || + p_Dpb->fs[i]->bottom_field == pic || + p_Dpb->fs[i]->frame == pic) { + ret = 1; + break; + } + } + return ret; +} + +int dpb_check_ref_list_error( + struct h264_dpb_stru *p_H264_Dpb) +{ + int i; + /*int j;*/ + struct Slice *currSlice = &p_H264_Dpb->mSlice; + if ((currSlice->slice_type != I_SLICE) && + (currSlice->slice_type != SI_SLICE)) { + for (i = 0; i < currSlice->listXsize[0]; i++) { + /*for (j = i + 1; j < currSlice->listXsize[0]; j++) { + if(currSlice->listX[0][i]->pic_num == + currSlice->listX[0][j]->pic_num) + return 1; + }*/ + if (!is_pic_in_dpb(p_H264_Dpb, + currSlice->listX[0][i])) + return 1; + if (currSlice->listX[0][i]->frame && + currSlice->listX[0][i]->frame->non_existing) + return 3; + } + } + + if (currSlice->slice_type == B_SLICE) { + for (i = 0; i < currSlice->listXsize[1]; i++) { + /*for (j = i + 1; j < currSlice->listXsize[1]; j++) { + if(currSlice->listX[1][i]->pic_num == + currSlice->listX[1][j]->pic_num) + return 2; + } + for (j = 0; j < currSlice->listXsize[0]; j++) { + if(currSlice->listX[1][i]->pic_num == + currSlice->listX[0][j]->pic_num) + return 3; + }*/ + + if (!is_pic_in_dpb(p_H264_Dpb, + currSlice->listX[1][i])) + return 2; + if (currSlice->listX[1][i]->frame && + currSlice->listX[1][i]->frame->non_existing) + return 4; +#if 0 + if (currSlice->listXsize[0] == 1 && + currSlice->listXsize[1] == 1 && + currSlice->listX[1][0] == + currSlice->listX[0][0]) + return 3; +#endif + } + } + return 0; +} + diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h index e8ffec815393..c76a26a43f85 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h @@ -16,6 +16,7 @@ #define PRINT_FRAMEBASE_DATA 0x0100 #define PRINT_FLAG_DEBUG_POC 0x0200 #define RRINT_FLAG_RPM 0x0400 +#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800 #define DISABLE_ERROR_HANDLE 0x10000 #define DEBUG_DUMP_STAT 0x80000 @@ -769,6 +770,8 @@ struct h264_dpb_stru { unsigned int aspect_ratio_sar_height; unsigned int dec_dpb_status; + unsigned char buf_alloc_fail; + unsigned int dpb_error_flag; }; @@ -821,4 +824,11 @@ void print_pic_info(int decindex, const char *info, int slice_type); void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force); +void dump_pic(struct h264_dpb_stru *p_H264_Dpb); + +enum PictureStructure get_cur_slice_picture_struct( + struct h264_dpb_stru *p_H264_Dpb); + +int dpb_check_ref_list_error( + struct h264_dpb_stru *p_H264_Dpb); #endif diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index 04320e563a6a..120d693bfac7 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -53,6 +53,7 @@ #include "../utils/decoder_mmu_box.h" #include "../utils/decoder_bmmu_box.h" #include "../utils/firmware.h" +#include #undef pr_info #define pr_info printk @@ -131,6 +132,7 @@ static unsigned int reference_buf_margin = 4; static unsigned int max_alloc_buf_count; static unsigned int decode_timeout_val = 100; +static unsigned int errordata_timeout_val = 50; static unsigned int get_data_timeout_val = 2000; static unsigned int frame_max_data_packet = 8; @@ -206,13 +208,16 @@ static unsigned int i_only_flag; bit[3] force sliding window ref_frames_in_buffer > num_ref_frames bit[4] check inactive of receiver bit[5] reset buffmgr if in deadlock + bit[6] reset buffmgr if bufspec, collocate buf, pic alloc fail bit[8] check total mbx/mby of decoded frame bit[9] check ERROR_STATUS_REG + bit[10] check reference list + bit[11] mark error if dpb error bit[12] i_only when error happen */ -static unsigned int error_proc_policy = 0x1214; /*0xc;*/ +static unsigned int error_proc_policy = 0x1f14; /*0xc;*/ /* error_skip_count: @@ -240,14 +245,25 @@ static unsigned int first_i_policy = (15 << 8) | 2; bit [2], if even poc only, output frame ifthe cuurent poc is 2 big than the previous poc */ -static unsigned int fast_output_enable = 3; +static unsigned int fast_output_enable; static unsigned int enable_itu_t35 = 1; +static unsigned int frmbase_cont_bitlevel = 0x40; + +static unsigned int frmbase_cont_bitlevel2 = 0x1; + +static void vmh264_dump_state(struct vdec_s *vdec); + #define is_in_parsing_state(status) \ ((status == H264_ACTION_SEARCH_HEAD) || \ ((status & 0xf0) == 0x80)) +#define is_interlace(frame) \ + (frame->frame &&\ + frame->top_field &&\ + frame->bottom_field &&\ + (!frame->frame->coded_frame)) static inline bool close_to(int a, int b, int m) { return (abs(a - b) < m) ? true : false; @@ -289,6 +305,7 @@ u32 V_BUF_ADDR_OFFSET = 0x200000; #define BUFSPEC_POOL_SIZE 64 #define VF_POOL_SIZE 64 +#define VF_POOL_NUM 2 #define MAX_VF_BUF_NUM 27 #define BMMU_MAX_BUFFERS (BUFSPEC_POOL_SIZE + 3) #define BMMU_REF_IDX (BUFSPEC_POOL_SIZE) @@ -308,8 +325,7 @@ u32 V_BUF_ADDR_OFFSET = 0x200000; #define SWITCHING_STATE_ON_CMD3 1 #define SWITCHING_STATE_ON_CMD1 2 -#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001 -#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002 + #define INCPTR(p) ptr_atomic_wrap_inc(&p) @@ -327,6 +343,8 @@ struct buffer_spec_s { 3, in disp queue, isolated, do not use for dpb when vf_put; 4, to release + 5, in disp queue, isolated (but not to release) + do not use for dpb when vf_put; */ int used; unsigned int info0; @@ -512,7 +530,8 @@ struct vdec_h264_hw_s { DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - struct vframe_s vfpool[VF_POOL_SIZE]; + int cur_pool; + struct vframe_s vfpool[VF_POOL_NUM][VF_POOL_SIZE]; struct buffer_spec_s buffer_spec[BUFSPEC_POOL_SIZE]; struct vframe_s switching_fense_vf; struct h264_dpb_stru dpb; @@ -550,7 +569,6 @@ struct vdec_h264_hw_s { u32 video_signal_from_vui; /*to do .. */ u32 timing_info_present_flag; u32 fixed_frame_rate_flag; - u32 fixed_frame_rate_check_count; u32 iframe_count; u32 aspect_ratio_info; u32 num_units_in_tick; @@ -562,9 +580,8 @@ struct vdec_h264_hw_s { u32 pts_duration; u32 h264_pts_count; u32 duration_from_pts_done; - u32 pts_unstable; u32 duration_on_correcting; + u32 pts_unstable; u32 last_checkout_pts; - u32 fatal_error_flag; u32 max_refer_buf; s32 vh264_stream_switching_state; @@ -572,7 +589,6 @@ struct vdec_h264_hw_s { u32 last_pts; u32 last_pts_remainder; u32 last_duration; - u32 saved_resolution; u32 last_mb_width, last_mb_height; bool check_pts_discontinue; bool pts_discontinue; @@ -659,6 +675,11 @@ struct vdec_h264_hw_s { u32 ucode_pause_pos; u8 reset_bufmgr_flag; + u32 reset_bufmgr_count; + u32 cfg_param1; + u32 cfg_param2; + u32 cfg_param3; + u32 cfg_param4; struct firmware_s *fw; }; @@ -1036,10 +1057,11 @@ static void hevc_sao_set_pic_buffer(struct vdec_h264_hw_s *hw, PRINT_FLAG_MMU_DETAIL, "release unused buf , used_4k_num %ld index %d\n", used_4k_num, hw->hevc_cur_buf_idx); - decoder_mmu_box_free_idx_tail( - hw->mmu_box, - hw->hevc_cur_buf_idx, - used_4k_num); + decoder_mmu_box_free_idx_tail( + hw->mmu_box, + hw->hevc_cur_buf_idx, + used_4k_num); + hw->hevc_cur_buf_idx = 0xffff; } WRITE_VREG(CURR_CANVAS_CTRL, pic->buf_spec_num << 24); @@ -1120,11 +1142,15 @@ static void hevc_set_unused_4k_buff_idx(struct vdec_h264_hw_s *hw, static void hevc_set_frame_done(struct vdec_h264_hw_s *hw) { + ulong timeout = jiffies + HZ; dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, "hevc_frame_done...set\n"); while ((READ_VREG(HEVC_SAO_INT_STATUS) & 0x1) == 0) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, " %s...wait\n", __func__); + if (time_after(jiffies, timeout)) { + dpb_print(DECODE_ID(hw), + PRINT_FLAG_MMU_DETAIL, " %s..timeout!\n", __func__); + break; + } } WRITE_VREG(HEVC_SAO_INT_STATUS, 0x1); hw->frame_done = 1; @@ -1133,19 +1159,28 @@ static void hevc_set_frame_done(struct vdec_h264_hw_s *hw) static void hevc_sao_wait_done(struct vdec_h264_hw_s *hw) { + ulong timeout = jiffies + HZ; dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...start\n"); - while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31)) - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...wait\n"); - + while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31)) { + if (time_after(jiffies, timeout)) { + dpb_print(DECODE_ID(hw), + PRINT_FLAG_MMU_DETAIL, + "hevc_sao_wait_done...wait timeout!\n"); + break; + } + } + timeout = jiffies + HZ; if ((hw->frame_busy == 1) && (hw->frame_done == 1)) { WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET); while ((READ_VREG(SYS_COMMAND) & 0xff) != H265_ABORT_SAO_4K_SET_DONE) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "hevc_sao_wait_done...wait h265_abort_sao_4k_set_done\n"); + if (time_after(jiffies, timeout)) { + dpb_print(DECODE_ID(hw), + PRINT_FLAG_MMU_DETAIL, + "wait h265_abort_sao_4k_set_done timeout!\n"); + break; + } } hw->frame_busy = 0; hw->frame_done = 0; @@ -1310,6 +1345,11 @@ int get_free_buf_idx(struct vdec_s *vdec) dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, "%s, buf_spec_num %d\n", __func__, index); + if (index < 0) { + dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, + "%s fail\n", __func__); + vmh264_dump_state(vdec); + } return index; } @@ -1367,12 +1407,14 @@ static void config_buf_specs(struct vdec_s *vdec) spin_unlock_irqrestore(&hw->bufspec_lock, flags); } -void dealloc_buf_specs(struct vdec_h264_hw_s *hw) +static void dealloc_buf_specs(struct vdec_h264_hw_s *hw, + unsigned char release_all) { int i; unsigned long flags; for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].used == 4) { + if (hw->buffer_spec[i].used == 4 || + release_all) { dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, "%s buf_spec_num %d\n", @@ -1444,7 +1486,7 @@ unsigned char have_free_buf_spec(struct vdec_s *vdec) } if (index >= 0) { mutex_lock(&vmh264_mutex); - dealloc_buf_specs(hw); + dealloc_buf_specs(hw, 0); if (max_alloc_buf_count == 0 || allocated_count < max_alloc_buf_count) { if (alloc_one_buf_spec(hw, index) >= 0) @@ -1492,6 +1534,34 @@ static void update_vf_memhandle(struct vdec_h264_hw_s *hw, } return; } +static int check_force_interlace(struct vdec_h264_hw_s *hw, + struct FrameStore *frame) +{ + int bForceInterlace = 0; + + if (frame->frame) { + if (frame->frame->coded_frame + && !frame->frame->frame_mbs_only_flag) { + if (frame->frame->structure == FRAME) + return 1; + } + } + + if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE) + && (hw->frame_width == 1920) + && (hw->frame_height >= 1080) + && (hw->frame_dur == 3203)) { + bForceInterlace = 1; + } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE) + && (hw->frame_width == 720) + && (hw->frame_height == 576) + && (hw->frame_dur == 3840)) { + bForceInterlace = 1; + } + + return bForceInterlace; +} + int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; @@ -1499,6 +1569,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) int buffer_index = frame->buf_spec_num; int vf_count = 1; int i; + int bForceInterlace = 0; + if (buffer_index < 0 || buffer_index >= BUFSPEC_POOL_SIZE) { dpb_print(DECODE_ID(hw), 0, "%s, buffer_index 0x%x is beyond range\n", @@ -1549,13 +1621,13 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) frame->bottom_field, -1); } - if (frame->frame == NULL || - frame->top_field == NULL || - frame->bottom_field == NULL || - frame->frame->coded_frame) + if (!is_interlace(frame)) vf_count = 1; else vf_count = 2; + bForceInterlace = check_force_interlace(hw, frame); + if (bForceInterlace) + vf_count = 2; hw->buffer_spec[buffer_index].vf_ref = 0; for (i = 0; i < vf_count; i++) { if (kfifo_get(&hw->newframe_q, &vf) == 0 || @@ -1597,14 +1669,20 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) hw->buffer_spec[buffer_index].used = 2; hw->buffer_spec[buffer_index].vf_ref++; - if (frame->frame && - frame->top_field && - frame->bottom_field && - (!frame->frame->coded_frame)) { + if (bForceInterlace || is_interlace(frame)) { vf->type = VIDTYPE_INTERLACE_FIRST | VIDTYPE_VIU_NV21; - if (frame->top_field->poc <= + + if (bForceInterlace) { + vf->type |= (i == 0 ? + VIDTYPE_INTERLACE_TOP : + VIDTYPE_INTERLACE_BOTTOM); + if (i == 1) { + vf->pts = 0; + vf->pts_us64 = 0; + } + } else if (frame->top_field->poc <= frame->bottom_field->poc) /*top first*/ vf->type |= (i == 0 ? VIDTYPE_INTERLACE_TOP : @@ -2482,9 +2560,12 @@ static struct vframe_s *vh264_vf_get(void *op_arg) 1000*(time - hw->last_frame_time)/HZ; if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS)) { + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; + int frame_index = FRAME_INDEX(vf->index); dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s buf_spec_num %d vf %p dur %d pts %d interval %dms\n", + "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n", __func__, BUFSPEC_INDEX(vf->index), vf, + p_H264_Dpb->mFrameStore[frame_index].poc, vf->duration, vf->pts, frame_interval); } if (hw->last_frame_time > 0) { @@ -2509,7 +2590,12 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg) int frame_index; if (vf == (&hw->vframe_dummy)) return; - + if (vf->index == -1) { + dpb_print(DECODE_ID(hw), 0, + "Warning: %s vf %p invalid index\r\n", + __func__, vf); + return; + } frame_index = FRAME_INDEX(vf->index); buf_spec_num = BUFSPEC_INDEX(vf->index); if (frame_index < 0 || @@ -2526,8 +2612,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg) if (hw->buffer_spec[buf_spec_num].used == 2) { struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n", - __func__, frame_index, + "%s %p to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n", + __func__, vf, frame_index, p_H264_Dpb->mFrameStore[frame_index].poc, buf_spec_num, hw->buffer_spec[buf_spec_num].used, @@ -2538,8 +2624,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg) } else { unsigned long flags; dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s isolated vf, buf_spec_num %d used %d vf_ref %d\n", - __func__, buf_spec_num, + "%s %p isolated vf, buf_spec_num %d used %d vf_ref %d\n", + __func__, vf, buf_spec_num, hw->buffer_spec[buf_spec_num].used, hw->buffer_spec[buf_spec_num].vf_ref); spin_lock_irqsave(&hw->bufspec_lock, flags); @@ -2713,7 +2799,8 @@ static int get_max_dec_frame_buf_size(int level_idc, return size; } -static int vh264_set_params(struct vdec_h264_hw_s *hw) +static int vh264_set_params(struct vdec_h264_hw_s *hw, + u32 param1, u32 param2, u32 param3, u32 param4) { int i, j; int mb_width, mb_total; @@ -2736,8 +2823,8 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) used_reorder_dpb_size_margin = reorder_dpb_size_margin_dv; #endif - seq_info2 = READ_VREG(AV_SCRATCH_1); - hw->seq_info = READ_VREG(AV_SCRATCH_2); + seq_info2 = param1; + hw->seq_info = param2; mb_width = seq_info2 & 0xff; mb_total = (seq_info2 >> 8) & 0xffff; @@ -2745,7 +2832,9 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) mb_width = 256; mb_height = mb_total/mb_width; if (mb_width > 0x110 || - mb_height > 0xa0) { + mb_height > 0xa0 || + mb_width <= 0 || + mb_height <= 0) { dpb_print(DECODE_ID(hw), 0, "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", seq_info2, @@ -2766,6 +2855,11 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) if (hw->config_bufmgr_done == 0) { struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; u32 reg_val; + hw->cfg_param1 = param1; + hw->cfg_param2 = param2; + hw->cfg_param3 = param3; + hw->cfg_param4 = param4; + hw->seq_info2 = seq_info2 & (~0x80000000); dpb_print(DECODE_ID(hw), 0, "AV_SCRATCH_1 = %x, AV_SCRATCH_2 %x\r\n", @@ -2789,11 +2883,12 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) /* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1 @AV_SCRATCH_6.15-0 = (top << 8 | bottom ) << (2 - frame_mbs_only_flag) */ - crop_infor = READ_VREG(AV_SCRATCH_6); + crop_infor = param3; crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag); crop_right = ((crop_infor >> 16) & 0xff) >> (2 - frame_mbs_only_flag); + p_H264_Dpb->mSPS.frame_mbs_only_flag = frame_mbs_only_flag; hw->frame_width = mb_width << 4; hw->frame_height = mb_height << 4; if (frame_mbs_only_flag) { @@ -2836,7 +2931,7 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) hevc_mcr_sao_global_hw_init(hw, hw->frame_width, hw->frame_height); - reg_val = READ_VREG(AV_SCRATCH_B); + reg_val = param4; level_idc = reg_val & 0xff; max_reference_size = (reg_val >> 8) & 0xff; dpb_print(DECODE_ID(hw), 0, @@ -2960,11 +3055,6 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw) /*end of config_bufmgr_done */ } - - WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | - (hw->dpb.mDPB.size<<16) | - (hw->dpb.mDPB.size<<8)); - return ret; } @@ -3187,6 +3277,10 @@ static bool is_buffer_available(struct vdec_s *vdec) is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB) ); buffer_available = 0; + if (dpb_is_debug(DECODE_ID(hw), + DEBUG_DISABLE_RUNREADY_RMBUF)) + return buffer_available; + if ((error_proc_policy & 0x4) && (error_proc_policy & 0x8)) { if ((kfifo_len(&hw->display_q) <= 0) && @@ -3236,11 +3330,14 @@ static bool is_buffer_available(struct vdec_s *vdec) static void check_decoded_pic_error(struct vdec_h264_hw_s *hw) { + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; unsigned mby_mbx = READ_VREG(MBY_MBX); unsigned mb_total = (hw->seq_info2 >> 8) & 0xffff; unsigned decode_mb_count = (((mby_mbx & 0xff) + 1) * (((mby_mbx >> 8) & 0xff) + 1)); + if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME) + mb_total /= 2; if ((error_proc_policy & 0x100) && decode_mb_count != mb_total) hw->data_flag |= ERROR_FLAG; @@ -3281,6 +3378,20 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec) /*unsigned char is_idr;*/ unsigned short *p = (unsigned short *)hw->lmem_addr; reset_process_time(hw); + + if (input_frame_based(vdec) && + frmbase_cont_bitlevel2 != 0 && + READ_VREG(VIFF_BIT_CNT) < + frmbase_cont_bitlevel2 && + hw->get_data_count >= 0x70000000) { + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s H264_SLICE_HEAD_DONE with small bitcnt %d, goto empty_proc\n", + __func__, + READ_VREG(VIFF_BIT_CNT)); + + goto empty_proc; + } + dma_sync_single_for_cpu( amports_get_dma_device(), hw->lmem_addr_remap, @@ -3341,7 +3452,14 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec) } } #endif - if ((first_i_policy & 0x3) != 0) { + if (hw->config_bufmgr_done == 0) { + hw->dec_result = DEC_RESULT_DONE; + vdec_schedule_work(&hw->work); + dpb_print(DECODE_ID(hw), + PRINT_FLAG_UCODE_EVT, + "config_bufmgr not done, discard frame\n"); + return IRQ_HANDLED; + } else if ((first_i_policy & 0x3) != 0) { unsigned char is_i_slice = (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] == I_Slice) @@ -3391,11 +3509,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec) val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt), val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt)); - if (hw->reset_bufmgr_flag) { - h264_reset_bufmgr(hw); - hw->reset_bufmgr_flag = 0; - } - slice_header_process_status = h264_slice_header_process(p_H264_Dpb); if (mmu_enable) @@ -3432,6 +3545,23 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec) hw->decode_pic_count+1, hw->skip_frame_count); } + if (error_proc_policy & 0x400) { + int ret = dpb_check_ref_list_error(p_H264_Dpb); + if (ret != 0) { + dpb_print(DECODE_ID(hw), 0, + "reference list error %d\n", + ret); + hw->data_flag |= ERROR_FLAG; + } + } + if ((error_proc_policy & 0x800) + && p_H264_Dpb->dpb_error_flag != 0) { + dpb_print(DECODE_ID(hw), 0, + "dpb error %d\n", + p_H264_Dpb->dpb_error_flag); + hw->data_flag |= ERROR_FLAG; + } + cfg_ret = config_decode_buf(hw, p_H264_Dpb->mVideo.dec_picture); if (cfg_ret < 0) { @@ -3538,7 +3668,23 @@ pic_done_proc: hw->dec_flag &= (~NODISP_FLAG); } } - + if (input_frame_based(vdec) && + 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)); + /*do not DEC_RESULT_GET_DATA*/ + hw->get_data_count = 0x7fffffff; + WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); + decode_frame_count[DECODE_ID(hw)]++; + start_process_time(hw); + return IRQ_HANDLED; + } amvdec_stop(); dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s %s decode slice count %d\n", @@ -3763,13 +3909,16 @@ send_again: dpb_print_cont(DECODE_ID(hw), 0, "\n"); } - if ((udebug_pause_pos == (debug_tag & 0xffff)) && + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hw->decode_pic_count) && (udebug_pause_val == 0 || - udebug_pause_val == READ_VREG(DEBUG_REG2))) + udebug_pause_val == READ_VREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; hw->ucode_pause_pos = udebug_pause_pos; + } else if (debug_tag & 0x20000) hw->ucode_pause_pos = 0xffffffff; if (hw->ucode_pause_pos) @@ -3780,13 +3929,16 @@ send_again: dpb_print(DECODE_ID(hw), 0, "dbg%x: %x\n", debug_tag, READ_VREG(DEBUG_REG2)); - if ((udebug_pause_pos == (debug_tag & 0xffff)) && + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hw->decode_pic_count) && (udebug_pause_val == 0 || - udebug_pause_val == READ_VREG(DEBUG_REG2))) + udebug_pause_val == READ_VREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; hw->ucode_pause_pos = udebug_pause_pos; + } if (hw->ucode_pause_pos) reset_process_time(hw); else @@ -3865,7 +4017,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\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\n", input_frame_based(vdec), hw->eos, hw->stat, @@ -3874,7 +4026,8 @@ static void vmh264_dump_state(struct vdec_s *vdec) display_frame_count[DECODE_ID(hw)], run_count[DECODE_ID(hw)], not_run_ready[DECODE_ID(hw)], - input_empty[DECODE_ID(hw)] + input_empty[DECODE_ID(hw)], + hw->reset_bufmgr_count ); if (vf_get_receiver(vdec->vf_provider_name)) { @@ -3905,7 +4058,10 @@ static void vmh264_dump_state(struct vdec_s *vdec) ); dump_dpb(&p_H264_Dpb->mDPB, 1); + dump_pic(p_H264_Dpb); for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { + if (hw->buffer_spec[i].used == -1) + continue; dpb_print(DECODE_ID(hw), 0, "bufspec (%d): used %d adr 0x%x canvas(%d) vf_ref(%d) ", i, hw->buffer_spec[i].used, @@ -3991,7 +4147,11 @@ static void check_timer_func(unsigned long arg) { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); - + int error_skip_frame_count = error_skip_count & 0xfff; + unsigned int timeout_val = decode_timeout_val; + if (timeout_val != 0 && + hw->no_error_count < error_skip_frame_count) + timeout_val = errordata_timeout_val; if ((h264_debug_cmd & 0x100) != 0 && DECODE_ID(hw) == (h264_debug_cmd & 0xff)) { hw->dec_result = DEC_RESULT_DONE; @@ -4001,6 +4161,12 @@ static void check_timer_func(unsigned long arg) h264_debug_cmd = 0; return; } + if ((h264_debug_cmd & 0x200) != 0 && + DECODE_ID(hw) == (h264_debug_cmd & 0xff)) { + hw->reset_bufmgr_flag = 1; + h264_debug_cmd = 0; + return; + } if (vdec->next_status == VDEC_STATUS_DISCONNECTED) { hw->dec_result = DEC_RESULT_FORCE_EXIT; @@ -4022,10 +4188,10 @@ static void check_timer_func(unsigned long arg) if ((input_frame_based(vdec) || (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) && ((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) && - (decode_timeout_val > 0) && + (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) - > decode_timeout_val) + > timeout_val) ) { u32 dpb_status = READ_VREG(DPB_STATUS_REG); u32 mby_mbx = READ_VREG(MBY_MBX); @@ -4176,7 +4342,8 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw) WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count); WRITE_VREG(AV_SCRATCH_8, hw->buf_offset); - WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle); + if (!is_secload_get()) + WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle); /* hw->error_recovery_mode = (error_recovery_mode != 0) ? error_recovery_mode : error_recovery_mode_in; */ @@ -4216,6 +4383,14 @@ static unsigned char amvdec_enable_flag; static void vh264_local_init(struct vdec_h264_hw_s *hw) { int i; + hw->init_flag = 0; + hw->eos = 0; + hw->config_bufmgr_done = 0; + hw->start_process_time = 0; + hw->has_i_frame = 0; + hw->no_error_count = 0xfff; + hw->no_error_i_count = 0xf; + hw->decode_timeout_count = 0; hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio; @@ -4264,9 +4439,9 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw) INIT_KFIFO(hw->newframe_q); for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &hw->vfpool[i]; - hw->vfpool[i].index = -1; /* VF_BUF_NUM; */ - hw->vfpool[i].bufWidth = 1920; + const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]); + hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */ + hw->vfpool[hw->cur_pool][i].bufWidth = 1920; kfifo_put(&hw->newframe_q, vf); } @@ -4276,10 +4451,6 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw) hw->vh264_stream_switching_state = SWITCHING_STATE_OFF; hw->hevc_cur_buf_idx = 0xffff; - INIT_WORK(&hw->work, vh264_work); - INIT_WORK(&hw->notify_work, vh264_notify_work); - INIT_WORK(&hw->user_data_work, user_data_push_work); - return; } @@ -4288,12 +4459,6 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) /* int trickmode_fffb = 0; */ int firmwareloaded = 0; - hw->init_flag = 0; - hw->eos = 0; - hw->config_bufmgr_done = 0; - hw->start_process_time = 0; - hw->has_i_frame = 0; - /* pr_info("\nvh264_init\n"); */ /* init_timer(&hw->recycle_timer); */ @@ -4308,11 +4473,11 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) hw->stat |= STAT_TIMER_ARM; hw->stat |= STAT_ISR_REG; - hw->duration_on_correcting = 0; - hw->fixed_frame_rate_check_count = 0; - hw->saved_resolution = 0; - vh264_local_init(hw); + INIT_WORK(&hw->work, vh264_work); + INIT_WORK(&hw->notify_work, vh264_notify_work); + INIT_WORK(&hw->user_data_work, user_data_push_work); + if (!amvdec_enable_flag) { amvdec_enable_flag = true; amvdec_enable(); @@ -4330,7 +4495,14 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) return -ENOMEM; } } - + if (is_secload_get() && !firmwareloaded) { + pr_info("VMH264 start load sec firmware ...\n"); + if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI) + != 0) { + amvdec_disable(); + return -1; + } + } else { /* -- ucode loading (amrisc and swap code) */ hw->mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE, @@ -4408,7 +4580,7 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) return -EBUSY; } } - + } #if 1 /* #ifdef BUFFER_MGR_IN_C */ hw->lmem_addr = __get_free_page(GFP_KERNEL); if (!hw->lmem_addr) { @@ -4614,12 +4786,20 @@ static void vh264_work(struct work_struct *work) READ_VREG(VLD_MEM_VIFIFO_RP)); if (!mmu_enable) { mutex_lock(&vmh264_mutex); - dealloc_buf_specs(hw); + dealloc_buf_specs(hw, 0); mutex_unlock(&vmh264_mutex); } if (hw->dec_result == DEC_RESULT_CONFIG_PARAM) { - if (vh264_set_params(hw) < 0) + u32 param1 = READ_VREG(AV_SCRATCH_1); + 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) hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; + 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 @@ -4745,6 +4925,8 @@ result_done: "%s: force exit\n", __func__); amvdec_stop(); + if (mmu_enable) + amhevc_stop(); if (hw->stat & STAT_ISR_REG) { vdec_free_irq(VDEC_IRQ_1, (void *)hw); hw->stat &= ~STAT_ISR_REG; @@ -4814,6 +4996,7 @@ static void run(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 size; run_count[DECODE_ID(hw)]++; @@ -4821,9 +5004,19 @@ static void run(struct vdec_s *vdec, hw->vdec_cb_arg = arg; hw->vdec_cb = callback; + if (hw->reset_bufmgr_flag || + ((error_proc_policy & 0x40) && + p_H264_Dpb->buf_alloc_fail)) { + h264_reset_bufmgr(hw); + hw->reset_bufmgr_flag = 0; + } + if (h264_debug_cmd & 0xf000) { - h264_reconfig(hw); - h264_debug_cmd &= (~0xf000); + if (((h264_debug_cmd >> 12) & 0xf) + == (DECODE_ID(hw) + 1)) { + h264_reconfig(hw); + h264_debug_cmd &= (~0xf000); + } } /* hw->chunk = vdec_prepare_input(vdec); */ #ifdef CONFIG_AM_VDEC_DV @@ -4902,11 +5095,18 @@ static void run(struct vdec_s *vdec, start_process_time(hw); - if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) { + if (is_secload_get()) { + if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI) + != 0) { + amvdec_enable_flag = false; + amvdec_disable(); + pr_info("%s: Error amvdec_vdec_loadmc fail\n", + __func__); + return; + } + } else if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) { amvdec_enable_flag = false; amvdec_disable(); - if (mmu_enable) - amhevc_disable(); pr_info("%s: Error amvdec_vdec_loadmc fail\n", __func__); return; @@ -5000,6 +5200,7 @@ static void h264_reconfig(struct vdec_h264_hw_s *hw) static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw) { int i; +#if 0 struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; int actual_dpb_size, max_reference_size; int reorder_pic_num; @@ -5008,19 +5209,9 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw) unsigned int colocated_mv_addr_end; dpb_print(DECODE_ID(hw), 0, "%s\n", __func__); - /* after calling flush_dpb() and bufmgr_h264_remove_unused_frame(), - all buffers are in display queue (used == 2), - or free (used == 0) - */ - flush_dpb(p_H264_Dpb); - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - /*make sure buffers not put back to bufmgr when - vf_put is called*/ - if (hw->buffer_spec[i].used == 2) - hw->buffer_spec[i].used = 5; - } + for (i = 0; i < VF_POOL_SIZE; i++) + hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */ actual_dpb_size = p_H264_Dpb->mDPB.size; max_reference_size = p_H264_Dpb->max_reference_size; @@ -5030,6 +5221,23 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw) colocated_mv_addr_start = p_H264_Dpb->colocated_mv_addr_start; colocated_mv_addr_end = p_H264_Dpb->colocated_mv_addr_end; + hw->cur_pool++; + if (hw->cur_pool >= VF_POOL_NUM) + hw->cur_pool = 0; + + INIT_KFIFO(hw->display_q); + INIT_KFIFO(hw->newframe_q); + + for (i = 0; i < VF_POOL_SIZE; i++) { + const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]); + hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */ + hw->vfpool[hw->cur_pool][i].bufWidth = 1920; + kfifo_put(&hw->newframe_q, vf); + } + + for (i = 0; i < BUFSPEC_POOL_SIZE; i++) + hw->buffer_spec[i].used = 0; + dpb_init_global(&hw->dpb, DECODE_ID(hw), 0, 0); p_H264_Dpb->mDPB.size = actual_dpb_size; @@ -5041,6 +5249,43 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw) p_H264_Dpb->colocated_mv_addr_end = colocated_mv_addr_end; p_H264_Dpb->fast_output_enable = fast_output_enable; + hw->has_i_frame = 0; +#else + dpb_print(DECODE_ID(hw), 0, + "%s\n", __func__); + + for (i = 0; i < VF_POOL_SIZE; i++) + hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */ + + hw->cur_pool++; + if (hw->cur_pool >= VF_POOL_NUM) + hw->cur_pool = 0; + + if (hw->collocate_cma_alloc_addr) { + decoder_bmmu_box_free_idx( + hw->bmmu_box, + BMMU_REF_IDX); + hw->collocate_cma_alloc_addr = 0; + hw->dpb.colocated_mv_addr_start = 0; + hw->dpb.colocated_mv_addr_end = 0; + } + + dealloc_buf_specs(hw, 1); + buf_spec_init(hw); + + vh264_local_init(hw); + /*hw->decode_pic_count = 0; + hw->seq_info2 = 0;*/ + if (vh264_set_params(hw, + hw->cfg_param1, + hw->cfg_param2, + hw->cfg_param3, + hw->cfg_param4) < 0) + hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; + hw->init_flag = 1; + hw->reset_bufmgr_count++; +#endif + } int ammvdec_h264_mmu_init(struct vdec_h264_hw_s *hw) @@ -5350,6 +5595,9 @@ MODULE_PARM_DESC(fixed_frame_rate_mode, "\namvdec_h264 fixed_frame_rate_mode\n") module_param(decode_timeout_val, uint, 0664); MODULE_PARM_DESC(decode_timeout_val, "\n amvdec_h264 decode_timeout_val\n"); +module_param(errordata_timeout_val, uint, 0664); +MODULE_PARM_DESC(errordata_timeout_val, "\n amvdec_h264 errordata_timeout_val\n"); + module_param(get_data_timeout_val, uint, 0664); MODULE_PARM_DESC(get_data_timeout_val, "\n amvdec_h264 get_data_timeout_val\n"); @@ -5428,6 +5676,14 @@ MODULE_PARM_DESC(i_only_flag, "\n amvdec_h264 i_only_flag\n"); module_param(first_i_policy, uint, 0664); MODULE_PARM_DESC(first_i_policy, "\n amvdec_h264 first_i_policy\n"); +module_param(frmbase_cont_bitlevel, uint, 0664); +MODULE_PARM_DESC(frmbase_cont_bitlevel, + "\n amvdec_h264 frmbase_cont_bitlevel\n"); + +module_param(frmbase_cont_bitlevel2, uint, 0664); +MODULE_PARM_DESC(frmbase_cont_bitlevel2, + "\n amvdec_h264 frmbase_cont_bitlevel\n"); + module_param(udebug_flag, uint, 0664); MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 025af9070c86..ac54b5279be8 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -74,6 +74,7 @@ #include #include +#define SEND_LMEM_WITH_RPM #define SUPPORT_10BIT /* #define ERROR_HANDLE_DEBUG */ #if 0/*MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8B*/ @@ -104,7 +105,8 @@ #define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3 #define DUR2PTS(x) ((x)*90/96) -#define HEVC_SIZE (4096*2304) +#define MAX_SIZE (4096 + 2304) +#define OVER_SIZE(w, h) (MAX_SIZE < (w + h)) static struct semaphore h265_sema; @@ -306,6 +308,7 @@ static u32 udebug_pause_decode_idx; static u32 decode_pic_begin; static uint slice_parse_begin; static u32 step; +static bool is_reset; static u32 dynamic_buf_num_margin = 8; static u32 buf_alloc_width; @@ -380,6 +383,8 @@ bit 4: 0, set error_mark after reset/recover 1, do not set error_mark after reset/recover bit 5: 0, check total lcu for every picture 1, do not check total lcu +bit 6: 0, do not check head error + 1, check head error */ @@ -1496,7 +1501,6 @@ struct hevc_state_s { unsigned int dec_status; - /* data for SEI_MASTER_DISPLAY_COLOR */ unsigned int primaries[3][2]; unsigned int white_point[2]; @@ -1520,9 +1524,43 @@ struct hevc_state_s { u32 vf_pre_count; u32 vf_get_count; u32 vf_put_count; + u8 head_error_flag; struct firmware_s *fw; } /*hevc_stru_t */; +#ifdef SEND_LMEM_WITH_RPM +#define get_lmem_params(hevc, ladr) \ + hevc->lmem_ptr[ladr - (ladr & 0x3) + 3 - (ladr & 0x3)] + +void check_head_error(struct hevc_state_s *hevc) +{ +#define pcm_enabled_flag 0x040 +#define pcm_sample_bit_depth_luma 0x041 +#define pcm_sample_bit_depth_chroma 0x042 + hevc->head_error_flag = 0; + if ((error_handle_policy & 0x40) == 0) + return; + if (get_lmem_params(hevc, pcm_enabled_flag)) { + uint16_t pcm_depth_luma = get_lmem_params( + hevc, pcm_sample_bit_depth_luma); + uint16_t pcm_sample_chroma = get_lmem_params( + hevc, pcm_sample_bit_depth_chroma); + if (pcm_depth_luma > + hevc->bit_depth_luma || + pcm_sample_chroma > + hevc->bit_depth_chroma) { + hevc_print(hevc, 0, + "error, pcm bit depth %d, %d is greater than normal bit depth %d, %d\n", + pcm_depth_luma, + pcm_sample_chroma, + hevc->bit_depth_luma, + hevc->bit_depth_chroma); + hevc->head_error_flag = 1; + } + } +} +#endif + #ifdef SUPPORT_10BIT /* Losless compression body buffer size 4K per 64x32 (jt) */ static int compute_losless_comp_body_size(struct hevc_state_s *hevc, @@ -1811,6 +1849,7 @@ static void hevc_init_stru(struct hevc_state_s *hevc, hevc->col_pic = NULL; hevc->wait_buf = 0; hevc->error_flag = 0; + hevc->head_error_flag = 0; hevc->error_skip_nal_count = 0; hevc->have_vps = 0; hevc->have_sps = 0; @@ -4738,7 +4777,7 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, } -static void check_pic_decoded_lcu_count_pre(struct hevc_state_s *hevc, +static void check_pic_decoded_error_pre(struct hevc_state_s *hevc, int decoded_lcu) { int current_lcu_idx = decoded_lcu; @@ -4778,11 +4817,16 @@ static void check_pic_decoded_lcu_count_pre(struct hevc_state_s *hevc, } } + if (hevc->cur_pic && hevc->head_error_flag) { + hevc->cur_pic->error_mark = 1; + hevc_print(hevc, 0, + "head has error, set error_mark\n"); + } hevc->lcu_x_num_pre = hevc->lcu_x_num; hevc->lcu_y_num_pre = hevc->lcu_y_num; } -static void check_pic_decoded_lcu_count(struct hevc_state_s *hevc, +static void check_pic_decoded_error(struct hevc_state_s *hevc, int decoded_lcu) { int current_lcu_idx = decoded_lcu; @@ -4816,6 +4860,12 @@ static void check_pic_decoded_lcu_count(struct hevc_state_s *hevc, } } + if (hevc->cur_pic && hevc->head_error_flag) { + hevc->cur_pic->error_mark = 1; + hevc_print(hevc, 0, + "head has error, set error_mark\n"); + } + } static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, @@ -4894,7 +4944,7 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, #endif } - if (HEVC_SIZE < hevc->pic_w * hevc->pic_h) { + if (OVER_SIZE(hevc->pic_w, hevc->pic_h)) { pr_info("over size : %u x %u.\n", hevc->pic_w, hevc->pic_h); if (!hevc->m_ins_flag) @@ -5053,7 +5103,7 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, #ifdef MULTI_INSTANCE_SUPPORT if (!hevc->m_ins_flag) #endif - check_pic_decoded_lcu_count_pre(hevc, + check_pic_decoded_error_pre(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff); /**/ if (use_cma == 0) { @@ -7177,8 +7227,8 @@ static void read_decode_info(struct hevc_state_s *hevc) { uint32_t decode_info = READ_HREG(HEVC_DECODE_INFO); - hevc->start_decoding_flag = - decode_info & 0xff; + hevc->start_decoding_flag |= + (decode_info & 0xff); hevc->rps_set_id = (decode_info >> 8) & 0xff; } @@ -7443,7 +7493,7 @@ pic_done: dolby_get_meta(hevc); } #endif - check_pic_decoded_lcu_count(hevc, + check_pic_decoded_error(hevc, hevc->pic_decoded_lcu_idx); pic = get_pic_by_POC(hevc, hevc->curr_POC); hevc->curr_POC = INVALID_POC; @@ -7637,6 +7687,14 @@ pic_done: - ii]; } } +#ifdef SEND_LMEM_WITH_RPM + dma_sync_single_for_cpu( + amports_get_dma_device(), + hevc->lmem_phy_addr, + LMEM_BUF_SIZE, + DMA_FROM_DEVICE); + check_head_error(hevc); +#endif } if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { hevc_print(hevc, 0, @@ -7934,12 +7992,15 @@ static irqreturn_t vh265_isr(int irq, void *data) hevc_print_cont(hevc, 0, "\n"); } - if ((udebug_pause_pos == (debug_tag & 0xffff)) && + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hevc->decode_idx) && (udebug_pause_val == 0 || - udebug_pause_val == READ_HREG(DEBUG_REG2))) + udebug_pause_val == READ_HREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; hevc->ucode_pause_pos = udebug_pause_pos; + } else if (debug_tag & 0x20000) hevc->ucode_pause_pos = 0xffffffff; if (hevc->ucode_pause_pos) @@ -7951,12 +8012,15 @@ static irqreturn_t vh265_isr(int irq, void *data) "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1), READ_HREG(DEBUG_REG2), READ_VREG(HEVC_PARSER_LCU_START)); - if ((udebug_pause_pos == (debug_tag & 0xffff)) && + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hevc->decode_idx) && (udebug_pause_val == 0 || - udebug_pause_val == READ_HREG(DEBUG_REG2))) + udebug_pause_val == READ_HREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; hevc->ucode_pause_pos = udebug_pause_pos; + } if (hevc->ucode_pause_pos) reset_process_time(hevc); else @@ -8290,6 +8354,12 @@ int vh265_dec_status(struct vdec_info *vstatus) return 0; } +int vh265_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static int vh265_vdec_info_init(void) { gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); @@ -8430,7 +8500,7 @@ static int vh265_local_init(struct hevc_state_s *hevc) hevc->get_frame_dur = false; hevc->frame_width = hevc->vh265_amstream_dec_info.width; hevc->frame_height = hevc->vh265_amstream_dec_info.height; - if (HEVC_SIZE < hevc->frame_width * hevc->frame_height) { + if (OVER_SIZE(hevc->frame_width, hevc->frame_height)) { pr_info("over size : %u x %u.\n", hevc->frame_width, hevc->frame_height); hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; @@ -8574,10 +8644,11 @@ static s32 vh265_init(struct hevc_state_s *hevc) vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START, NULL); if (hevc->frame_dur != 0) { - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long)hevc->frame_dur)); + if (!is_reset) + vf_notify_receiver(hevc->provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)hevc->frame_dur)); fr_hint_status = VDEC_HINTED; } else fr_hint_status = VDEC_NEED_HINT; @@ -8706,7 +8777,7 @@ static int vh265_stop(struct hevc_state_s *hevc) } if (hevc->stat & STAT_VF_HOOK) { - if (fr_hint_status == VDEC_HINTED) + if (fr_hint_status == VDEC_HINTED && !is_reset) vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); @@ -8774,7 +8845,7 @@ static void timeout_process(struct hevc_state_s *hevc) hevc_print(hevc, 0, "%s decoder timeout\n", __func__); - check_pic_decoded_lcu_count(hevc, + check_pic_decoded_error(hevc, hevc->pic_decoded_lcu_idx); hevc->decoded_poc = hevc->curr_POC; hevc->decoding_pic = NULL; @@ -9115,7 +9186,7 @@ static void vh265_work(struct work_struct *work) hevc->used_4k_num = -1; - check_pic_decoded_lcu_count(hevc, + check_pic_decoded_error(hevc, hevc->pic_decoded_lcu_idx); #ifdef CONFIG_AM_VDEC_DV #if 1 @@ -9183,7 +9254,7 @@ static void vh265_work(struct work_struct *work) READ_VREG(HEVC_AUX_DATA_SIZE) != 0) dolby_get_meta(hevc); #endif - check_pic_decoded_lcu_count(hevc, + check_pic_decoded_error(hevc, hevc->pic_decoded_lcu_idx); pic = get_pic_by_POC(hevc, hevc->curr_POC); hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, @@ -9263,6 +9334,10 @@ static bool run_ready(struct vdec_s *vdec) struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; bool ret = 0; + if (step == 0x12) + return 0; + else if (step == 0x11) + step = 0x12; if (hevc->eos) return 0; @@ -9509,6 +9584,8 @@ static int amvdec_h265_probe(struct platform_device *pdev) #ifdef MULTI_INSTANCE_SUPPORT pdata->private = hevc; pdata->dec_status = vh265_dec_status; + pdata->set_isreset = vh265_set_isreset; + is_reset = 0; if (vh265_init(pdata) < 0) { #else if (vh265_init(hevc) < 0) { diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c index ade4ab3f55c8..d8e28aa98f6d 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c @@ -122,6 +122,7 @@ static struct timer_list recycle_timer; static u32 stat; static u32 buf_size = 32 * 1024 * 1024; static DEFINE_SPINLOCK(lock); +static bool is_reset; static inline u32 index2canvas0(u32 index) { @@ -430,6 +431,12 @@ int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vmjpeg_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + /****************************************/ static int vmjpeg_canvas_init(void) { @@ -763,8 +770,11 @@ static s32 vmjpeg_init(void) vf_reg_provider(&vmjpeg_vf_prov); #endif - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vmjpeg_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)vmjpeg_amstream_dec_info.rate)); stat |= STAT_VF_HOOK; @@ -803,7 +813,8 @@ static int amvdec_mjpeg_probe(struct platform_device *pdev) vmjpeg_amstream_dec_info = *pdata->sys_info; pdata->dec_status = vmjpeg_dec_status; - + pdata->set_isreset = vmjpeg_set_isreset; + is_reset = 0; vmjpeg_vdec_info_init(); if (vmjpeg_init() < 0) { @@ -841,8 +852,10 @@ static int amvdec_mjpeg_remove(struct platform_device *pdev) } if (stat & STAT_VF_HOOK) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, + NULL); vf_unreg_provider(&vmjpeg_vf_prov); stat &= ~STAT_VF_HOOK; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c index e01184665d31..41c37be0f92a 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c @@ -186,6 +186,7 @@ static u32 first_i_frame_ready; static struct work_struct userdata_push_work; static struct work_struct notify_work; static struct work_struct reset_work; +static bool is_reset; static inline int pool_index(struct vframe_s *vf) { @@ -516,7 +517,10 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id) #ifdef NV21 vf->type |= VIDTYPE_VIU_NV21; #endif - vf->duration >>= 1; + if (info & PICINFO_RPT_FIRST) + vf->duration /= 3; + else + vf->duration >>= 1; vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? vf->duration >> 1 : 0; vf->duration += vf->duration_pulldown; @@ -562,7 +566,10 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id) #ifdef NV21 vf->type |= VIDTYPE_VIU_NV21; #endif - vf->duration >>= 1; + if (info & PICINFO_RPT_FIRST) + vf->duration /= 3; + else + vf->duration >>= 1; vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? vf->duration >> 1 : 0; vf->duration += vf->duration_pulldown; @@ -611,7 +618,7 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id) #ifdef NV21 vf->type |= VIDTYPE_VIU_NV21; #endif - vf->duration >>= 1; + vf->duration /= 3; vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? vf->duration >> 1 : 0; @@ -819,6 +826,12 @@ int vmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vmpeg12_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static int vmpeg12_vdec_info_init(void) { gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); @@ -1103,11 +1116,12 @@ static s32 vmpeg12_init(void) vf_reg_provider(&vmpeg_vf_prov); #endif if (vmpeg12_amstream_dec_info.rate != 0) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long) - vmpeg12_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long) + vmpeg12_amstream_dec_info.rate)); fr_hint_status = VDEC_HINTED; } else fr_hint_status = VDEC_NEED_HINT; @@ -1145,6 +1159,8 @@ static int amvdec_mpeg12_probe(struct platform_device *pdev) vmpeg12_amstream_dec_info = *pdata->sys_info; pdata->dec_status = vmpeg12_dec_status; + pdata->set_isreset = vmpeg12_set_isreset; + is_reset = 0; vmpeg12_vdec_info_init(); @@ -1186,7 +1202,7 @@ static int amvdec_mpeg12_remove(struct platform_device *pdev) } if (stat & STAT_VF_HOOK) { - if (fr_hint_status == VDEC_HINTED) + if (fr_hint_status == VDEC_HINTED && !is_reset) vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); fr_hint_status = VDEC_NO_NEED_HINT; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c index 42afe480a158..094fae3ebcc9 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c @@ -172,7 +172,7 @@ u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; static struct work_struct reset_work; static struct work_struct notify_work; - +static bool is_reset; static DEFINE_SPINLOCK(lock); @@ -752,6 +752,12 @@ int vmpeg4_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vmpeg4_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static int vmpeg4_vdec_info_init(void) { gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); @@ -1070,11 +1076,12 @@ static s32 vmpeg4_init(void) vf_reg_provider(&vmpeg_vf_prov); #endif if (vmpeg4_amstream_dec_info.rate != 0) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long) - vmpeg4_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long) + vmpeg4_amstream_dec_info.rate)); fr_hint_status = VDEC_HINTED; } else fr_hint_status = VDEC_NEED_HINT; @@ -1110,6 +1117,8 @@ static int amvdec_mpeg4_probe(struct platform_device *pdev) vmpeg4_amstream_dec_info = *pdata->sys_info; pdata->dec_status = vmpeg4_dec_status; + pdata->set_isreset = vmpeg4_set_isreset; + is_reset = 0; INIT_WORK(&reset_work, reset_do_work); INIT_WORK(¬ify_work, vmpeg4_notify_work); @@ -1144,7 +1153,7 @@ static int amvdec_mpeg4_remove(struct platform_device *pdev) } if (stat & STAT_VF_HOOK) { - if (fr_hint_status == VDEC_HINTED) + if (fr_hint_status == VDEC_HINTED && !is_reset) vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); fr_hint_status = VDEC_NO_NEED_HINT; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 2e34d0280cba..97fc0a89afa9 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -1137,6 +1137,7 @@ static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *), hw->dec_result = DEC_RESULT_NONE; if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) { + pr_err("VIDEO_DEC_FORMAT_MPEG4 ucode loading failed\n"); hw->dec_result = DEC_RESULT_ERROR; schedule_work(&hw->work); return; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c index 4fed6b7becaa..7af39aca0a6e 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c @@ -150,6 +150,7 @@ static u32 real_err_count; static u32 fatal_flag; static s32 wait_buffer_counter; +static bool is_reset; static DEFINE_SPINLOCK(lock); @@ -515,6 +516,12 @@ int vreal_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vreal_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + /****************************************/ static int vreal_canvas_init(void) { @@ -854,8 +861,9 @@ s32 vreal_init(struct vdec_s *vdec) vf_reg_provider(&vreal_vf_prov); #endif - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vreal_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long)vreal_amstream_dec_info.rate)); stat |= STAT_VF_HOOK; @@ -894,6 +902,8 @@ static int amvdec_real_probe(struct platform_device *pdev) vreal_amstream_dec_info = *pdata->sys_info; pdata->dec_status = vreal_dec_status; + pdata->set_isreset = vreal_set_isreset; + is_reset = 0; if (vreal_init(pdata) < 0) { pr_info("amvdec_real init failed.\n"); @@ -921,8 +931,9 @@ static int amvdec_real_remove(struct platform_device *pdev) } if (stat & STAT_VF_HOOK) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); vf_unreg_provider(&vreal_vf_prov); stat &= ~STAT_VF_HOOK; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c index 00a17a0abc40..5a857e19b1d2 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c @@ -43,6 +43,7 @@ #include "amvdec.h" #include #include "firmware.h" +#include #define MC_SIZE (4096 * 16) @@ -372,11 +373,68 @@ static s32 amvdec_loadmc(const u32 *p) return ret; } +s32 optee_load_fw(enum vformat_e type, const char *name) +{ + s32 ret = 0; + switch ((u32)type) { + case VFORMAT_VC1: + ret = tee_load_video_fw((u32)VIDEO_DEC_VC1); + break; + + case VFORMAT_AVS: + ret = tee_load_video_fw((u32)VIDEO_DEC_AVS); + break; + + case VFORMAT_MPEG12: + ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG12); + break; + + case VFORMAT_MJPEG: + ret = tee_load_video_fw((u32)VIDEO_DEC_MJPEG); + break; + + case VFORMAT_VP9: + ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_MMU); + break; + + case VFORMAT_HEVC: + if (!strcmp(name, "vh265_mc")) + ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC); + else if (!strcmp(name, "vh265_mc_mmu")) + ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU); + break; + + case VFORMAT_REAL: + if (!strcmp(name, "vreal_mc_8")) + ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V8); + else if (!strcmp(name, "vreal_mc_9")) + ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V9); + break; + + case VFORMAT_MPEG4: + if (!strcmp(name, "vmpeg4_mc_311")) + ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_3); + else if (!strcmp(name, "vmpeg4_mc_4")) + ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_4); + else if (!strcmp(name, "vmpeg4_mc_5")) + ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_5); + else if (!strcmp(name, "h263_mc")) + ret = tee_load_video_fw((u32)VIDEO_DEC_FORMAT_H263); + break; + } + return ret; +} +EXPORT_SYMBOL(optee_load_fw); + s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def) { - return am_loadmc_ex(type, name, def, &amvdec_loadmc); + if (is_secload_get()) + return optee_load_fw(type, name); + else + return am_loadmc_ex(type, name, def, &amvdec_loadmc); } EXPORT_SYMBOL(amvdec_loadmc_ex); + s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def) { return am_vdec_loadmc_ex(vdec, name, def, &amvdec_loadmc); @@ -559,11 +617,15 @@ static s32 amhevc_loadmc(const u32 *p) s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def) { if (has_hevc_vdec()) - return am_loadmc_ex(type, name, def, &amhevc_loadmc); + if (is_secload_get()) + return optee_load_fw(type, name); + else + return am_loadmc_ex(type, name, def, &amhevc_loadmc); else return 0; } EXPORT_SYMBOL(amhevc_loadmc_ex); + s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def) { if (has_hevc_vdec()) @@ -812,7 +874,7 @@ int amvdec_suspend(struct platform_device *dev, pm_message_t event) if (has_hevc_vdec()) amhevc_pg_enable(false); - + /*vdec_set_suspend_clk(1, 0);*//*DEBUG_TMP*/ return 0; } EXPORT_SYMBOL(amvdec_suspend); @@ -830,23 +892,27 @@ int amvdec_resume(struct platform_device *dev) if (has_hevc_vdec()) amhevc_pg_enable(true); /* #endif */ - + /*vdec_set_suspend_clk(0, 0);*//*DEBUG_TMP*/ return 0; } EXPORT_SYMBOL(amvdec_resume); int amhevc_suspend(struct platform_device *dev, pm_message_t event) { - if (has_hevc_vdec()) + if (has_hevc_vdec()) { amhevc_pg_enable(false); + /*vdec_set_suspend_clk(1, 1);*//*DEBUG_TMP*/ + } return 0; } EXPORT_SYMBOL(amhevc_suspend); int amhevc_resume(struct platform_device *dev) { - if (has_hevc_vdec()) + if (has_hevc_vdec()) { amhevc_pg_enable(true); + /*vdec_set_suspend_clk(0, 1);*//*DEBUG_TMP*/ + } return 0; } EXPORT_SYMBOL(amhevc_resume); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/decoder_bmmu_box.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/decoder_bmmu_box.c index 892f11f09189..6fb7ccbf9c19 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/decoder_bmmu_box.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/decoder_bmmu_box.c @@ -318,8 +318,10 @@ int decoder_bmmu_box_alloc_buf_phy( decoder_bmmu_box_get_phy_addr( handle, idx); - pr_info("%s malloc buf_idx = %d addr = %ld size = %d\n", - driver_name, idx, *buf_phy_addr, size); + /* + *pr_info("%s malloc buf_idx = %d addr = %ld size = %d\n", + * driver_name, idx, *buf_phy_addr, size); + */ } else { pr_info("%s malloc failed %d\n", driver_name, idx); return -ENOMEM; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c index 8a45be1d32c7..a1be82c750f6 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c @@ -65,6 +65,7 @@ #include #include #include "secprot.h" +#include static DEFINE_MUTEX(vdec_mutex); @@ -77,7 +78,7 @@ static int keep_vdec_mem; static unsigned int debug_trace_num = 16 * 20; static int step_mode; static unsigned int clk_config; - +static int is_secload; static int hevc_max_reset_count; #define MAX_INSTANCE_MUN 9 @@ -221,6 +222,16 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) } EXPORT_SYMBOL(vdec_set_trickmode); +int vdec_set_isreset(struct vdec_s *vdec, int isreset) +{ + vdec->is_reset = isreset; + pr_info("is_reset=%d\n", isreset); + if (vdec->set_isreset) + return vdec->set_isreset(vdec, isreset); + return 0; +} +EXPORT_SYMBOL(vdec_set_isreset); + void vdec_count_info(struct vdec_info *vs, unsigned int err, unsigned int offset) { @@ -1456,10 +1467,12 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) if (vdec_core->hint_fr_vdec == vdec) { if (p->sys_info->rate != 0) { - vf_notify_receiver(p->vf_provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long)p->sys_info->rate)); + if (!vdec->is_reset) + vf_notify_receiver(p->vf_provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long) + p->sys_info->rate)); vdec->fr_hint_state = VDEC_HINTED; } else { vdec->fr_hint_state = VDEC_NEED_HINT; @@ -1493,7 +1506,8 @@ void vdec_release(struct vdec_s *vdec) if (vdec->vframe_provider.name) { if (!vdec_single(vdec)) { if (vdec_core->hint_fr_vdec == vdec - && vdec->fr_hint_state == VDEC_HINTED) + && vdec->fr_hint_state == VDEC_HINTED + && !vdec->is_reset) vf_notify_receiver( vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -1679,7 +1693,10 @@ static inline bool vdec_ready_to_run(struct vdec_s *vdec) if ((vdec->slave || vdec->master) && (vdec->sched == 0)) return false; - + /* check frame based input underrun */ + if (input && input_frame_based(input) && + (!vdec_input_next_chunk(input))) + return false; /* check streaming prepare level threshold if not EOS */ if (input && input_stream_based(input) && !input->eos) { u32 rp, wp, level; @@ -3019,7 +3036,6 @@ static ssize_t dump_vdec_chunks_show(struct class *class, return pbuf - buf; } -#if 0 /*DEBUG_TMP*/ static ssize_t dump_decoder_state_show(struct class *class, struct class_attribute *attr, char *buf) { @@ -3043,7 +3059,35 @@ static ssize_t dump_decoder_state_show(struct class *class, return pbuf - buf; } -#endif + +int is_secload_get(void) +{ + return is_secload; +} +EXPORT_SYMBOL(is_secload_get); + +static ssize_t is_secload_show(struct class *cla, + struct class_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", is_secload ? 1 : 0); +} + +static ssize_t is_secload_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + size_t r; + int value; + + r = sscanf(buf, "%d", &value); + + if (r != 1) + return -EINVAL; + + is_secload = value & tee_enabled(); + return count; +} static struct class_attribute vdec_class_attrs[] = { __ATTR_RO(amrisc_regs), @@ -3059,6 +3103,9 @@ static struct class_attribute vdec_class_attrs[] = { __ATTR_RO(vdec_status), __ATTR_RO(dump_vdec_blocks), __ATTR_RO(dump_vdec_chunks), + __ATTR_RO(dump_decoder_state), + __ATTR(is_secload, S_IRUGO | S_IWUSR | S_IWGRP, is_secload_show, + is_secload_store), __ATTR_NULL }; @@ -3166,7 +3213,6 @@ static const struct of_device_id amlogic_vdec_dt_match[] = { }; static struct mconfig vdec_configs[] = { - MC_PI32("debugflags", &debugflags), MC_PU32("debug_trace_num", &debug_trace_num), MC_PI32("hevc_max_reset_count", &hevc_max_reset_count), MC_PU32("clk_config", &clk_config), @@ -3246,9 +3292,6 @@ module_param(hevc_max_reset_count, int, 0664); module_param(clk_config, uint, 0664); module_param(step_mode, int, 0664); -module_param(debugflags, uint, 0664); -MODULE_PARM_DESC(debugflags, "\n vdec debugflags\n"); - /* *module_init(vdec_module_init); *module_exit(vdec_module_exit); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h index c3d785e5bc8f..7c86d0e0ae54 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h @@ -193,12 +193,14 @@ struct vdec_s { bool use_vfm_path; char config[PAGE_SIZE]; int config_len; + bool is_reset; /* canvas */ int (*get_canvas)(unsigned int index, unsigned int base); int (*dec_status)(struct vdec_s *vdec, struct vdec_info *vstatus); int (*set_trickmode)(struct vdec_s *vdec, unsigned long trickmode); + int (*set_isreset)(struct vdec_s *vdec, int isreset); bool (*run_ready)(struct vdec_s *vdec); void (*run)(struct vdec_s *vdec, @@ -320,6 +322,8 @@ extern int vdec_status(struct vdec_s *vdec, struct vdec_info *vstatus); extern int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode); +extern int vdec_set_isreset(struct vdec_s *vdec, int isreset); + extern void vdec_set_flag(struct vdec_s *vdec, u32 flag); extern void vdec_set_eos(struct vdec_s *vdec, bool eos); @@ -341,8 +345,11 @@ extern bool vdec_need_more_data(struct vdec_s *vdec); extern void hevc_reset_core(struct vdec_s *vdec); +extern void vdec_set_suspend_clk(int mode, int hevc); + int vdec_get_debug_flags(void); unsigned char is_mult_inc(unsigned int); +int is_secload_get(void); #endif /* VDEC_H */ diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_input.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_input.c index 9626c5160195..99a6eeaa8bad 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_input.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_input.c @@ -44,6 +44,7 @@ #define MIN_FRAME_PADDING_SIZE ((u32)(L1_CACHE_BYTES)) +#define EXTRA_PADDING_SIZE (16 * SZ_1K) /*HEVC_PADDING_SIZE*/ #define MEM_NAME "VFRAME_INPUT" static int vdec_input_get_duration_u64(struct vdec_input_s *input); @@ -149,7 +150,9 @@ static void vframe_block_free_block(struct vframe_block_list_s *block) if (block->addr) { codec_mm_free_for_dma(MEM_NAME, block->addr); } - pr_err("free block %d, size=%d\n", block->id, block->size); + /* + *pr_err("free block %d, size=%d\n", block->id, block->size); + */ kfree(block); } @@ -277,9 +280,11 @@ int vdec_input_dump_blocks(struct vdec_input_s *input, char sbuf[256]; int s = 0; + if (size <= 0) + return 0; if (!bufs) lbuf = sbuf; - s += sprintf(lbuf + s, + s += snprintf(lbuf + s, size - s, "blocks:vdec-%d id:%d,bufsize=%d,dsize=%d,frames:%d,dur:%dms\n", input->id, input->block_nums, @@ -299,15 +304,21 @@ int vdec_input_dump_blocks(struct vdec_input_s *input, list_for_each_safe(p, tmp, &input->vframe_block_list) { struct vframe_block_list_s *block = list_entry( p, struct vframe_block_list_s, list); - if (bufs != NULL) + if (bufs != NULL) { lbuf = bufs + s; + if (size - s < 128) + break; + } s += vdec_input_dump_block_locked(block, lbuf, size - s); } list_for_each_safe(p, tmp, &input->vframe_block_free_list) { struct vframe_block_list_s *block = list_entry( p, struct vframe_block_list_s, list); - if (bufs != NULL) + if (bufs != NULL) { lbuf = bufs + s; + if (size - s < 128) + break; + } s += vdec_input_dump_block_locked(block, lbuf, size - s); } vdec_input_unlock(input, flags); @@ -363,10 +374,11 @@ int vdec_input_dump_chunks(struct vdec_input_s *input, char *lbuf = bufs; char sbuf[256]; int s = 0; - + if (size <= 0) + return 0; if (!bufs) lbuf = sbuf; - s += sprintf(lbuf + s, + snprintf(lbuf + s, size - s, "blocks:vdec-%d id:%d,bufsize=%d,dsize=%d,frames:%d,maxframe:%d\n", input->id, input->block_nums, @@ -515,11 +527,13 @@ static struct vframe_block_list_s * vdec_input_add_block(input, block); - pr_info("vdec-%d:new block id=%d, total_blocks:%d, size=%d\n", - input->id, - block->id, - input->block_nums, - block->size); + /* + *pr_info("vdec-%d:new block id=%d, total_blocks:%d, size=%d\n", + * input->id, + * block->id, + * input->block_nums, + * block->size); + */ if (0 && input->size > VFRAME_BLOCK_MAX_LEVEL * 2) { /* used @@ -726,7 +740,7 @@ int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, } if (!block) {/*try new block.*/ int ret = vdec_input_get_free_block(input, - count + need_pading_size, + count + need_pading_size + EXTRA_PADDING_SIZE, &block); if (ret < 0)/*no enough block now.*/ return ret; @@ -899,8 +913,6 @@ void vdec_input_release(struct vdec_input_s *input) p, struct vframe_chunk_s, list); vdec_input_release_chunk(input, chunk); } - - /* release input blocks */ list_for_each_safe(p, tmp, &input->vframe_block_list) { /*should never here.*/ list_move_tail(p, &input->vframe_block_free_list); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c index d66d75cf9fdb..8efcf771fb62 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c @@ -134,6 +134,7 @@ static u32 pts_by_offset = 1; static u32 total_frame; static u32 next_pts; static u64 next_pts_us64; +static bool is_reset; #ifdef DEBUG_PTS static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; @@ -735,6 +736,12 @@ int vvc1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vvc1_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + static int vvc1_vdec_info_init(void) { gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); @@ -1072,8 +1079,11 @@ static s32 vvc1_init(void) vf_reg_provider(&vvc1_vf_prov); #endif - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vvc1_amstream_dec_info.rate)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)vvc1_amstream_dec_info.rate)); stat |= STAT_VF_HOOK; @@ -1105,6 +1115,8 @@ static int amvdec_vc1_probe(struct platform_device *pdev) vvc1_amstream_dec_info = *pdata->sys_info; pdata->dec_status = vvc1_dec_status; + pdata->set_isreset = vvc1_set_isreset; + is_reset = 0; vvc1_vdec_info_init(); @@ -1136,8 +1148,10 @@ static int amvdec_vc1_remove(struct platform_device *pdev) } if (stat & STAT_VF_HOOK) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, + NULL); vf_unreg_provider(&vvc1_vf_prov); stat &= ~STAT_VF_HOOK; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index 5691dbcb1f27..53634654433a 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -362,7 +362,7 @@ typedef unsigned short u16; #endif static u32 debug; - +static bool is_reset; /*for debug*/ /* udebug_flag: @@ -1314,6 +1314,7 @@ struct VP9Decoder_s { int new_frame_displayed; void *mmu_box; void *bmmu_box; + struct vframe_master_display_colour_s vf_dp; struct firmware_s *fw; int max_pic_w; int max_pic_h; @@ -1322,7 +1323,7 @@ struct VP9Decoder_s { static int vp9_print(struct VP9Decoder_s *pbi, int flag, const char *fmt, ...) { -#define HEVC_PRINT_BUF 128 +#define HEVC_PRINT_BUF 256 unsigned char buf[HEVC_PRINT_BUF]; int len = 0; if (pbi == NULL || @@ -1393,7 +1394,7 @@ static int get_double_write_mode(struct VP9Decoder_s *pbi) pbi->double_write_mode : double_write_mode; } #endif - +#define MAX_4K_NUM 0x1200 #ifdef VP9_10B_MMU int vp9_alloc_mmu( struct VP9Decoder_s *pbi, @@ -1410,6 +1411,11 @@ int vp9_alloc_mmu( picture_size = compute_losless_comp_body_size(pic_width, pic_height, bit_depth_10); cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12); + if (cur_mmu_4k_number > MAX_4K_NUM) { + pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n", + cur_mmu_4k_number, pic_width, pic_height); + return -1; + } return decoder_mmu_box_alloc_idx( pbi->mmu_box, cur_buf_idx, @@ -5138,9 +5144,6 @@ static int vp9_local_init(struct VP9Decoder_s *pbi) pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param) & 0x40) >> 6; - pbi->video_signal_type = 0; - video_signal_type = pbi->video_signal_type; - if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) { pbi->rpm_addr = kmalloc(RPM_BUF_SIZE, GFP_KERNEL); if (pbi->rpm_addr == NULL) { @@ -5338,6 +5341,8 @@ static void set_frame_info(struct VP9Decoder_s *pbi, struct vframe_s *vf) vf->duration = pbi->frame_dur; vf->duration_pulldown = 0; vf->flag = 0; + vf->prop.master_display_colour = pbi->vf_dp; + vf->signal_type = pbi->video_signal_type; ar = min_t(u32, pbi->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX); vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); @@ -6446,6 +6451,12 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) return 0; } +int vvp9_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + #if 0 static void VP9_DECODE_INIT(void) { @@ -6669,9 +6680,9 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi) pbi); vf_reg_provider(&vvp9_vf_prov); vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)pbi->frame_dur)); + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long)pbi->frame_dur)); pbi->stat |= STAT_VF_HOOK; @@ -6722,8 +6733,10 @@ static int vvp9_stop(struct VP9Decoder_s *pbi) } if (pbi->stat & STAT_VF_HOOK) { - vf_notify_receiver(pbi->provider_name, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + if (!is_reset) + vf_notify_receiver(pbi->provider_name, + VFRAME_EVENT_PROVIDER_FR_END_HINT, + NULL); vf_unreg_provider(&vvp9_vf_prov); pbi->stat &= ~STAT_VF_HOOK; @@ -6859,6 +6872,8 @@ static int amvdec_vp9_probe(struct platform_device *pdev) cma_dev = pdata->cma_dev; #endif pdata->dec_status = vvp9_dec_status; + pdata->set_isreset = vvp9_set_isreset; + is_reset = 0; if (vvp9_init(pbi) < 0) { pr_info("\namvdec_vp9 init failed.\n"); @@ -7404,6 +7419,8 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; int ret; int config_val; + struct vframe_content_light_level_s content_light_level; + struct vframe_master_display_colour_s vf_dp; struct BUF_s BUF[MAX_BUF_NUM]; struct VP9Decoder_s *pbi = NULL; @@ -7414,6 +7431,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) } /*pbi = (struct VP9Decoder_s *)devm_kzalloc(&pdev->dev, sizeof(struct VP9Decoder_s), GFP_KERNEL);*/ + memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s)); pbi = vmalloc(sizeof(struct VP9Decoder_s)); memset(pbi, 0, sizeof(struct VP9Decoder_s)); if (pbi == NULL) { @@ -7452,6 +7470,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); pbi->platform_dev = pdev; + pbi->video_signal_type = 0; #if 1 if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config && pdata->config_len) { @@ -7474,6 +7493,44 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) pbi->max_pic_h = config_val; } #endif + if (get_config_int(pdata->config, "HDRStaticInfo", + &vf_dp.present_flag) == 0 + && vf_dp.present_flag == 1) { + get_config_int(pdata->config, "mG.x", + &vf_dp.primaries[0][0]); + get_config_int(pdata->config, "mG.y", + &vf_dp.primaries[0][1]); + get_config_int(pdata->config, "mB.x", + &vf_dp.primaries[1][0]); + get_config_int(pdata->config, "mB.y", + &vf_dp.primaries[1][1]); + get_config_int(pdata->config, "mR.x", + &vf_dp.primaries[2][0]); + get_config_int(pdata->config, "mR.y", + &vf_dp.primaries[2][1]); + get_config_int(pdata->config, "mW.x", + &vf_dp.white_point[0]); + get_config_int(pdata->config, "mW.y", + &vf_dp.white_point[1]); + get_config_int(pdata->config, "mMaxDL", + &vf_dp.luminance[0]); + get_config_int(pdata->config, "mMinDL", + &vf_dp.luminance[1]); + vf_dp.content_light_level.present_flag = 1; + get_config_int(pdata->config, "mMaxCLL", + &content_light_level.max_content); + get_config_int(pdata->config, "mMaxFALL", + &content_light_level.max_pic_average); + vf_dp.content_light_level = content_light_level; + pbi->video_signal_type = (1 << 29) + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /* color available */ + | (9 << 16) /* 2020 */ + | (16 << 8) /* 2084 */ + | (9 << 0); /* 2020 */ + } + pbi->vf_dp = vf_dp; } else #endif { @@ -7482,6 +7539,8 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) pbi->vvp9_amstream_dec_info.rate = 30;*/ pbi->double_write_mode = double_write_mode; } + video_signal_type = pbi->video_signal_type; + #if 0 pbi->buf_start = pdata->mem_start; pbi->buf_size = pdata->mem_end - pdata->mem_start + 1; diff --git a/drivers/amlogic/media_modules/stream_input/amports/amstream.c b/drivers/amlogic/media_modules/stream_input/amports/amstream.c index c9259b56fe39..7dfb6ec7c9ec 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amstream.c +++ b/drivers/amlogic/media_modules/stream_input/amports/amstream.c @@ -66,10 +66,7 @@ #include #include #include "../parser/thread_rw.h" - - #include - #include #include #include @@ -91,6 +88,8 @@ u32 amstream_port_num; u32 amstream_buf_num; +u32 amstream_audio_reset = 0; + #if 0 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV #define NO_VDEC2_INIT 1 @@ -557,6 +556,7 @@ static void video_port_release(struct port_priv_s *priv, { struct stream_port_s *port = priv->port; struct vdec_s *vdec = priv->vdec; + struct vdec_s *slave = NULL; bool is_multidec = !vdec_single(vdec); switch (release_num) { @@ -570,8 +570,10 @@ static void video_port_release(struct port_priv_s *priv, /*fallthrough*/ case 3: if (vdec->slave) - vdec_release(vdec->slave); + slave = vdec->slave; vdec_release(vdec); + if (slave) + vdec_release(slave); priv->vdec = NULL; /*fallthrough*/ case 2: @@ -696,6 +698,8 @@ static void audio_port_release(struct stream_port_s *port, case 1: ; } + amstream_audio_reset = 0; + return; } static int audio_port_reset(struct stream_port_s *port, @@ -737,7 +741,7 @@ static int audio_port_reset(struct stream_port_s *port, #endif pbuf->flag |= BUF_FLAG_IN_USE; - + amstream_audio_reset = 1; pts_start(PTS_TYPE_AUDIO); return 0; @@ -818,16 +822,14 @@ static void sub_port_release(struct stream_port_s *port, static int sub_port_init(struct stream_port_s *port, struct stream_buf_s *pbuf) { int r; - + r = stbuf_init(pbuf, NULL, false); + if (r < 0) + return r; if ((port->flag & PORT_FLAG_SID) == 0) { pr_err("subtitle id not set\n"); return 0; } - r = stbuf_init(pbuf, NULL, false); - if (r < 0) - return r; - if ((port->sid == 0xffff) && ((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) { /* es sub */ @@ -1652,9 +1654,9 @@ static int amstream_release(struct inode *inode, struct file *file) { struct port_priv_s *priv = file->private_data; struct stream_port_s *port = priv->port; + struct vdec_s *slave = NULL; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC u32 port_flag = 0; - u32 is_4k = 0; #endif if (iminor(inode) >= amstream_port_num) @@ -1669,13 +1671,11 @@ static int amstream_release(struct inode *inode, struct file *file) #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC port_flag = priv->vdec->port_flag; #endif - if ((priv->vdec->sys_info->height * - priv->vdec->sys_info->width) > 1920*1088) - is_4k = 1; if (priv->vdec->slave) - vdec_release(priv->vdec->slave); - + slave = priv->vdec->slave; vdec_release(priv->vdec); + if (slave) + vdec_release(slave); priv->vdec = NULL; } @@ -1714,7 +1714,7 @@ static int amstream_release(struct inode *inode, struct file *file) #else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX && port->vformat == VFORMAT_H264 - && is_4k) + && bufs[BUF_TYPE_VIDEO].for_4k) vdec_poweroff(VDEC_HEVC); if ((port->vformat == VFORMAT_HEVC @@ -2195,7 +2195,10 @@ static long amstream_ioctl_set(struct port_priv_s *priv, ulong arg) else r = -EINVAL; break; - + case AMSTREAM_SET_IS_RESET: + if (priv->vdec) + vdec_set_isreset(priv->vdec, parm.data_32); + break; default: r = -ENOIOCTLCMD; break; @@ -3805,6 +3808,11 @@ int get_sub_type(void) return sub_type; } +u32 get_audio_reset(void) +{ + return amstream_audio_reset; +} + /*get pes buffers */ struct stream_buf_s *get_stream_buffer(int id) diff --git a/drivers/amlogic/media_modules/stream_input/parser/tsdemux.c b/drivers/amlogic/media_modules/stream_input/parser/tsdemux.c index 8046f39bed3b..5521b40ccaba 100644 --- a/drivers/amlogic/media_modules/stream_input/parser/tsdemux.c +++ b/drivers/amlogic/media_modules/stream_input/parser/tsdemux.c @@ -67,8 +67,6 @@ static int demux_skipbyte; static struct tsdemux_ops *demux_ops; static DEFINE_SPINLOCK(demux_ops_lock); -#define ENABLE_DEMUX_DRIVER 1 - static int enable_demux_driver(void) { #ifdef ENABLE_DEMUX_DRIVER @@ -156,10 +154,8 @@ static int tsdemux_set_vid(int vpid) int r = 0; spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_vid) { - pr_info("set demux vpid[%d]\r\n", vpid); + if (demux_ops && demux_ops->set_vid) r = demux_ops->set_vid(vpid); - } spin_unlock_irqrestore(&demux_ops_lock, flags); return r; @@ -171,10 +167,8 @@ static int tsdemux_set_aid(int apid) int r = 0; spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_aid) { - pr_info("set demux apid[%d]\r\n", apid); + if (demux_ops && demux_ops->set_aid) r = demux_ops->set_aid(apid); - } spin_unlock_irqrestore(&demux_ops_lock, flags); return r; @@ -186,10 +180,8 @@ static int tsdemux_set_sid(int spid) int r = 0; spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_sid) { - pr_info("set demux spid[%d]\r\n", spid); + if (demux_ops && demux_ops->set_sid) r = demux_ops->set_sid(spid); - } spin_unlock_irqrestore(&demux_ops_lock, flags); return r; diff --git a/firmware/video/video_ucode.bin b/firmware/video/video_ucode.bin index 9f7753efa680b98279d56f76c61810ada6e34d32..276f0ade7d3f0ab19d7ec67d47037c9581426c18 100644 GIT binary patch delta 4773 zcmcJSdvsOB6^CcPWt_j1*q0h{&*OJs)8EF>)+XAI&%^Rgi6s4 zOcRC$(i{QGWKYtF2jF95Gn}*s;RqlrcEZ1cQa~}lshR-!ew1yTbCaMEaeN6io`;*D zj83~v<+3#F3e}Wb0O_b!QE34rq531$7C`p|wg+s>U586^m|m-LptRieq@sfba2VBN z)HGGQC(0=85jck8ZHg;|oUnWcnx&}hD9t_RS6FH_O)b>+#X_nrgxpwJi+0dr{)ufR zSHGn*g^-18IrS=nhf!8jZ4qRJ#cZ_qYpEE_@??FKjub&ck}5_!*OljR( zumpN@SP^wDhVCdUDYqD^%G5K^tW%Trqsi2MPxtnto;90oy8CL@Z>l$LYrBhM^}Gu7 z*8H`%k5C6`?i(Pvt-~m$nD$+Rg;Cj2nQEbDpBdiz0aqhEE-IVH>3)t0@daQ9FQwrG zs+tD*s17>kra>K`7PW4=7FE3NES~|Z5XD{8e>Rk$3eoGcAu~>W0`^|*;oiQ|+{;#4 z!JR8C`3+%-dw?wJUIH~f0Z6|uf$3p+2JH2*(hRT_JkTCED{@B6(MJRn6@>6k6pvFw z2(z3mrO**+aXCbi7*lqzE%2a`%@>}3lL!4i&X{0s(Yb$7yVm<@O12;-@xb|vTXBne(U?ovQ zxek~(Nk_^d!D5HYYE`m723j9Ivz+FBbI9pxPCY{DFgrM`~64*Vq{wVmtU-($>i8V(rkmcCb zCd+Y67B)Xh7L6H;Re5L;{amzso%+##Cky+~Ba7JXlBFwT(5@3MIBMziIOv6Jt&{$( zOBVSW<)747S1zK)lX`-hOJ~MI|FC$xC0f)oG~$##H)@WP_BR(TYNiwZ&P59w;#B?J zMT>|y=gzuliAZXkqObXi3Oen!pFc%u1zPaPv&(WZ9p(0ArKn^2!LnNHo}k{nG+RXD zvV(XSoIOvqKFp03Tfaw(J{B4+ec^X5 zSti0ds`X=5m@RGz7V!if@nb@gd+A-Uu%kZ)i<(cJ4bebEbQqhSf)XIf-1f=S;S0$Nh0oaI5( zU}5*UV3`A5=ye-2ua(Ds%oTx1zBZVOvXcuIg7&nl4K9xni#^9xHPCf)AU>=D*n%^n z*yYS82v5<}5ayz+a5QJ)5LG|=pdIG6jv9IT|AHD(b1`ZXgNHoQh(l4*)LcxOGVJiG z$B;cYNHeG;4^}ahj!T`fu$6jM=&QBah0aWPkv^z^zM(ZOnZs67X*{MOyT^kLn|uK} ziBafuxB#8AKMkEl=i$P3$EIoCDW z!GAd>Tk%pKpk^=K9JqeeWz_=zi^X@YhD9Bl?|tlVT*cTl@A?75pY6}uv-j(ol}5C> zSY=#Bbs={Lr*1EQPv*06rjWR|km8i^g0<+Go#6*mXp&W9GtpgGv)l8V+EgHXIk^=pkL zog$X6GunZ4maQ{B)DL|+O&UmtuSm5=QZnaR% z4C!jA!W)w`VVm)?rDjLXlu*Je#;4lDf4pLBL$;kZZ8!46>{{g;}qG6UiPYpDL8h1E4~pZ?ll?1dpz z|E94DWe$x|#t2}}T4i+AuW*vHf0wa33`3ma_l*Uy^@ohhc~n|Cxsm97TRFE6IDxN> zvk`y44B4l~LRaA8#jCT9x{YDqR!|i&5s#7-`b+&U_ZKCdyCYNo_@qSFo7wr@Kq->VDVt zOJcpe!QHxYF?G?UqsUmgHzsbQZ&Uc;pjg0diz$7L{@jJPYa`3Pw<8Hs`L!tKQ9>#o zs3V-0%J0+>-k8cC(p8TWPUH829-h>d|Fe@QDQ!L`s$5;O`}`(r-%f^Rx7)e-R>YE2 zem$QYql&yKvVd2=Ffuh!_UCqt*uqVri>kYqaPy$FWI?GdC-LgfM#j+{-Q3mhp@+Ni z+>m^W**)qI&0ko-K$!U@z1@xXT^b40cjsM9l*6m79{17Q4Bk6V4lwPZsmgQ}tL&mL zq2UXt!A?^Ke@WL4NzRO0co=-@XleD>^jrv6zm%Q=vDN$26P@^;{F_u%`^Xy04})+{ RjOE)*RPCH~5AiW^{{}X|=A!@r delta 4764 zcmb`K4OCTC7RS%t@7;Ufd)ye`OG&Ws;Rh%Mg5?)Xcn}L?MzW7-QU{Wpa;2c4=>U#! z&>*rR;U(K##fYhyjY(+Sl_j05#fZ~X)=bTEzHQPO8ZFD5YRu-`cONN}MYEK}T6>-I z_WhrI_BrQw_7Nvy#fez+2RYd@ScT5+Pq;EIbO2AZLjf3*=8nB`T>9Kb|G-c=1}9Em zv@n>rv^bbPA(%csW1RY*7#y3HK7mF4BJRCS#!4AGxV(7g&I3!+pxs?icEJQ&SER#E z_}Nb`v|^8|%>8JHL-Q;MDl>p4&W4fa9rc>C($HK0SGd^%m)YnaK{wy(PVug;G{YIY zidKIJ?~jx&bJPK@zgy3|!v{%Y_zN?*;Tr4;g``6Fn0eat;?fY8M{`rL(?@Gy;c<2-1f zmNLi)u)EQG&CV8-hn4su>M4V`cu|68zUt>k%FQn&^GrLn!N<|@kqcLt!>nBH@xa4t3JxB&iSon8X%YSo^n z_N8`8pS9L6gN=ydddf0!IheG&0>;LOx54aI0d{8!qnow*yf3MV_YhX9r0XX~Eep{T!rT9ilV zU=1WE$`4pLf%{af`$VhHliljGPlrz}m^@N#!rjcnk5KYTh>v3`S!c&uf0>F~sx6~i zorAC%hdf{HXk8%;uN1nsiJ{nCZ5AOjNYp|Kjjn|xl)LEZ!I%W?R9OqlP;R6ASj_Z4 z;e0GuxtXAn$F@*bot>~8x-)DSTMczk=t34n$L@ndWSW(~8kzv*`&QOajM1#LMtEa( zWANsVqu>Vj!`mlEH6QK8%CYZ)l}X=DSA~^7^wPEYLxmN&B7&6yNb#<5up%eX>H_FV z6mNYqSL6YQE3A#y7pgh(D`@X=n;YwFuuOo*t<;ZfuJBzn|6_G#<$cukvHD$<+gzFK zU)dKctby`Qs6E3ft;A1ktgvNP;NLb@c#hTdsf`sj#5#S-#>$*38!KaAl}(i~@PG}K zB%rnVn2Nk@Z576&{O#HnOpar(o*O9Qm9>ZPFiJuD0cY7KI1%v}@@|T8;k5zrdS9N% zCupHdiOXhcabbQm`{fy)@TchWQpiB@1dT6)JCU_giyJcnvaT;t*h=bgV_dv_+HIn+ zqhBYAsG?ySCL?R6d<~nbWvDMvM8&y@!WQ=>3JWm`6l7u)$R^O+7h}H7 znSsbYBfZ8xf#-=DwyuBFh{FzQ*x?9j)ardRYN`+f{p}vO*u$UuU%aSaZm=oCo(bbc zHILUqreALEix){(*C{VC!=_6T6!*eqa0D)aUbuXE1}+by6->gv-fAO8;CCt4`T>e6 z*TO)tt1Amu;dd#o`jO;kF{kFZ% z*5-_2me%ju^dF;2It@4FE>|P1+cg2WiSC z?Un>_s3KhJh<`bjF{#=rvR+HiZPFISijnFz@tGbuDsro2I+juPW^KqI?sJ*8W z{!q^?6<%YisWU3utmUBGLLHm6{lKYai*_+EYwZ^89raL1p@mzuI+SnF$*o$x3hSCD zwaLoVKB*=7#hd8psY}wBs!CvM&y!k?%g?r|8$pG^pK@*nPX6s$uKH@`cI|OB#24GO zfcJZ1&O?b80NBK&NZwiAUa z8K2eW2SkkXrHqZ(Buehku2tD7>(GwiI8p4B_i?H!ExAt{s)!W#qU7jYgBO)s!AKerYxyEUGrr0HX zkuO(S7Lebg6P;Q&Org#fwT;Mf>2|5*fv~nqElFMOL#?;>YL5qCidFeLtuDGT=;`>o z*6)4N|E3K_4o2&WiC}q-Xs3ei7k)42HXC~6WO(%RKN)=p;nN>=Z@1VldIR_v?yuhMydB|yfBQ# z66qhq^zu~EU1b`|BR5tWhI$qmSDX5;Qj~`%3O`NcTIWq@*wS6pFkH`y7vr41u%CKz z*$XUEoIW{`dWP$VlVz=L`k2(&jpgRPOldfpjxVb|qsiJrr-PRmHI8>^RKoX>=Y{S} zxE|9hLRLZ%%8x8xqJ9ggJyMjU{|99S6^_#5)Ly9=r7wu$WmVw~#!B?iFJ_F4Wm&oz z#oKiCST&~Iv_>}$2_Gv_K9n+AS46pq3PWCJw!YIqKG51SSDzL0Us2J{;s5{u