virgl/video: Add support for H.265 encoding
authorFeng Jiang <jiangfeng@kylinos.cn>
Tue, 20 Sep 2022 08:43:43 +0000 (16:43 +0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 18 Nov 2022 07:46:11 +0000 (07:46 +0000)
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
Signed-off-by: Weishi Li <liweishi@kylinos.cn>
Signed-off-by: Liming Sun <sunliming@kylinos.cn>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18831>

src/gallium/drivers/virgl/virgl_video.c
src/virtio/virtio-gpu/virgl_video_hw.h

index 128ddf3..eae12fb 100644 (file)
@@ -410,6 +410,121 @@ static int fill_h265_picture_desc(const struct pipe_picture_desc *desc,
     return 0;
 }
 
+static int fill_h265_enc_picture_desc(const struct pipe_picture_desc *desc,
+                                      union virgl_picture_desc *vdsc)
+{
+    unsigned i;
+    struct virgl_h265_enc_picture_desc *vh265 = &vdsc->h265_enc;
+    struct pipe_h265_enc_picture_desc *h265 = (struct pipe_h265_enc_picture_desc *)desc;
+
+    fill_base_picture_desc(desc, &vh265->base);
+
+    ITEM_SET(vh265, h265, seq.general_profile_idc);
+    ITEM_SET(vh265, h265, seq.general_level_idc);
+    ITEM_SET(vh265, h265, seq.general_tier_flag);
+    ITEM_SET(vh265, h265, seq.intra_period);
+    ITEM_SET(vh265, h265, seq.ip_period);
+    ITEM_SET(vh265, h265, seq.pic_width_in_luma_samples);
+    ITEM_SET(vh265, h265, seq.pic_height_in_luma_samples);
+    ITEM_SET(vh265, h265, seq.chroma_format_idc);
+    ITEM_SET(vh265, h265, seq.bit_depth_luma_minus8);
+    ITEM_SET(vh265, h265, seq.bit_depth_chroma_minus8);
+    ITEM_SET(vh265, h265, seq.strong_intra_smoothing_enabled_flag);
+    ITEM_SET(vh265, h265, seq.amp_enabled_flag);
+    ITEM_SET(vh265, h265, seq.sample_adaptive_offset_enabled_flag);
+    ITEM_SET(vh265, h265, seq.pcm_enabled_flag);
+    ITEM_SET(vh265, h265, seq.sps_temporal_mvp_enabled_flag);
+    ITEM_SET(vh265, h265, seq.log2_min_luma_coding_block_size_minus3);
+    ITEM_SET(vh265, h265, seq.log2_diff_max_min_luma_coding_block_size);
+    ITEM_SET(vh265, h265, seq.log2_min_transform_block_size_minus2);
+    ITEM_SET(vh265, h265, seq.log2_diff_max_min_transform_block_size);
+    ITEM_SET(vh265, h265, seq.max_transform_hierarchy_depth_inter);
+    ITEM_SET(vh265, h265, seq.max_transform_hierarchy_depth_intra);
+    ITEM_SET(vh265, h265, seq.conformance_window_flag);
+    ITEM_SET(vh265, h265, seq.conf_win_left_offset);
+    ITEM_SET(vh265, h265, seq.conf_win_right_offset);
+    ITEM_SET(vh265, h265, seq.conf_win_top_offset);
+    ITEM_SET(vh265, h265, seq.conf_win_bottom_offset);
+    ITEM_SET(vh265, h265, seq.vui_parameters_present_flag);
+    ITEM_SET(vh265, h265, seq.vui_flags.aspect_ratio_info_present_flag);
+    ITEM_SET(vh265, h265, seq.vui_flags.timing_info_present_flag);
+    ITEM_SET(vh265, h265, seq.aspect_ratio_idc);
+    ITEM_SET(vh265, h265, seq.sar_width);
+    ITEM_SET(vh265, h265, seq.sar_height);
+    ITEM_SET(vh265, h265, seq.num_units_in_tick);
+    ITEM_SET(vh265, h265, seq.time_scale);
+
+    ITEM_SET(vh265, h265, pic.log2_parallel_merge_level_minus2);
+    ITEM_SET(vh265, h265, pic.nal_unit_type);
+    ITEM_SET(vh265, h265, pic.constrained_intra_pred_flag);
+    ITEM_SET(vh265, h265, pic.pps_loop_filter_across_slices_enabled_flag);
+    ITEM_SET(vh265, h265, pic.transform_skip_enabled_flag);
+
+    ITEM_SET(vh265, h265, slice.max_num_merge_cand);
+    ITEM_SET(vh265, h265, slice.slice_cb_qp_offset);
+    ITEM_SET(vh265, h265, slice.slice_cr_qp_offset);
+    ITEM_SET(vh265, h265, slice.slice_beta_offset_div2);
+    ITEM_SET(vh265, h265, slice.slice_tc_offset_div2);
+    ITEM_SET(vh265, h265, slice.cabac_init_flag);
+    ITEM_SET(vh265, h265, slice.slice_deblocking_filter_disabled_flag);
+    ITEM_SET(vh265, h265, slice.slice_loop_filter_across_slices_enabled_flag);
+
+    ITEM_SET(vh265, h265, rc.rate_ctrl_method);
+    ITEM_SET(vh265, h265, rc.target_bitrate);
+    ITEM_SET(vh265, h265, rc.peak_bitrate);
+    ITEM_SET(vh265, h265, rc.frame_rate_num);
+    ITEM_SET(vh265, h265, rc.frame_rate_den);
+    ITEM_SET(vh265, h265, rc.quant_i_frames);
+    ITEM_SET(vh265, h265, rc.quant_p_frames);
+    ITEM_SET(vh265, h265, rc.quant_b_frames);
+    ITEM_SET(vh265, h265, rc.vbv_buffer_size);
+    ITEM_SET(vh265, h265, rc.vbv_buf_lv);
+    ITEM_SET(vh265, h265, rc.target_bits_picture);
+    ITEM_SET(vh265, h265, rc.peak_bits_picture_integer);
+    ITEM_SET(vh265, h265, rc.peak_bits_picture_fraction);
+    ITEM_SET(vh265, h265, rc.fill_data_enable);
+    ITEM_SET(vh265, h265, rc.skip_frame_enable);
+    ITEM_SET(vh265, h265, rc.enforce_hrd);
+    ITEM_SET(vh265, h265, rc.max_au_size);
+    ITEM_SET(vh265, h265, rc.max_qp);
+    ITEM_SET(vh265, h265, rc.min_qp);
+
+    ITEM_SET(vh265, h265, picture_type);
+    ITEM_SET(vh265, h265, decoded_curr_pic);
+
+    for (i = 0; i < 16; i++) {
+        ITEM_SET(vh265, h265, reference_frames[i]);
+    }
+
+    ITEM_SET(vh265, h265, frame_num);
+    ITEM_SET(vh265, h265, pic_order_cnt);
+    ITEM_SET(vh265, h265, pic_order_cnt_type);
+
+    ITEM_SET(vh265, h265, quality_modes.level);
+    ITEM_SET(vh265, h265, quality_modes.preset_mode);
+    ITEM_SET(vh265, h265, quality_modes.pre_encode_mode);
+    ITEM_SET(vh265, h265, quality_modes.vbaq_mode);
+
+    ITEM_SET(vh265, h265, num_ref_idx_l0_active_minus1);
+    ITEM_SET(vh265, h265, num_ref_idx_l1_active_minus1);
+
+    for (i = 0; i < 15; i++) {
+        ITEM_SET(vh265, h265, ref_idx_l0_list[i]);
+        ITEM_SET(vh265, h265, ref_idx_l1_list[i]);
+    }
+
+    ITEM_SET(vh265, h265, not_referenced);
+
+    ITEM_SET(vh265, h265, num_slice_descriptors);
+    for (i = 0; i < vh265->num_slice_descriptors; i++) {
+        ITEM_SET(vh265, h265, slices_descriptors[i].slice_segment_address);
+        ITEM_SET(vh265, h265, slices_descriptors[i].num_ctu_in_slice);
+        ITEM_SET(vh265, h265, slices_descriptors[i].slice_type);
+    }
+
+    return 0;
+}
+
 static int fill_mpeg4_picture_desc(const struct pipe_picture_desc *desc,
                                    union virgl_picture_desc *vdsc)
 {
@@ -468,6 +583,8 @@ static int fill_enc_picture_desc(const struct pipe_picture_desc *desc,
     switch (u_reduce_video_profile(desc->profile)) {
     case PIPE_VIDEO_FORMAT_MPEG4_AVC:
         return fill_h264_enc_picture_desc(desc, vdsc);
+    case PIPE_VIDEO_FORMAT_HEVC:
+        return fill_h265_enc_picture_desc(desc, vdsc);
     default:
         return -1;
     }
index 18ea130..2f50f96 100644 (file)
@@ -396,6 +396,143 @@ struct virgl_h265_picture_desc
    uint8_t reserved[2];
 };
 
+struct virgl_h265_enc_seq_param
+{
+   uint8_t  general_profile_idc;
+   uint8_t  general_level_idc;
+   uint8_t  general_tier_flag;
+   uint8_t  strong_intra_smoothing_enabled_flag;
+
+   uint32_t intra_period;
+   uint32_t ip_period;
+
+   uint16_t pic_width_in_luma_samples;
+   uint16_t pic_height_in_luma_samples;
+
+   uint32_t chroma_format_idc;
+   uint32_t bit_depth_luma_minus8;
+   uint32_t bit_depth_chroma_minus8;
+
+   uint8_t  amp_enabled_flag;
+   uint8_t  sample_adaptive_offset_enabled_flag;
+   uint8_t  pcm_enabled_flag;
+   uint8_t  sps_temporal_mvp_enabled_flag;
+
+   uint8_t  log2_min_luma_coding_block_size_minus3;
+   uint8_t  log2_diff_max_min_luma_coding_block_size;
+   uint8_t  log2_min_transform_block_size_minus2;
+   uint8_t  log2_diff_max_min_transform_block_size;
+
+   uint16_t conf_win_left_offset;
+   uint16_t conf_win_right_offset;
+   uint16_t conf_win_top_offset;
+   uint16_t conf_win_bottom_offset;
+
+   uint32_t vui_parameters_present_flag;
+   struct {
+      uint32_t aspect_ratio_info_present_flag: 1;
+      uint32_t timing_info_present_flag: 1;
+      uint32_t reserved:30;
+   } vui_flags;
+   uint32_t aspect_ratio_idc;
+   uint32_t sar_width;
+   uint32_t sar_height;
+   uint32_t num_units_in_tick;
+   uint32_t time_scale;
+
+   uint8_t  max_transform_hierarchy_depth_inter;
+   uint8_t  max_transform_hierarchy_depth_intra;
+   uint8_t  conformance_window_flag;
+   uint8_t  reserved;
+};
+
+struct virgl_h265_enc_pic_param
+{
+   uint8_t log2_parallel_merge_level_minus2;
+   uint8_t nal_unit_type;
+   uint8_t constrained_intra_pred_flag;
+   uint8_t pps_loop_filter_across_slices_enabled_flag;
+
+   uint8_t transform_skip_enabled_flag;
+   uint8_t reserved[3];
+};
+
+struct virgl_h265_enc_slice_param
+{
+   uint8_t max_num_merge_cand;
+   int8_t  slice_cb_qp_offset;
+   int8_t  slice_cr_qp_offset;
+   int8_t  slice_beta_offset_div2;
+
+   uint32_t slice_deblocking_filter_disabled_flag;
+
+   int8_t  slice_tc_offset_div2;
+   uint8_t cabac_init_flag;
+   uint8_t slice_loop_filter_across_slices_enabled_flag;
+   uint8_t reserved;
+};
+
+struct virgl_h265_enc_rate_control
+{
+   uint32_t target_bitrate;
+   uint32_t peak_bitrate;
+   uint32_t frame_rate_num;
+   uint32_t frame_rate_den;
+   uint32_t quant_i_frames;
+   uint32_t quant_p_frames;
+   uint32_t quant_b_frames;
+   uint32_t vbv_buffer_size;
+   uint32_t vbv_buf_lv;
+   uint32_t target_bits_picture;
+   uint32_t peak_bits_picture_integer;
+   uint32_t peak_bits_picture_fraction;
+   uint32_t fill_data_enable;
+   uint32_t skip_frame_enable;
+   uint32_t enforce_hrd;
+   uint32_t max_au_size;
+   uint32_t max_qp;
+   uint32_t min_qp;
+
+   uint8_t  rate_ctrl_method; /* see enum pipe_h2645_enc_rate_control_method */
+   uint8_t  reserved[3];
+};
+
+struct virgl_h265_slice_descriptor
+{
+   uint32_t slice_segment_address;
+   uint32_t num_ctu_in_slice;
+
+   uint8_t  slice_type; /* see enum pipe_h265_slice_type */
+   uint8_t  reserved[3];
+};
+
+struct virgl_h265_enc_picture_desc
+{
+   struct virgl_base_picture_desc base;
+
+   struct virgl_h265_enc_seq_param seq;
+   struct virgl_h265_enc_pic_param pic;
+   struct virgl_h265_enc_slice_param slice;
+   struct virgl_h265_enc_rate_control rc;
+
+   uint32_t decoded_curr_pic;
+   uint32_t reference_frames[16];
+   uint32_t frame_num;
+   uint32_t pic_order_cnt;
+   uint32_t pic_order_cnt_type;
+   uint32_t num_ref_idx_l0_active_minus1;
+   uint32_t num_ref_idx_l1_active_minus1;
+   uint32_t ref_idx_l0_list[15];
+   uint32_t ref_idx_l1_list[15];
+   uint32_t num_slice_descriptors;
+   struct virgl_h265_slice_descriptor slices_descriptors[128];
+   struct virgl_enc_quality_modes quality_modes;
+
+   uint8_t  picture_type; /* see enum pipe_h2645_enc_picture_type */
+   uint8_t  not_referenced;
+   uint8_t  reserved[2];
+};
+
 struct virgl_mpeg4_picture_desc
 {
    struct virgl_base_picture_desc base;
@@ -427,6 +564,7 @@ union virgl_picture_desc {
     struct virgl_h265_picture_desc h265;
     struct virgl_mpeg4_picture_desc mpeg4;
     struct virgl_h264_enc_picture_desc h264_enc;
+    struct virgl_h265_enc_picture_desc h265_enc;
 };
 
 enum virgl_video_encode_stat {