video: driver: Enhance fence support
- Introduce V4L2_EVENT_VIDC_METADATA to post fence fd returned in ETB metadata done buffer. - V4L2_CID_MPEG_VIDC_SW_FENCE_FD g_ctrl support for client to get fence fd for requested fence id. - Addition of fence delivery and subscribtion support. - Fence property packetization to send to firmware via FTB buffer. Change-Id: Ifb289849e352af2c4729aa95040bd83753979970 Signed-off-by: Akshata Sahukar <quic_asahukar@quicinc.com>
This commit is contained in:
@@ -277,18 +277,29 @@ static struct msm_platform_inst_capability instance_data_kalama[] = {
|
|||||||
{0},
|
{0},
|
||||||
NULL, msm_vidc_set_u32},
|
NULL, msm_vidc_set_u32},
|
||||||
|
|
||||||
{SW_FENCE_ENABLE, DEC, CODECS_ALL,
|
/*
|
||||||
|
* Client will enable V4L2_CID_MPEG_VIDC_INPUT_METADATA_OUTBUF_FENCE
|
||||||
|
* to get fence_id in input metadata buffer done.
|
||||||
|
*/
|
||||||
|
{INPUT_META_OUTBUF_FENCE, DEC, CODECS_ALL,
|
||||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||||
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||||
V4L2_CID_MPEG_VIDC_SW_FENCE_ENABLE,
|
V4L2_CID_MPEG_VIDC_INPUT_METADATA_OUTBUF_FENCE,
|
||||||
HFI_PROP_FENCE},
|
HFI_PROP_FENCE},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Client to do set_ctrl with FENCE_ID to set fence_id
|
||||||
|
* and then client will do get_ctrl with FENCE_FD to get
|
||||||
|
* fence_fd corresponding to client set fence_id.
|
||||||
|
*/
|
||||||
{FENCE_ID, DEC, CODECS_ALL,
|
{FENCE_ID, DEC, CODECS_ALL,
|
||||||
0, INT_MAX, 1, 0,
|
0, INT_MAX, 1, 0,
|
||||||
V4L2_CID_MPEG_VIDC_SW_FENCE_ID},
|
V4L2_CID_MPEG_VIDC_SW_FENCE_ID,
|
||||||
|
0,
|
||||||
|
CAP_FLAG_DYNAMIC_ALLOWED | CAP_FLAG_OUTPUT_PORT},
|
||||||
|
|
||||||
{FENCE_FD, DEC, CODECS_ALL,
|
{FENCE_FD, DEC, CODECS_ALL,
|
||||||
0, INT_MAX, 1, 0,
|
INVALID_FD, INT_MAX, 1, INVALID_FD,
|
||||||
V4L2_CID_MPEG_VIDC_SW_FENCE_FD},
|
V4L2_CID_MPEG_VIDC_SW_FENCE_FD},
|
||||||
|
|
||||||
{TS_REORDER, DEC, H264|HEVC,
|
{TS_REORDER, DEC, H264|HEVC,
|
||||||
|
@@ -298,7 +298,7 @@ int msm_vidc_alloc_and_queue_session_internal_buffers(struct msm_vidc_inst *inst
|
|||||||
enum msm_vidc_buffer_type buffer_type);
|
enum msm_vidc_buffer_type buffer_type);
|
||||||
int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
|
int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
|
||||||
enum msm_vidc_buffer_type buffer_type);
|
enum msm_vidc_buffer_type buffer_type);
|
||||||
int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
int msm_vidc_buffer_done(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf);
|
struct msm_vidc_buffer *buf);
|
||||||
int msm_vidc_remove_session(struct msm_vidc_inst *inst);
|
int msm_vidc_remove_session(struct msm_vidc_inst *inst);
|
||||||
int msm_vidc_add_session(struct msm_vidc_inst *inst);
|
int msm_vidc_add_session(struct msm_vidc_inst *inst);
|
||||||
|
@@ -61,6 +61,7 @@
|
|||||||
#define MAX_SUPPORTED_MIN_QUALITY 70
|
#define MAX_SUPPORTED_MIN_QUALITY 70
|
||||||
#define MIN_CHROMA_QP_OFFSET -12
|
#define MIN_CHROMA_QP_OFFSET -12
|
||||||
#define MAX_CHROMA_QP_OFFSET 0
|
#define MAX_CHROMA_QP_OFFSET 0
|
||||||
|
#define INVALID_FD -1
|
||||||
|
|
||||||
#define DCVS_WINDOW 16
|
#define DCVS_WINDOW 16
|
||||||
#define ENC_FPS_WINDOW 3
|
#define ENC_FPS_WINDOW 3
|
||||||
@@ -379,7 +380,7 @@ enum msm_vidc_inst_capability_type {
|
|||||||
MB_CYCLES_FW,
|
MB_CYCLES_FW,
|
||||||
MB_CYCLES_FW_VPP,
|
MB_CYCLES_FW_VPP,
|
||||||
SECURE_MODE,
|
SECURE_MODE,
|
||||||
SW_FENCE_ENABLE,
|
INPUT_META_OUTBUF_FENCE,
|
||||||
FENCE_ID,
|
FENCE_ID,
|
||||||
FENCE_FD,
|
FENCE_FD,
|
||||||
TS_REORDER,
|
TS_REORDER,
|
||||||
|
@@ -77,6 +77,7 @@ static const u32 msm_vdec_output_subscribe_for_properties[] = {
|
|||||||
HFI_PROP_PICTURE_TYPE,
|
HFI_PROP_PICTURE_TYPE,
|
||||||
HFI_PROP_DPB_LIST,
|
HFI_PROP_DPB_LIST,
|
||||||
HFI_PROP_CABAC_SESSION,
|
HFI_PROP_CABAC_SESSION,
|
||||||
|
HFI_PROP_FENCE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 msm_vdec_internal_buffer_type[] = {
|
static const u32 msm_vdec_internal_buffer_type[] = {
|
||||||
@@ -1230,6 +1231,8 @@ static int msm_vdec_subscribe_property(struct msm_vidc_inst *inst,
|
|||||||
HFI_PAYLOAD_U32_ARRAY,
|
HFI_PAYLOAD_U32_ARRAY,
|
||||||
&payload[0],
|
&payload[0],
|
||||||
(count + 1) * sizeof(u32));
|
(count + 1) * sizeof(u32));
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1244,15 @@ static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
|
|||||||
u32 payload[32] = {0};
|
u32 payload[32] = {0};
|
||||||
u32 i, count = 0;
|
u32 i, count = 0;
|
||||||
struct msm_vidc_inst_capability *capability;
|
struct msm_vidc_inst_capability *capability;
|
||||||
static const u32 metadata_list[] = {
|
const u32 metadata_input_list[] = {
|
||||||
|
INPUT_META_OUTBUF_FENCE,
|
||||||
|
/*
|
||||||
|
* when fence enabled, client needs output buffer_tag
|
||||||
|
* in input metadata buffer done.
|
||||||
|
*/
|
||||||
|
META_OUTPUT_BUF_TAG,
|
||||||
|
};
|
||||||
|
const u32 metadata_output_list[] = {
|
||||||
META_BITSTREAM_RESOLUTION,
|
META_BITSTREAM_RESOLUTION,
|
||||||
META_CROP_OFFSETS,
|
META_CROP_OFFSETS,
|
||||||
META_DPB_MISR,
|
META_DPB_MISR,
|
||||||
@@ -1253,6 +1264,9 @@ static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
|
|||||||
META_SEI_MASTERING_DISP,
|
META_SEI_MASTERING_DISP,
|
||||||
META_SEI_CLL,
|
META_SEI_CLL,
|
||||||
META_HDR10PLUS,
|
META_HDR10PLUS,
|
||||||
|
/*
|
||||||
|
* client needs input buffer tag in output metadata buffer done.
|
||||||
|
*/
|
||||||
META_BUF_TAG,
|
META_BUF_TAG,
|
||||||
META_DPB_TAG_LIST,
|
META_DPB_TAG_LIST,
|
||||||
META_SUBFRAME_OUTPUT,
|
META_SUBFRAME_OUTPUT,
|
||||||
@@ -1268,14 +1282,28 @@ static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
|
|||||||
|
|
||||||
capability = inst->capabilities;
|
capability = inst->capabilities;
|
||||||
payload[0] = HFI_MODE_METADATA;
|
payload[0] = HFI_MODE_METADATA;
|
||||||
for (i = 0; i < ARRAY_SIZE(metadata_list); i++) {
|
if (port == INPUT_PORT) {
|
||||||
if (capability->cap[metadata_list[i]].value &&
|
for (i = 0; i < ARRAY_SIZE(metadata_input_list); i++) {
|
||||||
msm_vidc_allow_metadata(inst, metadata_list[i])) {
|
if (capability->cap[metadata_input_list[i]].value &&
|
||||||
|
msm_vidc_allow_metadata(inst, metadata_input_list[i])) {
|
||||||
payload[count + 1] =
|
payload[count + 1] =
|
||||||
capability->cap[metadata_list[i]].hfi_id;
|
capability->cap[metadata_input_list[i]].hfi_id;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
} else if (port == OUTPUT_PORT) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(metadata_output_list); i++) {
|
||||||
|
if (capability->cap[metadata_output_list[i]].value &&
|
||||||
|
msm_vidc_allow_metadata(inst, metadata_output_list[i])) {
|
||||||
|
payload[count + 1] =
|
||||||
|
capability->cap[metadata_output_list[i]].hfi_id;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i_vpr_e(inst, "%s: invalid port: %d\n", __func__, port);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
rc = venus_hfi_session_command(inst,
|
rc = venus_hfi_session_command(inst,
|
||||||
HFI_CMD_SUBSCRIBE_MODE,
|
HFI_CMD_SUBSCRIBE_MODE,
|
||||||
@@ -1283,6 +1311,8 @@ static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
|
|||||||
HFI_PAYLOAD_U32_ARRAY,
|
HFI_PAYLOAD_U32_ARRAY,
|
||||||
&payload[0],
|
&payload[0],
|
||||||
(count + 1) * sizeof(u32));
|
(count + 1) * sizeof(u32));
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1294,10 +1324,10 @@ static int msm_vdec_set_delivery_mode_metadata(struct msm_vidc_inst *inst,
|
|||||||
u32 payload[32] = {0};
|
u32 payload[32] = {0};
|
||||||
u32 i, count = 0;
|
u32 i, count = 0;
|
||||||
struct msm_vidc_inst_capability *capability;
|
struct msm_vidc_inst_capability *capability;
|
||||||
static const u32 metadata_input_list[] = {
|
const u32 metadata_input_list[] = {
|
||||||
META_BUF_TAG,
|
META_BUF_TAG,
|
||||||
};
|
};
|
||||||
static const u32 metadata_output_list[] = {
|
const u32 metadata_output_list[] = {
|
||||||
META_OUTPUT_BUF_TAG,
|
META_OUTPUT_BUF_TAG,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1338,6 +1368,62 @@ static int msm_vdec_set_delivery_mode_metadata(struct msm_vidc_inst *inst,
|
|||||||
HFI_PAYLOAD_U32_ARRAY,
|
HFI_PAYLOAD_U32_ARRAY,
|
||||||
&payload[0],
|
&payload[0],
|
||||||
(count + 1) * sizeof(u32));
|
(count + 1) * sizeof(u32));
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_vdec_set_delivery_mode_property(struct msm_vidc_inst *inst,
|
||||||
|
enum msm_vidc_port_type port)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
u32 payload[32] = {0};
|
||||||
|
u32 i, count = 0;
|
||||||
|
struct msm_vidc_inst_capability *capability;
|
||||||
|
const u32 property_output_list[] = {
|
||||||
|
INPUT_META_OUTBUF_FENCE,
|
||||||
|
};
|
||||||
|
const u32 property_input_list[] = {};
|
||||||
|
|
||||||
|
if (!inst || !inst->capabilities) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
i_vpr_h(inst, "%s()\n", __func__);
|
||||||
|
|
||||||
|
capability = inst->capabilities;
|
||||||
|
payload[0] = HFI_MODE_PROPERTY;
|
||||||
|
|
||||||
|
if (port == INPUT_PORT) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(property_input_list); i++) {
|
||||||
|
if (capability->cap[property_input_list[i]].value) {
|
||||||
|
payload[count + 1] =
|
||||||
|
capability->cap[property_input_list[i]].hfi_id;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (port == OUTPUT_PORT) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(property_output_list); i++) {
|
||||||
|
if (capability->cap[property_output_list[i]].value) {
|
||||||
|
payload[count + 1] =
|
||||||
|
capability->cap[property_output_list[i]].hfi_id;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i_vpr_e(inst, "%s: invalid port: %d\n", __func__, port);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = venus_hfi_session_command(inst,
|
||||||
|
HFI_CMD_DELIVERY_MODE,
|
||||||
|
port,
|
||||||
|
HFI_PAYLOAD_U32_ARRAY,
|
||||||
|
&payload[0],
|
||||||
|
(count + 1) * sizeof(u32));
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1354,6 +1440,8 @@ static int msm_vdec_session_resume(struct msm_vidc_inst *inst,
|
|||||||
HFI_PAYLOAD_NONE,
|
HFI_PAYLOAD_NONE,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1984,6 +2072,10 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
rc = msm_vdec_set_delivery_mode_property(inst, OUTPUT_PORT);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = msm_vdec_set_delivery_mode_metadata(inst, OUTPUT_PORT);
|
rc = msm_vdec_set_delivery_mode_metadata(inst, OUTPUT_PORT);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2887,6 +2979,7 @@ int msm_vdec_subscribe_event(struct msm_vidc_inst *inst,
|
|||||||
|
|
||||||
switch (sub->type) {
|
switch (sub->type) {
|
||||||
case V4L2_EVENT_EOS:
|
case V4L2_EVENT_EOS:
|
||||||
|
case V4L2_EVENT_VIDC_METADATA:
|
||||||
rc = v4l2_event_subscribe(&inst->event_handler, sub, MAX_EVENTS, NULL);
|
rc = v4l2_event_subscribe(&inst->event_handler, sub, MAX_EVENTS, NULL);
|
||||||
break;
|
break;
|
||||||
case V4L2_EVENT_SOURCE_CHANGE:
|
case V4L2_EVENT_SOURCE_CHANGE:
|
||||||
|
@@ -82,7 +82,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
|||||||
{MB_CYCLES_FW, "MB_CYCLES_FW" },
|
{MB_CYCLES_FW, "MB_CYCLES_FW" },
|
||||||
{MB_CYCLES_FW_VPP, "MB_CYCLES_FW_VPP" },
|
{MB_CYCLES_FW_VPP, "MB_CYCLES_FW_VPP" },
|
||||||
{SECURE_MODE, "SECURE_MODE" },
|
{SECURE_MODE, "SECURE_MODE" },
|
||||||
{SW_FENCE_ENABLE, "SW_FENCE_ENABLE" },
|
{INPUT_META_OUTBUF_FENCE, "INPUT_META_OUTBUF_FENCE" },
|
||||||
{FENCE_ID, "FENCE_ID" },
|
{FENCE_ID, "FENCE_ID" },
|
||||||
{FENCE_FD, "FENCE_FD" },
|
{FENCE_FD, "FENCE_FD" },
|
||||||
{TS_REORDER, "TS_REORDER" },
|
{TS_REORDER, "TS_REORDER" },
|
||||||
@@ -1412,6 +1412,14 @@ bool msm_vidc_allow_property(struct msm_vidc_inst *inst, u32 hfi_id)
|
|||||||
is_allowed = false;
|
is_allowed = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HFI_PROP_FENCE:
|
||||||
|
if (!inst->capabilities->cap[INPUT_META_OUTBUF_FENCE].value) {
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: cap: %24s not enabled, hence not allowed to subscribe\n",
|
||||||
|
__func__, cap_name(INPUT_META_OUTBUF_FENCE));
|
||||||
|
is_allowed = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
is_allowed = true;
|
is_allowed = true;
|
||||||
break;
|
break;
|
||||||
@@ -2016,6 +2024,46 @@ int msm_vidc_state_change_last_flag(struct msm_vidc_inst *inst)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msm_vidc_get_fence_fd(struct msm_vidc_inst *inst, int *fence_fd)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct msm_vidc_fence *fence, *dummy_fence;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
*fence_fd = INVALID_FD;
|
||||||
|
|
||||||
|
if (!inst || !inst->capabilities) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
||||||
|
if (fence->dma_fence.seqno ==
|
||||||
|
(u64)inst->capabilities->cap[FENCE_ID].value) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
i_vpr_e(inst, "%s: could not find matching fence for fence id: %d\n",
|
||||||
|
__func__, inst->capabilities->cap[FENCE_ID].value);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fence->fd == INVALID_FD) {
|
||||||
|
rc = msm_vidc_create_fence_fd(inst, fence);
|
||||||
|
if (rc)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*fence_fd = fence->fd;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -2041,6 +2089,12 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
|||||||
i_vpr_h(inst, "%s: film grain present: %d\n",
|
i_vpr_h(inst, "%s: film grain present: %d\n",
|
||||||
__func__, ctrl->val);
|
__func__, ctrl->val);
|
||||||
break;
|
break;
|
||||||
|
case V4L2_CID_MPEG_VIDC_SW_FENCE_FD:
|
||||||
|
rc = msm_vidc_get_fence_fd(inst, &ctrl->val);
|
||||||
|
if (!rc)
|
||||||
|
i_vpr_l(inst, "%s: fence fd: %d\n",
|
||||||
|
__func__, ctrl->val);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
i_vpr_e(inst, "invalid ctrl %s id %d\n",
|
i_vpr_e(inst, "invalid ctrl %s id %d\n",
|
||||||
ctrl->name, ctrl->id);
|
ctrl->name, ctrl->id);
|
||||||
@@ -3272,7 +3326,7 @@ int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (inst->capabilities->cap[SW_FENCE_ENABLE].value &&
|
if (inst->capabilities->cap[INPUT_META_OUTBUF_FENCE].value &&
|
||||||
is_output_buffer(buf->type)) {
|
is_output_buffer(buf->type)) {
|
||||||
fence = msm_vidc_fence_create(inst);
|
fence = msm_vidc_fence_create(inst);
|
||||||
if (!fence)
|
if (!fence)
|
||||||
@@ -3646,7 +3700,7 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
static int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf)
|
struct msm_vidc_buffer *buf)
|
||||||
{
|
{
|
||||||
int type, port, state;
|
int type, port, state;
|
||||||
@@ -3714,6 +3768,53 @@ int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_vidc_v4l2_buffer_event(struct msm_vidc_inst *inst,
|
||||||
|
struct msm_vidc_buffer *buf)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct v4l2_event event = {0};
|
||||||
|
struct v4l2_event_vidc_metadata *event_data = NULL;
|
||||||
|
|
||||||
|
if (!inst || !buf) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->type != MSM_VIDC_BUF_INPUT_META) {
|
||||||
|
i_vpr_e(inst, "%s: unsupported buffer type %s\n",
|
||||||
|
__func__, buf_name(buf->type));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.type = V4L2_EVENT_VIDC_METADATA;
|
||||||
|
event_data = (struct v4l2_event_vidc_metadata *)event.u.data;
|
||||||
|
event_data->type = INPUT_META_PLANE;
|
||||||
|
event_data->fd = buf->fd;
|
||||||
|
|
||||||
|
v4l2_event_queue_fh(&inst->event_handler, &event);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_buffer_done(struct msm_vidc_inst *inst,
|
||||||
|
struct msm_vidc_buffer *buf)
|
||||||
|
{
|
||||||
|
if (!inst || !inst->capabilities || !buf) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->type == MSM_VIDC_BUF_INPUT_META &&
|
||||||
|
inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
|
||||||
|
if (inst->capabilities->cap[INPUT_META_OUTBUF_FENCE].value)
|
||||||
|
return msm_vidc_v4l2_buffer_event(inst, buf);
|
||||||
|
} else {
|
||||||
|
return msm_vidc_vb2_buffer_done(inst, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int msm_vidc_event_queue_init(struct msm_vidc_inst *inst)
|
int msm_vidc_event_queue_init(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -5086,7 +5187,7 @@ int msm_vidc_flush_buffers(struct msm_vidc_inst *inst,
|
|||||||
buf->attr & MSM_VIDC_ATTR_DEFERRED) {
|
buf->attr & MSM_VIDC_ATTR_DEFERRED) {
|
||||||
print_vidc_buffer(VIDC_HIGH, "high", "flushing buffer", inst, buf);
|
print_vidc_buffer(VIDC_HIGH, "high", "flushing buffer", inst, buf);
|
||||||
if (!(buf->attr & MSM_VIDC_ATTR_BUFFER_DONE))
|
if (!(buf->attr & MSM_VIDC_ATTR_BUFFER_DONE))
|
||||||
msm_vidc_vb2_buffer_done(inst, buf);
|
msm_vidc_buffer_done(inst, buf);
|
||||||
msm_vidc_put_driver_buf(inst, buf);
|
msm_vidc_put_driver_buf(inst, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5229,7 +5330,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
|||||||
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
|
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
|
||||||
print_vidc_buffer(VIDC_ERR, "err ", "destroying ", inst, buf);
|
print_vidc_buffer(VIDC_ERR, "err ", "destroying ", inst, buf);
|
||||||
if (!(buf->attr & MSM_VIDC_ATTR_BUFFER_DONE))
|
if (!(buf->attr & MSM_VIDC_ATTR_BUFFER_DONE))
|
||||||
msm_vidc_vb2_buffer_done(inst, buf);
|
msm_vidc_buffer_done(inst, buf);
|
||||||
msm_vidc_put_driver_buf(inst, buf);
|
msm_vidc_put_driver_buf(inst, buf);
|
||||||
}
|
}
|
||||||
msm_vidc_unmap_buffers(inst, ext_buf_types[i]);
|
msm_vidc_unmap_buffers(inst, ext_buf_types[i]);
|
||||||
@@ -5267,7 +5368,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
||||||
i_vpr_e(inst, "%s: destroying fence id: %llu",
|
i_vpr_e(inst, "%s: destroying fence id: %llu\n",
|
||||||
__func__, fence->dma_fence.seqno);
|
__func__, fence->dma_fence.seqno);
|
||||||
msm_vidc_fence_destroy(inst, fence);
|
msm_vidc_fence_destroy(inst, fence);
|
||||||
}
|
}
|
||||||
|
@@ -63,6 +63,7 @@ struct msm_vidc_fence *msm_vidc_fence_create(struct msm_vidc_inst *inst)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fence->fd = INVALID_FD;
|
||||||
spin_lock_init(&fence->lock);
|
spin_lock_init(&fence->lock);
|
||||||
dma_fence_init(&fence->dma_fence, &msm_vidc_dma_fence_ops,
|
dma_fence_init(&fence->dma_fence, &msm_vidc_dma_fence_ops,
|
||||||
&fence->lock, inst->fence_context.ctx_num,
|
&fence->lock, inst->fence_context.ctx_num,
|
||||||
|
@@ -3523,9 +3523,19 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->capabilities->cap[SW_FENCE_ENABLE].value &&
|
if (inst->capabilities->cap[INPUT_META_OUTBUF_FENCE].value &&
|
||||||
is_output_buffer(buffer->type)) {
|
is_output_buffer(buffer->type)) {
|
||||||
/* TODO(AS): create fence property packet to send to fw */
|
rc = hfi_create_packet(inst->packet,
|
||||||
|
inst->packet_size,
|
||||||
|
HFI_PROP_FENCE,
|
||||||
|
0,
|
||||||
|
HFI_PAYLOAD_U64,
|
||||||
|
HFI_PORT_RAW,
|
||||||
|
core->packet_id++,
|
||||||
|
&buffer->fence_id,
|
||||||
|
sizeof(u64));
|
||||||
|
if (rc)
|
||||||
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = venus_hfi_add_pending_packets(inst);
|
rc = venus_hfi_add_pending_packets(inst);
|
||||||
|
@@ -1115,7 +1115,7 @@ static int handle_dequeue_buffers(struct msm_vidc_inst *inst)
|
|||||||
"vb2 done already", inst, buf);
|
"vb2 done already", inst, buf);
|
||||||
} else {
|
} else {
|
||||||
buf->attr |= MSM_VIDC_ATTR_BUFFER_DONE;
|
buf->attr |= MSM_VIDC_ATTR_BUFFER_DONE;
|
||||||
msm_vidc_vb2_buffer_done(inst, buf);
|
msm_vidc_buffer_done(inst, buf);
|
||||||
}
|
}
|
||||||
msm_vidc_put_driver_buf(inst, buf);
|
msm_vidc_put_driver_buf(inst, buf);
|
||||||
}
|
}
|
||||||
@@ -1557,7 +1557,7 @@ static int handle_session_property(struct msm_vidc_inst *inst,
|
|||||||
__func__, payload_ptr[0], inst->capabilities->cap[PIPE].value);
|
__func__, payload_ptr[0], inst->capabilities->cap[PIPE].value);
|
||||||
break;
|
break;
|
||||||
case HFI_PROP_FENCE:
|
case HFI_PROP_FENCE:
|
||||||
if (inst->capabilities->cap[SW_FENCE_ENABLE].value) {
|
if (inst->capabilities->cap[INPUT_META_OUTBUF_FENCE].value) {
|
||||||
if (payload_ptr) {
|
if (payload_ptr) {
|
||||||
fence_id = payload_ptr[0];
|
fence_id = payload_ptr[0];
|
||||||
rc = msm_vidc_fence_signal(inst, fence_id);
|
rc = msm_vidc_fence_signal(inst, fence_id);
|
||||||
|
@@ -200,8 +200,8 @@ enum v4l2_mpeg_video_av1_tier {
|
|||||||
/* Control to enable input metadata via request api */
|
/* Control to enable input metadata via request api */
|
||||||
#define V4L2_CID_MPEG_VIDC_INPUT_METADATA_VIA_REQUEST_ENABLE \
|
#define V4L2_CID_MPEG_VIDC_INPUT_METADATA_VIA_REQUEST_ENABLE \
|
||||||
(V4L2_CID_MPEG_VIDC_BASE + 0x37)
|
(V4L2_CID_MPEG_VIDC_BASE + 0x37)
|
||||||
/* Control to enable software fence feature */
|
/* Enables Output buffer fence id via input metadata */
|
||||||
#define V4L2_CID_MPEG_VIDC_SW_FENCE_ENABLE \
|
#define V4L2_CID_MPEG_VIDC_INPUT_METADATA_OUTBUF_FENCE \
|
||||||
(V4L2_CID_MPEG_VIDC_BASE + 0x38)
|
(V4L2_CID_MPEG_VIDC_BASE + 0x38)
|
||||||
/* Control to set fence id to driver in order get corresponding fence fd */
|
/* Control to set fence id to driver in order get corresponding fence fd */
|
||||||
#define V4L2_CID_MPEG_VIDC_SW_FENCE_ID \
|
#define V4L2_CID_MPEG_VIDC_SW_FENCE_ID \
|
||||||
@@ -345,6 +345,7 @@ enum v4l2_mpeg_vidc_metadata {
|
|||||||
METADATA_ROI_INFO = 0x03000173,
|
METADATA_ROI_INFO = 0x03000173,
|
||||||
METADATA_DPB_TAG_LIST = 0x03000179,
|
METADATA_DPB_TAG_LIST = 0x03000179,
|
||||||
METADATA_MAX_NUM_REORDER_FRAMES = 0x03000127,
|
METADATA_MAX_NUM_REORDER_FRAMES = 0x03000127,
|
||||||
|
METADATA_FENCE = 0x0300018B,
|
||||||
};
|
};
|
||||||
enum meta_interlace_info {
|
enum meta_interlace_info {
|
||||||
META_INTERLACE_INFO_NONE = 0x00000000,
|
META_INTERLACE_INFO_NONE = 0x00000000,
|
||||||
@@ -358,4 +359,30 @@ enum meta_interlace_info {
|
|||||||
|
|
||||||
/* vendor controls end */
|
/* vendor controls end */
|
||||||
|
|
||||||
|
/* vendor events start */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vendor event structure looks like below (reference videodev2.h)
|
||||||
|
* struct v4l2_event {
|
||||||
|
* __u32 type;
|
||||||
|
* union {
|
||||||
|
* struct v4l2_event_src_change src_change;
|
||||||
|
* ...
|
||||||
|
* / ********** vendor event structure ******** /
|
||||||
|
* __u8 data[64];
|
||||||
|
* } u;
|
||||||
|
* __u32 pending;
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define V4L2_EVENT_VIDC_METADATA \
|
||||||
|
(V4L2_EVENT_PRIVATE_START + 0x1)
|
||||||
|
|
||||||
|
struct v4l2_event_vidc_metadata {
|
||||||
|
__u32 type;
|
||||||
|
__s32 fd;
|
||||||
|
__u8 reserved[56];
|
||||||
|
};
|
||||||
|
/* vendor events end */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user