vmh264: fix bug of cropping. [1/1]
authormiaohong chen <miaohong.chen@amlogic.com>
Wed, 15 Jul 2020 12:48:37 +0000 (20:48 +0800)
committermiaohong chen <miaohong.chen@amlogic.com>
Tue, 21 Jul 2020 05:40:13 +0000 (13:40 +0800)
PD#SWPL-29563

Problem:
A register uses 32 bits to store
four crop offset syntax parameters,
resulting in the loss of high bits when passed to the driver.

Solution:
Use rpm memory to pass crop offset parameters.

ucode gerrit : 117325
ucode commit id: 18db008

Verify:
u212

Change-Id: I854ba3da073e63150fa1216ce775dff87399cff4
Signed-off-by: miaohong chen <miaohong.chen@amlogic.com>
drivers/frame_provider/decoder/h264_multi/h264_dpb.h
drivers/frame_provider/decoder/h264_multi/vmh264.c
firmware/video_ucode.bin

index e94404b900fdbea4f86b6288c3cf76629e87b8e6..550c293d33cc950ab388211580ec8ae6c01ef76a 100644 (file)
@@ -375,6 +375,12 @@ union param {
                unsigned short colocated_mv_addr_start[2];
                unsigned short colocated_mv_addr_end[2];
                unsigned short colocated_mv_wr_addr[2];
+
+               unsigned short frame_crop_left_offset;
+               unsigned short frame_crop_right_offset;
+               unsigned short frame_crop_top_offset;
+               unsigned short frame_crop_bottom_offset;
+               unsigned short chroma_format_idc;
        } dpb;
        struct {
                unsigned short dump[MMCO_OFFSET];
@@ -896,6 +902,12 @@ struct h264_dpb_stru {
        u16 num_reorder_frames;
        u16 max_dec_frame_buffering;
 
+       unsigned int frame_crop_left_offset;
+       unsigned int frame_crop_right_offset;
+       unsigned int frame_crop_top_offset;
+       unsigned int frame_crop_bottom_offset;
+       unsigned int chroma_format_idc;
+
        unsigned int dec_dpb_status;
        unsigned int last_dpb_status;
        unsigned char buf_alloc_fail;
index 00fe87af343cfac68511bac492675bbceb8f4687..c215147c9f35ecdff4aa0d60b18aa6ab13605495 100644 (file)
@@ -4749,8 +4749,8 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw,
        int active_buffer_spec_num;
        unsigned int buf_size;
        unsigned int frame_mbs_only_flag;
-       unsigned int chroma_format_idc, chroma444;
-       unsigned int crop_infor, crop_bottom, crop_right;
+       unsigned int chroma_format_idc;
+       unsigned int crop_bottom, crop_right;
        unsigned int used_reorder_dpb_size_margin
                = hw->reorder_dpb_size_margin;
        u8 *colocate_vaddr = NULL;
@@ -4788,6 +4788,8 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw,
        if (hw->config_bufmgr_done == 0) {
                struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
                u32 reg_val;
+               int sub_width_c = 0, sub_height_c = 0;
+
                hw->cfg_param1 = param1;
                hw->cfg_param2 = param2;
                hw->cfg_param3 = param3;
@@ -4810,44 +4812,52 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw,
                   bit 15: frame_mbs_only_flag
                   bit 13-14: chroma_format_idc */
                frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01;
-               chroma_format_idc = (hw->seq_info >> 13) & 0x03;
-               chroma444 = (chroma_format_idc == 3) ? 1 : 0;
+               chroma_format_idc = p_H264_Dpb->chroma_format_idc;
 
                /* @AV_SCRATCH_6.31-16 =  (left  << 8 | right ) << 1
                   @AV_SCRATCH_6.15-0   =  (top << 8  | bottom ) <<
                   (2 - frame_mbs_only_flag) */
-               crop_infor = param3;
-               crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag);
-               crop_right = ((crop_infor >> 16) & 0xff)
-                       >> (2 - frame_mbs_only_flag);
+
+               switch (chroma_format_idc) {
+                       case 1:
+                               sub_width_c = 2;
+                               sub_height_c = 2;
+                               break;
+
+                       case 2:
+                               sub_width_c = 2;
+                               sub_height_c = 1;
+                               break;
+
+                       case 3:
+                               sub_width_c = 1;
+                               sub_height_c = 1;
+                               break;
+
+                       default:
+                               break;
+               }
+
+               if (chroma_format_idc == 0) {
+                       crop_right = p_H264_Dpb->frame_crop_right_offset;
+                       crop_bottom = p_H264_Dpb->frame_crop_bottom_offset *
+                               (2 - frame_mbs_only_flag);
+               } else {
+                       crop_right = sub_width_c * p_H264_Dpb->frame_crop_right_offset;
+                       crop_bottom = sub_height_c * p_H264_Dpb->frame_crop_bottom_offset *
+                               (2 - frame_mbs_only_flag);
+               }
 
                p_H264_Dpb->mSPS.frame_mbs_only_flag = frame_mbs_only_flag;
                hw->frame_width = mb_width << 4;
                hw->frame_height = mb_height << 4;
-               if (frame_mbs_only_flag) {
-                       hw->frame_height =
-                               hw->frame_height - (2 >> chroma444) *
-                               min(crop_bottom,
-                                       (unsigned int)((8 << chroma444) - 1));
-                       hw->frame_width =
-                               hw->frame_width -
-                                       (2 >> chroma444) * min(crop_right,
-                                               (unsigned
-                                                int)((8 << chroma444) - 1));
-               } else {
-                       hw->frame_height =
-                               hw->frame_height - (4 >> chroma444) *
-                               min(crop_bottom,
-                                       (unsigned int)((8 << chroma444)
-                                                         - 1));
-                       hw->frame_width =
-                               hw->frame_width -
-                               (4 >> chroma444) * min(crop_right,
-                               (unsigned int)((8 << chroma444) - 1));
-               }
+
+               hw->frame_width = hw->frame_width - crop_right;
+               hw->frame_height = hw->frame_height - crop_bottom;
+
                dpb_print(DECODE_ID(hw), 0,
-                       "frame_mbs_only_flag %d, crop_bottom %d,  frame_height %d,\n",
-                       frame_mbs_only_flag, crop_bottom, hw->frame_height);
+                       "chroma_format_idc = %d frame_mbs_only_flag %d, crop_bottom %d,  frame_height %d,\n",
+                       chroma_format_idc, frame_mbs_only_flag, crop_bottom, hw->frame_height);
                dpb_print(DECODE_ID(hw), 0,
                        "mb_height %d,crop_right %d, frame_width %d, mb_width %d\n",
                        mb_height, crop_right,
@@ -5921,6 +5931,21 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
                        p_H264_Dpb->num_reorder_frames;
                hw->max_dec_frame_buffering =
                        p_H264_Dpb->max_dec_frame_buffering;
+
+               /*crop*/
+               p_H264_Dpb->chroma_format_idc = p_H264_Dpb->dpb_param.dpb.chroma_format_idc;
+               p_H264_Dpb->frame_crop_left_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_left_offset;
+               p_H264_Dpb->frame_crop_right_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_right_offset;
+               p_H264_Dpb->frame_crop_top_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_top_offset;
+               p_H264_Dpb->frame_crop_bottom_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_bottom_offset;
+
+               dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
+               "%s chroma_format_idc %d crop offset: left %d right %d top %d bottom %d\n",
+               __func__, p_H264_Dpb->chroma_format_idc,
+               p_H264_Dpb->frame_crop_left_offset,
+               p_H264_Dpb->frame_crop_right_offset,
+               p_H264_Dpb->frame_crop_top_offset,
+               p_H264_Dpb->frame_crop_bottom_offset);
 #endif
 
                WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE);
@@ -8280,8 +8305,9 @@ static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw,
        int active_buffer_spec_num;
        int max_reference_size ,level_idc;
        u32 frame_mbs_only_flag;
-       u32 chroma_format_idc, chroma444;
-       u32 crop_infor, crop_bottom, crop_right;
+       u32 chroma_format_idc;
+       u32 crop_bottom, crop_right;
+       int sub_width_c = 0, sub_height_c = 0;
        u32 frame_width, frame_height;
        u32 used_reorder_dpb_size_margin
                = hw->reorder_dpb_size_margin;
@@ -8344,33 +8370,49 @@ static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw,
         * bit 13-14: chroma_format_idc
         */
        frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01;
-       chroma_format_idc = (hw->seq_info >> 13) & 0x03;
-       chroma444 = (chroma_format_idc == 3) ? 1 : 0;
+       chroma_format_idc = hw->dpb.chroma_format_idc;
 
        /*
         * AV_SCRATCH_6 bit 31-16 =  (left  << 8 | right ) << 1
         * AV_SCRATCH_6 bit 15-0 =  (top << 8  | bottom ) <<
         *                          (2 - frame_mbs_only_flag)
         */
-       crop_infor = param3;
-       crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag);
-       crop_right = ((crop_infor >> 16) & 0xff) >> (2 - frame_mbs_only_flag);
+       switch (chroma_format_idc) {
+               case 1:
+                       sub_width_c = 2;
+                       sub_height_c = 2;
+                       break;
 
-       frame_width = mb_width << 4;
-       frame_height = mb_height << 4;
+               case 2:
+                       sub_width_c = 2;
+                       sub_height_c = 1;
+                       break;
 
-       if (frame_mbs_only_flag) {
-               frame_height = frame_height - (2 >> chroma444) *
-                       min(crop_bottom, (u32)((8 << chroma444) - 1));
-               frame_width = frame_width - (2 >> chroma444) *
-                       min(crop_right, (u32)((8 << chroma444) - 1));
+               case 3:
+                       sub_width_c = 1;
+                       sub_height_c = 1;
+                       break;
+
+               default:
+                       break;
+       }
+
+       if (chroma_format_idc == 0) {
+               crop_right = hw->dpb.frame_crop_right_offset;
+               crop_bottom = hw->dpb.frame_crop_bottom_offset *
+                       (2 - frame_mbs_only_flag);
        } else {
-               frame_height = frame_height - (4 >> chroma444) *
-                       min(crop_bottom, (u32)((8 << chroma444) - 1));
-               frame_width = frame_width - (4 >> chroma444) *
-                       min(crop_right, (u32)((8 << chroma444) - 1));
+               crop_right = sub_width_c * hw->dpb.frame_crop_right_offset;
+               crop_bottom = sub_height_c * hw->dpb.frame_crop_bottom_offset *
+                       (2 - frame_mbs_only_flag);
        }
 
+       frame_width = mb_width << 4;
+       frame_height = mb_height << 4;
+
+       frame_width = frame_width - crop_right;
+       frame_height = frame_height - crop_bottom;
+
        ps->profile             = level_idc;
        ps->ref_frames          = max_reference_size;
        ps->mb_width            = mb_width;
index cfc5d61262e76139985016dc1203859d5fc9461b..be3265218fdf09508d6acb2de32ec34fe3650d52 100644 (file)
Binary files a/firmware/video_ucode.bin and b/firmware/video_ucode.bin differ