Merge "video: driver: add support to send input meta buffer via request"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
fe6594bcce
@@ -1523,6 +1523,15 @@ static struct msm_platform_inst_capability instance_data_kalama[] = {
|
||||
{0}, {0},
|
||||
NULL, NULL},
|
||||
|
||||
{INPUT_META_VIA_REQUEST, ENC|DEC, CODECS_ALL,
|
||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||
V4L2_CID_MPEG_VIDC_INPUT_METADATA_VIA_REQUEST_ENABLE,
|
||||
0,
|
||||
CAP_FLAG_INPUT_PORT,
|
||||
{0}, {0},
|
||||
NULL, NULL},
|
||||
|
||||
{META_LTR_MARK_USE, ENC, H264|HEVC,
|
||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||
|
@@ -452,5 +452,7 @@ bool res_is_less_than(u32 width, u32 height,
|
||||
bool res_is_less_than_or_equal_to(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height);
|
||||
int msm_vidc_get_properties(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_create_input_metadata_buffer(struct msm_vidc_inst *inst, u32 buf_fd);
|
||||
int msm_vidc_update_input_meta_buffer_index(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
|
||||
#endif // _MSM_VIDC_DRIVER_H_
|
||||
|
||||
|
@@ -144,6 +144,7 @@ struct msm_vidc_inst {
|
||||
struct list_head caps_list;
|
||||
struct list_head children_list;
|
||||
struct list_head firmware_list;
|
||||
struct list_head pending_pkts; /* list of struct hfi_pending_packet */
|
||||
bool once_per_session_set;
|
||||
bool ipsc_properties_set;
|
||||
bool opsc_properties_set;
|
||||
|
@@ -436,6 +436,7 @@ enum msm_vidc_inst_capability_type {
|
||||
SUPER_BLOCK,
|
||||
DRAP,
|
||||
INPUT_METADATA_FD,
|
||||
INPUT_META_VIA_REQUEST,
|
||||
META_BITSTREAM_RESOLUTION,
|
||||
META_CROP_OFFSETS,
|
||||
META_DPB_MISR,
|
||||
|
@@ -11,6 +11,8 @@
|
||||
struct msm_vidc_core;
|
||||
struct msm_vidc_inst;
|
||||
|
||||
#define MSM_MEM_POOL_PACKET_SIZE 1024
|
||||
|
||||
struct msm_memory_dmabuf {
|
||||
struct list_head list;
|
||||
struct dma_buf *dmabuf;
|
||||
@@ -23,6 +25,7 @@ enum msm_memory_pool_type {
|
||||
MSM_MEM_POOL_ALLOC,
|
||||
MSM_MEM_POOL_TIMESTAMP,
|
||||
MSM_MEM_POOL_DMABUF,
|
||||
MSM_MEM_POOL_PACKET,
|
||||
MSM_MEM_POOL_MAX,
|
||||
};
|
||||
|
||||
|
@@ -28,6 +28,11 @@ struct vidc_buffer_addr_info {
|
||||
u32 response_required;
|
||||
};
|
||||
|
||||
struct hfi_pending_packet {
|
||||
struct list_head list;
|
||||
void *data;
|
||||
};
|
||||
|
||||
int venus_hfi_session_property(struct msm_vidc_inst *inst,
|
||||
u32 pkt_type, u32 flags, u32 port,
|
||||
u32 payload_type, void *payload, u32 payload_size);
|
||||
|
@@ -1613,6 +1613,11 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* do not check for input meta port streamon when
|
||||
* request is enabled
|
||||
*/
|
||||
if (!inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
|
||||
if (is_input_meta_enabled(inst) &&
|
||||
!inst->bufq[INPUT_META_PORT].vb2q->streaming) {
|
||||
i_vpr_e(inst,
|
||||
@@ -1620,6 +1625,7 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_vidc_check_session_supported(inst);
|
||||
if (rc)
|
||||
|
@@ -814,6 +814,11 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* do not check for input meta port streamon when
|
||||
* request is enabled
|
||||
*/
|
||||
if (!inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
|
||||
if (is_input_meta_enabled(inst) &&
|
||||
!inst->bufq[INPUT_META_PORT].vb2q->streaming) {
|
||||
i_vpr_e(inst,
|
||||
@@ -821,6 +826,7 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_vidc_check_session_supported(inst);
|
||||
if (rc)
|
||||
|
@@ -946,6 +946,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
INIT_LIST_HEAD(&inst->firmware_list);
|
||||
INIT_LIST_HEAD(&inst->enc_input_crs);
|
||||
INIT_LIST_HEAD(&inst->dmabuf_tracker);
|
||||
INIT_LIST_HEAD(&inst->pending_pkts);
|
||||
for (i = 0; i < MAX_SIGNAL; i++)
|
||||
init_completion(&inst->completions[i]);
|
||||
|
||||
|
@@ -854,6 +854,17 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctrl->id == V4L2_CID_MPEG_VIDC_INPUT_METADATA_FD) {
|
||||
if (!capability->cap[INPUT_META_VIA_REQUEST].value) {
|
||||
i_vpr_e(inst,
|
||||
"%s: input metadata not enabled via request\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = msm_vidc_create_input_metadata_buffer(inst, ctrl->val);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
capability->cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
|
||||
/* Static setting */
|
||||
if (!inst->bufq[OUTPUT_PORT].vb2q->streaming) {
|
||||
@@ -945,14 +956,6 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
kfree(curr_node);
|
||||
}
|
||||
|
||||
/* dynamic controls with request will be set along with qbuf */
|
||||
if (inst->request) {
|
||||
i_vpr_l(inst,
|
||||
"%s: request api enabled, dynamic ctrls to be set with qbuf\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dynamic set control ASAP */
|
||||
rc = msm_vidc_set_v4l2_properties(inst);
|
||||
if (rc) {
|
||||
|
@@ -151,6 +151,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
||||
{SUPER_BLOCK, "SUPER_BLOCK" },
|
||||
{DRAP, "DRAP" },
|
||||
{INPUT_METADATA_FD, "INPUT_METADATA_FD" },
|
||||
{INPUT_META_VIA_REQUEST, "INPUT_META_VIA_REQUEST" },
|
||||
{META_BITSTREAM_RESOLUTION, "META_BITSTREAM_RESOLUTION" },
|
||||
{META_CROP_OFFSETS, "META_CROP_OFFSETS" },
|
||||
{META_DPB_MISR, "META_DPB_MISR" },
|
||||
@@ -1297,6 +1298,7 @@ bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id)
|
||||
case V4L2_CID_MPEG_VIDC_CODEC_CONFIG:
|
||||
case V4L2_CID_MPEG_VIDC_PRIORITY:
|
||||
case V4L2_CID_MPEG_VIDC_LOWLATENCY_REQUEST:
|
||||
case V4L2_CID_MPEG_VIDC_INPUT_METADATA_FD:
|
||||
allow = true;
|
||||
break;
|
||||
default:
|
||||
@@ -3649,7 +3651,7 @@ int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
||||
struct vb2_v4l2_buffer *vbuf;
|
||||
bool found;
|
||||
|
||||
if (!inst || !buf) {
|
||||
if (!inst || !inst->capabilities || !buf) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3660,6 +3662,14 @@ int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* vb2_buffer_done not required if input metadata
|
||||
* buffer sent via request api
|
||||
*/
|
||||
if (buf->type == MSM_VIDC_BUF_INPUT_META &&
|
||||
inst->capabilities->cap[INPUT_META_VIA_REQUEST].value)
|
||||
return 0;
|
||||
|
||||
q = inst->bufq[port].vb2q;
|
||||
if (!q->streaming) {
|
||||
i_vpr_e(inst, "%s: port %d is not streaming\n",
|
||||
@@ -6156,3 +6166,94 @@ int msm_vidc_get_properties(struct msm_vidc_inst *inst)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_create_input_metadata_buffer(struct msm_vidc_inst *inst, u32 fd)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_buffer *buf = NULL;
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fd <= 0) {
|
||||
i_vpr_e(inst, "%s: invalid input metadata buffer fd %d\n",
|
||||
__func__, fd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_INPUT_META, __func__);
|
||||
if (!buffers)
|
||||
return -EINVAL;
|
||||
|
||||
buf = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
|
||||
if (!buf) {
|
||||
i_vpr_e(inst, "%s: buffer pool alloc failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&buf->list);
|
||||
buf->type = MSM_VIDC_BUF_INPUT_META;
|
||||
buf->index = INT_MAX;
|
||||
buf->fd = fd;
|
||||
dma_buf = msm_vidc_memory_get_dmabuf(inst, fd);
|
||||
if (!dma_buf) {
|
||||
rc = -ENOMEM;
|
||||
goto error_dma_buf;
|
||||
}
|
||||
buf->dmabuf = dma_buf;
|
||||
buf->data_size = dma_buf->size;
|
||||
buf->buffer_size = dma_buf->size;
|
||||
buf->attr |= MSM_VIDC_ATTR_DEFERRED;
|
||||
|
||||
rc = msm_vidc_map_driver_buf(inst, buf);
|
||||
if (rc)
|
||||
goto error_map;
|
||||
|
||||
list_add_tail(&buf->list, &buffers->list);
|
||||
return rc;
|
||||
|
||||
error_map:
|
||||
msm_vidc_memory_put_dmabuf(inst, buf->dmabuf);
|
||||
error_dma_buf:
|
||||
msm_memory_pool_free(inst, buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_update_input_meta_buffer_index(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb2)
|
||||
{
|
||||
int rc = 0;
|
||||
bool found = false;
|
||||
struct msm_vidc_buffer *buf = NULL;
|
||||
struct msm_vidc_buffers *buffers;
|
||||
|
||||
if (!inst || !vb2) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vb2->type != INPUT_MPLANE)
|
||||
return 0;
|
||||
|
||||
buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_INPUT_META, __func__);
|
||||
if (!buffers)
|
||||
return -EINVAL;
|
||||
list_for_each_entry(buf, &buffers->list, list) {
|
||||
if (buf->index == INT_MAX) {
|
||||
buf->index = vb2->index;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
i_vpr_e(inst, "%s: missing input metabuffer for index %d\n",
|
||||
__func__, vb2->index);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_events.h"
|
||||
#include "venus_hfi.h"
|
||||
|
||||
struct msm_vidc_buf_region_name {
|
||||
enum msm_vidc_buffer_region region;
|
||||
@@ -589,6 +590,8 @@ static struct msm_vidc_type_size_name buftype_size_name_arr[] = {
|
||||
{MSM_MEM_POOL_ALLOC, sizeof(struct msm_vidc_alloc), "MSM_MEM_POOL_ALLOC" },
|
||||
{MSM_MEM_POOL_TIMESTAMP, sizeof(struct msm_vidc_timestamp), "MSM_MEM_POOL_TIMESTAMP" },
|
||||
{MSM_MEM_POOL_DMABUF, sizeof(struct msm_memory_dmabuf), "MSM_MEM_POOL_DMABUF" },
|
||||
{MSM_MEM_POOL_PACKET, sizeof(struct hfi_pending_packet) + MSM_MEM_POOL_PACKET_SIZE,
|
||||
"MSM_MEM_POOL_PACKET"},
|
||||
};
|
||||
|
||||
int msm_memory_pools_init(struct msm_vidc_inst *inst)
|
||||
|
@@ -172,10 +172,19 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
return -EINVAL;
|
||||
}
|
||||
inst = q->drv_priv;
|
||||
if (!inst || !inst->core) {
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (q->type == INPUT_META_PLANE &&
|
||||
inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
|
||||
i_vpr_e(inst,
|
||||
"%s: invalid input meta port start when request enabled\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) {
|
||||
i_vpr_h(inst, "%s: nothing to start on %s\n",
|
||||
__func__, v4l2_type_name(q->type));
|
||||
@@ -364,13 +373,16 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
|
||||
inst->request = false;
|
||||
i_vpr_e(inst, "%s: request setup failed, error %d\n",
|
||||
__func__, rc);
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
v4l2_ctrl_request_complete(vb2->req_obj.req, &inst->ctrl_handler);
|
||||
vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR);
|
||||
return;
|
||||
goto error;
|
||||
}
|
||||
inst->request = false;
|
||||
|
||||
if (inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
|
||||
rc = msm_vidc_update_input_meta_buffer_index(inst, vb2);
|
||||
if (rc)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (is_decode_session(inst))
|
||||
rc = msm_vdec_qbuf(inst, vb2);
|
||||
else if (is_encode_session(inst))
|
||||
@@ -380,11 +392,15 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
|
||||
|
||||
if (rc) {
|
||||
print_vb2_buffer("failed vb2-qbuf", inst, vb2);
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
v4l2_ctrl_request_complete(vb2->req_obj.req, &inst->ctrl_handler);
|
||||
vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void msm_vidc_buf_cleanup(struct vb2_buffer *vb)
|
||||
{
|
||||
|
@@ -3047,6 +3047,43 @@ unlock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int venus_hfi_cache_packet(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hfi_header *hdr;
|
||||
struct hfi_pending_packet *packet;
|
||||
|
||||
if (!inst->packet) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr = (struct hfi_header *)inst->packet;
|
||||
if (hdr->size < sizeof(struct hfi_header)) {
|
||||
d_vpr_e("%s: invalid hdr size %d\n", __func__, hdr->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
packet = msm_memory_pool_alloc(inst, MSM_MEM_POOL_PACKET);
|
||||
if (!packet) {
|
||||
i_vpr_e(inst, "%s: failed to allocate pending packet\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&packet->list);
|
||||
list_add_tail(&packet->list, &inst->pending_pkts);
|
||||
packet->data = (u8 *)packet + sizeof(struct hfi_pending_packet);
|
||||
|
||||
if (hdr->size > MSM_MEM_POOL_PACKET_SIZE) {
|
||||
i_vpr_e(inst, "%s: header size %d exceeds pool packet size %d\n",
|
||||
__func__, hdr->size, MSM_MEM_POOL_PACKET_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(packet->data, inst->packet, hdr->size);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int venus_hfi_session_property(struct msm_vidc_inst *inst,
|
||||
u32 pkt_type, u32 flags, u32 port, u32 payload_type,
|
||||
void *payload, u32 payload_size)
|
||||
@@ -3081,6 +3118,12 @@ int venus_hfi_session_property(struct msm_vidc_inst *inst,
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
/* skip sending packet to firmware */
|
||||
if (inst->request) {
|
||||
rc = venus_hfi_cache_packet(inst);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
rc = __iface_cmdq_write(inst->core, inst->packet);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
@@ -3381,6 +3424,48 @@ unlock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int venus_hfi_add_pending_packets(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
int num_packets = 0;
|
||||
struct hfi_pending_packet *pkt_info, *dummy;
|
||||
struct hfi_header *hdr, *src_hdr;
|
||||
struct hfi_packet *src_pkt;
|
||||
|
||||
if (!inst || !inst->packet) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr = (struct hfi_header *)inst->packet;
|
||||
if (hdr->size < sizeof(struct hfi_header)) {
|
||||
i_vpr_e(inst, "%s: invalid hdr size %d\n",
|
||||
__func__, hdr->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(pkt_info, dummy, &inst->pending_pkts, list) {
|
||||
src_hdr = (struct hfi_header *)(pkt_info->data);
|
||||
num_packets = src_hdr->num_packets;
|
||||
src_pkt = (struct hfi_packet *)((u8 *)src_hdr + sizeof(struct hfi_header));
|
||||
while (num_packets > 0) {
|
||||
memcpy((u8 *)hdr + hdr->size, (void *)src_pkt, src_pkt->size);
|
||||
hdr->num_packets++;
|
||||
hdr->size += src_pkt->size;
|
||||
num_packets--;
|
||||
src_pkt = (struct hfi_packet *)((u8 *)src_pkt + src_pkt->size);
|
||||
if ((u8 *)src_pkt < (u8 *)src_hdr ||
|
||||
(u8 *)src_pkt > (u8 *)src_hdr + hdr->size) {
|
||||
i_vpr_e(inst, "%s: invalid packet address\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
list_del(&pkt_info->list);
|
||||
msm_memory_pool_free(inst, pkt_info);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf)
|
||||
{
|
||||
@@ -3438,6 +3523,10 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
rc = venus_hfi_add_pending_packets(inst);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
rc = __iface_cmdq_write(inst->core, inst->packet);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
@@ -197,6 +197,9 @@ enum v4l2_mpeg_video_av1_tier {
|
||||
/* Control to set input metadata buffer fd */
|
||||
#define V4L2_CID_MPEG_VIDC_INPUT_METADATA_FD \
|
||||
(V4L2_CID_MPEG_VIDC_BASE + 0x36)
|
||||
/* Control to enable input metadata via request api */
|
||||
#define V4L2_CID_MPEG_VIDC_INPUT_METADATA_VIA_REQUEST_ENABLE \
|
||||
(V4L2_CID_MPEG_VIDC_BASE + 0x37)
|
||||
|
||||
/* add new controls above this line */
|
||||
/* Deprecate below controls once availble in gki and gsi bionic header */
|
||||
|
Reference in New Issue
Block a user