diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 0272b12e2e..fdec88710a 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -233,7 +233,11 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { 1, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_CID_HFLIP, HFI_PROP_FLIP, - CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED}, + CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | + CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED, + {0}, + {0}, + NULL, msm_vidc_set_flip}, {VFLIP, ENC, CODECS_ALL, V4L2_MPEG_MSM_VIDC_DISABLE, @@ -241,13 +245,20 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { 1, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_CID_VFLIP, HFI_PROP_FLIP, - CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED}, + CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + {0}, + {0}, + NULL, msm_vidc_set_flip}, {ROTATION, ENC, CODECS_ALL, 0, 270, 90, 0, V4L2_CID_ROTATE, HFI_PROP_ROTATION, - CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT}, + CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT, + {0}, + {0}, + NULL, msm_vidc_set_rotation}, {SUPER_FRAME, ENC, H264|HEVC, 0, 32, 1, 0, diff --git a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c index 19a16385fa..6248993519 100644 --- a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c @@ -13,6 +13,7 @@ #include "msm_vidc_driver.h" #include "msm_vidc_debug.h" #include "msm_media_info.h" +#include "msm_vidc_control.h" static u32 msm_vidc_decoder_bin_size_iris2(struct msm_vidc_inst *inst) { @@ -440,27 +441,34 @@ static u32 msm_vidc_encoder_arp_size_iris2(struct msm_vidc_inst *inst) static u32 msm_vidc_encoder_vpss_size_iris2(struct msm_vidc_inst* inst) { u32 size = 0; - bool ds_enable, rot_enable, flip_enable, is_tenbit; - u32 width, height, pixfmt; + bool ds_enable = false, is_tenbit = false; + u32 rotation_val = HFI_ROTATION_NONE; + u32 flip_val = HFI_DISABLE_FLIP; + u32 width, height, driver_colorfmt; struct v4l2_format* f; if (!inst || !inst->core || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); return 0; } - ds_enable = false; // TODO: fixme - rot_enable = false; // TODO: fixme - flip_enable = false; // TODO: fixme - f = &inst->fmts[OUTPUT_PORT]; - width = f->fmt.pix_mp.width; - height = f->fmt.pix_mp.height; + ds_enable = is_scaling_enabled(inst); + msm_vidc_v4l2_to_hfi_enum(inst, ROTATION, &rotation_val); + if (inst->capabilities->cap[HFLIP].value) + flip_val |= HFI_HORIZONTAL_FLIP; + if (inst->capabilities->cap[VFLIP].value) + flip_val = HFI_VERTICAL_FLIP; - pixfmt = inst->capabilities->cap[PIX_FMTS].value; - is_tenbit = (pixfmt == MSM_VIDC_FMT_P010 || pixfmt == MSM_VIDC_FMT_TP10C); + width = inst->compose.width; + height = inst->compose.height; + + f = &inst->fmts[INPUT_PORT]; + driver_colorfmt = v4l2_colorformat_to_driver( + f->fmt.pix_mp.pixelformat, __func__); + is_tenbit = is_10bit_colorformat(driver_colorfmt); HFI_BUFFER_VPSS_ENC(size, width, height, ds_enable, - rot_enable, flip_enable, is_tenbit); + rotation_val, flip_val, is_tenbit); i_vpr_l(inst, "%s: size %d\n", __func__, size); return size; } diff --git a/driver/vidc/inc/msm_venc.h b/driver/vidc/inc/msm_venc.h index af55a3c350..e10889ab69 100644 --- a/driver/vidc/inc/msm_venc.h +++ b/driver/vidc/inc/msm_venc.h @@ -16,6 +16,7 @@ int msm_venc_streamon_output(struct msm_vidc_inst *inst); int msm_venc_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2); int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd); int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); +int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); int msm_venc_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); diff --git a/driver/vidc/inc/msm_vidc_control.h b/driver/vidc/inc/msm_vidc_control.h index 45356d23df..7cc0635476 100644 --- a/driver/vidc/inc/msm_vidc_control.h +++ b/driver/vidc/inc/msm_vidc_control.h @@ -79,6 +79,10 @@ int msm_vidc_set_nal_length(void* instance, enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_session_priority(void *instance, enum msm_vidc_inst_capability_type cap_id); +int msm_vidc_set_flip(void *instance, + enum msm_vidc_inst_capability_type cap_id); +int msm_vidc_set_rotation(void *instance, + enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_s32(void *instance, enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_q16(void *instance, diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 36a308c80b..9b9ae32780 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -65,6 +65,14 @@ static inline is_output_meta_buffer(enum msm_vidc_buffer_type buffer_type) return buffer_type == MSM_VIDC_BUF_OUTPUT_META; } +static inline is_scaling_enabled(struct msm_vidc_inst *inst) +{ + return inst->crop.left != inst->compose.left || + inst->crop.top != inst->compose.top || + inst->crop.width != inst->compose.width || + inst->crop.height != inst->compose.height; +} + static inline is_internal_buffer(enum msm_vidc_buffer_type buffer_type) { return buffer_type == MSM_VIDC_BUF_BIN || diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index 230c2ff6b0..07f9c6d13f 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -154,6 +154,8 @@ u32 hfi_buf_type_from_driver(enum msm_vidc_domain_type domain, return HFI_BUFFER_DPB; case MSM_VIDC_BUF_PERSIST: return HFI_BUFFER_PERSIST; + case MSM_VIDC_BUF_VPSS: + return HFI_BUFFER_VPSS; default: d_vpr_e("invalid buffer type %d\n", buffer_type); @@ -200,6 +202,8 @@ u32 hfi_buf_type_to_driver(enum msm_vidc_domain_type domain, return MSM_VIDC_BUF_DPB; case HFI_BUFFER_PERSIST: return MSM_VIDC_BUF_PERSIST; + case HFI_BUFFER_VPSS: + return MSM_VIDC_BUF_VPSS; default: d_vpr_e("invalid buffer type %d\n", buffer_type); diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index 39ff6a5e9d..633ae356b6 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -29,7 +29,6 @@ static const u32 msm_venc_input_set_prop[] = { static const u32 msm_venc_output_set_prop[] = { HFI_PROP_BITSTREAM_RESOLUTION, HFI_PROP_CROP_OFFSETS, - HFI_PROP_SCALAR, HFI_PROP_BUFFER_HOST_MAX_COUNT, HFI_PROP_CSC, }; @@ -44,7 +43,7 @@ static const u32 msm_venc_output_subscribe_for_properties[] = { HFI_PROP_WORST_COMPRESSION_RATIO, }; -static const u32 msm_venc_internal_buffer_type[] = { +static const u32 msm_venc_output_internal_buffer_type[] = { MSM_VIDC_BUF_BIN, MSM_VIDC_BUF_COMV, MSM_VIDC_BUF_NON_COMV, @@ -52,6 +51,10 @@ static const u32 msm_venc_internal_buffer_type[] = { MSM_VIDC_BUF_DPB, }; +static const u32 msm_venc_input_internal_buffer_type[] = { + MSM_VIDC_BUF_VPSS, +}; + struct msm_venc_prop_type_handle { u32 type; int (*handle)(struct msm_vidc_inst *inst, enum msm_vidc_port_type port); @@ -232,6 +235,7 @@ static int msm_venc_set_crop_offsets(struct msm_vidc_inst *inst, int rc = 0; u32 left_offset, top_offset, right_offset, bottom_offset; u32 crop[2] = {0}; + u32 width, height; if (port != OUTPUT_PORT) { i_vpr_e(inst, "%s: invalid port %d\n", __func__, port); @@ -240,10 +244,17 @@ static int msm_venc_set_crop_offsets(struct msm_vidc_inst *inst, left_offset = inst->compose.left; top_offset = inst->compose.top; - right_offset = (inst->fmts[port].fmt.pix_mp.width - - inst->compose.width); - bottom_offset = (inst->fmts[port].fmt.pix_mp.height - - inst->compose.height); + + width = inst->compose.width; + height = inst->compose.height; + if (inst->capabilities->cap[ROTATION].value == 90 || + inst->capabilities->cap[ROTATION].value == 270) { + width = inst->compose.height; + height = inst->compose.width; + } + + right_offset = (inst->fmts[port].fmt.pix_mp.width - width); + bottom_offset = (inst->fmts[port].fmt.pix_mp.height - height); if (is_image_session(inst)) right_offset = bottom_offset = 0; @@ -266,43 +277,6 @@ static int msm_venc_set_crop_offsets(struct msm_vidc_inst *inst, return 0; } -static int msm_venc_set_scalar(struct msm_vidc_inst *inst, - enum msm_vidc_port_type port) -{ - int rc = 0; - u32 scalar = 0; - - if (port != OUTPUT_PORT) { - i_vpr_e(inst, "%s: invalid port %d\n", __func__, port); - return -EINVAL; - } - - if (inst->crop.left != inst->compose.left || - inst->crop.top != inst->compose.top || - inst->crop.width != inst->compose.width || - inst->crop.height != inst->compose.height) { - scalar = 1; - i_vpr_h(inst, - "%s: crop: l %d t %d w %d h %d compose: l %d t %d w %d h %d\n", - __func__, inst->crop.left, inst->crop.top, - inst->crop.width, inst->crop.height, - inst->compose.left, inst->compose.top, - inst->compose.width, inst->compose.height); - } - - i_vpr_h(inst, "%s: scalar: %d\n", __func__, scalar); - rc = venus_hfi_session_property(inst, - HFI_PROP_SCALAR, - HFI_HOST_FLAGS_NONE, - get_hfi_port(inst, port), - HFI_PAYLOAD_64_PACKED, - &scalar, - sizeof(u64)); - if (rc) - return rc; - return 0; -} - static int msm_venc_set_host_max_buf_count(struct msm_vidc_inst *inst, enum msm_vidc_port_type port) { @@ -553,7 +527,6 @@ static int msm_venc_set_output_properties(struct msm_vidc_inst *inst) static const struct msm_venc_prop_type_handle prop_type_handle_arr[] = { {HFI_PROP_BITSTREAM_RESOLUTION, msm_venc_set_bitstream_resolution }, {HFI_PROP_CROP_OFFSETS, msm_venc_set_crop_offsets }, - {HFI_PROP_SCALAR, msm_venc_set_scalar }, {HFI_PROP_BUFFER_HOST_MAX_COUNT, msm_venc_set_host_max_buf_count }, {HFI_PROP_CSC, msm_venc_set_csc }, }; @@ -613,8 +586,7 @@ static int msm_venc_set_internal_properties(struct msm_vidc_inst *inst) static int msm_venc_get_input_internal_buffers(struct msm_vidc_inst *inst) { - int rc = 0; -/* TODO: VPSS + int i, rc = 0; struct msm_vidc_core *core; if (!inst || !inst->core) { @@ -623,50 +595,51 @@ static int msm_venc_get_input_internal_buffers(struct msm_vidc_inst *inst) } core = inst->core; - inst->buffers.vpss.size = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_VPSS) + 100000000; + for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) { + rc = msm_vidc_get_internal_buffers(inst, + msm_venc_input_internal_buffer_type[i]); + if (rc) + return rc; + } - inst->buffers.dpb.min_count = call_session_op(core, min_count, - inst, MSM_VIDC_BUF_VPSS); - - i_vpr_h(inst, "%s: internal buffer: min size\n", __func__); - i_vpr_h(inst, "vpss buffer: %d %d\n", - inst->buffers.vpss.min_count, - inst->buffers.vpss.size); -*/ return rc; } static int msm_venc_create_input_internal_buffers(struct msm_vidc_inst *inst) { - int rc = 0; -/* TODO: VPSS + int i, rc = 0; + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_VPSS); - if (rc) - return rc; -*/ + for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) { + rc = msm_vidc_create_internal_buffers(inst, + msm_venc_input_internal_buffer_type[i]); + if (rc) + return rc; + } + return rc; } static int msm_venc_queue_input_internal_buffers(struct msm_vidc_inst *inst) { - int rc = 0; + int i, rc = 0; -/* TODO: VPSS if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_VPSS); - if (rc) - return rc; -*/ + for (i = 0; i < ARRAY_SIZE(msm_venc_input_internal_buffer_type); i++) { + rc = msm_vidc_queue_internal_buffers(inst, + msm_venc_input_internal_buffer_type[i]); + if (rc) + return rc; + } + return rc; } @@ -681,8 +654,9 @@ static int msm_venc_get_output_internal_buffers(struct msm_vidc_inst *inst) } core = inst->core; - for (i = 0; i < ARRAY_SIZE(msm_venc_internal_buffer_type); i++) { - rc = msm_vidc_get_internal_buffers(inst, msm_venc_internal_buffer_type[i]); + for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) { + rc = msm_vidc_get_internal_buffers(inst, + msm_venc_output_internal_buffer_type[i]); if (rc) return rc; } @@ -699,8 +673,9 @@ static int msm_venc_create_output_internal_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - for (i = 0; i < ARRAY_SIZE(msm_venc_internal_buffer_type); i++) { - rc = msm_vidc_create_internal_buffers(inst, msm_venc_internal_buffer_type[i]); + for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) { + rc = msm_vidc_create_internal_buffers(inst, + msm_venc_output_internal_buffer_type[i]); if (rc) return rc; } @@ -717,8 +692,9 @@ static int msm_venc_queue_output_internal_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - for (i = 0; i < ARRAY_SIZE(msm_venc_internal_buffer_type); i++) { - rc = msm_vidc_queue_internal_buffers(inst, msm_venc_internal_buffer_type[i]); + for (i = 0; i < ARRAY_SIZE(msm_venc_output_internal_buffer_type); i++) { + rc = msm_vidc_queue_internal_buffers(inst, + msm_venc_output_internal_buffer_type[i]); if (rc) return rc; } @@ -1108,12 +1084,13 @@ error: return rc; } -static int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f) +int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f) { int rc = 0; struct v4l2_format *fmt; struct msm_vidc_core *core; u32 codec_align; + u32 width, height; if (!inst || !inst->core || !f) { d_vpr_e("%s: invalid params\n", __func__); @@ -1134,9 +1111,17 @@ static int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format codec_align = (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC || f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEIC) ? 32 : 16; + /* use rotated width height if rotation is enabled */ + width = inst->compose.width; + height = inst->compose.height; + if (inst->capabilities->cap[ROTATION].value == 90 || + inst->capabilities->cap[ROTATION].value == 270) { + width = inst->compose.height; + height = inst->compose.width; + } /* width, height is readonly for client */ - fmt->fmt.pix_mp.width = ALIGN(inst->compose.width, codec_align); - fmt->fmt.pix_mp.height = ALIGN(inst->compose.height, codec_align); + fmt->fmt.pix_mp.width = ALIGN(width, codec_align); + fmt->fmt.pix_mp.height = ALIGN(height, codec_align); /* use grid dimension for image session */ if (is_image_session(inst)) fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.height = HEIC_GRID_DIMENSION; @@ -1520,6 +1505,18 @@ int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s) inst->compose.width = s->r.width; inst->compose.height= s->r.height; + if (inst->crop.left != inst->compose.left || + inst->crop.top != inst->compose.top || + inst->crop.width != inst->compose.width || + inst->crop.height != inst->compose.height) { + i_vpr_h(inst, + "%s: scaling enabled, crop: l %d t %d w %d h %d compose: l %d t %d w %d h %d\n", + __func__, inst->crop.left, inst->crop.top, + inst->crop.width, inst->crop.height, + inst->compose.left, inst->compose.top, + inst->compose.width, inst->compose.height); + } + /* update output format based on new compose dimensions */ output_fmt = &inst->fmts[OUTPUT_PORT]; rc = msm_venc_s_fmt_output(inst, output_fmt); diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index dbf2392e6a..eb70116349 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -10,6 +10,7 @@ #include "venus_hfi.h" #include "msm_vidc_internal.h" #include "msm_vidc_driver.h" +#include "msm_venc.h" #define CAP_TO_8BIT_QP(a) { \ if ((a) < 0) \ @@ -663,6 +664,24 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl) if (!inst->vb2q[OUTPUT_PORT].streaming) { msm_vidc_update_cap_value(inst, cap_id, ctrl->val, __func__); + if (ctrl->id == V4L2_CID_ROTATE) { + if (ctrl->val == 90 || ctrl->val == 270) { + struct v4l2_format *output_fmt; + + output_fmt = &inst->fmts[OUTPUT_PORT]; + rc = msm_venc_s_fmt_output(inst, output_fmt); + if (rc) + return rc; + + i_vpr_h(inst, + "%s: type %d: format %#x width %d height %d size %d\n", + __func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat, + output_fmt->fmt.pix_mp.width, + output_fmt->fmt.pix_mp.height, + output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage); + } + } + if (ctrl->id == V4L2_CID_MPEG_VIDC_MIN_BITSTREAM_SIZE_OVERWRITE) { rc = msm_vidc_update_bitstream_buffer_size(inst); if (rc) @@ -2382,7 +2401,6 @@ int msm_vidc_set_session_priority(void *instance, return rc; } -/* TODO int msm_vidc_set_flip(void *instance, enum msm_vidc_inst_capability_type cap_id) { @@ -2404,15 +2422,35 @@ int msm_vidc_set_flip(void *instance, if (vflip) hfi_value |= HFI_VERTICAL_FLIP; - i_vpr_h(inst, "set cap: name: %24s, value: %#10x, hfi: %#10x\n", cap_name(cap_id), - inst->capabilities->cap[cap_id].value, hfi_value); - rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM, &hfi_value, sizeof(u32), __func__); return rc; } -*/ + +int msm_vidc_set_rotation(void *instance, + enum msm_vidc_inst_capability_type cap_id) +{ + int rc = 0; + struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance; + u32 hfi_value; + + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = msm_vidc_v4l2_to_hfi_enum(inst, cap_id, &hfi_value); + if (rc) + return -EINVAL; + + rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32, + &hfi_value, sizeof(u32), __func__); + if (rc) + return rc; + + return rc; +} int msm_vidc_set_q16(void *instance, enum msm_vidc_inst_capability_type cap_id) diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 035bfc722e..d4beecf216 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -156,7 +156,8 @@ bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst, buffer_type != HFI_BUFFER_NON_COMV && buffer_type != HFI_BUFFER_LINE && buffer_type != HFI_BUFFER_DPB && - buffer_type != HFI_BUFFER_PERSIST) { + buffer_type != HFI_BUFFER_PERSIST && + buffer_type != HFI_BUFFER_VPSS) { i_vpr_e(inst, "%s: invalid buffer type %#x\n", func, buffer_type); return false; @@ -1035,6 +1036,7 @@ static int handle_session_buffer(struct msm_vidc_inst *inst, {HFI_BUFFER_LINE, handle_release_internal_buffer }, {HFI_BUFFER_ARP, handle_release_internal_buffer }, {HFI_BUFFER_DPB, handle_release_internal_buffer }, + {HFI_BUFFER_VPSS, handle_release_internal_buffer }, }; static const struct msm_vidc_hfi_buffer_handle dec_input_hfi_handle[] = { {HFI_BUFFER_METADATA, handle_input_metadata_buffer },