mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-17 17:47:52 -04:00
media: qcom: iris: Add rotation support for encoder
Add rotation control for encoder, enabling V4L2_CID_ROTATE and handling 90/180/270 degree rotation. Reviewed-by: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> Co-developed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com> Signed-off-by: Bryan O'Donoghue <bod@kernel.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
committed by
Hans Verkuil
parent
121d6d7a35
commit
49a940f37d
@@ -102,6 +102,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
|
||||
return PROFILE_AV1;
|
||||
case V4L2_CID_MPEG_VIDEO_AV1_LEVEL:
|
||||
return LEVEL_AV1;
|
||||
case V4L2_CID_ROTATE:
|
||||
return ROTATION;
|
||||
default:
|
||||
return INST_FW_CAP_MAX;
|
||||
}
|
||||
@@ -193,6 +195,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
|
||||
return V4L2_CID_MPEG_VIDEO_AV1_PROFILE;
|
||||
case LEVEL_AV1:
|
||||
return V4L2_CID_MPEG_VIDEO_AV1_LEVEL;
|
||||
case ROTATION:
|
||||
return V4L2_CID_ROTATE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -901,6 +905,36 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
|
||||
&range, sizeof(range));
|
||||
}
|
||||
|
||||
int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
||||
{
|
||||
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
|
||||
u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
||||
u32 hfi_val;
|
||||
|
||||
switch (inst->fw_caps[cap_id].value) {
|
||||
case 0:
|
||||
hfi_val = HFI_ROTATION_NONE;
|
||||
return 0;
|
||||
case 90:
|
||||
hfi_val = HFI_ROTATION_90;
|
||||
break;
|
||||
case 180:
|
||||
hfi_val = HFI_ROTATION_180;
|
||||
break;
|
||||
case 270:
|
||||
hfi_val = HFI_ROTATION_270;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return hfi_ops->session_set_property(inst, hfi_id,
|
||||
HFI_HOST_FLAGS_NONE,
|
||||
iris_get_port_info(inst, cap_id),
|
||||
HFI_PAYLOAD_U32,
|
||||
&hfi_val, sizeof(u32));
|
||||
}
|
||||
|
||||
int iris_set_properties(struct iris_inst *inst, u32 plane)
|
||||
{
|
||||
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
|
||||
|
||||
@@ -32,6 +32,7 @@ int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_i
|
||||
int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
|
||||
int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
|
||||
int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
|
||||
int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
|
||||
int iris_set_properties(struct iris_inst *inst, u32 plane);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -182,22 +182,36 @@ static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
static inline u32 iris_hfi_get_aligned_resolution(struct iris_inst *inst, u32 width, u32 height)
|
||||
{
|
||||
u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
|
||||
|
||||
return (ALIGN(width, codec_align) << 16 | ALIGN(height, codec_align));
|
||||
}
|
||||
|
||||
static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
|
||||
{
|
||||
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
|
||||
u32 port = iris_hfi_gen2_get_port(inst, plane);
|
||||
enum hfi_packet_payload_info payload_type;
|
||||
u32 resolution, codec_align;
|
||||
u32 width, height;
|
||||
u32 resolution;
|
||||
|
||||
if (inst->domain == DECODER) {
|
||||
resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
|
||||
inst->fmt_src->fmt.pix_mp.height;
|
||||
width = inst->fmt_src->fmt.pix_mp.width;
|
||||
height = inst->fmt_src->fmt.pix_mp.height;
|
||||
resolution = iris_hfi_get_aligned_resolution(inst, width, height);
|
||||
inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
|
||||
payload_type = HFI_PAYLOAD_U32;
|
||||
} else {
|
||||
codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
|
||||
resolution = ALIGN(inst->enc_scale_width, codec_align) << 16 |
|
||||
ALIGN(inst->enc_scale_height, codec_align);
|
||||
if (is_rotation_90_or_270(inst)) {
|
||||
width = inst->enc_scale_height;
|
||||
height = inst->enc_scale_width;
|
||||
} else {
|
||||
width = inst->enc_scale_width;
|
||||
height = inst->enc_scale_height;
|
||||
}
|
||||
resolution = iris_hfi_get_aligned_resolution(inst, width, height);
|
||||
inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
|
||||
payload_type = HFI_PAYLOAD_32_PACKED;
|
||||
}
|
||||
@@ -239,10 +253,17 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
|
||||
left_offset = inst->crop.left;
|
||||
top_offset = inst->crop.top;
|
||||
} else {
|
||||
bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) -
|
||||
inst->enc_scale_height);
|
||||
right_offset = (ALIGN(inst->enc_scale_width, codec_align) -
|
||||
inst->enc_scale_width);
|
||||
if (is_rotation_90_or_270(inst)) {
|
||||
bottom_offset = (ALIGN(inst->enc_scale_width, codec_align) -
|
||||
inst->enc_scale_width);
|
||||
right_offset = (ALIGN(inst->enc_scale_height, codec_align) -
|
||||
inst->enc_scale_height);
|
||||
} else {
|
||||
bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) -
|
||||
inst->enc_scale_height);
|
||||
right_offset = (ALIGN(inst->enc_scale_width, codec_align) -
|
||||
inst->enc_scale_width);
|
||||
}
|
||||
left_offset = 0;
|
||||
top_offset = 0;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,15 @@ enum hfi_seq_header_mode {
|
||||
};
|
||||
|
||||
#define HFI_PROP_SEQ_HEADER_MODE 0x03000149
|
||||
|
||||
enum hfi_rotation {
|
||||
HFI_ROTATION_NONE = 0x00000000,
|
||||
HFI_ROTATION_90 = 0x00000001,
|
||||
HFI_ROTATION_180 = 0x00000002,
|
||||
HFI_ROTATION_270 = 0x00000003,
|
||||
};
|
||||
|
||||
#define HFI_PROP_ROTATION 0x0300014b
|
||||
#define HFI_PROP_SIGNAL_COLOR_INFO 0x03000155
|
||||
#define HFI_PROP_PICTURE_TYPE 0x03000162
|
||||
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
|
||||
|
||||
@@ -150,6 +150,7 @@ enum platform_inst_fw_cap_type {
|
||||
P_FRAME_QP_HEVC,
|
||||
B_FRAME_QP_H264,
|
||||
B_FRAME_QP_HEVC,
|
||||
ROTATION,
|
||||
INST_FW_CAP_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -689,6 +689,16 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
|
||||
.flags = CAP_FLAG_OUTPUT_PORT,
|
||||
.set = iris_set_u32,
|
||||
},
|
||||
{
|
||||
.cap_id = ROTATION,
|
||||
.min = 0,
|
||||
.max = 270,
|
||||
.step_or_mask = 90,
|
||||
.value = 0,
|
||||
.hfi_id = HFI_PROP_ROTATION,
|
||||
.flags = CAP_FLAG_OUTPUT_PORT,
|
||||
.set = iris_set_rotation,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_inst_caps platform_inst_cap_sm8550 = {
|
||||
|
||||
@@ -125,3 +125,9 @@ int iris_check_core_mbps(struct iris_inst *inst)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_rotation_90_or_270(struct iris_inst *inst)
|
||||
{
|
||||
return inst->fw_caps[ROTATION].value == 90 ||
|
||||
inst->fw_caps[ROTATION].value == 270;
|
||||
}
|
||||
|
||||
@@ -51,5 +51,6 @@ void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
|
||||
int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush);
|
||||
int iris_check_core_mbpf(struct iris_inst *inst);
|
||||
int iris_check_core_mbps(struct iris_inst *inst);
|
||||
bool is_rotation_90_or_270(struct iris_inst *inst);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -822,6 +822,22 @@ static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)
|
||||
iris_vpu_dec_line_size(inst);
|
||||
}
|
||||
|
||||
static inline u32 iris_vpu_enc_get_bitstream_width(struct iris_inst *inst)
|
||||
{
|
||||
if (is_rotation_90_or_270(inst))
|
||||
return inst->fmt_dst->fmt.pix_mp.height;
|
||||
else
|
||||
return inst->fmt_dst->fmt.pix_mp.width;
|
||||
}
|
||||
|
||||
static inline u32 iris_vpu_enc_get_bitstream_height(struct iris_inst *inst)
|
||||
{
|
||||
if (is_rotation_90_or_270(inst))
|
||||
return inst->fmt_dst->fmt.pix_mp.width;
|
||||
else
|
||||
return inst->fmt_dst->fmt.pix_mp.height;
|
||||
}
|
||||
|
||||
static inline u32 size_bin_bitstream_enc(u32 width, u32 height,
|
||||
u32 rc_type)
|
||||
{
|
||||
@@ -904,10 +920,9 @@ static inline u32 hfi_buffer_bin_enc(u32 width, u32 height,
|
||||
static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
|
||||
{
|
||||
u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
||||
u32 height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 stage = inst->fw_caps[STAGE].value;
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 height = f->fmt.pix_mp.height;
|
||||
u32 width = f->fmt.pix_mp.width;
|
||||
u32 lcu_size;
|
||||
|
||||
if (inst->codec == V4L2_PIX_FMT_HEVC)
|
||||
@@ -951,9 +966,8 @@ u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
|
||||
|
||||
static u32 iris_vpu_enc_comv_size(struct iris_inst *inst)
|
||||
{
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 height = f->fmt.pix_mp.height;
|
||||
u32 width = f->fmt.pix_mp.width;
|
||||
u32 height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 num_recon = 1;
|
||||
u32 lcu_size = 16;
|
||||
|
||||
@@ -1233,9 +1247,8 @@ u32 hfi_buffer_non_comv_enc(u32 frame_width, u32 frame_height,
|
||||
static u32 iris_vpu_enc_non_comv_size(struct iris_inst *inst)
|
||||
{
|
||||
u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 height = f->fmt.pix_mp.height;
|
||||
u32 width = f->fmt.pix_mp.width;
|
||||
u32 height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 lcu_size = 16;
|
||||
|
||||
if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
||||
@@ -1326,9 +1339,8 @@ u32 hfi_buffer_line_enc_vpu33(u32 frame_width, u32 frame_height, bool is_ten_bit
|
||||
static u32 iris_vpu_enc_line_size(struct iris_inst *inst)
|
||||
{
|
||||
u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 height = f->fmt.pix_mp.height;
|
||||
u32 width = f->fmt.pix_mp.width;
|
||||
u32 height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 lcu_size = 16;
|
||||
|
||||
if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
||||
@@ -1344,9 +1356,8 @@ static u32 iris_vpu_enc_line_size(struct iris_inst *inst)
|
||||
static u32 iris_vpu33_enc_line_size(struct iris_inst *inst)
|
||||
{
|
||||
u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 height = f->fmt.pix_mp.height;
|
||||
u32 width = f->fmt.pix_mp.width;
|
||||
u32 height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 lcu_size = 16;
|
||||
|
||||
if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
||||
@@ -1567,9 +1578,8 @@ static inline u32 hfi_buffer_scratch1_enc(u32 frame_width, u32 frame_height,
|
||||
static u32 iris_vpu_enc_scratch1_size(struct iris_inst *inst)
|
||||
{
|
||||
u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 frame_height = f->fmt.pix_mp.height;
|
||||
u32 frame_width = f->fmt.pix_mp.width;
|
||||
u32 frame_height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 frame_width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 num_ref = 1;
|
||||
u32 lcu_size;
|
||||
bool is_h265;
|
||||
@@ -1665,9 +1675,8 @@ static inline u32 hfi_buffer_scratch2_enc(u32 frame_width, u32 frame_height,
|
||||
|
||||
static u32 iris_vpu_enc_scratch2_size(struct iris_inst *inst)
|
||||
{
|
||||
struct v4l2_format *f = inst->fmt_dst;
|
||||
u32 frame_width = f->fmt.pix_mp.width;
|
||||
u32 frame_height = f->fmt.pix_mp.height;
|
||||
u32 frame_height = iris_vpu_enc_get_bitstream_height(inst);
|
||||
u32 frame_width = iris_vpu_enc_get_bitstream_width(inst);
|
||||
u32 num_ref = 1;
|
||||
|
||||
return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref,
|
||||
|
||||
Reference in New Issue
Block a user