From 2f3f2d09aa3167a71d80426f968b3e85835bfd77 Mon Sep 17 00:00:00 2001 From: Rong Zhang Date: Mon, 8 Oct 2018 10:51:36 +0800 Subject: [PATCH] VDEC: AVS2 [1/2] PD#174425 Problem: Support AVS2 on G12A and GXLX2 for multi-instance Solution: 1. ucode support AVS2 HDR information push ucode gerrit id:47825 2. AVS2 C Driver support multi-instance 3. fix buffer leakage issue due to multi-task reentry 4. add stream buf empty check Verify: Verified U212 Change-Id: I28998ac9f7a66fa8738afdbc812bcc1ca7436b24 Signed-off-by: Rong Zhang --- .../common/chips/decoder_cpu_ver_info.c | 1 + .../common/media_clock/clk/clkg12.c | 5 + .../frame_provider/decoder/avs2/avs2_bufmgr.c | 114 +- .../frame_provider/decoder/avs2/avs2_global.h | 18 +- .../frame_provider/decoder/avs2/vavs2.c | 1420 ++++++++++++----- firmware/video/video_ucode.bin | Bin 957696 -> 957696 bytes 6 files changed, 1134 insertions(+), 424 deletions(-) diff --git a/drivers/amlogic/media_modules/common/chips/decoder_cpu_ver_info.c b/drivers/amlogic/media_modules/common/chips/decoder_cpu_ver_info.c index d91913623199..98e14773c76c 100644 --- a/drivers/amlogic/media_modules/common/chips/decoder_cpu_ver_info.c +++ b/drivers/amlogic/media_modules/common/chips/decoder_cpu_ver_info.c @@ -36,6 +36,7 @@ static enum AM_MESON_CPU_MAJOR_ID cpu_ver_info[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR AM_MESON_CPU_MAJOR_ID_TXHD, AM_MESON_CPU_MAJOR_ID_G12A, AM_MESON_CPU_MAJOR_ID_G12B, + AM_MESON_CPU_MAJOR_ID_GXLX2, AM_MESON_CPU_MAJOR_ID_TL1, }; diff --git a/drivers/amlogic/media_modules/common/media_clock/clk/clkg12.c b/drivers/amlogic/media_modules/common/media_clock/clk/clkg12.c index 5d6e26cacca9..79282a5bbfce 100644 --- a/drivers/amlogic/media_modules/common/media_clock/clk/clkg12.c +++ b/drivers/amlogic/media_modules/common/media_clock/clk/clkg12.c @@ -397,6 +397,11 @@ static struct clk_set_setting clks_for_formats[] = { 630}, {INT_MAX, 630}, } }, + {/*VFORMAT_AVS2*/ + {{1280*720*30, 100}, {1920*1080*30, 100}, + {1920*1080*60, 166}, {4096*2048*30, 333}, + {4096*2048*60, 630}, {INT_MAX, 630},} + }, }; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_bufmgr.c index df2adbb7d775..ecaae862f9fc 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_bufmgr.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_bufmgr.c @@ -481,6 +481,14 @@ void Get_I_Picture_Header(struct avs2_decoder *avs2_dec) hd->curr_RPS.num_to_remove = get_param(rpm_param->p.num_to_remove_cur, "num of removed picture"); +#ifdef SANITY_CHECK + if (hd->curr_RPS.num_to_remove > 8) { + hd->curr_RPS.num_to_remove = 8; + pr_info("Warning, %s: num_to_remove %d beyond range, force to 8\n", + __func__, hd->curr_RPS.num_to_remove); + } +#endif + for (j = 0; j < hd->curr_RPS.num_to_remove; j++) { hd->curr_RPS.remove_pic[j] = get_param( @@ -663,6 +671,13 @@ void Get_PB_Picture_Header(struct avs2_decoder *avs2_dec) get_param( rpm_param->p.num_to_remove_cur, "num of removed picture"); +#ifdef SANITY_CHECK + if (hd->curr_RPS.num_to_remove > 8) { + hd->curr_RPS.num_to_remove = 8; + pr_info("Warning, %s: num_to_remove %d beyond range, force to 8\n", + __func__, hd->curr_RPS.num_to_remove); + } +#endif for (j = 0; j < hd->curr_RPS.num_to_remove; j++) { hd->curr_RPS.remove_pic[j] = @@ -1065,12 +1080,14 @@ void prepare_RefInfo(struct avs2_decoder *avs2_dec) (avs2_dec->fref[0]->imgtr_fwRefDistance <= img->tr || avs2_dec->fref[1]->imgtr_fwRefDistance >= img->tr)) { - pr_info("wrong reference configuration for B frame"); + pr_info("wrong reference configuration for B frame\n"); pr_info( "fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, img->tr %d\n", avs2_dec->fref[0]->imgtr_fwRefDistance, avs2_dec->fref[1]->imgtr_fwRefDistance, img->tr); + hc->f_rec->error_mark = 1; + avs2_dec->bufmgr_error_flag = 1; return; /* exit(-1);*/ /*******************************************/ } @@ -1111,14 +1128,18 @@ void prepare_RefInfo(struct avs2_decoder *avs2_dec) && avs2_dec->fref[i]->bg_flag == 0 #ifndef NO_DISPLAY && avs2_dec->fref[i]->vf_ref == 0 - && avs2_dec->fref[i]->to_prepare_disp ==0 + && avs2_dec->fref[i]->to_prepare_disp == 0 #endif ) { break; } } - if (i == avs2_dec->ref_maxbuffer) + if (i == avs2_dec->ref_maxbuffer) { + pr_info( + "%s, warning, no enough buf\n", + __func__); i--; + } hc->f_rec = avs2_dec->fref[i]; hc->currentFrame = hc->f_rec->ref; @@ -1128,11 +1149,17 @@ void prepare_RefInfo(struct avs2_decoder *avs2_dec) hc->f_rec->temporal_id = hd->cur_layer; #endif hc->f_rec->is_output = 1; +#ifdef AML + hc->f_rec->error_mark = 0; + hc->f_rec->decoded_lcu = 0; + hc->f_rec->slice_type = img->type; +#endif hc->f_rec->refered_by_others = hd->curr_RPS.referd_by_others; if (is_avs2_print_bufmgr_detail()) pr_info( - "%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d\n", - __func__, i, img->tr, img->coding_order); + "%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d img_type %d\n", + __func__, i, img->tr, img->coding_order, + img->type); if (img->type != B_IMG) { for (j = 0; @@ -1181,24 +1208,24 @@ void prepare_RefInfo(struct avs2_decoder *avs2_dec) #if 1 /*rain*/ if (is_avs2_print_bufmgr_detail()) { - for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) { - pr_info( + for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) { + pr_info( "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, is_out %d, bg %d, vf_ref %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n", ii, avs2_dec->fref[ii]->index, avs2_dec->fref[ii]->imgcoi_ref, avs2_dec->fref[ii]->imgtr_fwRefDistance, - avs2_dec->fref[ii]->refered_by_others, - avs2_dec->fref[ii]->is_output, - avs2_dec->fref[ii]->bg_flag, - avs2_dec->fref[ii]->vf_ref, - avs2_dec->fref[ii]->ref_poc[0], - avs2_dec->fref[ii]->ref_poc[1], - avs2_dec->fref[ii]->ref_poc[2], - avs2_dec->fref[ii]->ref_poc[3], - avs2_dec->fref[ii]->ref_poc[4], - avs2_dec->fref[ii]->ref_poc[5], - avs2_dec->fref[ii]->ref_poc[6] - ); + avs2_dec->fref[ii]->refered_by_others, + avs2_dec->fref[ii]->is_output, + avs2_dec->fref[ii]->bg_flag, + avs2_dec->fref[ii]->vf_ref, + avs2_dec->fref[ii]->ref_poc[0], + avs2_dec->fref[ii]->ref_poc[1], + avs2_dec->fref[ii]->ref_poc[2], + avs2_dec->fref[ii]->ref_poc[3], + avs2_dec->fref[ii]->ref_poc[4], + avs2_dec->fref[ii]->ref_poc[5], + avs2_dec->fref[ii]->ref_poc[6] + ); } } #endif @@ -1270,7 +1297,7 @@ void flushDPB(struct avs2_decoder *avs2_dec) for (j = 0; j < search_times; j++) { pos = -1; tmp_min = (1 << 20); - //search for min poi picture to display + /*search for min poi picture to display*/ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) { if (avs2_dec->outprint.stdoutdata[i].tr < tmp_min) { pos = i; @@ -1281,20 +1308,23 @@ void flushDPB(struct avs2_decoder *avs2_dec) if (pos != -1) { hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr; report_frame(avs2_dec, &avs2_dec->outprint, pos); - if (avs2_dec->outprint.stdoutdata[pos].typeb == BACKGROUND_IMG && avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag == 0) { + if (avs2_dec->outprint.stdoutdata[pos].typeb + == BACKGROUND_IMG && + avs2_dec->outprint.stdoutdata[pos]. + background_picture_output_flag + == 0) { /*write_GB_frame(hd->p_out_background);*/ - } - else { - write_frame(avs2_dec, avs2_dec->outprint.stdoutdata[pos].tr); + } else { + write_frame(avs2_dec, + avs2_dec->outprint.stdoutdata[pos].tr); } delete_trbuffer(&avs2_dec->outprint, pos); } } - // clear dpb info - for (j = 0; j < REF_MAXBUFFER; j++) - { + /*clear dpb info*/ + for (j = 0; j < REF_MAXBUFFER; j++) { avs2_dec->fref[j]->imgtr_fwRefDistance = -256; avs2_dec->fref[j]->imgcoi_ref = -257; avs2_dec->fref[j]->temporal_id = -1; @@ -1310,19 +1340,19 @@ void cleanRefMVBufRef(int pos) { #if 0 int k, x, y; - //re-init mvbuf + /*re-init mvbuf*/ for (k = 0; k < 2; k++) { for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) { - for (x = 0; x < img->width / MIN_BLOCK_SIZE; x++) { + for (x = 0; x < img->width / MIN_BLOCK_SIZE; x++) fref[pos]->mvbuf[y][x][k] = 0; - } + } } - //re-init refbuf + /*re-init refbuf*/ for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) { - for (x = 0; x < img->width / MIN_BLOCK_SIZE ; x++) { + for (x = 0; x < img->width / MIN_BLOCK_SIZE ; x++) fref[pos]->refbuf[y][x] = -1; - } + } #endif } @@ -1510,6 +1540,7 @@ void write_frame(struct avs2_decoder *avs2_dec, int32_t pos) for (j = 0; j < avs2_dec->ref_maxbuffer; j++) { if (avs2_dec->fref[j]->imgtr_fwRefDistance == pos) { + avs2_dec->fref[j]->imgtr_fwRefDistance_bak = pos; avs2_dec->fref[j]->is_output = -1; avs2_dec->fref[j]->to_prepare_disp = avs2_dec->to_prepare_disp_count++; @@ -1523,7 +1554,8 @@ void write_frame(struct avs2_decoder *avs2_dec, int32_t pos) avs2_dec->fref[j]->temporal_id = -1; #endif if (is_avs2_print_bufmgr_detail()) - pr_info("%s, fref index %d\n", __func__, j); + pr_info("%s, fref index %d\n", + __func__, j); } break; } @@ -1689,6 +1721,7 @@ void avs2_prepare_header(struct avs2_decoder *avs2_dec, int32_t start_code) #endif img->number = 0; img->PrevPicDistanceLsb = 0; + avs2_dec->init_hw_flag = 0; } #endif @@ -1710,6 +1743,7 @@ void avs2_prepare_header(struct avs2_decoder *avs2_dec, int32_t start_code) #endif img->number = 0; img->PrevPicDistanceLsb = 0; + avs2_dec->init_hw_flag = 0; } #endif img->seq_header_indicate = 1; @@ -1772,6 +1806,8 @@ void avs2_prepare_header(struct avs2_decoder *avs2_dec, int32_t start_code) break; case SEQUENCE_END_CODE: + if (is_avs2_print_bufmgr_detail()) + pr_info("SEQUENCE_END_CODE\n"); #ifdef TO_CHECK #if SEQ_CHANGE_CHECKER if (seq_checker_buf != NULL) { @@ -1981,6 +2017,16 @@ int avs2_post_process(struct avs2_decoder *avs2_dec) /* delete the frame that will never be used*/ { int32_t i, j; + if (is_avs2_print_bufmgr_detail()) { + pr_info( + "%s, coding_order %d to remove %d buf: ", + __func__, + img->coding_order, + hd->curr_RPS.num_to_remove); + for (i = 0; i < hd->curr_RPS.num_to_remove; i++) + pr_info("%d ", hd->curr_RPS.remove_pic[i]); + pr_info("\n"); + } for (i = 0; i < hd->curr_RPS.num_to_remove; i++) { for (j = 0; j < avs2_dec->ref_maxbuffer; j++) { diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_global.h b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_global.h index 7f9cca4971c7..46ebc62c9949 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_global.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/avs2_global.h @@ -49,6 +49,7 @@ /* #include */ #define AML +#define SANITY_CHECK #undef NO_DISPLAY /* #include "define.h" */ @@ -792,6 +793,9 @@ struct avs2_frame_s { int vf_ref; int decode_idx; int slice_type; + int32_t imgtr_fwRefDistance_bak; + int32_t error_mark; + int32_t decoded_lcu; #endif #ifndef MV_USE_FIXED_BUF int mv_buf_index; @@ -1585,6 +1589,17 @@ union param_u { uint16_t chroma_quant_param_delta_cb; uint16_t chroma_quant_param_delta_cr; uint16_t loop_filter_disable; + + uint16_t video_signal_type; + uint16_t color_description; + uint16_t display_primaries_x[3]; + uint16_t display_primaries_y[3]; + uint16_t white_point_x; + uint16_t white_point_y; + uint16_t max_display_mastering_luminance; + uint16_t min_display_mastering_luminance; + uint16_t max_content_light_level; + uint16_t max_picture_average_light_level; } p; struct { uint16_t padding[ALF_BEGIN - RPM_BEGIN]; @@ -1629,7 +1644,8 @@ struct avs2_decoder { int32_t lcu_y_num; int32_t lcu_total; int32_t ref_maxbuffer; - int32_t to_prepare_disp_count; + int32_t to_prepare_disp_count; + int8_t bufmgr_error_flag; #endif }; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c index 17a6e5e022f3..c622ad00427b 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #define MIX_STREAM_SUPPORT - #define G12A_BRINGUP_DEBUG #include "vavs2.h" @@ -73,6 +73,7 @@ #define HEVC_SAO_MMU_VH0_ADDR 0x363a #define HEVC_SAO_MMU_STATUS 0x3639 + /* * AVS2_DEC_STATUS define */ @@ -140,8 +141,67 @@ #define PARSER_CMD_SKIP_CFG_2 0x001b1910 + #define PARSER_CMD_NUMBER 37 +static unsigned short parser_cmd[PARSER_CMD_NUMBER] = { +0x0401, +0x8401, +0x0800, +0x0402, +0x9002, +0x1423, +0x8CC3, +0x1423, +0x8804, +0x9825, +0x0800, +0x04FE, +0x8406, +0x8411, +0x1800, +0x8408, +0x8409, +0x8C2A, +0x9C2B, +0x1C00, +0x840F, +0x8407, +0x8000, +0x8408, +0x2000, +0xA800, +0x8410, +0x04DE, +0x840C, +0x840D, +0xAC00, +0xA000, +0x08C0, +0x08E0, +0xA40E, +0xFC00, +0x7C00 +}; + +static int32_t g_WqMDefault4x4[16] = { + 64, 64, 64, 68, + 64, 64, 68, 72, + 64, 68, 76, 80, + 72, 76, 84, 96 +}; + + +static int32_t g_WqMDefault8x8[64] = { + 64, 64, 64, 64, 68, 68, 72, 76, + 64, 64, 64, 68, 72, 76, 84, 92, + 64, 64, 68, 72, 76, 80, 88, 100, + 64, 68, 72, 80, 84, 92, 100, 112, + 68, 72, 80, 84, 92, 104, 112, 128, + 76, 80, 84, 92, 104, 116, 132, 152, + 96, 100, 104, 116, 124, 140, 164, 188, + 104, 108, 116, 128, 152, 172, 192, 216 +}; /*#define HEVC_PIC_STRUCT_SUPPORT*/ /* to remove, fix build error */ @@ -155,7 +215,7 @@ #endif #ifdef MULTI_INSTANCE_SUPPORT -#define MAX_DECODE_INSTANCE_NUM 9 +#define MAX_DECODE_INSTANCE_NUM 12 #define MULTI_DRIVER_NAME "ammvdec_avs2" #define lock_buffer(dec, flags) \ @@ -174,7 +234,7 @@ static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM]; static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM]; #ifdef G12A_BRINGUP_DEBUG -static u32 decode_timeout_val; +static u32 decode_timeout_val = 200; #else static u32 decode_timeout_val = 200; #endif @@ -186,6 +246,9 @@ static u32 work_buf_size = 32 * 1024 * 1024; #endif static u32 mv_buf_margin; +static int pre_decode_buf_level = 0x1000; +static u32 again_threshold = 0x40; + /* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */ /* double_write_mode: 0, no double write @@ -254,6 +317,14 @@ static u32 video_signal_type; static u32 pts_unstable; static u32 on_no_keyframe_skiped; +static u32 force_video_signal_type; +static u32 enable_force_video_signal_type; +#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000 + +static const char * const video_format_names[] = { + "component", "PAL", "NTSC", "SECAM", + "MAC", "unspecified", "Reserved", "Reserved" +}; #define PROB_SIZE (496 * 2 * 4) #define PROB_BUF_SIZE (0x5000) @@ -350,20 +421,25 @@ typedef unsigned short u16; #define AVS2_DBG_OUT_PTS 0x10 #define AVS2_DBG_PRINT_SOURCE_LINE 0x20 #define AVS2_DBG_PRINT_PARAM 0x40 +#define AVS2_DBG_PRINT_PIC_LIST 0x80 #define AVS2_DBG_SEND_PARAM_WITH_REG 0x100 #define AVS2_DBG_MERGE 0x200 #define AVS2_DBG_DBG_LF_PRINT 0x400 #define AVS2_DBG_REG 0x800 +#define AVS2_DBG_PIC_LEAK 0x1000 +#define AVS2_DBG_PIC_LEAK_WAIT 0x2000 +#define AVS2_DBG_HDR_INFO 0x4000 #define AVS2_DBG_DIS_LOC_ERROR_PROC 0x10000 #define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000 #define AVS2_DBG_DUMP_PIC_LIST 0x40000 #define AVS2_DBG_TRIG_SLICE_SEGMENT_PROC 0x80000 -#define AVS2_DBG_HW_RESET 0x100000 +#define AVS2_DBG_FORCE_UNCOMPRESS 0x100000 #define AVS2_DBG_LOAD_UCODE_FROM_FILE 0x200000 #define AVS2_DBG_FORCE_SEND_AGAIN 0x400000 #define AVS2_DBG_DUMP_DATA 0x800000 -#define AVS2_DBG_CACHE 0x1000000 -#define AVS2_DBG_CACHE_HIT_RATE 0x2000000 +#define AVS2_DBG_DUMP_LMEM_BUF 0x1000000 +#define AVS2_DBG_DUMP_RPM_BUF 0x2000000 +#define AVS2_DBG_CACHE 0x4000000 #define IGNORE_PARAM_FROM_CONFIG 0x8000000 /*MULTI_INSTANCE_SUPPORT*/ #define PRINT_FLAG_ERROR 0 @@ -372,11 +448,15 @@ typedef unsigned short u16; #define PRINT_FLAG_VDEC_DATA 0x80000000 #define PRINT_LINE() \ - if (debug & AVS2_DBG_PRINT_SOURCE_LINE)\ - pr_info("%s line %d\n", __func__, __LINE__) + do { \ + if (debug & AVS2_DBG_PRINT_SOURCE_LINE)\ + pr_info("%s line %d\n", __func__, __LINE__);\ + } while (0) static u32 debug; +static u32 debug_again; + bool is_avs2_print_param(void) { bool ret = false; @@ -451,16 +531,16 @@ static void WRITE_VREG_DBG2(unsigned adr, unsigned val) #define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) /*buffer + header buffer + workspace*/ #ifdef MV_USE_FIXED_BUF -#define MAX_BMMU_BUFFER_NUM (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1) +#define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1) #define VF_BUFFER_IDX(n) (n) -#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n) -#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS) +#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1) +#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1) #else -#define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS + 1) +#define MAX_BMMU_BUFFER_NUM (((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1) #define VF_BUFFER_IDX(n) (n) -#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n) -#define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n) -#define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS) +#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1) +#define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n+1) +#define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1) #endif /* static void set_canvas(struct AVS2Decoder_s *dec, @@ -561,8 +641,11 @@ struct AVS2Decoder_s { uint8_t init_flag; uint8_t process_busy; #define PROC_STATE_INIT 0 -#define PROC_STATE_DECODESLICE 1 -#define PROC_STATE_SENDAGAIN 2 +#define PROC_STATE_HEAD_DONE 1 +#define PROC_STATE_DECODING 2 +#define PROC_STATE_HEAD_AGAIN 3 +#define PROC_STATE_DECODE_AGAIN 4 +#define PROC_STATE_TEST1 5 uint8_t process_state; u32 ucode_pause_pos; @@ -599,6 +682,7 @@ struct AVS2Decoder_s { unsigned int losless_comp_body_size; u32 video_signal_type; + u32 video_ori_signal_type; int pts_mode; int last_lookup_pts; @@ -634,9 +718,11 @@ struct AVS2Decoder_s { int slice_idx; uint8_t wait_buf; uint8_t error_flag; + unsigned int bufmgr_error_count; /* bit 0, for decoding; bit 1, for displaying */ uint8_t ignore_bufmgr_error; + uint8_t skip_PB_before_I; int PB_skip_mode; int PB_skip_count_after_decoding; /*hw*/ @@ -663,6 +749,15 @@ struct AVS2Decoder_s { int32_t m_varIndTab[NO_VAR_BINS]; struct vframe_s vframe_dummy; + /* start_decoding_flag, + bit 0, SEQ ready + bit 1, I ready + */ + unsigned char start_decoding_flag; + uint32_t mpred_abv_start_addr; + uint32_t mpred_abv_start_addr_bak; + u8 next_again_flag; + u32 pre_parser_wr_ptr; }; @@ -731,14 +826,20 @@ static void start_process_time(struct AVS2Decoder_s *dec) dec->last_lcu_idx = 0; } +static void update_decoded_pic(struct AVS2Decoder_s *dec); + static void timeout_process(struct AVS2Decoder_s *dec) { + struct avs2_decoder *avs2_dec = &dec->avs2_dec; + struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic; dec->timeout_num++; amhevc_stop(); avs2_print(dec, 0, "%s decoder timeout\n", __func__); - + if (cur_pic) + cur_pic->error_mark = 1; dec->dec_result = DEC_RESULT_DONE; + update_decoded_pic(dec); reset_process_time(dec); vdec_schedule_work(&dec->work); } @@ -1001,6 +1102,7 @@ static int get_free_buf_count(struct AVS2Decoder_s *dec) && avs2_dec->fref[i]->bg_flag == 0 #ifndef NO_DISPLAY && avs2_dec->fref[i]->vf_ref == 0 + && avs2_dec->fref[i]->to_prepare_disp == 0 #endif ) { count++; @@ -1036,6 +1138,7 @@ int avs2_bufmgr_init(struct AVS2Decoder_s *dec, struct BuffInfo_s *buf_spec_i, /*int m_uiMaxCUHeight = 1<<7;*/ dec->wait_buf = 0; dec->error_flag = 0; + dec->skip_PB_before_I = 0; dec->pts_mode = PTS_NORMAL; dec->last_pts = 0; @@ -1050,6 +1153,7 @@ int avs2_bufmgr_init(struct AVS2Decoder_s *dec, struct BuffInfo_s *buf_spec_i, dec->buf_num = 0; + dec->bufmgr_error_count = 0; return 0; } @@ -1134,23 +1238,20 @@ static u32 max_decoding_time; error handling */ /*error_handle_policy: -bit 0: 0, auto skip error_skip_nal_count nals before error recovery; -1, skip error_skip_nal_count nals before error recovery; -bit 1 (valid only when bit0 == 1): -1, wait vps/sps/pps after error recovery; -bit 2 (valid only when bit0 == 0): -0, auto search after error recovery (avs2_recover() called); -1, manual search after error recovery -(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2)) - -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 0: search seq again if buffer mgr error occur + (buffer mgr error count need big than + re_search_seq_threshold) +bit 1: 1, display from I picture; + 0, display from any correct pic */ -static u32 error_handle_policy; +static u32 error_handle_policy = 1; +/* +re_search_seq_threshold: + bit 7~0: buffer mgr error research seq count + bit 15~8: frame count threshold +*/ +static u32 re_search_seq_threshold = 0x800; /*0x8;*/ /*static u32 parser_sei_enable = 1;*/ static u32 max_buf_num = (REF_BUFFER + 1); @@ -1161,7 +1262,7 @@ static DEFINE_MUTEX(vavs2_mutex); #define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 #define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 -#define AVS2_ALF_SWAP_BUFFER HEVC_ASSIST_SCRATCH_2 +#define AVS2_ALF_SWAP_BUFFER HEVC_ASSIST_SCRATCH_2 #define HEVC_RCS_BUFFER HEVC_ASSIST_SCRATCH_3 #define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4 #define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5 @@ -1208,15 +1309,20 @@ bit [17]: for NAL_SEI when bit0 is 0: bit [31:20]: used by ucode for debug purpose */ #define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I - /*set before start decoder*/ + /*DECODE_MODE: set before start decoder + bit 7~0: decode mode + bit 23~16: start_decoding_flag + bit [0] - SEQ_ready + bit [2:1] - I Picture Count + bit 31~24: chip feature + */ #define DECODE_MODE HEVC_ASSIST_SCRATCH_J #define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K - /*read only*/ #define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J -#define RPM_BUF_SIZE (0x400 * 2) -#define LMEM_BUF_SIZE (0x400 * 2) +#define RPM_BUF_SIZE (0x600 * 2) +#define LMEM_BUF_SIZE (0x600 * 2) #define WORK_BUF_SPEC_NUM 3 static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = { @@ -1412,68 +1518,87 @@ static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = { } }, { - .max_width = 4096*2, - .max_height = 2304*2, + .max_width = 4096 * 2, + .max_height = 2304 * 2, .ipp = { - // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k - .buf_size = 0x4000*2, + /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, + round to 16k*/ + .buf_size = 0x4000 * 2, }, .sao_abv = { - .buf_size = 0x30000*2, + .buf_size = 0x30000 * 2, }, .sao_vb = { - .buf_size = 0x30000*2, + .buf_size = 0x30000 * 2, }, .short_term_rps = { - // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800) + /*SHORT_TERM_RPS - Max 64 set, 16 entry every set, + total 64x16x2 = 2048 bytes (0x800)*/ .buf_size = 0x800, }, .rcs = { - // RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes + /*RCS STORE AREA - Max 16 RCS, each has 32 bytes, + total 0x0400 bytes*/ .buf_size = 0x400, }, .sps = { - // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes + /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, + total 0x0800 bytes*/ .buf_size = 0x800, }, .pps = { - // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes + /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total + 0x2000 bytes*/ .buf_size = 0x2000, }, .sao_up = { - // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes - .buf_size = 0x2800*2, + /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i + total 0x2800 bytes*/ + .buf_size = 0x2800 * 2, }, .swap_buf = { - // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid) + /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/ .buf_size = 0x800, }, - .swap_buf2 = { + .swap_buf2 = { .buf_size = 0x800, }, .scalelut = { - // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000) - .buf_size = 0x8000*2, + /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/ + .buf_size = 0x8000 * 2, + }, + .dblk_para = { + .buf_size = 0x40000 * 2, + }, + .dblk_data = { + .buf_size = 0x80000 * 2, + }, + .dblk_data2 = { + .buf_size = 0x80000 * 2, }, - .dblk_para = { .buf_size = 0x40000*2, }, - .dblk_data = { .buf_size = 0x80000*2, }, - .dblk_data2 = { .buf_size = 0x80000*2, }, #ifdef AVS2_10B_MMU .mmu_vbh = { - .buf_size = 0x5000*2, //2*16*2304/4, 4K + .buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/ }, .cm_header = { - .buf_size = MMU_COMPRESS_8K_HEADER_SIZE*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ + .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17, }, #endif .mpred_above = { - .buf_size = 0x8000*2, + .buf_size = 0x8000 * 2, }, +#ifdef MV_USE_FIXED_BUF .mpred_mv = { - .buf_size = 0x100000*16*4, //4k2k , 0x100000 per buffer + /*4k2k , 0x100000 per buffer*/ + .buf_size = 0x100000 * 16 * 4, }, +#endif .rpm = { - .buf_size = 0x80*2, + .buf_size = RPM_BUF_SIZE, + }, + .lmem = { + .buf_size = 0x400 * 2, } } }; @@ -2013,7 +2138,20 @@ static void init_pic_list(struct AVS2Decoder_s *dec, struct avs2_decoder *avs2_dec = &dec->avs2_dec; struct avs2_frame_s *pic; #ifdef AVS2_10B_MMU + unsigned long buf_addr1; /*alloc AVS2 compress header first*/ + if (decoder_bmmu_box_alloc_buf_phy + (dec->bmmu_box, + HEADER_BUFFER_IDX(-1), get_compress_header_size(), + DRIVER_HEADER_NAME, + &buf_addr1) < 0){ + avs2_print(dec, 0, + "%s malloc compress header failed %d\n", + DRIVER_HEADER_NAME, -1); + dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; + return; + } + for (i = 0; i < dec->used_buf_num; i++) { unsigned long buf_addr; if (decoder_bmmu_box_alloc_buf_phy @@ -2029,6 +2167,9 @@ static void init_pic_list(struct AVS2Decoder_s *dec, } } #endif + dec->frame_height = avs2_dec->img.height; + dec->frame_width = avs2_dec->img.width; + for (i = 0; i < dec->used_buf_num; i++) { if (i == (dec->used_buf_num - 1)) pic = avs2_dec->m_bg; @@ -2069,8 +2210,8 @@ static void init_pic_list_hw(struct AVS2Decoder_s *dec) int i; struct avs2_decoder *avs2_dec = &dec->avs2_dec; struct avs2_frame_s *pic; - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TL1) { /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/ +#if 0 WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2)); @@ -2078,7 +2219,7 @@ static void init_pic_list_hw(struct AVS2Decoder_s *dec) WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2)); #endif - } +#endif for (i = 0; i < dec->used_buf_num; i++) { if (i == (dec->used_buf_num - 1)) pic = avs2_dec->m_bg; @@ -2086,18 +2227,21 @@ static void init_pic_list_hw(struct AVS2Decoder_s *dec) pic = avs2_dec->fref[i]; if (pic->index < 0) break; - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TL1) { - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, - (0x1 << 1) | (i << 8)); -#ifdef DUAL_CORE_64 - WRITE_VREG(HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR, - (0x1 << 1) | (i << 8)); -#endif - } #ifdef AVS2_10B_MMU /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, pic->header_adr | (pic->mc_canvas_y << 8)|0x1);*/ + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, + (0x1 << 1) | (pic->index << 8)); + +#ifdef DUAL_CORE_64 + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2) + WRITE_VREG(HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR, + (0x1 << 1) | (pic->index << 8)); + else + WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, + (0x1 << 1) | (pic->index << 8)); +#endif WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5); #else /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, @@ -2145,33 +2289,32 @@ static void init_pic_list_hw(struct AVS2Decoder_s *dec) static void dump_pic_list(struct AVS2Decoder_s *dec) { -#if 0 + int ii; struct avs2_decoder *avs2_dec = &dec->avs2_dec; - int i; - for (i = 0; i < FRAME_BUFFERS; i++) { - struct avs2_frame_s *pic = - avs2_dec->fref[i]; - if (pic == NULL) - continue; - avs2_print(dec, - 0, - "Buf(%d) index %d mv_buf_index %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr%ld\n", - i, - pic->index, -#ifndef MV_USE_FIXED_BUF - pic->mv_buf_index, -#else - -1, -#endif - pic->vf_ref, - pic->decode_idx, - pic->slice_type, - pic->pic_w, - pic->pic_h, - pic->cma_alloc_addr - ); + for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) { + avs2_print(dec, 0, + "fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n", + ii, avs2_dec->fref[ii]->index, + avs2_dec->fref[ii]->decode_idx, + avs2_dec->fref[ii]->mv_buf_index, + avs2_dec->fref[ii]->imgcoi_ref, + avs2_dec->fref[ii]->imgtr_fwRefDistance, + avs2_dec->fref[ii]->refered_by_others, + avs2_dec->fref[ii]->to_prepare_disp, + avs2_dec->fref[ii]->is_output, + avs2_dec->fref[ii]->bg_flag, + avs2_dec->fref[ii]->vf_ref, + avs2_dec->fref[ii]->error_mark, + avs2_dec->fref[ii]->decoded_lcu, + avs2_dec->fref[ii]->ref_poc[0], + avs2_dec->fref[ii]->ref_poc[1], + avs2_dec->fref[ii]->ref_poc[2], + avs2_dec->fref[ii]->ref_poc[3], + avs2_dec->fref[ii]->ref_poc[4], + avs2_dec->fref[ii]->ref_poc[5], + avs2_dec->fref[ii]->ref_poc[6] + ); } -#endif return; } @@ -2180,6 +2323,8 @@ static int config_mc_buffer(struct AVS2Decoder_s *dec) int32_t i; struct avs2_decoder *avs2_dec = &dec->avs2_dec; struct avs2_frame_s *pic; + struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic; + /*if (avs2_dec->img.type == I_IMG) return 0; */ @@ -2223,9 +2368,14 @@ static int config_mc_buffer(struct AVS2Decoder_s *dec) (pic->mc_canvas_u_v << 16) | (pic->mc_canvas_u_v << 8) | pic->mc_canvas_y); + + if (pic->error_mark) + cur_pic->error_mark = 1; + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, - "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", - i, pic->mc_canvas_u_v, pic->mc_canvas_y); + "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n", + i, pic->mc_canvas_u_v, pic->mc_canvas_y, + pic->error_mark); } } else if (avs2_dec->img.type == F_IMG) { avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, @@ -2240,9 +2390,14 @@ static int config_mc_buffer(struct AVS2Decoder_s *dec) (pic->mc_canvas_u_v << 16) | (pic->mc_canvas_u_v << 8) | pic->mc_canvas_y); + + if (pic->error_mark) + cur_pic->error_mark = 1; + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, - "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", - i, pic->mc_canvas_u_v, pic->mc_canvas_y); + "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n", + i, pic->mc_canvas_u_v, pic->mc_canvas_y, + pic->error_mark); } WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1); @@ -2268,9 +2423,13 @@ static int config_mc_buffer(struct AVS2Decoder_s *dec) (pic->mc_canvas_u_v << 8) | pic->mc_canvas_y); + if (pic->error_mark) + cur_pic->error_mark = 1; + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, - "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", - 1, pic->mc_canvas_u_v, pic->mc_canvas_y); + "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n", + 1, pic->mc_canvas_u_v, pic->mc_canvas_y, + pic->error_mark); pic = avs2_dec->fref[0]; WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, @@ -2280,9 +2439,13 @@ static int config_mc_buffer(struct AVS2Decoder_s *dec) (pic->mc_canvas_u_v<<8) | pic->mc_canvas_y); + if (pic->error_mark) + cur_pic->error_mark = 1; + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, - "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", - 0, pic->mc_canvas_u_v, pic->mc_canvas_y); + "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n", + 0, pic->mc_canvas_u_v, pic->mc_canvas_y, + pic->error_mark); } return 0; } @@ -2571,7 +2734,7 @@ static void config_mpred_hw(struct AVS2Decoder_s *dec) avs2_dec->fref[0]->ref_poc[4], avs2_dec->fref[0]->ref_poc[5], avs2_dec->fref[0]->ref_poc[6] - ); + ); avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "pic_distance %d, imgtr_next_P %d\n", avs2_dec->img.pic_distance, avs2_dec->img.imgtr_next_P); @@ -3196,15 +3359,21 @@ static void avs2_config_work_space_hw(struct AVS2Decoder_s *dec) /* use HEVC_CM_HEADER_START_ADDR */ data32 = READ_VREG(HEVC_SAO_CTRL5); data32 |= (1<<10); +#if 1 + if (debug & AVS2_DBG_FORCE_UNCOMPRESS) + data32 |= 0x80; +#endif WRITE_VREG(HEVC_SAO_CTRL5, data32); #endif - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TL1) { - WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start); - } WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr); - +#if 1 +/*MULTI_INSTANCE_SUPPORT*/ + /*new added in simulation???*/ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2) + WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start); +#endif } static void decomp_perfcount_reset(void) @@ -3228,33 +3397,8 @@ static void mcrcc_perfcount_reset(void) static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec) { unsigned int data32; + unsigned int decode_mode; int i; - const unsigned short parser_cmd[PARSER_CMD_NUMBER] = { - 0x0401, 0x8401, 0x0800, 0x0402, 0x9002, 0x1423, - 0x8CC3, 0x1423, 0x8804, 0x9825, 0x0800, 0x04FE, - 0x8406, 0x8411, 0x1800, 0x8408, 0x8409, 0x8C2A, - 0x9C2B, 0x1C00, 0x840F, 0x8407, 0x8000, 0x8408, - 0x2000, 0xA800, 0x8410, 0x04DE, 0x840C, 0x840D, - 0xAC00, 0xA000, 0x08C0, 0x08E0, 0xA40E, 0xFC00, - 0x7C00 - }; - const int32_t g_WqMDefault4x4[16] = { - 64, 64, 64, 68, - 64, 64, 68, 72, - 64, 68, 76, 80, - 72, 76, 84, 96 - }; - - const int32_t g_WqMDefault8x8[64] = { - 64, 64, 64, 64, 68, 68, 72, 76, - 64, 64, 64, 68, 72, 76, 84, 92, - 64, 64, 68, 72, 76, 80, 88, 100, - 64, 68, 72, 80, 84, 92, 100, 112, - 68, 72, 80, 84, 92, 104, 112, 128, - 76, 80, 84, 92, 104, 116, 132, 152, - 96, 100, 104, 116, 124, 140, 164, 188, - 104, 108, 116, 128, 152, 172, 192, 216 - }; /*if (debug & AVS2_DBG_BUFMGR_MORE) pr_info("%s\n", __func__);*/ @@ -3322,11 +3466,34 @@ static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec) WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0); #endif if (!dec->m_ins_flag) - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); + decode_mode = DECODE_MODE_SINGLE; else if (vdec_frame_based(hw_to_vdec(dec))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); + decode_mode = DECODE_MODE_MULTI_FRAMEBASE; else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + decode_mode = DECODE_MODE_MULTI_STREAMBASE; + if (dec->avs2_dec.bufmgr_error_flag && + (error_handle_policy & 0x1)) { + dec->bufmgr_error_count++; + dec->avs2_dec.bufmgr_error_flag = 0; + if (dec->bufmgr_error_count > + (re_search_seq_threshold & 0xff) + && dec->frame_count > + ((re_search_seq_threshold >> 8) & 0xff)) { + struct avs2_decoder *avs2_dec = &dec->avs2_dec; + dec->start_decoding_flag = 0; + avs2_dec->hd.vec_flag = 1; + dec->skip_PB_before_I = 1; + avs2_print(dec, 0, + "!!Bufmgr error, search seq again (0x%x %d %d)\n", + error_handle_policy, + dec->frame_count, + dec->bufmgr_error_count); + dec->bufmgr_error_count = 0; + } + } + decode_mode |= (dec->start_decoding_flag << 16); + + WRITE_VREG(DECODE_MODE, decode_mode); WRITE_VREG(HEVC_DECODE_SIZE, 0); WRITE_VREG(HEVC_DECODE_COUNT, 0); @@ -3346,6 +3513,22 @@ static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec) (1 << 2) | /*parser_mpred_if_en*/ (1 << 0) /*parser_scaler_if_en*/ ); + +#ifdef MULTI_INSTANCE_SUPPORT + WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31)); + + WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff); + + for (i = 0; i < 8; i++) + data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR); + + WRITE_VREG(DOS_SW_RESET3, (1<<18)); /* reset mpred */ + WRITE_VREG(DOS_SW_RESET3, 0); + WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32); + WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32); + WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32); +#endif + /*End of Multi-instance*/ /*Changed to Start MPRED in microcode*/ /* pr_info("[test.c] Start MPRED\n"); @@ -3396,7 +3579,7 @@ static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec) else if (get_double_write_mode(dec) == 0x10) data32 |= (0x1 << 9); /*double write only*/ else - data32 |= ((0x1 << 8) |(0x1 << 9)); + data32 |= ((0x1 << 8) | (0x1 << 9)); WRITE_VREG(HEVC_DBLK_CFGB, data32); WRITE_VREG(HEVC_DBLK_CFG0, (1 << 0)); /* [0] rst_sync*/ @@ -3461,7 +3644,7 @@ static void config_avs2_clk_forced_on(void) -static struct AVS2Decoder_s *gHevc; +static struct AVS2Decoder_s gAVS2Decoder; static void avs2_local_uninit(struct AVS2Decoder_s *dec) { @@ -3475,10 +3658,10 @@ static void avs2_local_uninit(struct AVS2Decoder_s *dec) dec->rpm_addr = NULL; } if (dec->lmem_addr) { - if (dec->lmem_phy_addr) - dma_free_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, dec->lmem_addr, - dec->lmem_phy_addr); + if (dec->lmem_phy_addr) + dma_free_coherent(amports_get_dma_device(), + LMEM_BUF_SIZE, dec->lmem_addr, + dec->lmem_phy_addr); dec->lmem_addr = NULL; } @@ -3596,6 +3779,9 @@ static int avs2_local_init(struct AVS2Decoder_s *dec) kfree(dec->rpm_addr); dec->rpm_addr = NULL; return -1; + } else { + avs2_print(dec, AVS2_DBG_BUFMGR, + "rpm_phy_addr %x\n", (u32) dec->rpm_phy_addr); } dec->rpm_ptr = dec->rpm_addr; @@ -3607,7 +3793,10 @@ static int avs2_local_init(struct AVS2Decoder_s *dec) if (dec->lmem_addr == NULL) { pr_err("%s: failed to alloc lmem buffer\n", __func__); return -1; - } + } else + avs2_print(dec, AVS2_DBG_BUFMGR, + "%s, lmem_phy_addr %x\n", + __func__, (u32)dec->lmem_phy_addr); /* dec->lmem_phy_addr = dma_map_single(amports_get_dma_device(), dec->lmem_addr, LMEM_BUF_SIZE, DMA_BIDIRECTIONAL); @@ -3827,20 +4016,36 @@ static struct vframe_s *vavs2_vf_get(void *op_arg) if (kfifo_get(&dec->display_q, &vf)) { uint8_t index = vf->index & 0xff; - - if (index < dec->used_buf_num) { + if (index >= 0 && index < dec->used_buf_num) { struct avs2_frame_s *pic = get_pic_by_index(dec, index); - dec->vf_get_count++; + if (pic == NULL && + (debug & AVS2_DBG_PIC_LEAK)) { + int i; + avs2_print(dec, 0, + "%s error index 0x%x pic not exist\n", + __func__, index); + dump_pic_list(dec); + for (i = 0; i < 10; i++) { + pic = get_pic_by_index(dec, index); + pr_info("pic = %p\n", pic); + } + + if (debug & AVS2_DBG_PIC_LEAK) + debug |= AVS2_DBG_PIC_LEAK_WAIT; + return NULL; + } + dec->vf_get_count++; + if (pic) avs2_print(dec, AVS2_DBG_BUFMGR, - "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n", - __func__, index, - pic->imgtr_fwRefDistance, - dec->vf_get_count, - vf->type, - vf->width, vf->height, - vf->pts, - vf->pts_us64); - return vf; + "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n", + __func__, index, + pic->imgtr_fwRefDistance_bak, + dec->vf_get_count, + vf->type, + vf->width, vf->height, + vf->pts, + vf->pts_us64); + return vf; } } return NULL; @@ -3861,7 +4066,8 @@ static void vavs2_vf_put(struct vframe_s *vf, void *op_arg) __func__, vf->index, dec->vf_put_count); - if (index < dec->used_buf_num) { + if (index >= 0 + && index < dec->used_buf_num) { unsigned long flags; struct avs2_frame_s *pic; @@ -3921,6 +4127,7 @@ static void set_vframe(struct AVS2Decoder_s *dec, { unsigned long flags; int stream_offset; + int pts_discontinue; stream_offset = pic->stream_offset; avs2_print(dec, AVS2_DBG_BUFMGR, "%s index = %d pos = %d\r\n", @@ -3983,11 +4190,16 @@ static void set_vframe(struct AVS2Decoder_s *dec, } } + pts_discontinue = + (abs(dec->last_pts - vf->pts) >= + tsync_vpts_discontinuity_margin()); + if (vf->pts != 0) dec->last_lookup_pts = vf->pts; -#if 0 +#if 1 if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != KEY_FRAME)) + && ((pic->slice_type != I_IMG) || (!pts_discontinue && + !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) vf->pts = dec->last_pts + DUR2PTS(dec->frame_dur); #endif dec->last_pts = vf->pts; @@ -3995,9 +4207,10 @@ static void set_vframe(struct AVS2Decoder_s *dec, if (vf->pts_us64 != 0) dec->last_lookup_pts_us64 = vf->pts_us64; -#if 0 +#if 1 if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != KEY_FRAME)) { + && ((pic->slice_type != I_IMG) || (!pts_discontinue && + !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) { vf->pts_us64 = dec->last_pts_us64 + (DUR2PTS(dec->frame_dur) * 100 / 9); @@ -4006,17 +4219,16 @@ static void set_vframe(struct AVS2Decoder_s *dec, dec->last_pts_us64 = vf->pts_us64; avs2_print(dec, AVS2_DBG_OUT_PTS, "avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n", - vf->pts, vf->pts_us64); + vf->pts, vf->pts_us64); + } - } + vf->index = 0xff00 | pic->index; - vf->index = 0xff00 | pic->index; - - if (pic->double_write_mode & 0x10) { - /* double write only */ - vf->compBodyAddr = 0; - vf->compHeadAddr = 0; - } else { + if (pic->double_write_mode & 0x10) { + /* double write only */ + vf->compBodyAddr = 0; + vf->compHeadAddr = 0; + } else { #ifdef AVS2_10B_MMU vf->compBodyAddr = 0; vf->compHeadAddr = pic->header_adr; @@ -4026,109 +4238,109 @@ static void set_vframe(struct AVS2Decoder_s *dec, pic->comp_body_size; /*head adr*/ #endif - } - if (pic->double_write_mode) { - vf->type = VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; - if (pic->double_write_mode == 3) { - vf->type |= VIDTYPE_COMPRESS; + } + if (pic->double_write_mode) { + vf->type = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_FIELD; + vf->type |= VIDTYPE_VIU_NV21; + if (pic->double_write_mode == 3) { + vf->type |= VIDTYPE_COMPRESS; +#ifdef AVS2_10B_MMU + vf->type |= VIDTYPE_SCATTER; +#endif + } +#ifdef MULTI_INSTANCE_SUPPORT + if (dec->m_ins_flag) { + vf->canvas0Addr = vf->canvas1Addr = -1; + vf->plane_num = 2; + vf->canvas0_config[0] = + pic->canvas_config[0]; + vf->canvas0_config[1] = + pic->canvas_config[1]; + + vf->canvas1_config[0] = + pic->canvas_config[0]; + vf->canvas1_config[1] = + pic->canvas_config[1]; + + } else +#endif + vf->canvas0Addr = vf->canvas1Addr = + spec2canvas(pic); + } else { + vf->canvas0Addr = vf->canvas1Addr = 0; + vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; #ifdef AVS2_10B_MMU vf->type |= VIDTYPE_SCATTER; #endif } -#ifdef MULTI_INSTANCE_SUPPORT - if (dec->m_ins_flag) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->plane_num = 2; - vf->canvas0_config[0] = - pic->canvas_config[0]; - vf->canvas0_config[1] = - pic->canvas_config[1]; - vf->canvas1_config[0] = - pic->canvas_config[0]; - vf->canvas1_config[1] = - pic->canvas_config[1]; + switch (pic->bit_depth) { + case AVS2_BITS_8: + vf->bitdepth = BITDEPTH_Y8 | + BITDEPTH_U8 | BITDEPTH_V8; + break; + case AVS2_BITS_10: + case AVS2_BITS_12: + vf->bitdepth = BITDEPTH_Y10 | + BITDEPTH_U10 | BITDEPTH_V10; + break; + default: + vf->bitdepth = BITDEPTH_Y10 | + BITDEPTH_U10 | BITDEPTH_V10; + break; + } + if ((vf->type & VIDTYPE_COMPRESS) == 0) + vf->bitdepth = + BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; + if (pic->bit_depth == AVS2_BITS_8) + vf->bitdepth |= BITDEPTH_SAVING_MODE; - } else -#endif - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(pic); - } else { - vf->canvas0Addr = vf->canvas1Addr = 0; - vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; + set_frame_info(dec, vf); + /* if((vf->width!=pic->width)| + (vf->height!=pic->height)) */ + /* pr_info("aaa: %d/%d, %d/%d\n", + vf->width,vf->height, pic->width, + pic->height); */ + vf->width = pic->pic_w / + get_double_write_ratio(dec, + pic->double_write_mode); + vf->height = pic->pic_h / + get_double_write_ratio(dec, + pic->double_write_mode); + if (force_w_h != 0) { + vf->width = (force_w_h >> 16) & 0xffff; + vf->height = force_w_h & 0xffff; + } + vf->compWidth = pic->pic_w; + vf->compHeight = pic->pic_h; + if (force_fps & 0x100) { + u32 rate = force_fps & 0xff; + if (rate) + vf->duration = 96000/rate; + else + vf->duration = 0; + } #ifdef AVS2_10B_MMU - vf->type |= VIDTYPE_SCATTER; -#endif - } - - switch (pic->bit_depth) { - case AVS2_BITS_8: - vf->bitdepth = BITDEPTH_Y8 | - BITDEPTH_U8 | BITDEPTH_V8; - break; - case AVS2_BITS_10: - case AVS2_BITS_12: - vf->bitdepth = BITDEPTH_Y10 | - BITDEPTH_U10 | BITDEPTH_V10; - break; - default: - vf->bitdepth = BITDEPTH_Y10 | - BITDEPTH_U10 | BITDEPTH_V10; - break; - } - if ((vf->type & VIDTYPE_COMPRESS) == 0) - vf->bitdepth = - BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; - if (pic->bit_depth == AVS2_BITS_8) - vf->bitdepth |= BITDEPTH_SAVING_MODE; - - set_frame_info(dec, vf); - /* if((vf->width!=pic->width)| - (vf->height!=pic->height)) */ - /* pr_info("aaa: %d/%d, %d/%d\n", - vf->width,vf->height, pic->width, - pic->height); */ - vf->width = pic->pic_w / - get_double_write_ratio(dec, - pic->double_write_mode); - vf->height = pic->pic_h / - get_double_write_ratio(dec, - pic->double_write_mode); - if (force_w_h != 0) { - vf->width = (force_w_h >> 16) & 0xffff; - vf->height = force_w_h & 0xffff; - } - vf->compWidth = pic->pic_w; - vf->compHeight = pic->pic_h; - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } -#ifdef AVS2_10B_MMU - if (vf->type & VIDTYPE_SCATTER) { - vf->mem_handle = decoder_mmu_box_get_mem_handle( - dec->mmu_box, - pic->index); - vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( - dec->bmmu_box, - HEADER_BUFFER_IDX(pic->index)); - } else { + if (vf->type & VIDTYPE_SCATTER) { + vf->mem_handle = decoder_mmu_box_get_mem_handle( + dec->mmu_box, + pic->index); + vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( + dec->bmmu_box, + HEADER_BUFFER_IDX(pic->index)); + } else { + vf->mem_handle = decoder_bmmu_box_get_mem_handle( + dec->bmmu_box, + VF_BUFFER_IDX(pic->index)); + vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( + dec->bmmu_box, + HEADER_BUFFER_IDX(pic->index)); + } +#else vf->mem_handle = decoder_bmmu_box_get_mem_handle( dec->bmmu_box, VF_BUFFER_IDX(pic->index)); - vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( - dec->bmmu_box, - HEADER_BUFFER_IDX(pic->index)); - } -#else - vf->mem_handle = decoder_bmmu_box_get_mem_handle( - dec->bmmu_box, - VF_BUFFER_IDX(pic->index)); #endif if (!dummy) { @@ -4139,6 +4351,7 @@ static void set_vframe(struct AVS2Decoder_s *dec, dec->vf_pre_count++; } + static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) { #ifndef NO_DISPLAY @@ -4155,6 +4368,24 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) continue; } + if (pic->error_mark) { + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, + "!!!error pic, skip\n", + 0); + continue; + } + + if (dec->start_decoding_flag != 0) { + if (dec->skip_PB_before_I && + pic->slice_type != I_IMG) { + avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, + "!!!slice type %d (not I) skip\n", + 0, pic->slice_type); + continue; + } + dec->skip_PB_before_I = 0; + } + if (kfifo_get(&dec->newframe_q, &vf) == 0) { pr_info("fatal error, no available buffer slot."); return -1; @@ -4242,13 +4473,15 @@ static void dec_again_process(struct AVS2Decoder_s *dec) amhevc_stop(); dec->dec_result = DEC_RESULT_AGAIN; if (dec->process_state == - PROC_STATE_DECODESLICE) { + PROC_STATE_DECODING) { dec->process_state = - PROC_STATE_SENDAGAIN; -#ifdef AVS2_10B_MMU - avs2_recycle_mmu_buf(dec); -#endif + PROC_STATE_DECODE_AGAIN; + } else if (dec->process_state == + PROC_STATE_HEAD_DONE) { + dec->process_state = + PROC_STATE_HEAD_AGAIN; } + dec->next_again_flag = 1; reset_process_time(dec); vdec_schedule_work(&dec->work); } @@ -4263,6 +4496,83 @@ static uint32_t log2i(uint32_t val) return ret; } +static void check_pic_error(struct AVS2Decoder_s *dec, + struct avs2_frame_s *pic) +{ + if (pic->decoded_lcu == 0) { + pic->decoded_lcu = + (READ_VREG(HEVC_PARSER_LCU_START) + & 0xffffff) + 1; + } + if (pic->decoded_lcu != dec->avs2_dec.lcu_total) { + avs2_print(dec, AVS2_DBG_BUFMGR, + "%s error pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n", + __func__, pic->index, pic->imgtr_fwRefDistance, + pic->decoded_lcu, dec->avs2_dec.lcu_total); + pic->error_mark = 1; + } else { + avs2_print(dec, AVS2_DBG_BUFMGR_MORE, + "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n", + __func__, pic->index, pic->imgtr_fwRefDistance, + pic->decoded_lcu, dec->avs2_dec.lcu_total); + + } +} +static void update_decoded_pic(struct AVS2Decoder_s *dec) +{ + struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic; + if (pic) { + dec->avs2_dec.hc.cur_pic->decoded_lcu = + (READ_VREG(HEVC_PARSER_LCU_START) + & 0xffffff) + 1; + avs2_print(dec, AVS2_DBG_BUFMGR_MORE, + "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n", + __func__, pic->index, pic->imgtr_fwRefDistance, + pic->decoded_lcu, dec->avs2_dec.lcu_total); + } +} +/* +[SE] [BUG][BUG-171463][chuanqi.wang]: get frame rate by video sequeue*/ +static int get_frame_rate(union param_u *params, struct AVS2Decoder_s *dec) +{ + int tmp = 0; + + switch (params->p.frame_rate_code) { + case 1: + case 2: + tmp = 24; + break; + case 3: + tmp = 25; + break; + case 4: + case 5: + tmp = 30; + break; + case 6: + tmp = 50; + break; + case 7: + case 8: + tmp = 60; + break; + case 9: + tmp = 100; + break; + case 10: + tmp = 120; + break; + default: + tmp = 25; + break; + } + + if (!params->p.progressive_sequence) + tmp = tmp / 2; + dec->frame_dur = div_u64(96000ULL, tmp); + dec->get_frame_dur = true; + /*avs2_print(dec, 0, "avs2 frame_dur:%d,progressive:%d\n", dec->frame_dur, params->p.progressive_sequence);*/ + return 0; +} static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) { struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data; @@ -4273,46 +4583,63 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) /*if (dec->wait_buf) pr_info("set wait_buf to 0\r\n"); */ + avs2_print(dec, AVS2_DBG_BUFMGR_MORE, - "%s %x\n", __func__, dec_status); + "%s decode_status 0x%x process_state %d lcu 0x%x\n", + __func__, dec_status, dec->process_state, + READ_VREG(HEVC_PARSER_LCU_START)); + #ifndef G12A_BRINGUP_DEBUG if (dec->eos) { PRINT_LINE(); - dec->process_busy = 0; - return IRQ_HANDLED; + goto irq_handled_exit; } #endif dec->wait_buf = 0; - if ((dec_status == HEVC_NAL_DECODE_DONE) || - (dec_status == AVS2_DECODE_TIMEOUT) || - (dec_status == AVS2_DECODE_BUFEMPTY) - ) { + if (dec_status == AVS2_DECODE_BUFEMPTY) { PRINT_LINE(); if (dec->m_ins_flag) { reset_process_time(dec); if (!vdec_frame_based(hw_to_vdec(dec))) dec_again_process(dec); else { - dec->dec_result = DEC_RESULT_GET_DATA; + dec->dec_result = DEC_RESULT_DONE; + reset_process_time(dec); + amhevc_stop(); vdec_schedule_work(&dec->work); } } - dec->process_busy = 0; - return IRQ_HANDLED; + goto irq_handled_exit; } else if (dec_status == HEVC_DECPIC_DATA_DONE) { PRINT_LINE(); + dec->start_decoding_flag |= 0x3; if (dec->m_ins_flag) { + update_decoded_pic(dec); reset_process_time(dec); dec->dec_result = DEC_RESULT_DONE; amhevc_stop(); +#if 0 /*def AVS2_10B_MMU*/ + if (dec->m_ins_flag) { + /*avs2_recycle_mmu_buf_tail(dec);*/ + dec->used_4k_num = + (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); + } +#endif + +#if 0 + /*keep hardware state*/ + WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31)); + WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff); + dec->mpred_abv_start_addr = + READ_VREG(HEVC_MPRED_ABV_START_ADDR); + /**/ +#endif vdec_schedule_work(&dec->work); } - - dec->process_busy = 0; - return IRQ_HANDLED; + goto irq_handled_exit; } PRINT_LINE(); - +#if 0 if (dec_status == AVS2_EOS) { if (dec->m_ins_flag) reset_process_time(dec); @@ -4326,14 +4653,16 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) avs2_print(dec, AVS2_DBG_BUFMGR, "send AVS2_10B_DISCARD_NAL\r\n"); WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL); - dec->process_busy = 0; if (dec->m_ins_flag) { + update_decoded_pic(dec); dec->dec_result = DEC_RESULT_DONE; amhevc_stop(); vdec_schedule_work(&dec->work); } - return IRQ_HANDLED; - } else if (dec_status == AVS2_DECODE_OVER_SIZE) { + goto irq_handled_exit; + } else +#endif + if (dec_status == AVS2_DECODE_OVER_SIZE) { avs2_print(dec, 0, "avs2 decode oversize !!\n"); debug |= (AVS2_DBG_DIS_LOC_ERROR_PROC | @@ -4341,25 +4670,74 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) dec->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; if (dec->m_ins_flag) reset_process_time(dec); - dec->process_busy = 0; - return IRQ_HANDLED; + goto irq_handled_exit; } PRINT_LINE(); if (dec->m_ins_flag) reset_process_time(dec); - if ((dec_status == AVS2_HEAD_PIC_I_READY) - || (dec_status == AVS2_HEAD_PIC_PB_READY)) { + if (dec_status == AVS2_HEAD_SEQ_READY) + start_code = SEQUENCE_HEADER_CODE; + else if (dec_status == AVS2_HEAD_PIC_I_READY) + start_code = I_PICTURE_START_CODE; + else if (dec_status == AVS2_HEAD_PIC_PB_READY) + start_code = PB_PICTURE_START_CODE; + else if (dec_status == AVS2_STARTCODE_SEARCH_DONE) + /*SEQUENCE_END_CODE, VIDEO_EDIT_CODE*/ + start_code = READ_VREG(CUR_NAL_UNIT_TYPE); + + if (dec->process_state == + PROC_STATE_HEAD_AGAIN + ) { + if ((start_code == I_PICTURE_START_CODE) + || (start_code == PB_PICTURE_START_CODE)) { + avs2_print(dec, 0, + "PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n", + start_code); + goto irq_handled_exit; + } else { + avs2_print(dec, AVS2_DBG_BUFMGR, + "PROC_STATE_HEAD_AGAIN, start_code 0x%x\r\n", + start_code); + dec->process_state = PROC_STATE_HEAD_DONE; + WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); + goto irq_handled_exit; + } + } else if (dec->process_state == + PROC_STATE_DECODE_AGAIN) { + if ((start_code == I_PICTURE_START_CODE) + || (start_code == PB_PICTURE_START_CODE)) { + avs2_print(dec, AVS2_DBG_BUFMGR, + "PROC_STATE_DECODE_AGAIN=> decode_slice, start_code 0x%x\r\n", + start_code); + goto decode_slice; + } else { + avs2_print(dec, 0, + "PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n", + start_code); + WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); + goto irq_handled_exit; + } + } + + if ((start_code == I_PICTURE_START_CODE) + || (start_code == PB_PICTURE_START_CODE) + || (start_code == SEQUENCE_END_CODE) + || (start_code == VIDEO_EDIT_CODE)) { PRINT_LINE(); - if (dec->avs2_dec.hc.cur_pic != NULL && - dec->process_state != PROC_STATE_SENDAGAIN) { + if (dec->avs2_dec.hc.cur_pic != NULL) { int32_t ii; #ifdef AVS2_10B_MMU avs2_recycle_mmu_buf_tail(dec); #endif + check_pic_error(dec, dec->avs2_dec.hc.cur_pic); avs2_post_process(&dec->avs2_dec); + + if (debug & AVS2_DBG_PRINT_PIC_LIST) + dump_pic_list(dec); + avs2_prepare_display_buf(dec); dec->avs2_dec.hc.cur_pic = NULL; #ifdef AVS2_10B_MMU @@ -4385,6 +4763,11 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) } #endif } + } + + if ((dec_status == AVS2_HEAD_PIC_I_READY) + || (dec_status == AVS2_HEAD_PIC_PB_READY)) { + PRINT_LINE(); if (debug & AVS2_DBG_SEND_PARAM_WITH_REG) { get_rpm_param( @@ -4404,47 +4787,209 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) dec->rpm_ptr[i + 3 - ii]; } } +#ifdef SANITY_CHECK + if (dec->avs2_dec.param.p.num_of_ref_cur > + dec->avs2_dec.ref_maxbuffer) { + pr_info("Warning: Wrong num_of_ref_cur %d, force to %d\n", + dec->avs2_dec.param.p.num_of_ref_cur, + dec->avs2_dec.ref_maxbuffer); + dec->avs2_dec.param.p.num_of_ref_cur = + dec->avs2_dec.ref_maxbuffer; + } +#endif PRINT_LINE(); debug_buffer_mgr_more(dec); + get_frame_rate(&dec->avs2_dec.param, dec); + if (dec->avs2_dec.param.p.video_signal_type + & (1<<30)) { + union param_u *pPara; + + avs2_print(dec, 0, + "avs2 HDR meta data present\n"); + pPara = &dec->avs2_dec.param; + + /*clean this flag*/ + pPara->p.video_signal_type + &= ~(1<<30); + + dec->vf_dp.present_flag = 1; + + dec->vf_dp.white_point[0] + = pPara->p.white_point_x; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "white_point[0]:0x%x\n", + dec->vf_dp.white_point[0]); + + dec->vf_dp.white_point[1] + = pPara->p.white_point_y; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "white_point[1]:0x%x\n", + dec->vf_dp.white_point[1]); + + for (i = 0; i < 3; i++) { + dec->vf_dp.primaries[i][0] + = pPara->p.display_primaries_x[i]; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "primaries[%d][0]:0x%x\n", + i, + dec->vf_dp.primaries[i][0]); + } + + for (i = 0; i < 3; i++) { + dec->vf_dp.primaries[i][1] + = pPara->p.display_primaries_y[i]; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "primaries[%d][1]:0x%x\n", + i, + dec->vf_dp.primaries[i][1]); + } + + dec->vf_dp.luminance[0] + = pPara->p.max_display_mastering_luminance; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "luminance[0]:0x%x\n", + dec->vf_dp.luminance[0]); + + dec->vf_dp.luminance[1] + = pPara->p.min_display_mastering_luminance; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "luminance[1]:0x%x\n", + dec->vf_dp.luminance[1]); + + + dec->vf_dp.content_light_level.present_flag + = 1; + dec->vf_dp.content_light_level.max_content + = pPara->p.max_content_light_level; + avs2_print(dec, AVS2_DBG_HDR_INFO, + "max_content:0x%x\n", + dec->vf_dp.content_light_level.max_content); + + dec->vf_dp.content_light_level.max_pic_average + = pPara->p.max_picture_average_light_level; + + avs2_print(dec, AVS2_DBG_HDR_INFO, + "max_pic_average:0x%x\n", + dec->vf_dp.content_light_level.max_pic_average); + } + + + if (dec->video_ori_signal_type != + ((dec->avs2_dec.param.p.video_signal_type << 16) + | dec->avs2_dec.param.p.color_description)) { + u32 v = dec->avs2_dec.param.p.video_signal_type; + u32 c = dec->avs2_dec.param.p.color_description; + u32 convert_c = c; + + if (v & 0x2000) { + avs2_print(dec, 0, + "video_signal_type present:\n"); + avs2_print(dec, 0, + " %s %s\n", + video_format_names[(v >> 10) & 7], + ((v >> 9) & 1) ? + "full_range" : "limited"); + if (v & 0x100) { + u32 transfer; + u32 maxtrix; + + avs2_print(dec, 0, + "color_description present:\n"); + avs2_print(dec, 0, + "color_primarie = %d\n", + v & 0xff); + avs2_print(dec, 0, + "transfer_characteristic = %d\n", + (c >> 8) & 0xff); + avs2_print(dec, 0, + " matrix_coefficient = %d\n", + c & 0xff); + + transfer = (c >> 8) & 0xFF; + if (transfer >= 15) + avs2_print(dec, 0, + "unsupport transfer_characteristic\n"); + else if (transfer == 14) + transfer = 18; /* HLG */ + else if (transfer == 13) + transfer = 32; + else if (transfer == 12) + transfer = 16; + else if (transfer == 11) + transfer = 15; + + maxtrix = c & 0xFF; + if (maxtrix >= 10) + avs2_print(dec, 0, + "unsupport matrix_coefficient\n"); + else if (maxtrix == 9) + maxtrix = 10; + else if (maxtrix == 8) + maxtrix = 9; + + convert_c = (transfer << 8) | (maxtrix); + + avs2_print(dec, 0, + " convered c:0x%x\n", + convert_c); + } + } + + if (enable_force_video_signal_type) + dec->video_signal_type + = force_video_signal_type; + else { + dec->video_signal_type + = (v << 16) | convert_c; + + dec->video_ori_signal_type + = (v << 16) | c; + } + + video_signal_type = dec->video_signal_type; + } } - - if (dec_status == AVS2_HEAD_SEQ_READY) - start_code = SEQUENCE_HEADER_CODE; - else if (dec_status == AVS2_HEAD_PIC_I_READY) - start_code = I_PICTURE_START_CODE; - else if (dec_status == AVS2_HEAD_PIC_PB_READY) - start_code = PB_PICTURE_START_CODE; - else if (dec_status == AVS2_HEAD_SEQ_END_READY) - start_code = SEQUENCE_END_CODE; - else if (dec_status == AVS2_STARTCODE_SEARCH_DONE) - start_code = READ_VREG(CUR_NAL_UNIT_TYPE); - +#if 0 + if ((debug_again & 0x4) && + dec->process_state == + PROC_STATE_INIT) { + if (start_code == PB_PICTURE_START_CODE) { + dec->process_state = PROC_STATE_TEST1; + dec_again_process(dec); + goto irq_handled_exit; + } + } +#endif PRINT_LINE(); avs2_prepare_header(&dec->avs2_dec, start_code); if (start_code == SEQUENCE_HEADER_CODE || - start_code == VIDEO_EDIT_CODE) + start_code == VIDEO_EDIT_CODE || + start_code == SEQUENCE_END_CODE) { + if (dec->m_ins_flag && + vdec_frame_based(hw_to_vdec(dec))) + dec->start_decoding_flag |= 0x1; + dec->process_state = PROC_STATE_HEAD_DONE; WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); - else if (start_code == I_PICTURE_START_CODE || + } else if (start_code == I_PICTURE_START_CODE || start_code == PB_PICTURE_START_CODE) { ret = 0; - if (dec->process_state != PROC_STATE_SENDAGAIN) { - if (dec->pic_list_init_flag == 0) { - int32_t lcu_size_log2 = - log2i(dec->avs2_dec.param.p.lcu_size); + if (dec->pic_list_init_flag == 0) { + int32_t lcu_size_log2 = + log2i(dec->avs2_dec.param.p.lcu_size); - avs2_init_global_buffers(&dec->avs2_dec); - /*avs2_dec->m_bg->index is - set to dec->used_buf_num - 1*/ - init_pic_list(dec, lcu_size_log2); - init_pic_list_hw(dec); - } - ret = avs2_process_header(&dec->avs2_dec); - if (!dec->m_ins_flag) - dec->slice_idx++; + avs2_init_global_buffers(&dec->avs2_dec); + /*avs2_dec->m_bg->index is + set to dec->used_buf_num - 1*/ + init_pic_list(dec, lcu_size_log2); + init_pic_list_hw(dec); } + ret = avs2_process_header(&dec->avs2_dec); + if (!dec->m_ins_flag) + dec->slice_idx++; + PRINT_LINE(); #ifdef AVS2_10B_MMU if (ret >= 0) { @@ -4469,7 +5014,6 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) "avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n", ret); WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL); - dec->process_busy = 0; #ifdef AVS2_10B_MMU avs2_recycle_mmu_buf(dec); #endif @@ -4479,35 +5023,36 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) vdec_schedule_work(&dec->work); } - return IRQ_HANDLED; + goto irq_handled_exit; } else { PRINT_LINE(); + dec->avs2_dec.hc.cur_pic->stream_offset = + READ_VREG(HEVC_SHIFT_BYTE_COUNT); /* struct PIC_BUFFER_CONFIG_s *cur_pic = &cm->cur_frame->buf; cur_pic->decode_idx = dec->frame_count; */ - if (dec->process_state != PROC_STATE_SENDAGAIN) { - if (!dec->m_ins_flag) { - dec->frame_count++; - decode_frame_count[dec->index] - = dec->frame_count; - } - /*MULTI_INSTANCE_SUPPORT*/ - if (dec->chunk) { - dec->avs2_dec.hc.cur_pic->pts = - dec->chunk->pts; - dec->avs2_dec.hc.cur_pic->pts64 = - dec->chunk->pts64; - } - /**/ + if (!dec->m_ins_flag) { + dec->frame_count++; + decode_frame_count[dec->index] + = dec->frame_count; } + /*MULTI_INSTANCE_SUPPORT*/ + if (dec->chunk) { + dec->avs2_dec.hc.cur_pic->pts = + dec->chunk->pts; + dec->avs2_dec.hc.cur_pic->pts64 = + dec->chunk->pts64; + } + /**/ dec->avs2_dec.hc.cur_pic->bit_depth = dec->avs2_dec.input.sample_bit_depth; dec->avs2_dec.hc.cur_pic->double_write_mode = get_double_write_mode(dec); - +decode_slice: PRINT_LINE(); + config_mc_buffer(dec); config_mcrcc_axi_hw(dec); config_mpred_hw(dec); @@ -4525,17 +5070,26 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) dec->avs2_dec.fref[4]->imgtr_fwRefDistance, dec->avs2_dec.img.tr); + if ((debug_again & 0x2) && + dec->process_state == + PROC_STATE_INIT) { + dec->process_state = PROC_STATE_DECODING; + dec_again_process(dec); + goto irq_handled_exit; + } + + dec->process_state = PROC_STATE_DECODING; + WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); } - dec->process_busy = 0; - dec->process_state = PROC_STATE_DECODESLICE; if (dec->m_ins_flag) start_process_time(dec); } - dec->process_busy = 0; +irq_handled_exit: PRINT_LINE(); + dec->process_busy = 0; return IRQ_HANDLED; } @@ -4545,6 +5099,7 @@ static irqreturn_t vavs2_isr(int irq, void *data) unsigned int dec_status; struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data; uint debug_tag; + WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); dec_status = READ_VREG(HEVC_DEC_STATUS_REG); @@ -4755,25 +5310,6 @@ static void vavs2_put_timer_func(unsigned long arg) dec->ucode_pause_pos = 0; WRITE_HREG(DEBUG_REG1, 0); } - if (debug & AVS2_DBG_FORCE_SEND_AGAIN) { - pr_info( - "Force Send Again\r\n"); - debug &= ~AVS2_DBG_FORCE_SEND_AGAIN; - reset_process_time(dec); - dec->dec_result = DEC_RESULT_AGAIN; - if (dec->process_state == - PROC_STATE_DECODESLICE) { -#ifdef AVS2_10B_MMU - avs2_recycle_mmu_buf(dec); -#endif - dec->process_state = - PROC_STATE_SENDAGAIN; - } - amhevc_stop(); - - vdec_schedule_work(&dec->work); - } - if (debug & AVS2_DBG_DUMP_DATA) { debug &= ~AVS2_DBG_DUMP_DATA; avs2_print(dec, 0, @@ -4793,6 +5329,50 @@ static void vavs2_put_timer_func(unsigned long arg) WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1); debug &= ~AVS2_DBG_TRIG_SLICE_SEGMENT_PROC; } + if (debug & AVS2_DBG_DUMP_RPM_BUF) { + int i; + dma_sync_single_for_cpu( + amports_get_dma_device(), + dec->rpm_phy_addr, + RPM_BUF_SIZE, + DMA_FROM_DEVICE); + + pr_info("RPM:\n"); + for (i = 0; i < RPM_BUF_SIZE; i += 4) { + int ii; + if ((i & 0xf) == 0) + pr_info("%03x: ", i); + for (ii = 0; ii < 4; ii++) { + pr_info("%04x ", + dec->lmem_ptr[i + 3 - ii]); + } + if (((i + ii) & 0xf) == 0) + pr_info("\n"); + } + debug &= ~AVS2_DBG_DUMP_RPM_BUF; + } + if (debug & AVS2_DBG_DUMP_LMEM_BUF) { + int i; + dma_sync_single_for_cpu( + amports_get_dma_device(), + dec->lmem_phy_addr, + LMEM_BUF_SIZE, + DMA_FROM_DEVICE); + + pr_info("LMEM:\n"); + for (i = 0; i < LMEM_BUF_SIZE; i += 4) { + int ii; + if ((i & 0xf) == 0) + pr_info("%03x: ", i); + for (ii = 0; ii < 4; ii++) { + pr_info("%04x ", + dec->lmem_ptr[i + 3 - ii]); + } + if (((i + ii) & 0xf) == 0) + pr_info("\n"); + } + debug &= ~AVS2_DBG_DUMP_LMEM_BUF; + } /*if (debug & AVS2_DBG_HW_RESET) { }*/ @@ -4863,8 +5443,9 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private; - vstatus->frame_width = frame_width; - vstatus->frame_height = frame_height; + vstatus->frame_width = dec->frame_width; + vstatus->frame_height = dec->frame_height; + if (dec->frame_dur != 0) vstatus->frame_rate = 96000 / dec->frame_dur; else @@ -5148,6 +5729,10 @@ static int vmavs2_stop(struct AVS2Decoder_s *dec) reset_process_time(dec); cancel_work_sync(&dec->work); uninit_mmu_buffers(dec); + if (dec->fw) { + vfree(dec->fw); + dec->fw = NULL; + } return 0; } @@ -5191,8 +5776,6 @@ static int vavs2_stop(struct AVS2Decoder_s *dec) else amhevc_disable(); uninit_mmu_buffers(dec); - vfree(dec->fw); - dec->fw = NULL; return 0; } @@ -5232,17 +5815,11 @@ static int amvdec_avs2_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct BUF_s BUF[MAX_BUF_NUM]; - struct AVS2Decoder_s *dec; + struct AVS2Decoder_s *dec = &gAVS2Decoder; int ret; pr_info("%s\n", __func__); mutex_lock(&vavs2_mutex); - dec = vmalloc(sizeof(struct AVS2Decoder_s)); - if (dec == NULL) { - pr_info("failed to vamlloc amvdec_avs2 dec struct\n"); - return -ENOMEM; - } - gHevc = dec; memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); memset(dec, 0, sizeof(struct AVS2Decoder_s)); memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); @@ -5257,7 +5834,6 @@ static int amvdec_avs2_probe(struct platform_device *pdev) if (pdata == NULL) { avs2_print(dec, 0, "\namvdec_avs2 memory resource undefined.\n"); - vfree(dec); mutex_unlock(&vavs2_mutex); return -EFAULT; } @@ -5266,7 +5842,6 @@ static int amvdec_avs2_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); if (amvdec_avs2_mmu_init(dec) < 0) { - vfree(dec); mutex_unlock(&vavs2_mutex); pr_err("avs2 alloc bmmu box failed!!\n"); return -1; @@ -5276,7 +5851,6 @@ static int amvdec_avs2_probe(struct platform_device *pdev) work_buf_size, DRIVER_NAME, &pdata->mem_start); if (ret < 0) { uninit_mmu_buffers(dec); - vfree(dec); mutex_unlock(&vavs2_mutex); return ret; } @@ -5291,9 +5865,11 @@ static int amvdec_avs2_probe(struct platform_device *pdev) pdata->mem_start, dec->buf_size); } - if (pdata->sys_info) + if (pdata->sys_info) { dec->vavs2_amstream_dec_info = *pdata->sys_info; - else { + dec->frame_width = dec->vavs2_amstream_dec_info.width; + dec->frame_height = dec->vavs2_amstream_dec_info.height; + } else { dec->vavs2_amstream_dec_info.width = 0; dec->vavs2_amstream_dec_info.height = 0; dec->vavs2_amstream_dec_info.rate = 30; @@ -5302,13 +5878,12 @@ static int amvdec_avs2_probe(struct platform_device *pdev) pdata->private = dec; pdata->dec_status = vavs2_dec_status; - pdata->set_isreset = vavs2_set_isreset; + /*pdata->set_isreset = vavs2_set_isreset;*/ is_reset = 0; if (vavs2_init(pdata) < 0) { pr_info("\namvdec_avs2 init failed.\n"); avs2_local_uninit(dec); uninit_mmu_buffers(dec); - vfree(dec); mutex_unlock(&vavs2_mutex); return -ENODEV; } @@ -5322,7 +5897,7 @@ static int amvdec_avs2_probe(struct platform_device *pdev) static int amvdec_avs2_remove(struct platform_device *pdev) { - struct AVS2Decoder_s *dec = gHevc; + struct AVS2Decoder_s *dec = &gAVS2Decoder; if (debug) pr_info("amvdec_avs2_remove\n"); @@ -5339,8 +5914,6 @@ static int amvdec_avs2_remove(struct platform_device *pdev) dec->pts_missed, dec->pts_hit, dec->frame_dur); #endif - vfree(dec); - mutex_unlock(&vavs2_mutex); return 0; @@ -5533,6 +6106,7 @@ static void avs2_work(struct work_struct *work) "%s: end of stream\n", __func__); dec->eos = 1; + check_pic_error(dec, dec->avs2_dec.hc.cur_pic); avs2_post_process(&dec->avs2_dec); avs2_prepare_display_buf(dec); vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk); @@ -5575,12 +6149,45 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private; - bool ret = 0; + unsigned long ret = 0; avs2_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); + if (debug & AVS2_DBG_PIC_LEAK_WAIT) + return ret; + if (dec->eos) return ret; + if (dec->next_again_flag && + (!vdec_frame_based(vdec))) { + u32 parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + if (parser_wr_ptr >= dec->pre_parser_wr_ptr && + (parser_wr_ptr - dec->pre_parser_wr_ptr) < + again_threshold) { + int r = vdec_sync_input(vdec); + avs2_print(dec, + PRINT_FLAG_VDEC_DETAIL, "%s buf lelvel:%x\n", __func__, r); + return 0; + } + } +/* + if (vdec_stream_based(vdec) && (dec->pic_list_init_flag == 0) + && pre_decode_buf_level != 0) { + u32 rp, wp, level; + + rp = READ_PARSER_REG(PARSER_VIDEO_RP); + wp = READ_PARSER_REG(PARSER_VIDEO_WP); + if (wp < rp) + level = vdec->input.size + wp - rp; + else + level = wp - rp; + + if (level < pre_decode_buf_level) + return 0; + } +*/ + if ((dec->pic_list_init_flag == 0) || get_free_buf_count(dec) >= run_ready_min_buf_num) @@ -5604,6 +6211,9 @@ static void run(struct vdec_s *vdec, unsigned long mask, dec->vdec_cb = callback; /* dec->chunk = vdec_prepare_input(vdec); */ hevc_reset_core(vdec); + dec->pre_parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + dec->next_again_flag = 0; r = vdec_prepare_input(vdec, &dec->chunk); if (r < 0) { @@ -5917,11 +6527,12 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->platform_dev = pdev; dec->video_signal_type = 0; + dec->video_ori_signal_type = 0; if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX) dec->stat |= VP9_TRIGGER_FRAME_ENABLE; #if 1 if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && - pdata->config_len) { + pdata->config && pdata->config_len) { /*use ptr config for doubel_write_mode, etc*/ avs2_print(dec, 0, "pdata->config=%s\n", pdata->config); if (get_config_int(pdata->config, "avs2_double_write_mode", @@ -6005,6 +6616,13 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->init_flag = 0; dec->fatal_error = 0; dec->show_frame_num = 0; + if (pdata == NULL) { + pr_info("\namvdec_avs2 memory resource undefined.\n"); + uninit_mmu_buffers(dec); + /* devm_kfree(&pdev->dev, (void *)dec); */ + vfree((void *)dec); + return -EFAULT; + } if (debug) { pr_info("===AVS2 decoder mem resource 0x%lx size 0x%x\n", @@ -6012,9 +6630,11 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->buf_size); } - if (pdata->sys_info) + if (pdata->sys_info) { dec->vavs2_amstream_dec_info = *pdata->sys_info; - else { + dec->frame_width = dec->vavs2_amstream_dec_info.width; + dec->frame_height = dec->vavs2_amstream_dec_info.height; + } else { dec->vavs2_amstream_dec_info.width = 0; dec->vavs2_amstream_dec_info.height = 0; dec->vavs2_amstream_dec_info.rate = 30; @@ -6135,8 +6755,6 @@ static int __init amvdec_avs2_driver_init_module(void) #endif pr_debug("amvdec_avs2 module init\n"); - error_handle_policy = 0; - #ifdef ERROR_HANDLE_DEBUG dbg_nal_skip_flag = 0; dbg_nal_skip_count = 0; @@ -6154,19 +6772,19 @@ static int __init amvdec_avs2_driver_init_module(void) return -ENODEV; } - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL - /*&& get_cpu_major_id() != MESON_CPU_MAJOR_ID_GXLX*/) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2 + /*&& get_cpu_type() != MESON_CPU_MAJOR_ID_GXLX*/) { if (vdec_is_support_4k()) amvdec_avs2_profile.profile = "4k, 10bit, dwrite, compressed"; else amvdec_avs2_profile.profile = "10bit, dwrite, compressed"; + vcodec_profile_register(&amvdec_avs2_profile); } else { amvdec_avs2_profile.name = "avs2_unsupport"; } - vcodec_profile_register(&amvdec_avs2_profile); INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node, "avs2", avs2_configs, CONFIG_FOR_RW); @@ -6197,6 +6815,9 @@ MODULE_PARM_DESC(frame_height, "\n amvdec_avs2 frame_height\n"); module_param(debug, uint, 0664); MODULE_PARM_DESC(debug, "\n amvdec_avs2 debug\n"); +module_param(debug_again, uint, 0664); +MODULE_PARM_DESC(debug_again, "\n amvdec_avs2 debug_again\n"); + module_param(radr, uint, 0664); MODULE_PARM_DESC(radr, "\nradr\n"); @@ -6230,6 +6851,9 @@ MODULE_PARM_DESC(i_only_flag, "\n amvdec_avs2 i_only_flag\n"); module_param(error_handle_policy, uint, 0664); MODULE_PARM_DESC(error_handle_policy, "\n amvdec_avs2 error_handle_policy\n"); +module_param(re_search_seq_threshold, uint, 0664); +MODULE_PARM_DESC(re_search_seq_threshold, "\n amvdec_avs2 re_search_seq_threshold\n"); + module_param(buf_alloc_width, uint, 0664); MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n"); @@ -6310,6 +6934,16 @@ module_param_array(input_empty, uint, module_param_array(not_run_ready, uint, &max_decode_instance_num, 0664); +module_param(video_signal_type, uint, 0664); +MODULE_PARM_DESC(video_signal_type, "\n amvdec_avs2 video_signal_type\n"); + +module_param(force_video_signal_type, uint, 0664); +MODULE_PARM_DESC(force_video_signal_type, "\n amvdec_avs2 force_video_signal_type\n"); + +module_param(enable_force_video_signal_type, uint, 0664); +MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs2 enable_force_video_signal_type\n"); + + module_param(udebug_flag, uint, 0664); MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); @@ -6322,6 +6956,14 @@ MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n"); module_param(udebug_pause_decode_idx, uint, 0664); MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n"); +module_param(pre_decode_buf_level, int, 0664); +MODULE_PARM_DESC(pre_decode_buf_level, + "\n amvdec_avs2 pre_decode_buf_level\n"); + +module_param(again_threshold, uint, 0664); +MODULE_PARM_DESC(again_threshold, "\n again_threshold\n"); + + module_param(force_disp_pic_index, int, 0664); MODULE_PARM_DESC(force_disp_pic_index, "\n amvdec_h265 force_disp_pic_index\n"); diff --git a/firmware/video/video_ucode.bin b/firmware/video/video_ucode.bin index 937ee2bb0c994e11feda571df3a6180f8048cf4a..305fe0e714ae8226a3d040f1aa8770d38d9763ef 100644 GIT binary patch delta 7369 zcmeI1eNYtV9mk(%ciG$9+vgBN#F{i-0F8CzINs#EC@x0BfsG=*5CNm8s0j(2#b6xk@13;&LYMiWOlM2ko)X>qP1L&E9eaP5 znbY&-ss_V@oxQq^PhY6qdF;j5gKs^_4g9|1>Z^O6AAF~*?2WEph@))_2d-~?;^_8* zmtJlwEVOJ)Dl2#`ZL#Ib`pVb&hJ=QL+heX}o-G(Pb7F5^-6`kR?xGdXca^`=H{rm! zr6tc<^FdX0{x$CBeP=W36Uzp>4lj6XN8yp~Kej%Qv*p}`^0zO)8f~UiSC4zT?%9!1 zAAU3OdfP(wk@pub`#dx5%-jcdnb)6-HO5sPzc_7a+_wF=xAd8*lWME#?tGC)Jz7{* z1kP?qoWH5j`Pu1r-#m3`500*%8oTCDFIStG)i!u%)qLH+l;o90n{)PK+4*3%5ty&n zKH4b2n=y*F-N0QzV?^ZQV(HTpL~=<7vjx!K?{)4u%*G5di;~A1-Ia4kjbQ5|#i7 zD`n}RsBou82p548QH(`qYV{GeQ9sm1>vny;>o6bT#0`{)=j)qpae7%lmR}HN?uO{D zZ|S&Z8HUq}%Wi=6GQ7n_7+3*5T(>z@1fmFw1k4Z@gJ@BvdxWCMj!2-$2?2^S979Fe ziDPI6yM9cmKO${#SVi7}sz}`r;bbPFA=6Xh&S;v6OnAa9lo8%)BE*~t=)9&JltiC~ z0$KMY;sw=A5bZ+wHglyJngdDfkqUQ$5HCN@Q>?jA`KfZ>|%`P=G=hd+K6Uz+Ewi>qChP!i7 zJEbJ!XY$aDEZ~No_9_{PRnIM?UFBC=8Tcg>9##McPHCFbDInyMdXCYtl~N50KEPk) zp~mVH%{+L}`&dIB#eSukm%29#-;gHMM|@d*#2Hq-Q*7a#Gg^4nF&M4grvP%~{cXIW zURy9(Z!gH#+d+co+Mzb>TSa|tqojY0*soSA>eU;lhxNYx*rvt<5C5WINSMGEV|R8vgBU{yr=eBRzGX z3RjNPZ;)$?kr>5GdBBseARcG^0p(#+DY8EV5`f2+@+0k73CS~L0nY>iarmm;_&8MX z$E7Ha0x@__t}%-e)A6=k&mZXbz?P4S%v6 zje;Wn`cw29dB+OWIL|fF$Up||A05*)(P+YA9W?@5XQ6S!NRK3AQe$@ceOTN{i@a#_ zqT?U<^&FG{|B2gkP%hV&V$`y0dF|-z1@w#IwS}qPj3pw|o<+v9u zof=xC6Ph+S8HAR86)o{Nwg;{KKE8m?Vde|zi$K13JLg^;Q9JEk<^K_1@_p0W#}|Kr z#+RU&n|JpHjW0p<_Tc)U*c}ve1-|xte7RfT^e6M0pfa&im=2;F{@16Lr!Hm7^b_%{pFLpg~2PBonAi zhCc{UWCE1_e3y&}OH%r`e9$D5MTo|dBg4v)cs_~l_pL;7P&x(vu5u)v0ykBVm}vqK zjU);PB#C&?JCpw$9!bD}mn82YLXt5WNla#qBUkc*BZFG&={ zlcmbWK$3_XRFXu~RCEZCygRCyq^C*}H7!+=XzBS~BpHiii&3q7<|DN7zlf2{d9Hje z!ms0^|JBb5Wo|xqYq|_kq~FJbR7QAI8i!e>$)j>w7vcBVATJ;5Zcmq)6d2)6r6DS0 z3p^bz$qsMXY5o2kT?+sM{vF*-kh93#7i_pYx*G~9Cp zvcp658N%Js4dEn6rQbk1WTu6Uu$LkIMTUJJs}p5i1sm=^1tF{iPQtaUx;y K3EX;tGyMyuin;Ru delta 5917 zcmd6q4^R}>9mn6>U2fmITMkbPnDI{z8Z|}0<8M$WxZo5Kn}n#bCW3!r5)B>o$fzZ; zfrm+|L98g|o`WN~Bm(}4_y@g*Sjno1VxlqPpJLikCMISwHA!1BhK_0b_Lje$#_P^- zGr1XNmt}50`~Ces@AnqcG=VftC`rAs^2}?Wef#wCtDeozvz|I!`Lov^O3pYI3YPHTvD?+UFwf z=6-%>&62;n_qHuAdu@7QXZ^W?ynL;*b$R{Rx*I3*TQG6FWw~u`e#`oAzTlzi|wUDxSH@mzx*7lW+%hTwZy(UR+w2!|vZE{8~*lGv6RPU@x z1%A(@6XKIler9}1TH?Z_N(cNITDo9q(eq2=3#ntV5IG)Xz3{yAv4zW>3FDoKt_dj* zO-Oo(pCqJ#u20ujyMG111;DY3r{^>*nC*hTlcMBeQbkZ1m7?Hc!Xx6Gfz6@z&5&sU^K8h)(8ux<=DMAncJBmk0M7IzI4?stgLC9OlMH={++$^M#@QamTt6cN z1(zYYnY6;RQ2}x|`{pQ8pp(H;7{na4uR^zHs2svV774S1*OJ--!R_mS`N1Rj?m*ei zWILP{M1}(*H$$HaW*10+ruUUsZ^(hIK`hjPYUpl&YX{h=K|S6+3>!k%-41II1e2Ra zvWY4k2+1!rHwOdUy#MnTb%ZfE#Xi6_a`n`R@7_6fefO5^W_ODKIry&EI|pUEtTK6n zEoe(30W!GBmS?UNDXxH{{9|L3C%`%wqVVnFvejfO0x@`*x)^DYp)1zAlbDoiHQ5Vu zkQvs_NeqStH_0GBq%yb=k00`q+2s+aTzu>6>WK^1zHE2;GA$;@U?4(8AA;|f7FfaH zcj5q>)t6D*DOUJ~hXgT2ZMjt8dtC}5!B;Nnb=n&e#5(y7gy@Wop##it_w-vIRGULZ z{>C;kbbwcRe@Ij)f4vok$|m=|K<4(&E53CMlcCDsCCdO;s~@AyBC1S0h#-_^J!skF zIf$I}!9ys;)TWz~5OC6;>wanXFcc^5feQaW`2jj}8%`Fq>$EHe{~VsC^)YxHY@=5h zdTKOjg$h!Dl&yKKB&kRN{DYJX%UU}`XtfKYn_equWd)6B3Jk}kmZ=#FY~Hw13qCgA z<{eRL@s6NZV{ts~IE;uuhR~HwC^KE%4gEJ-CJ~E%?gGRD)*IK<)liAj0Md3DFm*Rj zrt-fdNwzE_r51Gu{Z|~0rbCaQ!f^gjKLp|Bp+|%eO(Lw5fBJ&~%=K&%mKuMze4@pC)vLA0|?z1R1#0qkNKP8Ex z_QN=b{;d^dk0jB+Uk3F)Y-r%0y27Ogng3{q7yC!?8u(MKK zJBX%j#iPur^?$!axS*$8iW8f=)pEc%YvhamoZw0kUB^(AKt84Q48@D!D@d=!;3w17 z>xN}5r3^3Z+n4yi?bAM>+`chvXEk=h@E?d@L8rq|P(L~yx`J=Q z2wEJ6GtrK=Xy;k4L`CqI0wS2~rS`zPKz z#x-?|A)Q)d7^T(pmriZ|QRzr6EpTz^NEM4o=$0-KKPL^=%KJ;Ft<$Bmi=sL@fOUuT YIJ$It3|%@S&W}mw6t4YLockU859^WLkpKVy