| /* |
| * drivers/amlogic/amports/vh265.c |
| * |
| * Copyright (C) 2015 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| */ |
| #define DEBUG |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/types.h> |
| #include <linux/errno.h> |
| #include <linux/interrupt.h> |
| #include <linux/semaphore.h> |
| #include <linux/delay.h> |
| #include <linux/timer.h> |
| #include <linux/kfifo.h> |
| #include <linux/kthread.h> |
| #include <linux/platform_device.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/utils/amstream.h> |
| #include <linux/amlogic/media/utils/vformat.h> |
| #include <linux/amlogic/media/frame_sync/ptsserv.h> |
| #include <linux/amlogic/media/canvas/canvas.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/vfm/vframe_provider.h> |
| #include <linux/amlogic/media/vfm/vframe_receiver.h> |
| #include <linux/dma-mapping.h> |
| #include <linux/dma-contiguous.h> |
| #include <linux/slab.h> |
| #include <linux/mm.h> |
| #include <linux/timer.h> |
| //#include <linux/amlogic/tee.h> |
| #include <uapi/linux/tee.h> |
| #include <linux/sched/clock.h> |
| #include "../../../stream_input/amports/amports_priv.h" |
| #include <linux/amlogic/media/codec_mm/codec_mm.h> |
| #include "../../decoder/utils/decoder_mmu_box.h" |
| #include "../../decoder/utils/decoder_bmmu_box.h" |
| #include "../../decoder/utils/config_parser.h" |
| #include "../../decoder/utils/firmware.h" |
| #include "../../../common/chips/decoder_cpu_ver_info.h" |
| #include "../../decoder/utils/vdec_v4l2_buffer_ops.h" |
| #include <media/v4l2-mem2mem.h> |
| #include <linux/crc32.h> |
| |
| /* |
| to enable DV of frame mode |
| #define DOLBY_META_SUPPORT in ucode |
| */ |
| |
| #define HEVC_8K_LFTOFFSET_FIX |
| #define SUPPORT_LONG_TERM_RPS |
| |
| //#define CO_MV_COMPRESS |
| |
| #define CONSTRAIN_MAX_BUF_NUM |
| |
| #define SWAP_HEVC_UCODE |
| #define DETREFILL_ENABLE |
| |
| #define AGAIN_HAS_THRESHOLD |
| /*#define TEST_NO_BUF*/ |
| #define HEVC_PIC_STRUCT_SUPPORT |
| #define MULTI_INSTANCE_SUPPORT |
| #define USE_UNINIT_SEMA |
| |
| /* .buf_size = 0x100000*16, |
| //4k2k , 0x100000 per buffer */ |
| /* 4096x2304 , 0x120000 per buffer */ |
| #define MPRED_8K_MV_BUF_SIZE (0x120000*4) |
| #define MPRED_4K_MV_BUF_SIZE (0x120000) |
| #define MPRED_MV_BUF_SIZE (0x3fc00) |
| |
| #define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000 |
| #define MMU_COMPRESS_HEADER_SIZE_4K 0x48000 |
| #define MMU_COMPRESS_HEADER_SIZE_8K 0x120000 |
| #define DB_NUM 20 |
| |
| #define MAX_FRAME_4K_NUM 0x1200 |
| #define MAX_FRAME_8K_NUM ((MAX_FRAME_4K_NUM) * 4) |
| |
| //#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4) |
| #define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7 |
| |
| #define HEVC_ASSIST_MMU_MAP_ADDR 0x3009 |
| |
| #define HEVC_CM_HEADER_START_ADDR 0x3628 |
| #define HEVC_SAO_MMU_VH1_ADDR 0x363b |
| #define HEVC_SAO_MMU_VH0_ADDR 0x363a |
| |
| #define HEVC_DBLK_CFGB 0x350b |
| #define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7 |
| #define SWAP_HEVC_OFFSET (3 * 0x1000) |
| |
| #define MEM_NAME "codec_265" |
| /* #include <mach/am_regs.h> */ |
| #include <linux/amlogic/media/utils/vdec_reg.h> |
| |
| #include "../../decoder/utils/vdec.h" |
| #include "../../decoder/utils/amvdec.h" |
| #include <linux/amlogic/media/video_sink/video.h> |
| #include <linux/amlogic/media/codec_mm/configs.h> |
| #include "../../decoder/utils/vdec_feature.h" |
| |
| #define SEND_LMEM_WITH_RPM |
| #define SUPPORT_10BIT |
| /* #define ERROR_HANDLE_DEBUG */ |
| |
| #ifndef STAT_KTHREAD |
| #define STAT_KTHREAD 0x40 |
| #endif |
| |
| #ifdef MULTI_INSTANCE_SUPPORT |
| #define MAX_DECODE_INSTANCE_NUM 9 |
| #define MULTI_DRIVER_NAME "ammvdec_h265_v4l" |
| #endif |
| #define DRIVER_NAME "amvdec_h265_v4l" |
| #define DRIVER_HEADER_NAME "amvdec_h265_header" |
| |
| #define PUT_INTERVAL (HZ/100) |
| #define ERROR_SYSTEM_RESET_COUNT 200 |
| |
| #define PTS_NORMAL 0 |
| #define PTS_NONE_REF_USE_DURATION 1 |
| |
| #define PTS_MODE_SWITCHING_THRESHOLD 3 |
| #define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3 |
| |
| #define DUR2PTS(x) ((x)*90/96) |
| |
| #define MAX_SIZE_8K (8192 * 4608) |
| #define MAX_SIZE_4K (4096 * 2304) |
| #define MAX_SIZE_2K (1920 * 1088) |
| |
| #define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K) |
| #define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088)) |
| |
| #define SEI_UserDataITU_T_T35 4 |
| #define INVALID_IDX -1 /* Invalid buffer index.*/ |
| |
| static struct semaphore h265_sema; |
| |
| struct hevc_state_s; |
| static int hevc_print(struct hevc_state_s *hevc, |
| int debug_flag, const char *fmt, ...); |
| static int hevc_print_cont(struct hevc_state_s *hevc, |
| int debug_flag, const char *fmt, ...); |
| static int vh265_vf_states(struct vframe_states *states, void *); |
| static struct vframe_s *vh265_vf_peek(void *); |
| static struct vframe_s *vh265_vf_get(void *); |
| static void vh265_vf_put(struct vframe_s *, void *); |
| static int vh265_event_cb(int type, void *data, void *private_data); |
| #ifdef MULTI_INSTANCE_SUPPORT |
| static int vmh265_stop(struct hevc_state_s *hevc); |
| static s32 vh265_init(struct vdec_s *vdec); |
| static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask); |
| static void reset_process_time(struct hevc_state_s *hevc); |
| static void start_process_time(struct hevc_state_s *hevc); |
| static void restart_process_time(struct hevc_state_s *hevc); |
| static void timeout_process(struct hevc_state_s *hevc); |
| #else |
| static s32 vh265_init(struct hevc_state_s *hevc); |
| #endif |
| static void vh265_prot_init(struct hevc_state_s *hevc); |
| static int vh265_local_init(struct hevc_state_s *hevc); |
| static void vh265_check_timer_func(struct timer_list *timer); |
| static void config_decode_mode(struct hevc_state_s *hevc); |
| |
| static const char vh265_dec_id[] = "vh265-dev"; |
| |
| #define PROVIDER_NAME "decoder.h265" |
| #define MULTI_INSTANCE_PROVIDER_NAME "vdec.h265" |
| |
| static const struct vframe_operations_s vh265_vf_provider = { |
| .peek = vh265_vf_peek, |
| .get = vh265_vf_get, |
| .put = vh265_vf_put, |
| .event_cb = vh265_event_cb, |
| .vf_states = vh265_vf_states, |
| }; |
| |
| static struct vframe_provider_s vh265_vf_prov; |
| |
| static u32 bit_depth_luma; |
| static u32 bit_depth_chroma; |
| static u32 video_signal_type; |
| static int start_decode_buf_level = 0x8000; |
| static unsigned int decode_timeout_val = 200; |
| |
| static u32 run_ready_min_buf_num = 1; |
| static u32 disable_ip_mode; |
| static u32 print_lcu_error = 1; |
| /*data_resend_policy: |
| bit 0, stream base resend data when decoding buf empty |
| */ |
| static u32 data_resend_policy = 1; |
| static int poc_num_margin = 1000; |
| static int poc_error_limit = 30; |
| |
| static u32 dirty_time_threshold = 2000; |
| static u32 dirty_count_threshold = 200; |
| static u32 dirty_buffersize_threshold = 0x800000; |
| |
| |
| #define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000 |
| /* |
| static const char * const video_format_names[] = { |
| "component", "PAL", "NTSC", "SECAM", |
| "MAC", "unspecified", "unspecified", "unspecified" |
| }; |
| |
| static const char * const color_primaries_names[] = { |
| "unknown", "bt709", "undef", "unknown", |
| "bt470m", "bt470bg", "smpte170m", "smpte240m", |
| "film", "bt2020" |
| }; |
| |
| static const char * const transfer_characteristics_names[] = { |
| "unknown", "bt709", "undef", "unknown", |
| "bt470m", "bt470bg", "smpte170m", "smpte240m", |
| "linear", "log100", "log316", "iec61966-2-4", |
| "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", |
| "smpte-st-2084", "smpte-st-428" |
| }; |
| |
| static const char * const matrix_coeffs_names[] = { |
| "GBR", "bt709", "undef", "unknown", |
| "fcc", "bt470bg", "smpte170m", "smpte240m", |
| "YCgCo", "bt2020nc", "bt2020c" |
| }; |
| */ |
| #ifdef SUPPORT_10BIT |
| #define HEVC_CM_BODY_START_ADDR 0x3626 |
| #define HEVC_CM_BODY_LENGTH 0x3627 |
| #define HEVC_CM_HEADER_LENGTH 0x3629 |
| #define HEVC_CM_HEADER_OFFSET 0x362b |
| #define HEVC_SAO_CTRL9 0x362d |
| #define LOSLESS_COMPRESS_MODE |
| /* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */ |
| /* double_write_mode: |
| * 0, no double write; |
| * 1, 1:1 ratio; |
| * 2, (1/4):(1/4) ratio; |
| * 3, (1/4):(1/4) ratio, with both compressed frame included |
| * 4, (1/2):(1/2) ratio; |
| * 5, (1/2):(1/2) ratio, with both compressed frame included |
| * 8, (1/8):(1/8) ratio, from t7 |
| * 0x10, double write only |
| * 0x100, if > 1080p,use mode 4,else use mode 1; |
| * 0x200, if > 1080p,use mode 2,else use mode 1; |
| * 0x300, if > 720p, use mode 4, else use mode 1; |
| * 0x1000,if > 1080p,use mode 3, else if > 960*540, use mode 4, else use mode 1; |
| */ |
| static u32 double_write_mode; |
| |
| /*#define DECOMP_HEADR_SURGENT*/ |
| |
| static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */ |
| static u32 enable_mem_saving = 1; |
| static u32 workaround_enable; |
| static u32 force_w_h; |
| #endif |
| static u32 force_fps; |
| static u32 pts_unstable; |
| #define H265_DEBUG_BUFMGR 0x01 |
| #define H265_DEBUG_BUFMGR_MORE 0x02 |
| #define H265_DEBUG_DETAIL 0x04 |
| #define H265_DEBUG_REG 0x08 |
| #define H265_DEBUG_MAN_SEARCH_NAL 0x10 |
| #define H265_DEBUG_MAN_SKIP_NAL 0x20 |
| #define H265_DEBUG_DISPLAY_CUR_FRAME 0x40 |
| #define H265_DEBUG_FORCE_CLK 0x80 |
| #define H265_DEBUG_SEND_PARAM_WITH_REG 0x100 |
| #define H265_DEBUG_NO_DISPLAY 0x200 |
| #define H265_DEBUG_DISCARD_NAL 0x400 |
| #define H265_DEBUG_OUT_PTS 0x800 |
| #define H265_DEBUG_DUMP_PIC_LIST 0x1000 |
| #define H265_DEBUG_PRINT_SEI 0x2000 |
| #define H265_DEBUG_PIC_STRUCT 0x4000 |
| #define H265_DEBUG_HAS_AUX_IN_SLICE 0x8000 |
| #define H265_DEBUG_DIS_LOC_ERROR_PROC 0x10000 |
| #define H265_DEBUG_DIS_SYS_ERROR_PROC 0x20000 |
| #define H265_NO_CHANG_DEBUG_FLAG_IN_CODE 0x40000 |
| #define H265_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000 |
| #define H265_DEBUG_HW_RESET 0x100000 |
| #define H265_CFG_CANVAS_IN_DECODE 0x200000 |
| #define H265_DEBUG_DV 0x400000 |
| #define H265_DEBUG_NO_EOS_SEARCH_DONE 0x800000 |
| #define H265_DEBUG_NOT_USE_LAST_DISPBUF 0x1000000 |
| #define H265_DEBUG_IGNORE_CONFORMANCE_WINDOW 0x2000000 |
| #define H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x4000000 |
| #ifdef MULTI_INSTANCE_SUPPORT |
| #define PRINT_FLAG_ERROR 0x0 |
| #define IGNORE_PARAM_FROM_CONFIG 0x08000000 |
| #define PRINT_FRAMEBASE_DATA 0x10000000 |
| #define PRINT_FLAG_VDEC_STATUS 0x20000000 |
| #define PRINT_FLAG_VDEC_DETAIL 0x40000000 |
| #define PRINT_FLAG_V4L_DETAIL 0x80000000 |
| #endif |
| |
| #define BUF_POOL_SIZE 32 |
| #define MAX_BUF_NUM 24 |
| #define MAX_REF_PIC_NUM 24 |
| #define MAX_REF_ACTIVE 16 |
| |
| #ifdef MV_USE_FIXED_BUF |
| #define BMMU_MAX_BUFFERS (BUF_POOL_SIZE + 1) |
| #define VF_BUFFER_IDX(n) (n) |
| #define BMMU_WORKSPACE_ID (BUF_POOL_SIZE) |
| #else |
| #define BMMU_MAX_BUFFERS (BUF_POOL_SIZE + 1 + MAX_REF_PIC_NUM) |
| #define VF_BUFFER_IDX(n) (n) |
| #define BMMU_WORKSPACE_ID (BUF_POOL_SIZE) |
| #define MV_BUFFER_IDX(n) (BUF_POOL_SIZE + 1 + n) |
| #endif |
| |
| #define HEVC_MV_INFO 0x310d |
| #define HEVC_QP_INFO 0x3137 |
| #define HEVC_SKIP_INFO 0x3136 |
| |
| const u32 h265_version = 201602101; |
| static u32 debug_mask = 0xffffffff; |
| static u32 log_mask; |
| static u32 debug; |
| static u32 radr; |
| static u32 rval; |
| static u32 dbg_cmd; |
| static u32 dump_nal; |
| static u32 dbg_skip_decode_index; |
| /* |
| * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config |
| * bit 8~23, for HEVC_SAO_CTRL1 endian config |
| */ |
| static u32 endian; |
| #define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8) |
| #define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf) |
| |
| #ifdef ERROR_HANDLE_DEBUG |
| static u32 dbg_nal_skip_flag; |
| /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */ |
| static u32 dbg_nal_skip_count; |
| #endif |
| /*for debug*/ |
| static u32 force_bufspec; |
| |
| /* |
| udebug_flag: |
| bit 0, enable ucode print |
| bit 1, enable ucode detail print |
| bit [31:16] not 0, pos to dump lmem |
| bit 2, pop bits to lmem |
| bit [11:8], pre-pop bits for alignment (when bit 2 is 1) |
| */ |
| static u32 udebug_flag; |
| /* |
| when udebug_flag[1:0] is not 0 |
| udebug_pause_pos not 0, |
| pause position |
| */ |
| static u32 udebug_pause_pos; |
| /* |
| when udebug_flag[1:0] is not 0 |
| and udebug_pause_pos is not 0, |
| pause only when DEBUG_REG2 is equal to this val |
| */ |
| static u32 udebug_pause_val; |
| |
| static u32 udebug_pause_decode_idx; |
| |
| static u32 decode_pic_begin; |
| static uint slice_parse_begin; |
| static u32 step; |
| static bool is_reset; |
| |
| #ifdef CONSTRAIN_MAX_BUF_NUM |
| static u32 run_ready_max_vf_only_num; |
| static u32 run_ready_display_q_num; |
| /*0: not check |
| 0xff: work_pic_num |
| */ |
| static u32 run_ready_max_buf_num = 0xff; |
| #endif |
| |
| static u32 dynamic_buf_num_margin = 7; |
| static u32 buf_alloc_width; |
| static u32 buf_alloc_height; |
| |
| static u32 max_buf_num = 16; |
| static u32 buf_alloc_size; |
| /*static u32 re_config_pic_flag;*/ |
| /* |
| *bit[0]: 0, |
| *bit[1]: 0, always release cma buffer when stop |
| *bit[1]: 1, never release cma buffer when stop |
| *bit[0]: 1, when stop, release cma buffer if blackout is 1; |
| *do not release cma buffer is blackout is not 1 |
| * |
| *bit[2]: 0, when start decoding, check current displayed buffer |
| * (only for buffer decoded by h265) if blackout is 0 |
| * 1, do not check current displayed buffer |
| * |
| *bit[3]: 1, if blackout is not 1, do not release current |
| * displayed cma buffer always. |
| */ |
| /* set to 1 for fast play; |
| * set to 8 for other case of "keep last frame" |
| */ |
| static u32 buffer_mode = 1; |
| |
| /* buffer_mode_dbg: debug only*/ |
| static u32 buffer_mode_dbg = 0xffff0000; |
| /**/ |
| /* |
| *bit[1:0]PB_skip_mode: 0, start decoding at begin; |
| *1, start decoding after first I; |
| *2, only decode and display none error picture; |
| *3, start decoding and display after IDR,etc |
| *bit[31:16] PB_skip_count_after_decoding (decoding but not display), |
| *only for mode 0 and 1. |
| */ |
| static u32 nal_skip_policy = 2; |
| |
| /* |
| *bit 0, 1: only display I picture; |
| *bit 1, 1: only decode I picture; |
| */ |
| static u32 i_only_flag; |
| static u32 skip_nal_count = 500; |
| /* |
| bit 0, fast output first I picture |
| */ |
| static u32 fast_output_enable = 1; |
| |
| static u32 frmbase_cont_bitlevel = 0x60; |
| |
| /* |
| use_cma: 1, use both reserver memory and cma for buffers |
| 2, only use cma for buffers |
| */ |
| static u32 use_cma = 2; |
| |
| #define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf)) |
| /* |
| static u32 prefix_aux_buf_size = (16 * 1024); |
| static u32 suffix_aux_buf_size; |
| */ |
| static u32 prefix_aux_buf_size = (12 * 1024); |
| static u32 suffix_aux_buf_size = (12 * 1024); |
| |
| 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 (hevc_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 6: 0, do not check head error |
| * 1, check head error |
| * |
| *bit 7: 0, allow to print over decode |
| * 1, NOT allow to print over decode |
| * |
| *bit 8: 0, use interlace policy |
| * 1, NOT use interlace policy |
| *bit 9: 0, discard dirty data on playback start |
| * 1, do not discard dirty data on playback start |
| * |
| */ |
| |
| static u32 error_handle_policy; |
| static u32 error_skip_nal_count = 6; |
| static u32 error_handle_threshold = 30; |
| static u32 error_handle_nal_skip_threshold = 10; |
| static u32 error_handle_system_threshold = 30; |
| static u32 interlace_enable = 1; |
| static u32 fr_hint_status; |
| |
| /* |
| *parser_sei_enable: |
| * bit 0, sei; |
| * bit 1, sei_suffix (fill aux buf) |
| * bit 2, fill sei to aux buf (when bit 0 is 1) |
| * bit 8, debug flag |
| */ |
| static u32 parser_sei_enable; |
| static u32 parser_dolby_vision_enable = 1; |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| static u32 dolby_meta_with_el; |
| static u32 dolby_el_flush_th = 2; |
| #endif |
| /* this is only for h265 mmu enable */ |
| |
| static u32 mmu_enable = 1; |
| static u32 mmu_enable_force; |
| static u32 work_buf_size; |
| static unsigned int force_disp_pic_index; |
| static unsigned int disp_vframe_valve_level; |
| static int pre_decode_buf_level = 0x1000; |
| static unsigned int pic_list_debug; |
| #ifdef HEVC_8K_LFTOFFSET_FIX |
| /* performance_profile: bit 0, multi slice in ucode |
| */ |
| static unsigned int performance_profile = 1; |
| #endif |
| #ifdef MULTI_INSTANCE_SUPPORT |
| static unsigned int max_decode_instance_num |
| = MAX_DECODE_INSTANCE_NUM; |
| static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int max_get_frame_interval[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int run_count[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM]; |
| static unsigned int ref_frame_mark_flag[MAX_DECODE_INSTANCE_NUM] = |
| {1, 1, 1, 1, 1, 1, 1, 1, 1}; |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static unsigned char get_idx(struct hevc_state_s *hevc); |
| #endif |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| static u32 dv_toggle_prov_name; |
| |
| static u32 dv_debug; |
| |
| static u32 force_bypass_dvenl; |
| #endif |
| #endif |
| |
| /* |
| *[3:0] 0: default use config from omx. |
| * 1: force enable fence. |
| * 2: disable fence. |
| *[7:4] 0: fence use for driver. |
| * 1: fence fd use for app. |
| */ |
| static u32 force_config_fence; |
| |
| /* |
| *The parameter sps_max_dec_pic_buffering_minus1_0+1 |
| *in SPS is the minimum DPB size required for stream |
| *(note: this parameter does not include the frame |
| *currently being decoded) +1 (decoding the current |
| *frame) +1 (decoding the current frame will only |
| *update refrence frame information, such as reference |
| *relation, when the next frame is decoded) |
| */ |
| static u32 detect_stuck_buffer_margin = 3; |
| |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| #define get_dbg_flag(hevc) ((debug_mask & (1 << hevc->index)) ? debug : 0) |
| #define get_dbg_flag2(hevc) ((debug_mask & (1 << get_idx(hevc))) ? debug : 0) |
| #define is_log_enable(hevc) ((log_mask & (1 << hevc->index)) ? 1 : 0) |
| #else |
| #define get_dbg_flag(hevc) debug |
| #define get_dbg_flag2(hevc) debug |
| #define is_log_enable(hevc) (log_mask ? 1 : 0) |
| #define get_valid_double_write_mode(hevc) double_write_mode |
| #define get_buf_alloc_width(hevc) buf_alloc_width |
| #define get_buf_alloc_height(hevc) buf_alloc_height |
| #define get_dynamic_buf_num_margin(hevc) dynamic_buf_num_margin |
| #endif |
| #define get_buffer_mode(hevc) buffer_mode |
| |
| |
| static DEFINE_SPINLOCK(lock); |
| struct task_struct *h265_task = NULL; |
| #undef DEBUG_REG |
| #ifdef DEBUG_REG |
| void WRITE_VREG_DBG(unsigned adr, unsigned val) |
| { |
| if (debug & H265_DEBUG_REG) |
| pr_info("%s(%x, %x)\n", __func__, adr, val); |
| WRITE_VREG(adr, val); |
| } |
| |
| #undef WRITE_VREG |
| #define WRITE_VREG WRITE_VREG_DBG |
| #endif |
| extern u32 trickmode_i; |
| |
| static DEFINE_MUTEX(vh265_mutex); |
| |
| static DEFINE_MUTEX(vh265_log_mutex); |
| |
| //static struct vdec_info *gvs; |
| |
| static u32 without_display_mode; |
| |
| static u32 mv_buf_dynamic_alloc; |
| |
| /************************************************** |
| * |
| *h265 buffer management include |
| * |
| *************************************************** |
| */ |
| enum NalUnitType { |
| NAL_UNIT_CODED_SLICE_TRAIL_N = 0, /* 0 */ |
| NAL_UNIT_CODED_SLICE_TRAIL_R, /* 1 */ |
| |
| NAL_UNIT_CODED_SLICE_TSA_N, /* 2 */ |
| /* Current name in the spec: TSA_R */ |
| NAL_UNIT_CODED_SLICE_TLA, /* 3 */ |
| |
| NAL_UNIT_CODED_SLICE_STSA_N, /* 4 */ |
| NAL_UNIT_CODED_SLICE_STSA_R, /* 5 */ |
| |
| NAL_UNIT_CODED_SLICE_RADL_N, /* 6 */ |
| /* Current name in the spec: RADL_R */ |
| NAL_UNIT_CODED_SLICE_DLP, /* 7 */ |
| |
| NAL_UNIT_CODED_SLICE_RASL_N, /* 8 */ |
| /* Current name in the spec: RASL_R */ |
| NAL_UNIT_CODED_SLICE_TFD, /* 9 */ |
| |
| NAL_UNIT_RESERVED_10, |
| NAL_UNIT_RESERVED_11, |
| NAL_UNIT_RESERVED_12, |
| NAL_UNIT_RESERVED_13, |
| NAL_UNIT_RESERVED_14, |
| NAL_UNIT_RESERVED_15, |
| |
| /* Current name in the spec: BLA_W_LP */ |
| NAL_UNIT_CODED_SLICE_BLA, /* 16 */ |
| /* Current name in the spec: BLA_W_DLP */ |
| NAL_UNIT_CODED_SLICE_BLANT, /* 17 */ |
| NAL_UNIT_CODED_SLICE_BLA_N_LP, /* 18 */ |
| /* Current name in the spec: IDR_W_DLP */ |
| NAL_UNIT_CODED_SLICE_IDR, /* 19 */ |
| NAL_UNIT_CODED_SLICE_IDR_N_LP, /* 20 */ |
| NAL_UNIT_CODED_SLICE_CRA, /* 21 */ |
| NAL_UNIT_RESERVED_22, |
| NAL_UNIT_RESERVED_23, |
| |
| NAL_UNIT_RESERVED_24, |
| NAL_UNIT_RESERVED_25, |
| NAL_UNIT_RESERVED_26, |
| NAL_UNIT_RESERVED_27, |
| NAL_UNIT_RESERVED_28, |
| NAL_UNIT_RESERVED_29, |
| NAL_UNIT_RESERVED_30, |
| NAL_UNIT_RESERVED_31, |
| |
| NAL_UNIT_VPS, /* 32 */ |
| NAL_UNIT_SPS, /* 33 */ |
| NAL_UNIT_PPS, /* 34 */ |
| NAL_UNIT_ACCESS_UNIT_DELIMITER, /* 35 */ |
| NAL_UNIT_EOS, /* 36 */ |
| NAL_UNIT_EOB, /* 37 */ |
| NAL_UNIT_FILLER_DATA, /* 38 */ |
| NAL_UNIT_SEI, /* 39 Prefix SEI */ |
| NAL_UNIT_SEI_SUFFIX, /* 40 Suffix SEI */ |
| NAL_UNIT_RESERVED_41, |
| NAL_UNIT_RESERVED_42, |
| NAL_UNIT_RESERVED_43, |
| NAL_UNIT_RESERVED_44, |
| NAL_UNIT_RESERVED_45, |
| NAL_UNIT_RESERVED_46, |
| NAL_UNIT_RESERVED_47, |
| NAL_UNIT_UNSPECIFIED_48, |
| NAL_UNIT_UNSPECIFIED_49, |
| NAL_UNIT_UNSPECIFIED_50, |
| NAL_UNIT_UNSPECIFIED_51, |
| NAL_UNIT_UNSPECIFIED_52, |
| NAL_UNIT_UNSPECIFIED_53, |
| NAL_UNIT_UNSPECIFIED_54, |
| NAL_UNIT_UNSPECIFIED_55, |
| NAL_UNIT_UNSPECIFIED_56, |
| NAL_UNIT_UNSPECIFIED_57, |
| NAL_UNIT_UNSPECIFIED_58, |
| NAL_UNIT_UNSPECIFIED_59, |
| NAL_UNIT_UNSPECIFIED_60, |
| NAL_UNIT_UNSPECIFIED_61, |
| NAL_UNIT_UNSPECIFIED_62, |
| NAL_UNIT_UNSPECIFIED_63, |
| NAL_UNIT_INVALID, |
| }; |
| |
| /* --------------------------------------------------- */ |
| /* Amrisc Software Interrupt */ |
| /* --------------------------------------------------- */ |
| #define AMRISC_STREAM_EMPTY_REQ 0x01 |
| #define AMRISC_PARSER_REQ 0x02 |
| #define AMRISC_MAIN_REQ 0x04 |
| |
| /* --------------------------------------------------- */ |
| /* HEVC_DEC_STATUS define */ |
| /* --------------------------------------------------- */ |
| #define HEVC_DEC_IDLE 0x0 |
| #define HEVC_NAL_UNIT_VPS 0x1 |
| #define HEVC_NAL_UNIT_SPS 0x2 |
| #define HEVC_NAL_UNIT_PPS 0x3 |
| #define HEVC_NAL_UNIT_CODED_SLICE_SEGMENT 0x4 |
| #define HEVC_CODED_SLICE_SEGMENT_DAT 0x5 |
| #define HEVC_SLICE_DECODING 0x6 |
| #define HEVC_NAL_UNIT_SEI 0x7 |
| #define HEVC_SLICE_SEGMENT_DONE 0x8 |
| #define HEVC_NAL_SEARCH_DONE 0x9 |
| #define HEVC_DECPIC_DATA_DONE 0xa |
| #define HEVC_DECPIC_DATA_ERROR 0xb |
| #define HEVC_SEI_DAT 0xc |
| #define HEVC_SEI_DAT_DONE 0xd |
| #define HEVC_NAL_DECODE_DONE 0xe |
| #define HEVC_OVER_DECODE 0xf |
| |
| #define HEVC_DATA_REQUEST 0x12 |
| |
| #define HEVC_DECODE_BUFEMPTY 0x20 |
| #define HEVC_DECODE_TIMEOUT 0x21 |
| #define HEVC_SEARCH_BUFEMPTY 0x22 |
| #define HEVC_DECODE_OVER_SIZE 0x23 |
| #define HEVC_DECODE_BUFEMPTY2 0x24 |
| #define HEVC_FIND_NEXT_PIC_NAL 0x50 |
| #define HEVC_FIND_NEXT_DVEL_NAL 0x51 |
| |
| #define HEVC_DUMP_LMEM 0x30 |
| |
| #define HEVC_4k2k_60HZ_NOT_SUPPORT 0x80 |
| #define HEVC_DISCARD_NAL 0xf0 |
| #define HEVC_ACTION_DEC_CONT 0xfd |
| #define HEVC_ACTION_ERROR 0xfe |
| #define HEVC_ACTION_DONE 0xff |
| |
| /* --------------------------------------------------- */ |
| /* Include "parser_cmd.h" */ |
| /* --------------------------------------------------- */ |
| #define PARSER_CMD_SKIP_CFG_0 0x0000090b |
| |
| #define PARSER_CMD_SKIP_CFG_1 0x1b14140f |
| |
| #define PARSER_CMD_SKIP_CFG_2 0x001b1910 |
| |
| #define PARSER_CMD_NUMBER 37 |
| |
| /************************************************** |
| * |
| *h265 buffer management |
| * |
| *************************************************** |
| */ |
| /* #define BUFFER_MGR_ONLY */ |
| /* #define CONFIG_HEVC_CLK_FORCED_ON */ |
| /* #define ENABLE_SWAP_TEST */ |
| #define MCRCC_ENABLE |
| #define INVALID_POC 0x80000000 |
| |
| #define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 |
| #define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 |
| #define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2 |
| #define HEVC_VPS_BUFFER HEVC_ASSIST_SCRATCH_3 |
| #define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4 |
| #define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5 |
| #define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6 |
| #define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7 |
| #define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8 |
| #define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9 |
| #define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A |
| #define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B |
| #define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C |
| #define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D |
| #define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E |
| #define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F |
| #define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F |
| #ifdef ENABLE_SWAP_TEST |
| #define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L |
| #endif |
| |
| /*#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M*/ |
| /*#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N*/ |
| #define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N |
| /*do not define ENABLE_SWAP_TEST*/ |
| #define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L |
| #define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_M |
| |
| #define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G |
| #define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H |
| /* |
| *ucode parser/search control |
| *bit 0: 0, header auto parse; 1, header manual parse |
| *bit 1: 0, auto skip for noneseamless stream; 1, no skip |
| *bit [3:2]: valid when bit1==0; |
| *0, auto skip nal before first vps/sps/pps/idr; |
| *1, auto skip nal before first vps/sps/pps |
| *2, auto skip nal before first vps/sps/pps, |
| * and not decode until the first I slice (with slice address of 0) |
| * |
| *3, auto skip before first I slice (nal_type >=16 && nal_type<=21) |
| *bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) ) |
| *bit [16]: for NAL_UNIT_EOS when bit0 is 0: |
| * 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm |
| *bit [17]: for NAL_SEI when bit0 is 0: |
| * 0, do not parse/fetch SEI in ucode; |
| * 1, parse/fetch SEI in ucode |
| *bit [18]: for NAL_SEI_SUFFIX when bit0 is 0: |
| * 0, do not fetch NAL_SEI_SUFFIX to aux buf; |
| * 1, fetch NAL_SEL_SUFFIX data to aux buf |
| *bit [19]: |
| * 0, parse NAL_SEI in ucode |
| * 1, fetch NAL_SEI to aux buf |
| *bit [20]: for DOLBY_VISION_META |
| * 0, do not fetch DOLBY_VISION_META to aux buf |
| * 1, fetch DOLBY_VISION_META to aux buf |
| */ |
| #define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I |
| /*read only*/ |
| #define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J |
| /* |
| [15 : 8] rps_set_id |
| [7 : 0] start_decoding_flag |
| */ |
| #define HEVC_DECODE_INFO HEVC_ASSIST_SCRATCH_1 |
| /*set before start decoder*/ |
| #define HEVC_DECODE_MODE HEVC_ASSIST_SCRATCH_J |
| #define HEVC_DECODE_MODE2 HEVC_ASSIST_SCRATCH_H |
| #define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K |
| |
| #define DECODE_MODE_SINGLE 0x0 |
| #define DECODE_MODE_MULTI_FRAMEBASE 0x1 |
| #define DECODE_MODE_MULTI_STREAMBASE 0x2 |
| #define DECODE_MODE_MULTI_DVBAL 0x3 |
| #define DECODE_MODE_MULTI_DVENL 0x4 |
| |
| #define MAX_INT 0x7FFFFFFF |
| |
| #define RPM_BEGIN 0x100 |
| #define modification_list_cur 0x148 |
| #define RPM_END 0x180 |
| #ifdef SUPPORT_LONG_TERM_RPS |
| /* |
| */ |
| #define RPS_END 0x8000 |
| #define RPS_LT_BIT 14 |
| #define RPS_USED_BIT 13 |
| #define RPS_SIGN_BIT 12 |
| |
| |
| #else |
| #define RPS_END 0x8000 |
| #define RPS_USED_BIT 14 |
| #define RPS_SIGN_BIT 13 |
| #endif |
| /* MISC_FLAG0 */ |
| #define PCM_LOOP_FILTER_DISABLED_FLAG_BIT 0 |
| #define PCM_ENABLE_FLAG_BIT 1 |
| #define LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT 2 |
| #define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 3 |
| #define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT 4 |
| #define PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 5 |
| #define DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT 6 |
| #define SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 7 |
| #define SLICE_SAO_LUMA_FLAG_BIT 8 |
| #define SLICE_SAO_CHROMA_FLAG_BIT 9 |
| #define SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 10 |
| |
| union param_u { |
| struct { |
| unsigned short data[RPM_END - RPM_BEGIN]; |
| } l; |
| struct { |
| /* from ucode lmem, do not change this struct */ |
| unsigned short CUR_RPS[0x10]; |
| unsigned short num_ref_idx_l0_active; |
| unsigned short num_ref_idx_l1_active; |
| unsigned short slice_type; |
| unsigned short slice_temporal_mvp_enable_flag; |
| unsigned short dependent_slice_segment_flag; |
| unsigned short slice_segment_address; |
| unsigned short num_title_rows_minus1; |
| unsigned short pic_width_in_luma_samples; |
| unsigned short pic_height_in_luma_samples; |
| unsigned short log2_min_coding_block_size_minus3; |
| unsigned short log2_diff_max_min_coding_block_size; |
| unsigned short log2_max_pic_order_cnt_lsb_minus4; |
| unsigned short POClsb; |
| unsigned short collocated_from_l0_flag; |
| unsigned short collocated_ref_idx; |
| unsigned short log2_parallel_merge_level; |
| unsigned short five_minus_max_num_merge_cand; |
| unsigned short sps_num_reorder_pics_0; |
| unsigned short modification_flag; |
| unsigned short tiles_enabled_flag; |
| unsigned short num_tile_columns_minus1; |
| unsigned short num_tile_rows_minus1; |
| unsigned short tile_width[12]; |
| unsigned short tile_height[8]; |
| unsigned short misc_flag0; |
| unsigned short pps_beta_offset_div2; |
| unsigned short pps_tc_offset_div2; |
| unsigned short slice_beta_offset_div2; |
| unsigned short slice_tc_offset_div2; |
| unsigned short pps_cb_qp_offset; |
| unsigned short pps_cr_qp_offset; |
| unsigned short first_slice_segment_in_pic_flag; |
| unsigned short m_temporalId; |
| unsigned short m_nalUnitType; |
| |
| unsigned short vui_num_units_in_tick_hi; |
| unsigned short vui_num_units_in_tick_lo; |
| unsigned short vui_time_scale_hi; |
| unsigned short vui_time_scale_lo; |
| unsigned short bit_depth; |
| unsigned short profile_etc; |
| unsigned short sei_frame_field_info; |
| unsigned short video_signal_type; |
| unsigned short modification_list[0x20]; |
| unsigned short conformance_window_flag; |
| unsigned short conf_win_left_offset; |
| unsigned short conf_win_right_offset; |
| unsigned short conf_win_top_offset; |
| unsigned short conf_win_bottom_offset; |
| unsigned short chroma_format_idc; |
| unsigned short color_description; |
| unsigned short aspect_ratio_idc; |
| unsigned short sar_width; |
| unsigned short sar_height; |
| unsigned short sps_max_dec_pic_buffering_minus1_0; |
| } p; |
| }; |
| |
| #define RPM_BUF_SIZE (0x80*2) |
| /* non mmu mode lmem size : 0x400, mmu mode : 0x500*/ |
| #define LMEM_BUF_SIZE (0x500 * 2) |
| |
| struct buff_s { |
| u32 buf_start; |
| u32 buf_size; |
| u32 buf_end; |
| }; |
| |
| struct BuffInfo_s { |
| u32 max_width; |
| u32 max_height; |
| unsigned int start_adr; |
| unsigned int end_adr; |
| struct buff_s ipp; |
| struct buff_s sao_abv; |
| struct buff_s sao_vb; |
| struct buff_s short_term_rps; |
| struct buff_s vps; |
| struct buff_s sps; |
| struct buff_s pps; |
| struct buff_s sao_up; |
| struct buff_s swap_buf; |
| struct buff_s swap_buf2; |
| struct buff_s scalelut; |
| struct buff_s dblk_para; |
| struct buff_s dblk_data; |
| struct buff_s dblk_data2; |
| struct buff_s mmu_vbh; |
| struct buff_s cm_header; |
| struct buff_s mpred_above; |
| #ifdef MV_USE_FIXED_BUF |
| struct buff_s mpred_mv; |
| #endif |
| struct buff_s rpm; |
| struct buff_s lmem; |
| }; |
| |
| //#define VBH_BUF_SIZE (2 * 16 * 2304) |
| //#define VBH_BUF_COUNT 4 |
| |
| /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/ |
| #define VBH_BUF_SIZE_1080P 0x3000 |
| #define VBH_BUF_SIZE_4K 0x5000 |
| #define VBH_BUF_SIZE_8K 0xa000 |
| #define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2) |
| /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2, |
| HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/ |
| #define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2) |
| #define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2) |
| #define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2) |
| #define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4) |
| |
| /* necessary 4K page size align for t7/t3 decoder and after */ |
| #define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE)) |
| |
| #define WORK_BUF_SPEC_NUM 6 |
| static struct BuffInfo_s amvh265_workbuff_spec[WORK_BUF_SPEC_NUM] = { |
| { |
| /* 8M bytes */ |
| .max_width = 1920, |
| .max_height = 1088, |
| .ipp = { |
| /* IPP work space calculation : |
| * 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| */ |
| .buf_size = 0x4000, |
| }, |
| .sao_abv = { |
| .buf_size = 0x30000, |
| }, |
| .sao_vb = { |
| .buf_size = 0x30000, |
| }, |
| .short_term_rps = { |
| /* SHORT_TERM_RPS - Max 64 set, 16 entry every set, |
| * total 64x16x2 = 2048 bytes (0x800) |
| */ |
| .buf_size = 0x800, |
| }, |
| .vps = { |
| /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, |
| * total 0x0800 bytes |
| */ |
| .buf_size = 0x800, |
| }, |
| .sps = { |
| /* 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 |
| */ |
| .buf_size = 0x2000, |
| }, |
| .sao_up = { |
| /* SAO UP STORE AREA - Max 640(10240/16) LCU, |
| * each has 16 bytes total 0x2800 bytes |
| */ |
| .buf_size = 0x2800, |
| }, |
| .swap_buf = { |
| /* 256cyclex64bit = 2K bytes 0x800 |
| * (only 144 cycles valid) |
| */ |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = { |
| .buf_size = 0x800, |
| }, |
| .scalelut = { |
| /* support up to 32 SCALELUT 1024x32 = |
| * 32Kbytes (0x8000) |
| */ |
| .buf_size = 0x8000, |
| }, |
| .dblk_para = { |
| #ifdef SUPPORT_10BIT |
| .buf_size = 0x40000, |
| #else |
| /* DBLK -> Max 256(4096/16) LCU, each para |
| *512bytes(total:0x20000), data 1024bytes(total:0x40000) |
| */ |
| .buf_size = 0x20000, |
| #endif |
| }, |
| .dblk_data = { |
| .buf_size = 0x40000, |
| }, |
| .dblk_data2 = { |
| .buf_size = 0x80000 * 2, |
| }, /*dblk data for adapter*/ |
| .mmu_vbh = { |
| .buf_size = 0x5000, /*2*16*2304/4, 4K*/ |
| }, |
| #if 0 |
| .cm_header = {/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ |
| .buf_size = MMU_COMPRESS_HEADER_SIZE * |
| (MAX_REF_PIC_NUM + 1), |
| }, |
| #endif |
| .mpred_above = { |
| .buf_size = 0x8000, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = {/* 1080p, 0x40000 per buffer */ |
| .buf_size = 0x40000 * MAX_REF_PIC_NUM, |
| }, |
| #endif |
| .rpm = { |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = { |
| .buf_size = 0x500 * 2, |
| } |
| }, |
| { |
| .max_width = 4096, |
| .max_height = 2048, |
| .ipp = { |
| /* IPP work space calculation : |
| * 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| */ |
| .buf_size = 0x4000, |
| }, |
| .sao_abv = { |
| .buf_size = 0x30000, |
| }, |
| .sao_vb = { |
| .buf_size = 0x30000, |
| }, |
| .short_term_rps = { |
| /* SHORT_TERM_RPS - Max 64 set, 16 entry every set, |
| * total 64x16x2 = 2048 bytes (0x800) |
| */ |
| .buf_size = 0x800, |
| }, |
| .vps = { |
| /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, |
| * total 0x0800 bytes |
| */ |
| .buf_size = 0x800, |
| }, |
| .sps = { |
| /* 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 |
| */ |
| .buf_size = 0x2000, |
| }, |
| .sao_up = { |
| /* SAO UP STORE AREA - Max 640(10240/16) LCU, |
| * each has 16 bytes total 0x2800 bytes |
| */ |
| .buf_size = 0x2800, |
| }, |
| .swap_buf = { |
| /* 256cyclex64bit = 2K bytes 0x800 |
| * (only 144 cycles valid) |
| */ |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = { |
| .buf_size = 0x800, |
| }, |
| .scalelut = { |
| /* support up to 32 SCALELUT 1024x32 = 32Kbytes |
| * (0x8000) |
| */ |
| .buf_size = 0x8000, |
| }, |
| .dblk_para = { |
| /* DBLK -> Max 256(4096/16) LCU, each para |
| * 512bytes(total:0x20000), |
| * data 1024bytes(total:0x40000) |
| */ |
| .buf_size = 0x20000, |
| }, |
| .dblk_data = { |
| .buf_size = 0x80000, |
| }, |
| .dblk_data2 = { |
| .buf_size = 0x80000, |
| }, /*dblk data for adapter*/ |
| .mmu_vbh = { |
| .buf_size = 0x5000, /*2*16*2304/4, 4K*/ |
| }, |
| #if 0 |
| .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ |
| .buf_size = MMU_COMPRESS_HEADER_SIZE * |
| (MAX_REF_PIC_NUM + 1), |
| }, |
| #endif |
| .mpred_above = { |
| .buf_size = 0x8000, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = { |
| /* .buf_size = 0x100000*16, |
| //4k2k , 0x100000 per buffer */ |
| /* 4096x2304 , 0x120000 per buffer */ |
| .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM, |
| }, |
| #endif |
| .rpm = { |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = { |
| .buf_size = 0x500 * 2, |
| } |
| }, |
| |
| { |
| .max_width = 4096*2, |
| .max_height = 2048*2, |
| .ipp = { |
| // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| .buf_size = 0x4000*2, |
| }, |
| .sao_abv = { |
| .buf_size = 0x30000*2, |
| }, |
| .sao_vb = { |
| .buf_size = 0x30000*2, |
| }, |
| .short_term_rps = { |
| // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800) |
| .buf_size = 0x800, |
| }, |
| .vps = { |
| // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes |
| .buf_size = 0x800, |
| }, |
| .sps = { |
| // 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 |
| .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, |
| }, |
| .swap_buf = { |
| // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid) |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = { |
| .buf_size = 0x800, |
| }, |
| .scalelut = { |
| // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000) |
| .buf_size = 0x8000*2, |
| }, |
| .dblk_para = {.buf_size = 0x40000*2, }, // dblk parameter |
| .dblk_data = {.buf_size = 0x80000*2, }, // dblk data for left/top |
| .dblk_data2 = {.buf_size = 0x80000*2, }, // dblk data for adapter |
| .mmu_vbh = { |
| .buf_size = 0x5000*2, //2*16*2304/4, 4K |
| }, |
| #if 0 |
| .cm_header = { |
| .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * |
| MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) |
| }, |
| #endif |
| .mpred_above = { |
| .buf_size = 0x8000*2, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = { |
| .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer |
| }, |
| #endif |
| .rpm = { |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = { |
| .buf_size = 0x500 * 2, |
| }, |
| }, |
| { |
| /* 8M bytes */ |
| .max_width = 1920, |
| .max_height = 1088, |
| .ipp = {/*checked*/ |
| /* IPP work space calculation : |
| * 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| */ |
| .buf_size = 0x1e00, |
| }, |
| .sao_abv = { |
| .buf_size = 0, //0x30000, |
| }, |
| .sao_vb = { |
| .buf_size = 0, //0x30000, |
| }, |
| .short_term_rps = {/*checked*/ |
| /* SHORT_TERM_RPS - Max 64 set, 16 entry every set, |
| * total 64x16x2 = 2048 bytes (0x800) |
| */ |
| .buf_size = 0x800, |
| }, |
| .vps = {/*checked*/ |
| /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, |
| * total 0x0800 bytes |
| */ |
| .buf_size = 0x800, |
| }, |
| .sps = {/*checked*/ |
| /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, |
| * total 0x0800 bytes |
| */ |
| .buf_size = 0x800, |
| }, |
| .pps = {/*checked*/ |
| /* 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 = 0, //0x2800, |
| }, |
| .swap_buf = {/*checked*/ |
| /* 256cyclex64bit = 2K bytes 0x800 |
| * (only 144 cycles valid) |
| */ |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = {/*checked*/ |
| .buf_size = 0x800, |
| }, |
| .scalelut = {/*checked*/ |
| /* support up to 32 SCALELUT 1024x32 = |
| * 32Kbytes (0x8000) |
| */ |
| .buf_size = 0x8000, |
| }, |
| .dblk_para = {.buf_size = 0x14500, }, // dblk parameter |
| .dblk_data = {.buf_size = 0x62800, }, // dblk data for left/top |
| .dblk_data2 = {.buf_size = 0x22800, }, // dblk data for adapter |
| .mmu_vbh = {/*checked*/ |
| .buf_size = VBH_BUF_SIZE_1080P, /*2*16*2304/4, 4K*/ |
| }, |
| #if 0 |
| .cm_header = {/*checked*//* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ |
| .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P * |
| (MAX_REF_PIC_NUM + 1), |
| }, |
| #endif |
| .mpred_above = {/*checked*/ |
| .buf_size = 0x1e00, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = {/*checked*//* 1080p, 0x40000 per buffer */ |
| .buf_size = MPRED_MV_BUF_SIZE * MAX_REF_PIC_NUM, |
| }, |
| #endif |
| .rpm = {/*checked*/ |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = {/*checked*/ |
| .buf_size = 0x500 * 2, |
| } |
| }, |
| { |
| .max_width = 4096, |
| .max_height = 2048, |
| .ipp = { |
| /* IPP work space calculation : |
| * 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| */ |
| .buf_size = 0x4000, |
| }, |
| .sao_abv = { |
| .buf_size = 0, //0x30000, |
| }, |
| .sao_vb = { |
| .buf_size = 0, //0x30000, |
| }, |
| .short_term_rps = { |
| /* SHORT_TERM_RPS - Max 64 set, 16 entry every set, |
| * total 64x16x2 = 2048 bytes (0x800) |
| */ |
| .buf_size = 0x800, |
| }, |
| .vps = { |
| /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, |
| * total 0x0800 bytes |
| */ |
| .buf_size = 0x800, |
| }, |
| .sps = { |
| /* 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 |
| */ |
| .buf_size = 0x2000, |
| }, |
| .sao_up = { |
| /* SAO UP STORE AREA - Max 640(10240/16) LCU, |
| * each has 16 bytes total 0x2800 bytes |
| */ |
| .buf_size = 0, //0x2800, |
| }, |
| .swap_buf = { |
| /* 256cyclex64bit = 2K bytes 0x800 |
| * (only 144 cycles valid) |
| */ |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = { |
| .buf_size = 0x800, |
| }, |
| .scalelut = { |
| /* support up to 32 SCALELUT 1024x32 = 32Kbytes |
| * (0x8000) |
| */ |
| .buf_size = 0x8000, |
| }, |
| .dblk_para = {.buf_size = 0x19100, }, // dblk parameter |
| .dblk_data = {.buf_size = 0x88800, }, // dblk data for left/top |
| .dblk_data2 = {.buf_size = 0x48800, }, // dblk data for adapter |
| .mmu_vbh = { |
| .buf_size = VBH_BUF_SIZE_4K, /*2*16*2304/4, 4K*/ |
| }, |
| #if 0 |
| .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ |
| .buf_size = MMU_COMPRESS_HEADER_SIZE_4K * |
| (MAX_REF_PIC_NUM + 1), |
| }, |
| #endif |
| .mpred_above = { |
| .buf_size = 0x4000, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = { |
| /* .buf_size = 0x100000*16, |
| //4k2k , 0x100000 per buffer */ |
| /* 4096x2304 , 0x120000 per buffer */ |
| .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM, |
| }, |
| #endif |
| .rpm = { |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = { |
| .buf_size = 0x500 * 2, |
| } |
| }, |
| |
| { |
| .max_width = 4096*2, |
| .max_height = 2048*2, |
| .ipp = { |
| // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k |
| .buf_size = 0x4000*2, |
| }, |
| .sao_abv = { |
| .buf_size = 0, //0x30000*2, |
| }, |
| .sao_vb = { |
| .buf_size = 0, //0x30000*2, |
| }, |
| .short_term_rps = { |
| // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800) |
| .buf_size = 0x800, |
| }, |
| .vps = { |
| // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes |
| .buf_size = 0x800, |
| }, |
| .sps = { |
| // 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 |
| .buf_size = 0x2000, |
| }, |
| .sao_up = { |
| // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes |
| .buf_size = 0, //0x2800*2, |
| }, |
| .swap_buf = { |
| // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid) |
| .buf_size = 0x800, |
| }, |
| .swap_buf2 = { |
| .buf_size = 0x800, |
| }, |
| .scalelut = { |
| // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000) |
| .buf_size = 0x8000, //0x8000*2, |
| }, |
| .dblk_para = {.buf_size = 0x32100, }, // dblk parameter |
| .dblk_data = {.buf_size = 0x110800, }, // dblk data for left/top |
| .dblk_data2 = {.buf_size = 0x90800, }, // dblk data for adapter |
| .mmu_vbh = { |
| .buf_size = VBH_BUF_SIZE_8K, //2*16*2304/4, 4K |
| }, |
| #if 0 |
| .cm_header = { |
| .buf_size = MMU_COMPRESS_HEADER_SIZE_8K * |
| MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) |
| }, |
| #endif |
| .mpred_above = { |
| .buf_size = 0x8000, |
| }, |
| #ifdef MV_USE_FIXED_BUF |
| .mpred_mv = { |
| .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer |
| }, |
| #endif |
| .rpm = { |
| .buf_size = RPM_BUF_SIZE, |
| }, |
| .lmem = { |
| .buf_size = 0x500 * 2, |
| }, |
| } |
| }; |
| |
| static void init_buff_spec(struct hevc_state_s *hevc, |
| struct BuffInfo_s *buf_spec) |
| { |
| buf_spec->ipp.buf_start = |
| WORKBUF_ALIGN(buf_spec->start_adr); |
| buf_spec->sao_abv.buf_start = |
| WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); |
| buf_spec->sao_vb.buf_start = |
| WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size); |
| buf_spec->short_term_rps.buf_start = |
| WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size); |
| buf_spec->vps.buf_start = |
| WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size); |
| buf_spec->sps.buf_start = |
| WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size); |
| buf_spec->pps.buf_start = |
| WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size); |
| buf_spec->sao_up.buf_start = |
| WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size); |
| buf_spec->swap_buf.buf_start = |
| WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size); |
| buf_spec->swap_buf2.buf_start = |
| WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size); |
| buf_spec->scalelut.buf_start = |
| WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size); |
| buf_spec->dblk_para.buf_start = |
| WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size); |
| buf_spec->dblk_data.buf_start = |
| WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size); |
| buf_spec->dblk_data2.buf_start = |
| WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size); |
| buf_spec->mmu_vbh.buf_start = |
| WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size); |
| buf_spec->mpred_above.buf_start = |
| WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size); |
| #ifdef MV_USE_FIXED_BUF |
| buf_spec->mpred_mv.buf_start = |
| WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size); |
| buf_spec->rpm.buf_start = |
| WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size); |
| #else |
| buf_spec->rpm.buf_start = |
| WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size); |
| #endif |
| buf_spec->lmem.buf_start = |
| WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size); |
| buf_spec->end_adr = |
| WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size); |
| |
| if (hevc && get_dbg_flag2(hevc)) { |
| hevc_print(hevc, 0, |
| "%s workspace (%x %x) size = %x\n", __func__, |
| buf_spec->start_adr, buf_spec->end_adr, |
| buf_spec->end_adr - buf_spec->start_adr); |
| |
| hevc_print(hevc, 0, |
| "ipp.buf_start :%x\n", |
| buf_spec->ipp.buf_start); |
| hevc_print(hevc, 0, |
| "sao_abv.buf_start :%x\n", |
| buf_spec->sao_abv.buf_start); |
| hevc_print(hevc, 0, |
| "sao_vb.buf_start :%x\n", |
| buf_spec->sao_vb.buf_start); |
| hevc_print(hevc, 0, |
| "short_term_rps.buf_start :%x\n", |
| buf_spec->short_term_rps.buf_start); |
| hevc_print(hevc, 0, |
| "vps.buf_start :%x\n", |
| buf_spec->vps.buf_start); |
| hevc_print(hevc, 0, |
| "sps.buf_start :%x\n", |
| buf_spec->sps.buf_start); |
| hevc_print(hevc, 0, |
| "pps.buf_start :%x\n", |
| buf_spec->pps.buf_start); |
| hevc_print(hevc, 0, |
| "sao_up.buf_start :%x\n", |
| buf_spec->sao_up.buf_start); |
| hevc_print(hevc, 0, |
| "swap_buf.buf_start :%x\n", |
| buf_spec->swap_buf.buf_start); |
| hevc_print(hevc, 0, |
| "swap_buf2.buf_start :%x\n", |
| buf_spec->swap_buf2.buf_start); |
| hevc_print(hevc, 0, |
| "scalelut.buf_start :%x\n", |
| buf_spec->scalelut.buf_start); |
| hevc_print(hevc, 0, |
| "dblk_para.buf_start :%x\n", |
| buf_spec->dblk_para.buf_start); |
| hevc_print(hevc, 0, |
| "dblk_data.buf_start :%x\n", |
| buf_spec->dblk_data.buf_start); |
| hevc_print(hevc, 0, |
| "dblk_data2.buf_start :%x\n", |
| buf_spec->dblk_data2.buf_start); |
| hevc_print(hevc, 0, |
| "mpred_above.buf_start :%x\n", |
| buf_spec->mpred_above.buf_start); |
| #ifdef MV_USE_FIXED_BUF |
| hevc_print(hevc, 0, |
| "mpred_mv.buf_start :%x\n", |
| buf_spec->mpred_mv.buf_start); |
| #endif |
| if ((get_dbg_flag2(hevc) |
| & |
| H265_DEBUG_SEND_PARAM_WITH_REG) |
| == 0) { |
| hevc_print(hevc, 0, |
| "rpm.buf_start :%x\n", |
| buf_spec->rpm.buf_start); |
| } |
| } |
| |
| } |
| |
| enum SliceType { |
| B_SLICE, |
| P_SLICE, |
| I_SLICE |
| }; |
| |
| /*USE_BUF_BLOCK*/ |
| struct BUF_s { |
| ulong start_adr; |
| u32 size; |
| u32 luma_size; |
| ulong header_addr; |
| u32 header_size; |
| int used_flag; |
| ulong v4l_ref_buf_addr; |
| ulong chroma_addr; |
| u32 chroma_size; |
| } /*BUF_t */; |
| |
| /* level 6, 6.1 maximum slice number is 800; other is 200 */ |
| #define MAX_SLICE_NUM 800 |
| struct PIC_s { |
| int index; |
| int scatter_alloc; |
| int BUF_index; |
| int mv_buf_index; |
| int POC; |
| int decode_idx; |
| int slice_type; |
| int RefNum_L0; |
| int RefNum_L1; |
| int num_reorder_pic; |
| int stream_offset; |
| unsigned char referenced; |
| unsigned char output_mark; |
| unsigned char recon_mark; |
| unsigned char output_ready; |
| unsigned char error_mark; |
| //dis_mark = 0:discard mark,dis_mark = 1:no discard mark |
| unsigned char dis_mark; |
| /**/ int slice_idx; |
| int m_aiRefPOCList0[MAX_SLICE_NUM][16]; |
| int m_aiRefPOCList1[MAX_SLICE_NUM][16]; |
| #ifdef SUPPORT_LONG_TERM_RPS |
| unsigned char long_term_ref; |
| unsigned char m_aiRefLTflgList0[MAX_SLICE_NUM][16]; |
| unsigned char m_aiRefLTflgList1[MAX_SLICE_NUM][16]; |
| #endif |
| /*buffer */ |
| unsigned int header_adr; |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| unsigned char dv_enhance_exist; |
| #endif |
| char *aux_data_buf; |
| int aux_data_size; |
| unsigned long cma_alloc_addr; |
| struct page *alloc_pages; |
| unsigned int mpred_mv_wr_start_addr; |
| int mv_size; |
| unsigned int mc_y_adr; |
| unsigned int mc_u_v_adr; |
| #ifdef SUPPORT_10BIT |
| /*unsigned int comp_body_size;*/ |
| unsigned int dw_y_adr; |
| unsigned int dw_u_v_adr; |
| #endif |
| u32 luma_size; |
| u32 chroma_size; |
| |
| int mc_canvas_y; |
| int mc_canvas_u_v; |
| int width; |
| int height; |
| |
| int y_canvas_index; |
| int uv_canvas_index; |
| #ifdef MULTI_INSTANCE_SUPPORT |
| struct canvas_config_s canvas_config[2]; |
| #endif |
| #ifdef SUPPORT_10BIT |
| int mem_saving_mode; |
| u32 bit_depth_luma; |
| u32 bit_depth_chroma; |
| #endif |
| #ifdef LOSLESS_COMPRESS_MODE |
| unsigned int losless_comp_body_size; |
| #endif |
| unsigned char pic_struct; |
| int vf_ref; |
| |
| u32 pts; |
| u64 pts64; |
| u64 timestamp; |
| |
| u32 aspect_ratio_idc; |
| u32 sar_width; |
| u32 sar_height; |
| u32 double_write_mode; |
| u32 video_signal_type; |
| unsigned short conformance_window_flag; |
| unsigned short conf_win_left_offset; |
| unsigned short conf_win_right_offset; |
| unsigned short conf_win_top_offset; |
| unsigned short conf_win_bottom_offset; |
| unsigned short chroma_format_idc; |
| |
| /* picture qos infomation*/ |
| int max_qp; |
| int avg_qp; |
| int min_qp; |
| int max_skip; |
| int avg_skip; |
| int min_skip; |
| int max_mv; |
| int min_mv; |
| int avg_mv; |
| |
| u32 hw_decode_time; |
| u32 frame_size; // For frame base mode |
| bool ip_mode; |
| u32 hdr10p_data_size; |
| char *hdr10p_data_buf; |
| struct dma_fence *fence; |
| bool show_frame; |
| int ctx_buf_idx; |
| } /*PIC_t */; |
| |
| #define MAX_TILE_COL_NUM 10 |
| #define MAX_TILE_ROW_NUM 20 |
| struct tile_s { |
| int width; |
| int height; |
| int start_cu_x; |
| int start_cu_y; |
| |
| unsigned int sao_vb_start_addr; |
| unsigned int sao_abv_start_addr; |
| }; |
| |
| #define SEI_MASTER_DISPLAY_COLOR_MASK 0x00000001 |
| #define SEI_CONTENT_LIGHT_LEVEL_MASK 0x00000002 |
| #define SEI_HDR10PLUS_MASK 0x00000004 |
| #define SEI_HDR_CUVA_MASK 0x00000008 |
| |
| |
| #define VF_POOL_SIZE 32 |
| |
| #ifdef MULTI_INSTANCE_SUPPORT |
| #define DEC_RESULT_NONE 0 |
| #define DEC_RESULT_DONE 1 |
| #define DEC_RESULT_AGAIN 2 |
| #define DEC_RESULT_CONFIG_PARAM 3 |
| #define DEC_RESULT_ERROR 4 |
| #define DEC_INIT_PICLIST 5 |
| #define DEC_UNINIT_PICLIST 6 |
| #define DEC_RESULT_GET_DATA 7 |
| #define DEC_RESULT_GET_DATA_RETRY 8 |
| #define DEC_RESULT_EOS 9 |
| #define DEC_RESULT_FORCE_EXIT 10 |
| #define DEC_RESULT_FREE_CANVAS 11 |
| |
| |
| static void vh265_work(struct work_struct *work); |
| static void vh265_timeout_work(struct work_struct *work); |
| static void vh265_notify_work(struct work_struct *work); |
| |
| #endif |
| |
| struct debug_log_s { |
| struct list_head list; |
| uint8_t data; /*will alloc more size*/ |
| }; |
| |
| struct mh265_fence_vf_t { |
| u32 used_size; |
| struct vframe_s *fence_vf[VF_POOL_SIZE]; |
| }; |
| |
| struct hevc_state_s { |
| #ifdef MULTI_INSTANCE_SUPPORT |
| struct platform_device *platform_dev; |
| void (*vdec_cb)(struct vdec_s *, void *); |
| void *vdec_cb_arg; |
| struct vframe_chunk_s *chunk; |
| int dec_result; |
| u32 timeout_processing; |
| struct work_struct work; |
| struct work_struct timeout_work; |
| struct work_struct notify_work; |
| struct work_struct set_clk_work; |
| /* timeout handle */ |
| unsigned long int start_process_time; |
| unsigned int last_lcu_idx; |
| unsigned int decode_timeout_count; |
| unsigned int timeout_num; |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| unsigned char switch_dvlayer_flag; |
| unsigned char no_switch_dvlayer_count; |
| unsigned char bypass_dvenl_enable; |
| unsigned char bypass_dvenl; |
| #endif |
| unsigned char start_parser_type; |
| /*start_decoding_flag: |
| vps/pps/sps/idr info from ucode*/ |
| unsigned char start_decoding_flag; |
| unsigned char rps_set_id; |
| unsigned char eos; |
| int pic_decoded_lcu_idx; |
| u8 over_decode; |
| u8 empty_flag; |
| #endif |
| struct vframe_s vframe_dummy; |
| char *provider_name; |
| int index; |
| struct device *cma_dev; |
| unsigned char m_ins_flag; |
| unsigned char dolby_enhance_flag; |
| unsigned long buf_start; |
| u32 buf_size; |
| u32 mv_buf_size; |
| |
| struct BuffInfo_s work_space_buf_store; |
| struct BuffInfo_s *work_space_buf; |
| |
| u8 aux_data_dirty; |
| u32 prefix_aux_size; |
| u32 suffix_aux_size; |
| void *aux_addr; |
| void *rpm_addr; |
| void *lmem_addr; |
| dma_addr_t aux_phy_addr; |
| dma_addr_t rpm_phy_addr; |
| dma_addr_t lmem_phy_addr; |
| |
| unsigned int pic_list_init_flag; |
| unsigned int use_cma_flag; |
| |
| unsigned short *rpm_ptr; |
| unsigned short *lmem_ptr; |
| unsigned short *debug_ptr; |
| int debug_ptr_size; |
| int pic_w; |
| int pic_h; |
| int lcu_x_num; |
| int lcu_y_num; |
| int lcu_total; |
| int lcu_size; |
| int lcu_size_log2; |
| int lcu_x_num_pre; |
| int lcu_y_num_pre; |
| int first_pic_after_recover; |
| |
| int num_tile_col; |
| int num_tile_row; |
| int tile_enabled; |
| int tile_x; |
| int tile_y; |
| int tile_y_x; |
| int tile_start_lcu_x; |
| int tile_start_lcu_y; |
| int tile_width_lcu; |
| int tile_height_lcu; |
| |
| int slice_type; |
| unsigned int slice_addr; |
| unsigned int slice_segment_addr; |
| |
| unsigned char interlace_flag; |
| unsigned char curr_pic_struct; |
| unsigned char frame_field_info_present_flag; |
| |
| unsigned short sps_num_reorder_pics_0; |
| unsigned short misc_flag0; |
| int m_temporalId; |
| int m_nalUnitType; |
| int TMVPFlag; |
| int isNextSliceSegment; |
| int LDCFlag; |
| int m_pocRandomAccess; |
| int plevel; |
| int MaxNumMergeCand; |
| |
| int new_pic; |
| int new_tile; |
| int curr_POC; |
| int iPrevPOC; |
| #ifdef MULTI_INSTANCE_SUPPORT |
| int decoded_poc; |
| struct PIC_s *decoding_pic; |
| #endif |
| int iPrevTid0POC; |
| int list_no; |
| int RefNum_L0; |
| int RefNum_L1; |
| int ColFromL0Flag; |
| int LongTerm_Curr; |
| int LongTerm_Col; |
| int Col_POC; |
| int LongTerm_Ref; |
| #ifdef MULTI_INSTANCE_SUPPORT |
| int m_pocRandomAccess_bak; |
| int curr_POC_bak; |
| int iPrevPOC_bak; |
| int iPrevTid0POC_bak; |
| unsigned char start_parser_type_bak; |
| unsigned char start_decoding_flag_bak; |
| unsigned char rps_set_id_bak; |
| int pic_decoded_lcu_idx_bak; |
| int decode_idx_bak; |
| #endif |
| struct PIC_s *cur_pic; |
| struct PIC_s *col_pic; |
| int skip_flag; |
| int decode_idx; |
| int slice_idx; |
| unsigned char have_vps; |
| unsigned char have_sps; |
| unsigned char have_pps; |
| unsigned char have_valid_start_slice; |
| unsigned char wait_buf; |
| unsigned char error_flag; |
| unsigned int error_skip_nal_count; |
| long used_4k_num; |
| |
| unsigned char |
| ignore_bufmgr_error; /* bit 0, for decoding; |
| bit 1, for displaying |
| bit 1 must be set if bit 0 is 1*/ |
| int PB_skip_mode; |
| int PB_skip_count_after_decoding; |
| #ifdef SUPPORT_10BIT |
| int mem_saving_mode; |
| #endif |
| #ifdef LOSLESS_COMPRESS_MODE |
| unsigned int losless_comp_body_size; |
| #endif |
| int pts_mode; |
| int last_lookup_pts; |
| int last_pts; |
| u64 last_lookup_pts_us64; |
| u64 last_pts_us64; |
| u32 shift_byte_count_lo; |
| u32 shift_byte_count_hi; |
| int pts_mode_switching_count; |
| int pts_mode_recovery_count; |
| |
| int pic_num; |
| |
| /**/ |
| union param_u param; |
| |
| struct tile_s m_tile[MAX_TILE_ROW_NUM][MAX_TILE_COL_NUM]; |
| |
| struct timer_list timer; |
| struct BUF_s m_BUF[BUF_POOL_SIZE]; |
| struct BUF_s m_mv_BUF[MAX_REF_PIC_NUM]; |
| struct PIC_s *m_PIC[MAX_REF_PIC_NUM]; |
| |
| DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); |
| DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); |
| DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE); |
| struct vframe_s vfpool[VF_POOL_SIZE]; |
| |
| u32 stat; |
| u32 frame_width; |
| u32 frame_height; |
| u32 frame_dur; |
| u32 frame_ar; |
| u32 bit_depth_luma; |
| u32 bit_depth_chroma; |
| u32 video_signal_type; |
| u32 video_signal_type_debug; |
| u32 saved_resolution; |
| bool get_frame_dur; |
| u32 error_watchdog_count; |
| u32 error_skip_nal_wt_cnt; |
| u32 error_system_watchdog_count; |
| |
| #ifdef DEBUG_PTS |
| unsigned long pts_missed; |
| unsigned long pts_hit; |
| #endif |
| struct dec_sysinfo vh265_amstream_dec_info; |
| unsigned char init_flag; |
| unsigned char first_sc_checked; |
| unsigned char uninit_list; |
| u32 start_decoding_time; |
| |
| int show_frame_num; |
| #ifdef USE_UNINIT_SEMA |
| struct semaphore h265_uninit_done_sema; |
| #endif |
| int fatal_error; |
| |
| |
| u32 sei_present_flag; |
| void *frame_mmu_map_addr; |
| dma_addr_t frame_mmu_map_phy_addr; |
| unsigned int mmu_mc_buf_start; |
| unsigned int mmu_mc_buf_end; |
| unsigned int mmu_mc_start_4k_adr; |
| void *mmu_box; |
| void *bmmu_box; |
| int mmu_enable; |
| |
| unsigned int dec_status; |
| |
| /* data for SEI_MASTER_DISPLAY_COLOR */ |
| unsigned int primaries[3][2]; |
| unsigned int white_point[2]; |
| unsigned int luminance[2]; |
| /* data for SEI_CONTENT_LIGHT_LEVEL */ |
| unsigned int content_light_level[2]; |
| |
| struct PIC_s *pre_top_pic; |
| struct PIC_s *pre_bot_pic; |
| |
| #ifdef MULTI_INSTANCE_SUPPORT |
| int double_write_mode; |
| int dynamic_buf_num_margin; |
| int start_action; |
| int save_buffer_mode; |
| #endif |
| u32 i_only; |
| struct list_head log_list; |
| u32 ucode_pause_pos; |
| u32 start_shift_bytes; |
| |
| atomic_t vf_pre_count; |
| atomic_t vf_get_count; |
| atomic_t vf_put_count; |
| #ifdef SWAP_HEVC_UCODE |
| dma_addr_t mc_dma_handle; |
| void *mc_cpu_addr; |
| int swap_size; |
| ulong swap_addr; |
| #endif |
| #ifdef DETREFILL_ENABLE |
| dma_addr_t detbuf_adr; |
| u16 *detbuf_adr_virt; |
| u8 delrefill_check; |
| #endif |
| u8 head_error_flag; |
| int valve_count; |
| struct firmware_s *fw; |
| int max_pic_w; |
| int max_pic_h; |
| #ifdef AGAIN_HAS_THRESHOLD |
| u8 next_again_flag; |
| u32 pre_parser_wr_ptr; |
| #endif |
| u32 ratio_control; |
| u32 first_pic_flag; |
| u32 decode_size; |
| struct mutex chunks_mutex; |
| int need_cache_size; |
| u64 sc_start_time; |
| u32 skip_nal_count; |
| bool is_swap; |
| bool is_4k; |
| |
| int frameinfo_enable; |
| struct vframe_qos_s vframe_qos; |
| bool is_used_v4l; |
| void *v4l2_ctx; |
| bool v4l_params_parsed; |
| u32 mem_map_mode; |
| u32 performance_profile; |
| struct vdec_info *gvs; |
| bool ip_mode; |
| u32 kpi_first_i_comming; |
| u32 kpi_first_i_decoded; |
| int sidebind_type; |
| int sidebind_channel_id; |
| u32 again_count; |
| u64 again_timeout_jiffies; |
| u32 pre_parser_video_rp; |
| u32 pre_parser_video_wp; |
| bool dv_duallayer; |
| u32 poc_error_count; |
| u32 timeout_flag; |
| ulong timeout; |
| bool discard_dv_data; |
| bool enable_fence; |
| int fence_usage; |
| int buffer_wrap[MAX_REF_PIC_NUM]; |
| int low_latency_flag; |
| u32 metadata_config_flag; |
| int last_width; |
| int last_height; |
| int used_buf_num; |
| u32 dirty_shift_flag; |
| u32 endian; |
| ulong fb_token; |
| int send_frame_flag; |
| struct vdec_v4l2_buffer *pair_fb[2]; |
| struct mh265_fence_vf_t fence_vf_s; |
| struct mutex fence_mutex; |
| bool resolution_change; |
| dma_addr_t rdma_phy_adr; |
| unsigned *rdma_adr; |
| bool no_need_aux_data; |
| struct trace_decoder_name trace; |
| } /*hevc_stru_t */; |
| |
| #ifdef AGAIN_HAS_THRESHOLD |
| static u32 again_threshold; |
| #endif |
| #ifdef SEND_LMEM_WITH_RPM |
| #define get_lmem_params(hevc, ladr) \ |
| hevc->lmem_ptr[ladr - (ladr & 0x3) + 3 - (ladr & 0x3)] |
| |
| |
| static int get_frame_mmu_map_size(void) |
| { |
| if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) |
| return (MAX_FRAME_8K_NUM * 4); |
| |
| return (MAX_FRAME_4K_NUM * 4); |
| } |
| |
| static int is_oversize(int w, int h) |
| { |
| int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? |
| MAX_SIZE_8K : MAX_SIZE_4K; |
| |
| if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) |
| max = MAX_SIZE_2K; |
| |
| if (w < 0 || h < 0) |
| return true; |
| |
| if (h != 0 && (w > max / h)) |
| return true; |
| |
| return false; |
| } |
| |
| int is_oversize_ex(int w, int h) |
| { |
| int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) ? |
| MAX_SIZE_8K : MAX_SIZE_4K; |
| |
| if (w == 0 || h == 0) |
| return true; |
| if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { |
| if (w > 8192 || h > 4608) |
| return true; |
| } else { |
| if (w > 4096 || h > 2304) |
| return true; |
| } |
| |
| if (w < 0 || h < 0) |
| return true; |
| |
| if (h != 0 && (w > max / h)) |
| return true; |
| |
| return false; |
| } |
| |
| |
| 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, |
| int width, int height, int mem_saving_mode) |
| { |
| int width_x64; |
| int height_x32; |
| int bsize; |
| |
| width_x64 = width + 63; |
| width_x64 >>= 6; |
| |
| height_x32 = height + 31; |
| height_x32 >>= 5; |
| if (mem_saving_mode == 1 && hevc->mmu_enable) |
| bsize = 3200 * width_x64 * height_x32; |
| else if (mem_saving_mode == 1) |
| bsize = 3072 * width_x64 * height_x32; |
| else |
| bsize = 4096 * width_x64 * height_x32; |
| |
| return bsize; |
| } |
| |
| /* Losless compression header buffer size 32bytes per 128x64 (jt) */ |
| static int compute_losless_comp_header_size(int width, int height) |
| { |
| int width_x128; |
| int height_x64; |
| int hsize; |
| |
| width_x128 = width + 127; |
| width_x128 >>= 7; |
| |
| height_x64 = height + 63; |
| height_x64 >>= 6; |
| |
| hsize = 32*width_x128*height_x64; |
| |
| return hsize; |
| } |
| #endif |
| |
| static int add_log(struct hevc_state_s *hevc, |
| const char *fmt, ...) |
| { |
| #define HEVC_LOG_BUF 196 |
| struct debug_log_s *log_item; |
| unsigned char buf[HEVC_LOG_BUF]; |
| int len = 0; |
| va_list args; |
| mutex_lock(&vh265_log_mutex); |
| va_start(args, fmt); |
| len = sprintf(buf, "<%ld> <%05d> ", |
| jiffies, hevc->decode_idx); |
| len += vsnprintf(buf + len, |
| HEVC_LOG_BUF - len, fmt, args); |
| va_end(args); |
| log_item = kmalloc( |
| sizeof(struct debug_log_s) + len, |
| GFP_KERNEL); |
| if (log_item) { |
| INIT_LIST_HEAD(&log_item->list); |
| strcpy(&log_item->data, buf); |
| list_add_tail(&log_item->list, |
| &hevc->log_list); |
| } |
| mutex_unlock(&vh265_log_mutex); |
| return 0; |
| } |
| |
| static void dump_log(struct hevc_state_s *hevc) |
| { |
| int i = 0; |
| struct debug_log_s *log_item, *tmp; |
| mutex_lock(&vh265_log_mutex); |
| list_for_each_entry_safe(log_item, tmp, &hevc->log_list, list) { |
| hevc_print(hevc, 0, |
| "[LOG%04d]%s\n", |
| i++, |
| &log_item->data); |
| list_del(&log_item->list); |
| kfree(log_item); |
| } |
| mutex_unlock(&vh265_log_mutex); |
| } |
| |
| static unsigned char is_skip_decoding(struct hevc_state_s *hevc, |
| struct PIC_s *pic) |
| { |
| if (pic->error_mark |
| && ((hevc->ignore_bufmgr_error & 0x1) == 0)) |
| return 1; |
| return 0; |
| } |
| |
| static int get_pic_poc(struct hevc_state_s *hevc, |
| unsigned int idx) |
| { |
| if (idx != 0xff |
| && idx < MAX_REF_PIC_NUM |
| && hevc->m_PIC[idx]) |
| return hevc->m_PIC[idx]->POC; |
| return INVALID_POC; |
| } |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static int get_valid_double_write_mode(struct hevc_state_s *hevc) |
| { |
| return (hevc->m_ins_flag && |
| ((double_write_mode & 0x80000000) == 0)) ? |
| hevc->double_write_mode : |
| (double_write_mode & 0x7fffffff); |
| } |
| |
| static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc) |
| { |
| return (hevc->m_ins_flag && |
| ((dynamic_buf_num_margin & 0x80000000) == 0)) ? |
| hevc->dynamic_buf_num_margin : |
| (dynamic_buf_num_margin & 0x7fffffff); |
| } |
| #endif |
| |
| static int get_double_write_mode(struct hevc_state_s *hevc) |
| { |
| u32 valid_dw_mode = get_valid_double_write_mode(hevc); |
| int w = hevc->pic_w; |
| int h = hevc->pic_h; |
| u32 dw = 0x1; /*1:1*/ |
| |
| if (hevc->is_used_v4l) { |
| unsigned int out; |
| |
| vdec_v4l_get_dw_mode(hevc->v4l2_ctx, &out); |
| dw = out; |
| return dw; |
| } |
| |
| switch (valid_dw_mode) { |
| case 0x100: |
| if (w > 1920 && h > 1088) |
| dw = 0x4; /*1:2*/ |
| break; |
| case 0x200: |
| if (w > 1920 && h > 1088) |
| dw = 0x2; /*1:4*/ |
| break; |
| case 0x300: |
| if (w > 1280 && h > 720) |
| dw = 0x4; /*1:2*/ |
| break; |
| case 0x1000: |
| if (w * h > 1920 * 1080) |
| dw = 3; |
| else if (w * h > 960 * 540) |
| dw = 5; |
| else |
| dw = 1; |
| break; |
| default: |
| dw = valid_dw_mode; |
| break; |
| } |
| return dw; |
| } |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| static unsigned char get_idx(struct hevc_state_s *hevc) |
| { |
| return hevc->index; |
| } |
| #endif |
| |
| #undef pr_info |
| #define pr_info printk |
| static int hevc_print(struct hevc_state_s *hevc, |
| int flag, const char *fmt, ...) |
| { |
| #define HEVC_PRINT_BUF 512 |
| unsigned char buf[HEVC_PRINT_BUF]; |
| int len = 0; |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| if (hevc == NULL || |
| (flag == 0) || |
| ((debug_mask & |
| (1 << hevc->index)) |
| && (debug & flag))) { |
| #endif |
| va_list args; |
| |
| va_start(args, fmt); |
| if (hevc) |
| len = sprintf(buf, "[%d]", hevc->index); |
| vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); |
| pr_debug("%s", buf); |
| va_end(args); |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| } |
| #endif |
| return 0; |
| } |
| |
| static int hevc_print_cont(struct hevc_state_s *hevc, |
| int flag, const char *fmt, ...) |
| { |
| unsigned char buf[HEVC_PRINT_BUF]; |
| int len = 0; |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| if (hevc == NULL || |
| (flag == 0) || |
| ((debug_mask & |
| (1 << hevc->index)) |
| && (debug & flag))) { |
| #endif |
| va_list args; |
| |
| va_start(args, fmt); |
| vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); |
| pr_info("%s", buf); |
| va_end(args); |
| #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC |
| } |
| #endif |
| return 0; |
| } |
| |
| static void put_mv_buf(struct hevc_state_s *hevc, |
| struct PIC_s *pic); |
| |
| static void update_vf_memhandle(struct hevc_state_s *hevc, |
| struct vframe_s *vf, struct PIC_s *pic); |
| |
| static void set_canvas(struct hevc_state_s *hevc, struct PIC_s *pic); |
| |
| static void release_aux_data(struct hevc_state_s *hevc, |
| struct PIC_s *pic); |
| static void release_pic_mmu_buf(struct hevc_state_s *hevc, struct PIC_s *pic); |
| |
| #ifdef MULTI_INSTANCE_SUPPORT |
| static void backup_decode_state(struct hevc_state_s *hevc) |
| { |
| hevc->m_pocRandomAccess_bak = hevc->m_pocRandomAccess; |
| hevc->curr_POC_bak = hevc->curr_POC; |
| hevc->iPrevPOC_bak = hevc->iPrevPOC; |
| hevc->iPrevTid0POC_bak = hevc->iPrevTid0POC; |
| hevc->start_parser_type_bak = hevc->start_parser_type; |
| hevc->start_decoding_flag_bak = hevc->start_decoding_flag; |
| hevc->rps_set_id_bak = hevc->rps_set_id; |
| hevc->pic_decoded_lcu_idx_bak = hevc->pic_decoded_lcu_idx; |
| hevc->decode_idx_bak = hevc->decode_idx; |
| |
| } |
| |
| static void restore_decode_state(struct hevc_state_s *hevc) |
| { |
| struct vdec_s *vdec = hw_to_vdec(hevc); |
| if (!vdec_has_more_input(vdec)) { |
| hevc->pic_decoded_lcu_idx = |
| READ_VREG(HEVC_PARSER_LCU_START) |
| & 0xffffff; |
| return; |
| } |
| hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, |
| "%s: discard pic index 0x%x\n", |
| __func__, hevc->decoding_pic ? |
| hevc->decoding_pic->index : 0xff); |
| if (hevc->decoding_pic) { |
| hevc->decoding_pic->error_mark = 0; |
| hevc->decoding_pic->output_ready = 0; |
| hevc->decoding_pic->show_frame = false; |
| hevc->decoding_pic->output_mark = 0; |
| hevc->decoding_pic->referenced = 0; |
| hevc->decoding_pic->POC = INVALID_POC; |
| put_mv_buf(hevc, hevc->decoding_pic); |
| release_aux_data(hevc, hevc->decoding_pic); |
| hevc->decoding_pic = NULL; |
| } |
| /*if (vdec_stream_based(vdec) && |
| (hevc->decode_idx - hevc->decode_idx_bak > 1)) { |
| int i; |
| hevc_print(hevc, 0, "decode_idx %d, decode_idx_bak %d\n", |
| hevc->decode_idx, hevc->decode_idx_bak); |
| for (i = 0; i < MAX_REF_PIC_NUM; i++) { |
| struct PIC_s *pic; |
| pic = hevc->m_PIC[i]; |
| if (pic == NULL || |
| (pic->index == -1) || |
| (pic->BUF_index == -1) || |
| (pic->POC == INVALID_POC)) |
| continue; |
| if ((pic->decode_idx >= hevc->decode_idx_bak) && |
| pic->decode_idx != (hevc->decode_idx - 1)) { |
| hevc_print(hevc, 0, "release error buffer\n"); |
| pic->error_mark = 0; |
| pic->output_ready = 0; |
| pic->show_frame = false; |
| pic->output_mark = 0; |
| pic->referenced = 0; |
| pic->POC = INVALID_POC; |
| put_mv_buf(hevc, pic); |
| release_aux_data(hevc, pic); |
| } |
| } |
| }*/ |
| hevc->decode_idx = hevc->decode_idx_bak; |
| hevc->m_pocRandomAccess = hevc->m_pocRandomAccess_bak; |
| hevc->curr_POC = hevc->curr_POC_bak; |
| hevc->iPrevPOC = hevc->iPrevPOC_bak; |
| hevc->iPrevTid0POC = hevc->iPrevTid0POC_bak; |
| hevc->start_parser_type = hevc->start_parser_type_bak; |
| hevc->start_decoding_flag = hevc->start_decoding_flag_bak; |
| hevc->rps_set_id = hevc->rps_set_id_bak; |
| hevc->pic_decoded_lcu_idx = hevc->pic_decoded_lcu_idx_bak; |
| |
| if (hevc->pic_list_init_flag == 1) |
| hevc->pic_list_init_flag = 0; |
| /*if (hevc->decode_idx == 0) |
| hevc->start_decoding_flag = 0;*/ |
| |
| hevc->slice_idx = 0; |
| hevc->used_4k_num = -1; |
| } |
| #endif |
| |
| static void hevc_init_stru(struct hevc_state_s *hevc, |
| struct BuffInfo_s *buf_spec_i) |
| { |
| int i; |
| INIT_LIST_HEAD(&hevc->log_list); |
| hevc->work_space_buf = buf_spec_i; |
| hevc->prefix_aux_size = 0; |
| hevc->suffix_aux_size = 0; |
| hevc->aux_addr = NULL; |
| hevc->rpm_addr = NULL; |
| hevc->lmem_addr = NULL; |
| |
| hevc->curr_POC = INVALID_POC; |
| |
| hevc->pic_list_init_flag = 0; |
| hevc->use_cma_flag = 0; |
| hevc->decode_idx = 0; |
| hevc->slice_idx = 0; |
| hevc->new_pic = 0; |
| hevc->new_tile = 0; |
| hevc->iPrevPOC = 0; |
| hevc->list_no = 0; |
| /* int m_uiMaxCUWidth = 1<<7; */ |
| /* int m_uiMaxCUHeight = 1<<7; */ |
| hevc->m_pocRandomAccess = MAX_INT; |
| hevc->tile_enabled = 0; |
| hevc->tile_x = 0; |
| hevc->tile_y = 0; |
| hevc->iPrevTid0POC = 0; |
| hevc->slice_addr = 0; |
| hevc->slice_segment_addr = 0; |
| hevc->skip_flag = 0; |
| hevc->misc_flag0 = 0; |
| |
| hevc->cur_pic = NULL; |
| 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; |
| hevc->have_pps = 0; |
| hevc->have_valid_start_slice = 0; |
| |
| hevc->pts_mode = PTS_NORMAL; |
| hevc->last_pts = 0; |
| hevc->last_lookup_pts = 0; |
| hevc->last_pts_us64 = 0; |
| hevc->last_lookup_pts_us64 = 0; |
| hevc->pts_mode_switching_count = 0; |
| hevc->pts_mode_recovery_count = 0; |
| |
| hevc->PB_skip_mode = nal_skip_policy & 0x3; |
| hevc->PB_skip_count_after_decoding = (nal_skip_policy >> 16) & 0xffff; |
| if (hevc->PB_skip_mode == 0) |
| hevc->ignore_bufmgr_error = 0x1; |
| else |
| hevc->ignore_bufmgr_error = 0x0; |
| |
| if (hevc->is_used_v4l) { |
| for (i = 0; i < MAX_REF_PIC_NUM; i++) { |
| if (hevc->m_PIC[i] != NULL) { |
| char *addr = NULL; |
| int size; |
| unsigned long flags; |
| |
| spin_lock_irqsave(&lock, flags); |
| addr = hevc->m_PIC[i]->aux_data_buf; |
| size = hevc->m_PIC[i]->aux_data_size; |
| |
| memset(hevc->m_PIC[i], 0 ,sizeof(struct PIC_s)); |
| hevc->m_PIC[i]->index = i; |
| hevc->m_PIC[i]->aux_data_buf = addr; |
| hevc->m_PIC[i]->aux_data_size = size; |
| spin_unlock_irqrestore(&lock, flags); |
| } |
| } |
| } |
| |
| hevc->pic_num = 0; |
| hevc->lcu_x_num_pre = 0; |
| hevc->lcu_y_num_pre = 0; |
| hevc->first_pic_after_recover = 0; |
| |
| hevc->pre_top_pic = NULL; |
| hevc->pre_bot_pic = NULL; |
| |
| hevc->sei_present_flag = 0; |
| hevc->valve_count = 0; |
| hevc->first_pic_flag = 0; |
| #ifdef MULTI_INSTANCE_SUPPORT |
| hevc->decoded_poc = INVALID_POC; |
| hevc->start_process_time = 0; |
| hevc->last_lcu_idx = 0; |
| hevc->decode_timeout_count = 0; |
| hevc->timeout_num = 0; |
| hevc->eos = 0; |
| hevc->pic_decoded_lcu_idx = -1; |
| hevc->over_decode = 0; |
| hevc->used_4k_num = -1; |
| hevc->start_decoding_flag = 0; |
| hevc->rps_set_id = 0; |
| backup_decode_state(hevc); |
| #endif |
| #ifdef DETREFILL_ENABLE |
| hevc->detbuf_adr = 0; |
| hevc->detbuf_adr_virt = NULL; |
| #endif |
| } |
| |
| static int post_picture_early(struct vdec_s *vdec, int index); |
| static int prepare_display_buf(struct vdec_s *vdec, struct PIC_s *pic); |
| static int H265_alloc_mmu(struct hevc_state_s *hevc, |
| struct PIC_s *new_pic, unsigned short bit_depth, |
| unsigned int *mmu_index_adr); |
| |
| #ifdef DETREFILL_ENABLE |
| #define DETREFILL_BUF_SIZE (4 * 0x4000) |
| #define HEVC_SAO_DBG_MODE0 0x361e |
| #define HEVC_SAO_DBG_MODE1 0x361f |
| #define HEVC_SAO_CTRL10 0x362e |
| #define HEVC_SAO_CTRL11 0x362f |
| static int init_detrefill_buf(struct hevc_state_s *hevc) |
| { |
| if (hevc->detbuf_adr_virt) |
| return 0; |
| |
| hevc->detbuf_adr_virt = |
| (void *)dma_alloc_coherent(amports_get_dma_device(), |
| DETREFILL_BUF_SIZE, &hevc->detbuf_adr, |
| GFP_KERNEL); |
| |
| if (hevc->detbuf_adr_virt == NULL) { |
| pr_err("%s: failed to alloc ETREFILL_BUF\n", __func__); |
| return -1; |
| } |
| return 0; |
| } |
| |
| static void uninit_detrefill_buf(struct hevc_state_s *hevc) |
| { |
| if (hevc->detbuf_adr_virt) { |
| dma_free_coherent(amports_get_dma_device(), |
| DETREFILL_BUF_SIZE, hevc->detbuf_adr_virt, |
| hevc->detbuf_adr); |
| |
| hevc->detbuf_adr_virt = NULL; |
| hevc->detbuf_adr = 0; |
| } |
| } |
| |
| /* |
| * convert uncompressed frame buffer data from/to ddr |
| */ |
| static void convUnc8x4blk(uint16_t* blk8x4Luma, |
| uint16_t* blk8x4Cb, uint16_t* blk8x4Cr, uint16_t* cmBodyBuf, int32_t direction) |
| { |
| if (direction == 0) { |
| blk8x4Luma[3 + 0 * 8] = ((cmBodyBuf[0] >> 0)) & 0x3ff; |
| blk8x4Luma[3 + 1 * 8] = ((cmBodyBuf[1] << 6) |
| | (cmBodyBuf[0] >> 10)) & 0x3ff; |
| blk8x4Luma[3 + 2 * 8] = ((cmBodyBuf[1] >> 4)) & 0x3ff; |
| blk8x4Luma[3 + 3 * 8] = ((cmBodyBuf[2] << 2) |
| | (cmBodyBuf[1] >> 14)) & 0x3ff; |
| blk8x4Luma[7 + 0 * 8] = ((cmBodyBuf[3] << 8) |
| | (cmBodyBuf[2] >> 8)) & 0x3ff; |
| blk8x4Luma[7 + 1 * 8] = ((cmBodyBuf[3] >> 2)) & 0x3ff; |
| blk8x4Luma[7 + 2 * 8] = ((cmBodyBuf[4] << 4) |
| | (cmBodyBuf[3] >> 12)) & 0x3ff; |
| blk8x4Luma[7 + 3 * 8] = ((cmBodyBuf[4] >> 6)) & 0x3ff; |
| blk8x4Cb [0 + 0 * 4] = ((cmBodyBuf[5] >> 0)) & 0x3ff; |
| blk8x4Cr [0 + 0 * 4] = ((cmBodyBuf[6] << 6) |
| | (cmBodyBuf[5] >> 10)) & 0x3ff; |
| blk8x4Cb [0 + 1 * 4] = ((cmBodyBuf[6] >> 4)) & 0x3ff; |
| blk8x4Cr [0 + 1 * 4] = ((cmBodyBuf[7] << 2) |
| | (cmBodyBuf[6] >> 14)) & 0x3ff; |
| |
| blk8x4Luma[0 + 0 * 8] = ((cmBodyBuf[0 + 8] >> 0)) & 0x3ff; |
| blk8x4Luma[1 + 0 * 8] = ((cmBodyBuf[1 + 8] << 6) | |
| (cmBodyBuf[0 + 8] >> 10)) & 0x3ff; |
| blk8x4Luma[2 + 0 * 8] = ((cmBodyBuf[1 + 8] >> 4)) & 0x3ff; |
| blk8x4Luma[0 + 1 * 8] = ((cmBodyBuf[2 + 8] << 2) | |
| (cmBodyBuf[1 + 8] >> 14)) & 0x3ff; |
| blk8x4Luma[1 + 1 * 8] = ((cmBodyBuf[3 + 8] << 8) | |
| (cmBodyBuf[2 + 8] >> 8)) & 0x3ff; |
| blk8x4Luma[2 + 1 * 8] = ((cmBodyBuf[3 + 8] >> 2)) & 0x3ff; |
| blk8x4Luma[0 + 2 * 8] = ((cmBodyBuf[4 + 8] << 4) | |
| (cmBodyBuf[3 + 8] >> 12)) & 0x3ff; |
| blk8x4Luma[1 + 2 * 8] = ((cmBodyBuf[4 + 8] >> 6)) & 0x3ff; |
| blk8x4Luma[2 + 2 * 8] = ((cmBodyBuf[5 + 8] >> 0)) & 0x3ff; |
| blk8x4Luma[0 + 3 * 8] = ((cmBodyBuf[6 + 8] << 6) | |
| (cmBodyBuf[5 + 8] >> 10)) & 0x3ff; |
| blk8x4Luma[1 + 3 * 8] = ((cmBodyBuf[6 + 8] >> 4)) & 0x3ff; |
| blk8x4Luma[2 + 3 * 8] = ((cmBodyBuf[7 + 8] << 2) | |
| (cmBodyBuf[6 + 8] >> 14)) & 0x3ff; |
| |
| blk8x4Luma[4 + 0 * 8] = ((cmBodyBuf[0 + 16] >> 0)) & 0x3ff; |
| blk8x4Luma[5 + 0 * 8] = ((cmBodyBuf[1 + 16] << 6) | |
| (cmBodyBuf[0 + 16] >> 10)) & 0x3ff; |
| blk8x4Luma[6 + 0 * 8] = ((cmBodyBuf[1 + 16] >> 4)) & 0x3ff; |
| blk8x4Luma[4 + 1 * 8] = ((cmBodyBuf[2 + 16] << 2) | |
| (cmBodyBuf[1 + 16] >> 14)) & 0x3ff; |
| blk8x4Luma[5 + 1 * 8] = ((cmBodyBuf[3 + 16] << 8) | |
| (cmBodyBuf[2 + 16] >> 8)) & 0x3ff; |
| blk8x4Luma[6 + 1 * 8] = ((cmBodyBuf[3 + 16] >> 2)) & 0x3ff; |
| blk8x4Luma[4 + 2 * 8] = ((cmBodyBuf[4 + 16] << 4) | |
| (cmBodyBuf[3 + 16] >> 12)) & 0x3ff; |
| blk8x4Luma[5 + 2 * 8] = ((cmBodyBuf[4 + 16] >> 6)) & 0x3ff; |
| blk8x4Luma[6 + 2 * 8] = ((cmBodyBuf[5 + 16] >> 0)) & 0x3ff; |
| blk8x4Luma[4 + 3 * 8] = ((cmBodyBuf[6 + 16] << 6) | |
| (cmBodyBuf[5 + 16] >> 10)) & 0x3ff; |
| blk8x4Luma[5 + 3 * 8] = ((cmBodyBuf[6 + 16] >> 4)) & 0x3ff; |
| blk8x4Luma[6 + 3 * 8] = ((cmBodyBuf[7 + 16] << 2) | |
| (cmBodyBuf[6 + 16] >> 14)) & 0x3ff; |
| |
| blk8x4Cb[1 + 0 * 4] = ((cmBodyBuf[0 + 24] >> 0)) & 0x3ff; |
| blk8x4Cr[1 + 0 * 4] = ((cmBodyBuf[1 + 24] << 6) | |
| (cmBodyBuf[0 + 24] >> 10)) & 0x3ff; |
| blk8x4Cb[2 + 0 * 4] = ((cmBodyBuf[1 + 24] >> 4)) & 0x3ff; |
| blk8x4Cr[2 + 0 * 4] = ((cmBodyBuf[2 + 24] << 2) | |
| (cmBodyBuf[1 + 24] >> 14)) & 0x3ff; |
| blk8x4Cb[3 + 0 * 4] = ((cmBodyBuf[3 + 24] << 8) | |
| (cmBodyBuf[2 + 24] >> 8)) & 0x3ff; |
| blk8x4Cr[3 + 0 * 4] = ((cmBodyBuf[3 + 24] >> 2)) & 0x3ff; |
| blk8x4Cb[1 + 1 * 4] = ((cmBodyBuf[4 + 24] << 4) | |
| (cmBodyBuf[3 + 24] >> 12)) & 0x3ff; |
| blk8x4Cr[1 + 1 * 4] = ((cmBodyBuf[4 + 24] >> 6)) & 0x3ff; |
| blk8x4Cb[2 + 1 * 4] = ((cmBodyBuf[5 + 24] >> 0)) & 0x3ff; |
| blk8x4Cr[2 + 1 * 4] = ((cmBodyBuf[6 + 24] << 6) | |
| (cmBodyBuf[5 + 24] >> 10)) & 0x3ff; |
| blk8x4Cb[3 + 1 * 4] = ((cmBodyBuf[6 + 24] >> 4)) & 0x3ff; |
| blk8x4Cr[3 + 1 * 4] = ((cmBodyBuf[7 + 24] << 2) | |
| (cmBodyBuf[6 + 24] >> 14)) & 0x3ff; |
| } else { |
| cmBodyBuf[0 + 8 * 0] = (blk8x4Luma[3 + 1 * 8] << 10) | |
| blk8x4Luma[3 + 0 * 8]; |
| cmBodyBuf[1 + 8 * 0] = (blk8x4Luma[3 + 3 * 8] << 14) | |
| (blk8x4Luma[3 + 2 * 8] << 4) | (blk8x4Luma[3 + 1 * 8] >> 6); |
| cmBodyBuf[2 + 8 * 0] = (blk8x4Luma[7 + 0 * 8] << 8) | |
| (blk8x4Luma[3 + 3 * 8] >> 2); |
| cmBodyBuf[3 + 8 * 0] = (blk8x4Luma[7 + 2 * 8] << 12) | |
| (blk8x4Luma[7 + 1 * 8] << 2) | (blk8x4Luma[7 + 0 * 8] >>8); |
| cmBodyBuf[4 + 8 * 0] = (blk8x4Luma[7 + 3 * 8] << 6) | |
| (blk8x4Luma[7 + 2 * 8] >>4); |
| cmBodyBuf[5 + 8 * 0] = (blk8x4Cr[0 + 0 * 4] << 10) | |
| blk8x4Cb[0 + 0 * 4]; |
| cmBodyBuf[6 + 8 * 0] = (blk8x4Cr[0 + 1 * 4] << 14) | |
| (blk8x4Cb[0 + 1 * 4] << 4) | (blk8x4Cr[0 + 0 * 4] >> 6); |
| cmBodyBuf[7 + 8 * 0] = (0<< 8) | (blk8x4Cr[0 + 1 * 4] >> 2); |
| |
| cmBodyBuf[0 + 8 * 1] = (blk8x4Luma[1 + 0 * 8] << 10) | |
| blk8x4Luma[0 + 0 * 8]; |
| cmBodyBuf[1 + 8 * 1] = (blk8x4Luma[0 + 1 * 8] << 14) | |
| (blk8x4Luma[2 + 0 * 8] << 4) | (blk8x4Luma[1 + 0 * 8] >> 6); |
| cmBodyBuf[2 + 8 * 1] = (blk8x4Luma[1 + 1 * 8] << 8) | |
| (blk8x4Luma[0 + 1 * 8] >> 2); |
| cmBodyBuf[3 + 8 * 1] = (blk8x4Luma[0 + 2 * 8] << 12) | |
| (blk8x4Luma[2 + 1 * 8] << 2) | (blk8x4Luma[1 + 1 * 8] >>8); |
| cmBodyBuf[4 + 8 * 1] = (blk8x4Luma[1 + 2 * 8] << 6) | |
| (blk8x4Luma[0 + 2 * 8] >>4); |
| cmBodyBuf[5 + 8 * 1] = (blk8x4Luma[0 + 3 * 8] << 10) | |
| blk8x4Luma[2 + 2 * 8]; |
| cmBodyBuf[6 + 8 * 1] = (blk8x4Luma[2 + 3 * 8] << 14) | |
| (blk8x4Luma[1 + 3 * 8] << 4) | (blk8x4Luma[0 + 3 * 8] >> 6); |
| cmBodyBuf[7 + 8 * 1] = (0<< 8) | (blk8x4Luma[2 + 3 * 8] >> 2); |
| |
| cmBodyBuf[0 + 8 * 2] = (blk8x4Luma[5 + 0 * 8] << 10) | |
| blk8x4Luma[4 + 0 * 8]; |
| cmBodyBuf[1 + 8 * 2] = (blk8x4Luma[4 + 1 * 8] << 14) | |
| (blk8x4Luma[6 + 0 * 8] << 4) | (blk8x4Luma[5 + 0 * 8] >> 6); |
| cmBodyBuf[2 + 8 * 2] = (blk8x4Luma[5 + 1 * 8] << 8) | |
| (blk8x4Luma[4 + 1 * 8] >> 2); |
| cmBodyBuf[3 + 8 * 2] = (blk8x4Luma[4 + 2 * 8] << 12) | |
| (blk8x4Luma[6 + 1 * 8] << 2) | (blk8x4Luma[5 + 1 * 8] >>8); |
| cmBodyBuf[4 + 8 * 2] = (blk8x4Luma[5 + 2 * 8] << 6) | |
| (blk8x4Luma[4 + 2 * 8] >>4); |
| cmBodyBuf[5 + 8 * 2] = (blk8x4Luma[4 + 3 * 8] << 10) | |
| blk8x4Luma[6 + 2 * 8]; |
| cmBodyBuf[6 + 8 * 2] = (blk8x4Luma[6 + 3 * 8] << 14) | |
| (blk8x4Luma[5 + 3 * 8] << 4) | (blk8x4Luma[4 + 3 * 8] >> 6); |
| cmBodyBuf[7 + 8 * 2] = (0<< 8) | (blk8x4Luma[6 + 3 * 8] >> 2); |
| |
| cmBodyBuf[0 + 8 * 3] = (blk8x4Cr[1 + 0 * 4] << 10) | |
| blk8x4Cb[1 + 0 * 4]; |
| cmBodyBuf[1 + 8 * 3] = (blk8x4Cr[2 + 0 * 4] << 14) | |
| (blk8x4Cb[2 + 0 * 4] << 4) | (blk8x4Cr[1 + 0 * 4] >> 6); |
| cmBodyBuf[2 + 8 * 3] = (blk8x4Cb[3 + 0 * 4] << 8) | |
| (blk8x4Cr[2 + 0 * 4] >> 2); |
| cmBodyBuf[3 + 8 * 3] = (blk8x4Cb[1 + 1 * 4] << 12) | |
| (blk8x4Cr[3 + 0 * 4] << 2) | (blk8x4Cb[3 + 0 * 4] >>8); |
| cmBodyBuf[4 + 8 * 3] = (blk8x4Cr[1 + 1 * 4] << 6) | |
| (blk8x4Cb[1 + 1 * 4] >>4); |
| cmBodyBuf[5 + 8 * 3] = (blk8x4Cr[2 + 1 * 4] << 10) | |
| blk8x4Cb[2 + 1 * 4]; |
| cmBodyBuf[6 + 8 * 3] = (blk8x4Cr[3 + 1 * 4] << 14) | |
| (blk8x4Cb[3 + 1 * 4] << 4) | (blk8x4Cr[2 + 1 * 4] >> 6); |
| cmBodyBuf[7 + 8 * 3] = (0 << 8) | (blk8x4Cr[3 + 1 * 4] >> 2); |
| } |
| } |
| |
| static void corrRefillWithAmrisc ( |
| struct hevc_state_s *hevc, |
| uint32_t cmHeaderBaseAddr, |
| uint32_t picWidth, |
| uint32_t ctuPosition) |
| { |
| int32_t i; |
| uint16_t ctux = (ctuPosition>>16) & 0xffff; |
| uint16_t ctuy = (ctuPosition>> 0) & 0xffff; |
| int32_t aboveCtuAvailable = (ctuy) ? 1 : 0; |
| |
| uint16_t *cmBodyBuf = NULL; |
| |
| uint32_t pic_width_x64_pre = picWidth + 0x3f; |
| uint32_t pic_width_x64 = pic_width_x64_pre >> 6; |
| uint32_t stride64x64 = pic_width_x64 * 128; |
| uint32_t addr_offset64x64_abv = stride64x64 * |
| (aboveCtuAvailable ? ctuy - 1 : ctuy) + 128 * ctux; |
| uint32_t addr_offset64x64_cur = stride64x64*ctuy + 128 * ctux; |
| uint32_t cmHeaderAddrAbv = cmHeaderBaseAddr + addr_offset64x64_abv; |
| uint32_t cmHeaderAddrCur = cmHeaderBaseAddr + addr_offset64x64_cur; |
| unsigned int tmpData32; |
| |
| uint16_t blkBuf0Y[32]; |
| uint16_t blkBuf0Cb[8]; |
| uint16_t blkBuf0Cr[8]; |
| uint16_t blkBuf1Y[32]; |
| uint16_t blkBuf1Cb[8]; |
| uint16_t blkBuf1Cr[8]; |
| int32_t blkBufCnt = 0; |
| |
| int32_t blkIdx; |
| PR_INIT(128); |
| |
| cmBodyBuf = vzalloc(sizeof(uint16_t) * 32 * 18); |
| if (!cmBodyBuf) |
| return; |
| |
| WRITE_VREG(HEVC_SAO_CTRL10, cmHeaderAddrAbv); |
| WRITE_VREG(HEVC_SAO_CTRL11, cmHeaderAddrCur); |
| WRITE_VREG(HEVC_SAO_DBG_MODE0, hevc->detbuf_adr); |
| WRITE_VREG(HEVC_SAO_DBG_MODE1, 2); |
| |
| for (i = 0; i < 32 * 18; i++) |
| cmBodyBuf[i] = 0; |
| |
| hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, |
| "%s, %d\n", __func__, __LINE__); |
| do { |
| tmpData32 = READ_VREG(HEVC_SAO_DBG_MODE1); |
| } while (tmpData32); |
| hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, |
| "%s, %d\n", __func__, __LINE__); |
| |
| hevc_print(hevc, H265_DEBUG_DETAIL, |
| "cmBodyBuf from detbuf:\n"); |
| for (i = 0; i < 32 * 18; i++) { |
| cmBodyBuf[i] = hevc->detbuf_adr_virt[i]; |
| if (get_dbg_flag(hevc) & |
| H265_DEBUG_DETAIL) { |
| if ((i & 0xf) == 0) |
| PR_INFO(hevc->index); |
| PR_FILL("%02x ", cmBodyBuf[i]); |
| } |
| } |
| PR_INFO(hevc->index); |
| |
| for (i = 0; i < 32; i++) |
| blkBuf0Y[i] = 0; |
| for (i = 0; i < 8; i++) |
| blkBuf0Cb[i] = 0; |
| for (i = 0; i < 8; i++) |
| blkBuf0Cr[i] = 0; |
| for (i = 0; i < 32; i++) |
| blkBuf1Y[i] = 0; |
| for (i = 0; i < 8; i++) |
| blkBuf1Cb[i] = 0; |
| for (i = 0; i < 8; i++) |
| blkBuf1Cr[i] = 0; |
| |
| for (blkIdx = 0; blkIdx < 18; blkIdx++) { |
| int32_t inAboveCtu = (blkIdx<2) ? 1 : 0; |
| int32_t restoreEnable = (blkIdx>0) ? 1 : 0; |
| uint16_t* blkY = (blkBufCnt==0) ? blkBuf0Y : blkBuf1Y ; |
| uint16_t* blkCb = (blkBufCnt==0) ? blkBuf0Cb : blkBuf1Cb; |
| uint16_t* blkCr = (blkBufCnt==0) ? blkBuf0Cr : blkBuf1Cr; |
| uint16_t* cmBodyBufNow = cmBodyBuf + (blkIdx * 32); |
| |
| if (!aboveCtuAvailable && inAboveCtu) |
| continue; |
| |
| /* detRefillBuf --> 8x4block*/ |
| convUnc8x4blk(blkY, blkCb, blkCr, cmBodyBufNow, 0); |
| |
| if (restoreEnable) { |
| blkY[3 + 0 * 8] = blkY[2 + 0 * 8] + 2; |
| blkY[4 + 0 * 8] = blkY[1 + 0 * 8] + 3; |
| blkY[5 + 0 * 8] = blkY[0 + 0 * 8] + 1; |
| blkY[6 + 0 * 8] = blkY[0 + 0 * 8] + 2; |
| blkY[7 + 0 * 8] = blkY[1 + 0 * 8] + 2; |
| blkY[3 + 1 * 8] = blkY[2 + 1 * 8] + 1; |
| blkY[4 + 1 * 8] = blkY[1 + 1 * 8] + 2; |
| blkY[5 + 1 * 8] = blkY[0 + 1 * 8] + 2; |
| blkY[6 + 1 * 8] = blkY[0 + 1 * 8] + 2; |
| blkY[7 + 1 * 8] = blkY[1 + 1 * 8] + 3; |
| blkY[3 + 2 * 8] = blkY[2 + 2 * 8] + 3; |
| blkY[4 + 2 * 8] = blkY[1 + 2 * 8] + 1; |
| blkY[5 + 2 * 8] = blkY[0 + 2 * 8] + 3; |
| blkY[6 + 2 * 8] = blkY[0 + 2 * 8] + 3; |
| blkY[7 + 2 * 8] = blkY[1 + 2 * 8] + 3; |
| blkY[3 + 3 * 8] = blkY[2 + 3 * 8] + 0; |
| blkY[4 + 3 * 8] = blkY[1 + |