video: driver: add restrictions for dec fence enablement
- Allow dec sw fence enablement only if decode order is set and non interlace type session. - Enable low latency mode if sw fence is enabled. - Signal fence if FBD length > 0. Change-Id: Ib59c2de51f621b796e68fe2aba68d9fca3ff4272 Signed-off-by: Akshata Sahukar <quic_asahukar@quicinc.com>
This commit is contained in:
@@ -330,7 +330,7 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
|
||||
* Client will enable V4L2_CID_MPEG_VIDC_METADATA_OUTBUF_FENCE
|
||||
* to get fence_id in input metadata buffer done.
|
||||
*/
|
||||
{META_OUTBUF_FENCE, DEC, CODECS_ALL,
|
||||
{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9|AV1,
|
||||
V4L2_MPEG_VIDC_META_DISABLE,
|
||||
V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT,
|
||||
0, V4L2_MPEG_VIDC_META_DISABLE,
|
||||
@@ -1327,7 +1327,10 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
|
||||
0,
|
||||
HFI_PROP_PIPE},
|
||||
|
||||
{POC, DEC, H264, 0, 18, 1, 1},
|
||||
{POC, DEC, H264,
|
||||
0, 18, 1, 1,
|
||||
0,
|
||||
HFI_PROP_PIC_ORDER_CNT_TYPE},
|
||||
|
||||
{QUALITY_MODE, ENC, CODECS_ALL,
|
||||
MSM_VIDC_MAX_QUALITY_MODE,
|
||||
@@ -1729,6 +1732,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
|
||||
NULL,
|
||||
msm_vidc_set_u32},
|
||||
|
||||
{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9|AV1,
|
||||
{OUTPUT_ORDER},
|
||||
{LOWLATENCY_MODE},
|
||||
msm_vidc_adjust_dec_outbuf_fence,
|
||||
NULL},
|
||||
|
||||
{HFLIP, ENC, CODECS_ALL,
|
||||
{0},
|
||||
{0},
|
||||
@@ -1860,7 +1869,13 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
|
||||
{LOWLATENCY_MODE, ENC, H264 | HEVC,
|
||||
{BITRATE_MODE},
|
||||
{STAGE},
|
||||
msm_vidc_adjust_lowlatency_mode,
|
||||
msm_vidc_adjust_enc_lowlatency_mode,
|
||||
NULL},
|
||||
|
||||
{LOWLATENCY_MODE, DEC, H264|HEVC|VP9|AV1,
|
||||
{META_OUTBUF_FENCE},
|
||||
{STAGE},
|
||||
msm_vidc_adjust_dec_lowlatency_mode,
|
||||
NULL},
|
||||
|
||||
{LTR_COUNT, ENC, H264|HEVC,
|
||||
@@ -2150,7 +2165,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
|
||||
|
||||
{OUTPUT_ORDER, DEC, H264|HEVC|VP9|AV1,
|
||||
{THUMBNAIL_MODE, DISPLAY_DELAY, DISPLAY_DELAY_ENABLE},
|
||||
{0},
|
||||
{META_OUTBUF_FENCE},
|
||||
msm_vidc_adjust_output_order,
|
||||
msm_vidc_set_u32},
|
||||
|
||||
@@ -2190,7 +2205,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
|
||||
NULL,
|
||||
msm_vidc_set_u32_packed},
|
||||
|
||||
{STAGE, DEC|ENC, CODECS_ALL,
|
||||
{STAGE, ENC | DEC, CODECS_ALL,
|
||||
{0},
|
||||
{0},
|
||||
NULL,
|
||||
@@ -2202,6 +2217,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
|
||||
NULL,
|
||||
msm_vidc_set_stage},
|
||||
|
||||
{STAGE, DEC, H264|HEVC|VP9|AV1,
|
||||
{LOWLATENCY_MODE},
|
||||
{0},
|
||||
NULL,
|
||||
msm_vidc_set_stage},
|
||||
|
||||
{PIPE, DEC|ENC, CODECS_ALL,
|
||||
{0},
|
||||
{0},
|
||||
|
@@ -46,7 +46,8 @@ int msm_vidc_adjust_blur_resolution(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_brs(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_min_quality(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_enc_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_dec_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_set_v4l2_properties(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_prepare_dependency_list(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl);
|
||||
@@ -54,6 +55,7 @@ int msm_vidc_adjust_roi_info(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_all_intra(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_dec_frame_rate(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_dec_operating_rate(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl);
|
||||
|
||||
int msm_vidc_set_header_mode(void *instance,
|
||||
|
@@ -197,6 +197,11 @@ static inline bool is_meta_enabled(struct msm_vidc_inst *inst, unsigned int type
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static inline bool is_outbuf_fence_enabled(struct msm_vidc_inst *inst)
|
||||
{
|
||||
return is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE);
|
||||
}
|
||||
|
||||
static inline bool is_linear_yuv_colorformat(enum msm_vidc_colorformat_type colorformat)
|
||||
{
|
||||
return colorformat == MSM_VIDC_FMT_NV12 ||
|
||||
|
@@ -13,10 +13,12 @@ struct msm_vidc_fence *msm_vidc_fence_create(
|
||||
struct msm_vidc_inst *inst);
|
||||
int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_fence *fence);
|
||||
struct msm_vidc_fence *msm_vidc_get_fence_from_id(
|
||||
struct msm_vidc_inst *inst, u32 fence_id);
|
||||
int msm_vidc_fence_signal(struct msm_vidc_inst *inst,
|
||||
u32 fence_id);
|
||||
void msm_vidc_fence_destroy(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_fence *fence);
|
||||
u32 fence_id);
|
||||
int msm_vidc_fence_init(struct msm_vidc_inst *inst);
|
||||
void msm_vidc_fence_deinit(struct msm_vidc_inst *inst);
|
||||
|
||||
|
@@ -762,6 +762,7 @@ struct msm_vidc_hfi_frame_info {
|
||||
u32 cf;
|
||||
u32 data_corrupt;
|
||||
u32 overflow;
|
||||
u32 fence_id;
|
||||
};
|
||||
|
||||
struct msm_vidc_decode_vpp_delay {
|
||||
|
@@ -1190,7 +1190,7 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
|
||||
u32 colour_description_present_flag = 0;
|
||||
u32 video_signal_type_present_flag = 0;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1298,6 +1298,14 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
|
||||
subsc_params.av1_super_block_enabled, __func__);
|
||||
}
|
||||
|
||||
/* disable META_OUTBUF_FENCE if session is Interlace type */
|
||||
if (inst->capabilities->cap[CODED_FRAMES].value ==
|
||||
CODED_FRAMES_INTERLACE) {
|
||||
msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
|
||||
V4L2_MPEG_VIDC_META_RX_INPUT |
|
||||
V4L2_MPEG_VIDC_META_DISABLE, __func__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -443,7 +443,6 @@ int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap_id,
|
||||
s32 adjusted_val, const char *func)
|
||||
{
|
||||
int prev_value = 0;
|
||||
bool is_updated = false;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -464,19 +463,15 @@ int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap_id,
|
||||
/* disable metadata */
|
||||
inst->capabilities->cap[cap_id].value &= ~adjusted_val;
|
||||
}
|
||||
if (prev_value != (prev_value | adjusted_val))
|
||||
is_updated = true;
|
||||
} else {
|
||||
inst->capabilities->cap[cap_id].value = adjusted_val;
|
||||
if (prev_value != adjusted_val)
|
||||
is_updated = true;
|
||||
}
|
||||
|
||||
if (is_updated) {
|
||||
if (prev_value != inst->capabilities->cap[cap_id].value) {
|
||||
i_vpr_h(inst,
|
||||
"%s: updated database: name: %s, value: %#x -> %#x\n",
|
||||
func, cap_name(cap_id),
|
||||
prev_value, adjusted_val);
|
||||
prev_value, inst->capabilities->cap[cap_id].value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2743,7 +2738,7 @@ int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
|
||||
int msm_vidc_adjust_enc_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
s32 adjusted_value;
|
||||
@@ -2773,6 +2768,36 @@ int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_dec_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
s32 adjusted_value;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
|
||||
s32 outbuf_fence = V4L2_MPEG_VIDC_META_DISABLE;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
adjusted_value = ctrl ? ctrl->val :
|
||||
capability->cap[LOWLATENCY_MODE].value;
|
||||
|
||||
if (msm_vidc_get_parent_value(inst, LOWLATENCY_MODE, META_OUTBUF_FENCE,
|
||||
&outbuf_fence, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (outbuf_fence & V4L2_MPEG_VIDC_META_ENABLE &&
|
||||
outbuf_fence & V4L2_MPEG_VIDC_META_RX_INPUT)
|
||||
adjusted_value = 1;
|
||||
|
||||
msm_vidc_update_cap_value(inst, LOWLATENCY_MODE,
|
||||
adjusted_value, __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
int adjusted_value;
|
||||
@@ -2893,6 +2918,37 @@ int msm_vidc_adjust_dec_operating_rate(void *instance, struct v4l2_ctrl *ctrl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
|
||||
u32 adjusted_value = 0;
|
||||
s32 picture_order = -1;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
adjusted_value = ctrl ? ctrl->val : capability->cap[META_OUTBUF_FENCE].value;
|
||||
|
||||
if (msm_vidc_get_parent_value(inst, META_OUTBUF_FENCE, OUTPUT_ORDER,
|
||||
&picture_order, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (picture_order == V4L2_MPEG_MSM_VIDC_DISABLE) {
|
||||
/* disable outbuf fence */
|
||||
adjusted_value = V4L2_MPEG_VIDC_META_DISABLE |
|
||||
V4L2_MPEG_VIDC_META_RX_INPUT;
|
||||
}
|
||||
|
||||
msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
|
||||
adjusted_value, __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_prepare_dependency_list(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct list_head root_list, opt_list;
|
||||
|
@@ -3481,7 +3481,7 @@ exit:
|
||||
if (rc) {
|
||||
i_vpr_e(inst, "%s: qbuf failed\n", __func__);
|
||||
if (fence)
|
||||
msm_vidc_fence_destroy(inst, fence);
|
||||
msm_vidc_fence_destroy(inst, (u32)fence->dma_fence.seqno);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -5569,7 +5569,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
||||
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
||||
i_vpr_e(inst, "%s: destroying fence id: %llu\n",
|
||||
__func__, fence->dma_fence.seqno);
|
||||
msm_vidc_fence_destroy(inst, fence);
|
||||
msm_vidc_fence_destroy(inst, (u32)fence->dma_fence.seqno);
|
||||
}
|
||||
|
||||
/* destroy buffers from pool */
|
||||
|
@@ -117,15 +117,15 @@ err_fd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
|
||||
struct msm_vidc_fence *msm_vidc_get_fence_from_id(
|
||||
struct msm_vidc_inst *inst, u32 fence_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_fence *fence, *dummy_fence;
|
||||
bool found = false;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
||||
@@ -135,12 +135,30 @@ int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!found)
|
||||
return NULL;
|
||||
|
||||
return fence;
|
||||
}
|
||||
|
||||
int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_fence *fence;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fence = msm_vidc_get_fence_from_id(inst, fence_id);
|
||||
if (!fence) {
|
||||
i_vpr_e(inst, "%s: no fence available to signal with id: %u",
|
||||
__func__, fence_id);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i_vpr_l(inst, "%s: fence %s\n", __func__, fence->name);
|
||||
dma_fence_signal(&fence->dma_fence);
|
||||
dma_fence_put(&fence->dma_fence);
|
||||
@@ -150,28 +168,18 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_vidc_fence_destroy(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_fence *fence_to_destroy)
|
||||
{
|
||||
struct msm_vidc_fence *fence, *dummy_fence;
|
||||
bool found = false;
|
||||
|
||||
if (!inst || !fence_to_destroy) {
|
||||
void msm_vidc_fence_destroy(struct msm_vidc_inst *inst, u32 fence_id)
|
||||
{
|
||||
struct msm_vidc_fence *fence;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
||||
if (fence->dma_fence.seqno ==
|
||||
fence_to_destroy->dma_fence.seqno) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
i_vpr_e(inst, "%s: no fence available to destroy with id: %llu",
|
||||
__func__, fence_to_destroy->dma_fence.seqno);
|
||||
fence = msm_vidc_get_fence_from_id(inst, fence_id);
|
||||
if (!fence) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -864,7 +864,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
||||
if (buffer->data_size) {
|
||||
i_vpr_e(inst, "%s: reset data size to zero for last flag buffer\n",
|
||||
__func__);
|
||||
buffer->data_size = 0;
|
||||
buf->data_size = 0;
|
||||
}
|
||||
if (buffer->flags & HFI_BUF_FW_FLAG_READONLY) {
|
||||
i_vpr_e(inst, "%s: reset RO flag for last flag buffer\n",
|
||||
@@ -895,6 +895,19 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
||||
buf->flags = 0;
|
||||
buf->flags = get_driver_buffer_flags(inst, buffer->flags);
|
||||
|
||||
/* fence signalling */
|
||||
if (inst->hfi_frame_info.fence_id) {
|
||||
if (buf->data_size) {
|
||||
/* signal fence */
|
||||
msm_vidc_fence_signal(inst,
|
||||
inst->hfi_frame_info.fence_id);
|
||||
} else {
|
||||
/* destroy fence */
|
||||
msm_vidc_fence_destroy(inst,
|
||||
inst->hfi_frame_info.fence_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_decode_session(inst)) {
|
||||
inst->power.fw_cr = inst->hfi_frame_info.cr;
|
||||
inst->power.fw_cf = inst->hfi_frame_info.cf;
|
||||
@@ -1435,7 +1448,6 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
|
||||
{
|
||||
int rc = 0;
|
||||
u32 *payload_ptr = NULL;
|
||||
u32 fence_id = 0;
|
||||
|
||||
payload_ptr = (u32 *)((u8 *)pkt + sizeof(struct hfi_packet));
|
||||
if (!payload_ptr) {
|
||||
@@ -1536,13 +1548,7 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
|
||||
__func__, payload_ptr[0], inst->capabilities->cap[PIPE].value);
|
||||
break;
|
||||
case HFI_PROP_FENCE:
|
||||
if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
|
||||
fence_id = payload_ptr[0];
|
||||
rc = msm_vidc_fence_signal(inst, fence_id);
|
||||
} else {
|
||||
i_vpr_e(inst, "%s: fence is not enabled for this session\n",
|
||||
__func__);
|
||||
}
|
||||
inst->hfi_frame_info.fence_id = payload_ptr[0];
|
||||
break;
|
||||
default:
|
||||
i_vpr_e(inst, "%s: invalid property %#x\n",
|
||||
|
@@ -389,6 +389,16 @@ enum meta_interlace_info {
|
||||
META_INTERLACE_FRAME_INTERLACE_BOTTOMFIELD_FIRST = 0x00000020,
|
||||
};
|
||||
|
||||
enum meta_picture_type {
|
||||
META_PICTURE_TYPE_IDR = 0x00000001,
|
||||
META_PICTURE_TYPE_P = 0x00000002,
|
||||
META_PICTURE_TYPE_B = 0x00000004,
|
||||
META_PICTURE_TYPE_I = 0x00000008,
|
||||
META_PICTURE_TYPE_CRA = 0x00000010,
|
||||
META_PICTURE_TYPE_BLA = 0x00000020,
|
||||
META_PICTURE_TYPE_NOSHOW = 0x00000040,
|
||||
};
|
||||
|
||||
/* vendor controls end */
|
||||
|
||||
/* vendor events start */
|
||||
|
Reference in New Issue
Block a user