diff --git a/driver/vidc/inc/msm_vdec.h b/driver/vidc/inc/msm_vdec.h index f58a3440b4..921b482722 100644 --- a/driver/vidc/inc/msm_vdec.h +++ b/driver/vidc/inc/msm_vdec.h @@ -13,6 +13,7 @@ int msm_vdec_stop_input(struct msm_vidc_inst *inst); int msm_vdec_start_input(struct msm_vidc_inst *inst); int msm_vdec_stop_output(struct msm_vidc_inst *inst); int msm_vdec_start_output(struct msm_vidc_inst *inst); +int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2); int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f); diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 18459cbc19..73cc625857 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -66,11 +66,17 @@ static inline bool is_thumbnail_session(struct msm_vidc_inst *inst) return false; // TODO: fix it } -u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec); -enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec); -u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat); -enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 colorformat); -u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt); +void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct msm_vidc_buffer *vbuf); +void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, + struct vb2_buffer *vb2); +enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec); +u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec); +u32 v4l2_colorformat_to_media(u32 v4l2_fmt); +enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 colorformat); +u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat); +int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type, + const char *func); int msm_vidc_change_inst_state(struct msm_vidc_inst *inst, enum msm_vidc_inst_state state, const char *func); int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, @@ -94,16 +100,26 @@ void msm_vidc_batch_handler(struct work_struct *work); int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst); int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst); int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); -int msm_vidc_get_port_from_v4l2_type(struct msm_vidc_inst *inst, u32 type, - const char *func); u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, const char *func); -struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst, +struct msm_vidc_buffers *msm_vidc_get_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, const char *func); -struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type, const char *func); -struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst, +struct msm_vidc_mappings *msm_vidc_get_mappings(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, const char *func); +struct msm_vidc_allocations *msm_vidc_get_allocations( + struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, + const char *func); +struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2); +int msm_vidc_unmap_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf); +int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf); +int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf); +int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2); +struct msm_vidc_buffer *get_meta_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *vbuf); struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, u32 session_id); void put_inst(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index e8b46f24ca..86a2996c63 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -25,36 +25,36 @@ struct msm_vidc_session_ops { int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type); }; -struct msm_vidc_allocations { - struct msm_vidc_alloc_info scratch; - struct msm_vidc_alloc_info scratch_1; - struct msm_vidc_alloc_info scratch_2; - struct msm_vidc_alloc_info persist; - struct msm_vidc_alloc_info persist_1; +struct msm_vidc_allocations_info { + struct msm_vidc_allocations scratch; + struct msm_vidc_allocations scratch_1; + struct msm_vidc_allocations scratch_2; + struct msm_vidc_allocations persist; + struct msm_vidc_allocations persist_1; }; -struct msm_vidc_maps { - struct msm_vidc_map_info input; - struct msm_vidc_map_info output; - struct msm_vidc_map_info input_meta; - struct msm_vidc_map_info output_meta; - struct msm_vidc_map_info scratch; - struct msm_vidc_map_info scratch_1; - struct msm_vidc_map_info scratch_2; - struct msm_vidc_map_info persist; - struct msm_vidc_map_info persist_1; +struct msm_vidc_mappings_info { + struct msm_vidc_mappings input; + struct msm_vidc_mappings output; + struct msm_vidc_mappings input_meta; + struct msm_vidc_mappings output_meta; + struct msm_vidc_mappings scratch; + struct msm_vidc_mappings scratch_1; + struct msm_vidc_mappings scratch_2; + struct msm_vidc_mappings persist; + struct msm_vidc_mappings persist_1; }; -struct msm_vidc_buffers { - struct msm_vidc_buffer_info input; - struct msm_vidc_buffer_info output; - struct msm_vidc_buffer_info input_meta; - struct msm_vidc_buffer_info output_meta; - struct msm_vidc_buffer_info scratch; - struct msm_vidc_buffer_info scratch_1; - struct msm_vidc_buffer_info scratch_2; - struct msm_vidc_buffer_info persist; - struct msm_vidc_buffer_info persist_1; +struct msm_vidc_buffers_info { + struct msm_vidc_buffers input; + struct msm_vidc_buffers output; + struct msm_vidc_buffers input_meta; + struct msm_vidc_buffers output_meta; + struct msm_vidc_buffers scratch; + struct msm_vidc_buffers scratch_1; + struct msm_vidc_buffers scratch_2; + struct msm_vidc_buffers persist; + struct msm_vidc_buffers persist_1; }; enum msm_vidc_inst_state { @@ -96,9 +96,9 @@ struct msm_vidc_inst { struct msm_vidc_crop crop; struct msm_vidc_properties prop; struct msm_vidc_power power; - struct msm_vidc_buffers buffers; - struct msm_vidc_maps maps; - struct msm_vidc_allocations allocations; + struct msm_vidc_buffers_info buffers; + struct msm_vidc_mappings_info mappings; + struct msm_vidc_allocations_info allocations; bool subscribed_input_psc; bool subscribed_output_psc; bool subscribed_input_prop; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 99ba18e6c4..7f1d27ca32 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -115,7 +115,7 @@ enum msm_vidc_buffer_type { }; enum msm_vidc_buffer_attributes { - MSM_VIDC_ATTR_DEFERRED_SUBMISSION = BIT(0), + MSM_VIDC_ATTR_DEFERRED = BIT(0), MSM_VIDC_ATTR_READ_ONLY = BIT(1), MSM_VIDC_ATTR_PENDING_RELEASE = BIT(2), MSM_VIDC_ATTR_QUEUED = BIT(3), @@ -487,7 +487,7 @@ struct msm_vidc_power { struct msm_vidc_alloc { struct list_head list; - enum msm_vidc_buffer_type buffer_type; + enum msm_vidc_buffer_type type; enum msm_vidc_buffer_region region; u32 size; u8 cached:1; @@ -497,14 +497,14 @@ struct msm_vidc_alloc { void *kvaddr; }; -struct msm_vidc_alloc_info { +struct msm_vidc_allocations { struct list_head list; // list of "struct msm_vidc_alloc" }; struct msm_vidc_map { struct list_head list; bool valid; - enum msm_vidc_buffer_type buffer_type; + enum msm_vidc_buffer_type type; enum msm_vidc_buffer_region region; struct dma_buf *dmabuf; u32 refcount; @@ -513,7 +513,7 @@ struct msm_vidc_map { struct dma_buf_attachment *attach; }; -struct msm_vidc_map_info { +struct msm_vidc_mappings { struct list_head list; // list of "struct msm_vidc_map" }; @@ -533,7 +533,7 @@ struct msm_vidc_buffer { enum msm_vidc_buffer_attributes attr; }; -struct msm_vidc_buffer_info { +struct msm_vidc_buffers { struct list_head list; // list of "struct msm_vidc_buffer" u32 min_count; u32 extra_count; diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index fe1083b9d7..412041348d 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -22,7 +22,7 @@ static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec) d_vpr_h("%s()\n", __func__); - inst->codec = get_vidc_codec_from_v4l2(codec); + inst->codec = v4l2_codec_to_driver(codec); rc = msm_vidc_get_inst_capability(inst); return rc; } @@ -45,7 +45,6 @@ static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst) int rc = 0; struct msm_vidc_core *core; - d_vpr_h("%s()\n", __func__); if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; @@ -66,6 +65,17 @@ static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst) inst->buffers.persist_1.min_count = call_session_op(core, min_count, inst, MSM_VIDC_BUF_PERSIST_1); + s_vpr_h(inst->sid, "internal buffer: min size\n"); + s_vpr_h(inst->sid, "scratch buffer: %d %d\n", + inst->buffers.scratch.min_count, + inst->buffers.scratch.size); + s_vpr_h(inst->sid, "scratch1 buffer: %d %d\n", + inst->buffers.scratch_1.min_count, + inst->buffers.scratch_1.size); + s_vpr_h(inst->sid, "persist1 buffer: %d %d\n", + inst->buffers.persist_1.min_count, + inst->buffers.persist_1.size); + return rc; } @@ -298,8 +308,8 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - d_vpr_h("%s()\n", __func__); core = inst->core; + s_vpr_h(inst->sid, "%s()\n", __func__); //rc = msm_vidc_check_session_supported(inst); if (rc) @@ -330,24 +340,30 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) //msm_vidc_scale_power(inst); rc = msm_vdec_set_input_properties(inst); + rc = 0; // TODO if (rc) goto error; rc = msm_vdec_create_input_internal_buffers(inst); + rc = 0; // TODO if (rc) goto error; rc = msm_vdec_queue_input_internal_buffers(inst); + rc = 0; // TODO if (rc) goto error; rc = msm_vdec_port_settings_subscription(inst, INPUT_PORT); + rc = 0; // TODO if (rc) goto error; rc = msm_vdec_property_subscription(inst, INPUT_PORT); + rc = 0; // TODO if (rc) goto error; rc = msm_vdec_metadata_delivery(inst, INPUT_PORT); + rc = 0; // TODO if (rc) goto error; @@ -355,14 +371,11 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vidc_change_inst_state(inst, MSM_VIDC_START_INPUT, __func__); - if (rc) - goto error; - - d_vpr_h("%s: done\n", __func__); + s_vpr_h(inst->sid, "%s: done\n", __func__); return 0; error: + s_vpr_e(inst->sid, "%s: failed\n", __func__); msm_vdec_stop_input(inst); return rc; } @@ -410,6 +423,32 @@ error: return rc; } +static int msm_vdec_qbuf_batch(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc = 0; + + if (!inst || !vb2) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + d_vpr_h("%s()\n", __func__); + + return rc; +} + +int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) +{ + int rc = 0; + + if (inst->decode_batch.enable) + rc = msm_vdec_qbuf_batch(inst, vb2); + else + rc = msm_vidc_queue_buffer(inst, vb2); + + return rc; +} + int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) { int rc = 0; @@ -515,10 +554,10 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt->type = OUTPUT_PLANE; fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; fmt->fmt.pix.width = VENUS_Y_STRIDE( - get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat), + v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), f->fmt.pix.width); fmt->fmt.pix.height = VENUS_Y_SCANLINES( - get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat), + v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), f->fmt.pix.height); fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, @@ -588,7 +627,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(inst, f->type, __func__); + port = v4l2_type_to_driver_port(inst, f->type, __func__); if (port < 0) return -EINVAL; @@ -623,7 +662,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; codecs >>= 1; } - f->pixelformat = get_v4l2_codec_from_vidc(array[f->index]); + f->pixelformat = v4l2_codec_from_driver(array[f->index]); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; @@ -641,7 +680,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; formats >>= 1; } - f->pixelformat = get_v4l2_colorformat_from_vidc(array[f->index]); + f->pixelformat = v4l2_colorformat_from_driver(array[f->index]); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -710,9 +749,9 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) f->type = OUTPUT_PLANE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC; f->fmt.pix.width = VENUS_Y_STRIDE( - get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH); + v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_WIDTH); f->fmt.pix.height = VENUS_Y_SCANLINES( - get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); + v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.sizeimage = call_session_op(core, buffer_size, inst, MSM_VIDC_BUF_OUTPUT); diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index a6e5007138..e991e63b69 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -20,7 +20,7 @@ static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec) d_vpr_h("%s()\n", __func__); - inst->codec = get_vidc_codec_from_v4l2(codec); + inst->codec = v4l2_codec_to_driver(codec); rc = msm_vidc_get_inst_capability(inst); return rc; } @@ -52,10 +52,10 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt->type = INPUT_PLANE; fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; fmt->fmt.pix.width = VENUS_Y_STRIDE( - get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat), + v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), f->fmt.pix.width); fmt->fmt.pix.height = VENUS_Y_SCANLINES( - get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat), + v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), f->fmt.pix.height); fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, @@ -205,7 +205,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(inst, f->type, __func__); + port = v4l2_type_to_driver_port(inst, f->type, __func__); if (port < 0) return -EINVAL; @@ -240,7 +240,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; codecs >>= 1; } - f->pixelformat = get_v4l2_codec_from_vidc(array[f->index]); + f->pixelformat = v4l2_codec_from_driver(array[f->index]); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; @@ -258,7 +258,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; formats >>= 1; } - f->pixelformat = get_v4l2_colorformat_from_vidc(array[f->index]); + f->pixelformat = v4l2_colorformat_from_driver(array[f->index]); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -325,9 +325,9 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) f->type = INPUT_PLANE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC; f->fmt.pix.width = VENUS_Y_STRIDE( - get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH); + v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_WIDTH); f->fmt.pix.height = VENUS_Y_SCANLINES( - get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); + v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.sizeimage = call_session_op(core, buffer_size, inst, MSM_VIDC_BUF_INPUT); diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 3c8f6630d9..2834b705ab 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -319,7 +319,8 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) s_vpr_e(inst->sid, "%s: reqbufs(%d) not allowed in %d state\n", __func__, b->type, inst->state); - return -EINVAL; + rc = -EINVAL; + goto unlock; } } else if (b->type == OUTPUT_PLANE) { if (inst->state != MSM_VIDC_OPEN && @@ -328,13 +329,16 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) s_vpr_e(inst->sid, "%s: reqbufs(%d) not allowed in %d state\n", __func__, b->type, inst->state); - return -EINVAL; + rc = -EINVAL; + goto unlock; } } - port = msm_vidc_get_port_from_v4l2_type(inst, b->type, __func__); - if (port < 0) - return -EINVAL; + port = v4l2_type_to_driver_port(inst, b->type, __func__); + if (port < 0) { + rc = -EINVAL; + goto unlock; + } rc = vb2_reqbufs(&inst->vb2q[port], b); if (rc) { @@ -352,13 +356,85 @@ EXPORT_SYMBOL(msm_vidc_reqbufs); int msm_vidc_qbuf(void *instance, struct media_device *mdev, struct v4l2_buffer *b) { - return 0; + int rc = 0; + struct msm_vidc_inst *inst = instance; + struct vb2_queue *q; + + if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b); + return -EINVAL; + } + + mutex_lock(&inst->lock); + + if (inst->state == MSM_VIDC_ERROR) { + s_vpr_e(inst->sid, "%s: error state\n", __func__); + rc = -EINVAL; + goto unlock; + } + if (b->type == INPUT_PLANE) { + q = &inst->vb2q[INPUT_PORT]; + } else if (b->type == OUTPUT_PLANE) { + q = &inst->vb2q[OUTPUT_PORT]; + } else if (b->type == INPUT_META_PLANE) { + q = &inst->vb2q[INPUT_META_PORT]; + } else if (b->type == OUTPUT_META_PLANE) { + q = &inst->vb2q[OUTPUT_META_PORT]; + } else { + s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + __func__, b->type); + rc = -EINVAL; + goto unlock; + } + + rc = vb2_qbuf(q, mdev, b); + if (rc) + s_vpr_e(inst->sid, "%s: failed with %d\n", __func__, rc); + +unlock: + mutex_unlock(&inst->lock); + return rc; } EXPORT_SYMBOL(msm_vidc_qbuf); int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) { - return 0; + int rc = 0; + struct msm_vidc_inst *inst = instance; + struct vb2_queue *q; + + if (!inst || !b || !valid_v4l2_buffer(b, inst)) { + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b); + return -EINVAL; + } + + mutex_lock(&inst->lock); + if (b->type == INPUT_PLANE) { + q = &inst->vb2q[INPUT_PORT]; + } else if (b->type == OUTPUT_PLANE) { + q = &inst->vb2q[OUTPUT_PORT]; + } else if (b->type == INPUT_META_PLANE) { + q = &inst->vb2q[INPUT_META_PORT]; + } else if (b->type == OUTPUT_META_PLANE) { + q = &inst->vb2q[OUTPUT_META_PORT]; + } else { + s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + __func__, b->type); + rc = -EINVAL; + goto unlock; + } + + rc = vb2_dqbuf(q, b, true); + if (rc == -EAGAIN) { + goto unlock; + } else if (rc) { + s_vpr_e(inst->sid, "%s: failed with %d\n", __func__, rc); + goto unlock; + } + +unlock: + mutex_unlock(&inst->lock); + return rc; } EXPORT_SYMBOL(msm_vidc_dqbuf); @@ -397,7 +473,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) } } - port = msm_vidc_get_port_from_v4l2_type(inst, type, __func__); + port = v4l2_type_to_driver_port(inst, type, __func__); if (port < 0) { rc = -EINVAL; goto unlock; @@ -475,7 +551,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) } } - port = msm_vidc_get_port_from_v4l2_type(inst, type, __func__); + port = v4l2_type_to_driver_port(inst, type, __func__); if (port < 0) { rc = -EINVAL; goto unlock; @@ -676,6 +752,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) s_vpr_i(inst->sid, "Opening video instance: %d\n", session_type); kref_init(&inst->kref); + mutex_init(&inst->lock); INIT_LIST_HEAD(&inst->buffers.input.list); INIT_LIST_HEAD(&inst->buffers.input_meta.list); INIT_LIST_HEAD(&inst->buffers.output.list); @@ -690,15 +767,15 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) INIT_LIST_HEAD(&inst->allocations.scratch_2.list); INIT_LIST_HEAD(&inst->allocations.persist.list); INIT_LIST_HEAD(&inst->allocations.persist_1.list); - INIT_LIST_HEAD(&inst->maps.input.list); - INIT_LIST_HEAD(&inst->maps.input_meta.list); - INIT_LIST_HEAD(&inst->maps.output.list); - INIT_LIST_HEAD(&inst->maps.output_meta.list); - INIT_LIST_HEAD(&inst->maps.scratch.list); - INIT_LIST_HEAD(&inst->maps.scratch_1.list); - INIT_LIST_HEAD(&inst->maps.scratch_2.list); - INIT_LIST_HEAD(&inst->maps.persist.list); - INIT_LIST_HEAD(&inst->maps.persist_1.list); + INIT_LIST_HEAD(&inst->mappings.input.list); + INIT_LIST_HEAD(&inst->mappings.input_meta.list); + INIT_LIST_HEAD(&inst->mappings.output.list); + INIT_LIST_HEAD(&inst->mappings.output_meta.list); + INIT_LIST_HEAD(&inst->mappings.scratch.list); + INIT_LIST_HEAD(&inst->mappings.scratch_1.list); + INIT_LIST_HEAD(&inst->mappings.scratch_2.list); + INIT_LIST_HEAD(&inst->mappings.persist.list); + INIT_LIST_HEAD(&inst->mappings.persist_1.list); INIT_LIST_HEAD(&inst->children.list); INIT_LIST_HEAD(&inst->firmware.list); inst->domain = session_type; diff --git a/driver/vidc/src/msm_vidc_buffer.c b/driver/vidc/src/msm_vidc_buffer.c index 7b31c89e9b..f95850c6a1 100644 --- a/driver/vidc/src/msm_vidc_buffer.c +++ b/driver/vidc/src/msm_vidc_buffer.c @@ -139,18 +139,23 @@ u32 msm_vidc_output_extra_count(struct msm_vidc_inst *inst) u32 msm_vidc_decoder_input_size(struct msm_vidc_inst *inst) { - return ALIGN(15 * 1024 * 1024, SZ_4K); + u32 size = ALIGN(15 * 1024 * 1024, SZ_4K); + size = 4; // TODO + return size; } u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst) { + u32 size; u32 format; struct v4l2_format *f; f = &inst->fmts[OUTPUT_PORT]; - format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat); - return VENUS_BUFFER_SIZE(format, f->fmt.pix.width, + format = v4l2_colorformat_to_media(f->fmt.pix.pixelformat); + size = VENUS_BUFFER_SIZE(format, f->fmt.pix.width, f->fmt.pix.height); + size = 4; // TODO + return size; } u32 msm_vidc_decoder_input_meta_size(struct msm_vidc_inst *inst) @@ -165,18 +170,23 @@ u32 msm_vidc_decoder_output_meta_size(struct msm_vidc_inst *inst) u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst) { + u32 size; u32 format; struct v4l2_format *f; f = &inst->fmts[INPUT_PORT]; - format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat); - return VENUS_BUFFER_SIZE(format, f->fmt.pix.width, + format = v4l2_colorformat_to_media(f->fmt.pix.pixelformat); + size = VENUS_BUFFER_SIZE(format, f->fmt.pix.width, f->fmt.pix.height); + size = 4; // TODO + return size; } u32 msm_vidc_encoder_output_size(struct msm_vidc_inst *inst) { - return ALIGN(15 * 1024 * 1024, SZ_4K); + u32 size = ALIGN(15 * 1024 * 1024, SZ_4K); + size = 4; // TODO + return size; } u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst) diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index 3fa29e550b..df3ccdaf03 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -273,7 +273,7 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst) core = inst->core; capability = inst->capabilities; - if (core->v4l2_ctrl_ops) { + if (!core->v4l2_ctrl_ops) { s_vpr_e(inst->sid, "%s: no control ops\n", __func__); return -EINVAL; } @@ -300,11 +300,6 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst) return rc; } - if (!core->v4l2_ctrl_ops) { - s_vpr_e(inst->sid, "%s: no control ops\n", __func__); - return -EINVAL; - } - for (idx = 0; idx < INST_CAP_MAX; idx++) { struct v4l2_ctrl *ctrl; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index e58804b805..bea74766f7 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -23,11 +23,97 @@ } \ }) -void print_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *b) +void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct msm_vidc_buffer *vbuf) { + struct msm_vidc_buffer *mbuf; + + if (!(tag & msm_vidc_debug) || !inst || !vbuf) + return; + + mbuf = get_meta_buffer(inst, vbuf); + if (!mbuf) + dprintk(tag, inst->sid, + "%s: %s: idx %2d fd %3d off %d daddr %#x size %d filled %d flags %#x ts %lld attr %#x\n", + str, vbuf->type == MSM_VIDC_BUF_INPUT ? "INPUT" : "OUTPUT", + vbuf->index, vbuf->fd, vbuf->data_offset, + vbuf->device_addr, vbuf->buffer_size, vbuf->data_size, + vbuf->flags, vbuf->timestamp, vbuf->attr); + else + dprintk(tag, inst->sid, + "%s: %s: idx %2d fd %3d off %d daddr %#x size %d filled %d flags %#x ts %lld attr %#x meta: fd %3d daddr %#x size %d\n", + str, vbuf->type == MSM_VIDC_BUF_INPUT ? "INPUT" : "OUTPUT", + vbuf->index, vbuf->fd, vbuf->data_offset, + vbuf->device_addr, vbuf->buffer_size, vbuf->data_size, + vbuf->flags, vbuf->timestamp, vbuf->attr, + mbuf->fd, mbuf->device_addr, mbuf->buffer_size); } -enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec) +void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + if (!inst || !vb2) + return; + + s_vpr_e(inst->sid, + "%s: %s: idx %2d fd %d off %d size %d filled %d\n", + str, vb2->type == INPUT_PLANE ? "INPUT" : "OUTPUT", + vb2->index, vb2->planes[0].m.fd, + vb2->planes[0].data_offset, vb2->planes[0].length, + vb2->planes[0].bytesused); +} + +enum msm_vidc_buffer_type v4l2_type_to_driver(u32 type) +{ + enum msm_vidc_buffer_type buffer_type = 0; + + switch (type) { + case INPUT_PLANE: + buffer_type = MSM_VIDC_BUF_INPUT; + break; + case OUTPUT_PLANE: + buffer_type = MSM_VIDC_BUF_OUTPUT; + break; + case INPUT_META_PLANE: + buffer_type = MSM_VIDC_BUF_INPUT_META; + break; + case OUTPUT_META_PLANE: + buffer_type = MSM_VIDC_BUF_OUTPUT_META; + break; + default: + d_vpr_e("%s: vidc buffer type not found for %#x\n", + __func__, type); + break; + } + return buffer_type; +} + +u32 v4l2_type_from_driver(enum msm_vidc_buffer_type buffer_type) +{ + u32 type = 0; + + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + type = INPUT_PLANE; + break; + case MSM_VIDC_BUF_OUTPUT: + type = OUTPUT_PLANE; + break; + case MSM_VIDC_BUF_INPUT_META: + type = INPUT_META_PLANE; + break; + case MSM_VIDC_BUF_OUTPUT_META: + type = OUTPUT_META_PLANE; + break; + default: + d_vpr_e("%s: v4l2 type not found for %#x\n", + __func__, buffer_type); + break; + } + return buffer_type; +} + +enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec) { enum msm_vidc_codec_type codec = 0; @@ -51,7 +137,7 @@ enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec) return codec; } -u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec) +u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec) { u32 v4l2_codec = 0; @@ -75,7 +161,7 @@ u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec) return v4l2_codec; } -enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 v4l2_colorformat) +enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 v4l2_colorformat) { enum msm_vidc_colorformat_type colorformat = 0; @@ -108,7 +194,7 @@ enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 v4l2_colorform return colorformat; } -u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat) +u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat) { u32 v4l2_colorformat = 0; @@ -141,7 +227,7 @@ u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat) return v4l2_colorformat; } -u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt) +u32 v4l2_colorformat_to_media(u32 v4l2_fmt) { switch (v4l2_fmt) { case V4L2_PIX_FMT_NV12: @@ -166,7 +252,7 @@ u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt) } } -int msm_vidc_get_port_from_v4l2_type(struct msm_vidc_inst *inst, u32 type, +int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type, const char *func) { int port; @@ -237,8 +323,9 @@ u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, return region; } -struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type, const char *func) +struct msm_vidc_buffers *msm_vidc_get_buffers( + struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, + const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_INPUT: @@ -261,42 +348,44 @@ struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst return &inst->buffers.persist_1; default: s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", - __func__, buffer_type); + func, buffer_type); return NULL; } } -struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type, const char *func) +struct msm_vidc_mappings *msm_vidc_get_mappings( + struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, + const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_INPUT: - return &inst->maps.input; + return &inst->mappings.input; case MSM_VIDC_BUF_INPUT_META: - return &inst->maps.input_meta; + return &inst->mappings.input_meta; case MSM_VIDC_BUF_OUTPUT: - return &inst->maps.output; + return &inst->mappings.output; case MSM_VIDC_BUF_OUTPUT_META: - return &inst->maps.output_meta; + return &inst->mappings.output_meta; case MSM_VIDC_BUF_SCRATCH: - return &inst->maps.scratch; + return &inst->mappings.scratch; case MSM_VIDC_BUF_SCRATCH_1: - return &inst->maps.scratch_1; + return &inst->mappings.scratch_1; case MSM_VIDC_BUF_SCRATCH_2: - return &inst->maps.scratch_2; + return &inst->mappings.scratch_2; case MSM_VIDC_BUF_PERSIST: - return &inst->maps.persist; + return &inst->mappings.persist; case MSM_VIDC_BUF_PERSIST_1: - return &inst->maps.persist_1; + return &inst->mappings.persist_1; default: s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", - __func__, buffer_type); + func, buffer_type); return NULL; } } -struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type, const char *func) +struct msm_vidc_allocations *msm_vidc_get_allocations( + struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, + const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_SCRATCH: @@ -311,7 +400,7 @@ struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst, return &inst->allocations.persist_1; default: s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", - __func__, buffer_type); + func, buffer_type); return NULL; } } @@ -368,13 +457,314 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return rc; } +static int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct msm_vidc_buffer *buf) +{ + int rc = 0; + + if (!vb2 || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + buf->valid = true; + buf->type = v4l2_type_to_driver(vb2->type); + if (!buf->type) + return -EINVAL; + buf->index = vb2->index; + buf->fd = vb2->planes[0].m.fd; + buf->data_offset = vb2->planes[0].data_offset; + buf->data_size = vb2->planes[0].bytesused; + buf->buffer_size = vb2->planes[0].length; + buf->timestamp = vb2->timestamp; + + return rc; +} + +int msm_vidc_unmap_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf) +{ + int rc = 0; + struct msm_vidc_mappings *mappings; + struct msm_vidc_map *map = NULL; + bool found = false; + + if (!inst || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + mappings = msm_vidc_get_mappings(inst, buf->type, __func__); + if (!mappings) + return -EINVAL; + + /* sanity check to see if it was not removed */ + list_for_each_entry(map, &mappings->list, list) { + if (map->dmabuf == buf->dmabuf) { + found = true; + break; + } + } + if (!found) { + print_vidc_buffer(VIDC_ERR, "no buf in mappings", inst, buf); + return -EINVAL; + } + + rc = msm_vidc_memory_unmap(inst->core, map); + if (rc) { + print_vidc_buffer(VIDC_ERR, "unmap failed", inst, buf); + return -EINVAL; + } + + /* finally delete if refcount is zero */ + if (!map->refcount) { + list_del(&map->list); + kfree(map); + } + + return 0; +} + +int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf) +{ + int rc = 0; + + if (!inst || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + /* do not unmap / delete read only buffer */ + if (buf->attr & MSM_VIDC_ATTR_READ_ONLY) + return 0; + + rc = msm_vidc_unmap_driver_buf(inst, buf); + if (rc) + return rc; + + /* delete the buffer from buffers->list */ + list_del(&buf->list); + kfree(buf); + + return 0; +} + +int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf) +{ + int rc = 0; + struct msm_vidc_mappings *mappings; + struct msm_vidc_map *map = NULL; + bool found = false; + + if (!inst || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + mappings = msm_vidc_get_mappings(inst, buf->type, __func__); + if (!mappings) + return -EINVAL; + + /* check if it is an existing one */ + list_for_each_entry(map, &mappings->list, list) { + if (map->dmabuf == buf->dmabuf) { + found = true; + break; + } + } + if (found) { + /* skip mapping for RO buffer */ + if (!(buf->attr & MSM_VIDC_ATTR_READ_ONLY)) { + rc = msm_vidc_memory_map(inst->core, map); + if (rc) + return -ENOMEM; + buf->device_addr = map->device_addr; + } + return 0; + } + map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL); + if (!map) { + s_vpr_e(inst->sid, "%s: alloc failed\n", __func__); + return -ENOMEM; + } + INIT_LIST_HEAD(&map->list); + map->type = buf->type; + map->dmabuf = buf->dmabuf; + map->region = msm_vidc_get_buffer_region(inst, buf->type, __func__); + rc = msm_vidc_memory_map(inst->core, map); + if (rc) { + kfree(map); + return -ENOMEM; + } + buf->device_addr = map->device_addr; + list_add_tail(&map->list, &mappings->list); + + return 0; +} + +struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc = 0; + struct msm_vidc_buffer *buf = NULL; + struct msm_vidc_buffers *buffers; + struct dma_buf *dmabuf; + enum msm_vidc_buffer_type buf_type; + bool found = false; + + if (!inst || !vb2) { + d_vpr_e("%s: invalid params\n", __func__); + return NULL; + } + + buf_type = v4l2_type_to_driver(vb2->type); + if (!buf_type) + return NULL; + + buffers = msm_vidc_get_buffers(inst, buf_type, __func__); + if (!buffers) + return NULL; + + dmabuf = msm_vidc_memory_get_dmabuf(vb2->planes[0].m.fd); + if (!dmabuf) + return NULL; + msm_vidc_memory_put_dmabuf(dmabuf); + + /* check if it is an existing buffer */ + list_for_each_entry(buf, &buffers->list, list) { + if (buf->dmabuf == dmabuf && + buf->data_offset == vb2->planes[0].data_offset) { + found = true; + break; + } + } + if (found) { + /* only YUV buffers are allowed to repeat */ + if ((is_decode_session(inst) && vb2->type != OUTPUT_PLANE) || + (is_encode_session(inst) && vb2->type != INPUT_PLANE)) { + print_vidc_buffer(VIDC_ERR, + "existing buffer", inst, buf); + goto error; + } + /* for decoder, YUV with RO flag are allowed to repeat */ + if (is_decode_session(inst) && + !(buf->attr & MSM_VIDC_ATTR_READ_ONLY)) { + print_vidc_buffer(VIDC_ERR, + "existing buffer without RO flag", inst, buf); + goto error; + } + /* for encoder, treat the repeated buffer as new buffer */ + if (is_encode_session(inst) && vb2->type == INPUT_PLANE) + found = false; + } else { + buf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL); + if (!buf) { + s_vpr_e(inst->sid, "%s: alloc failed\n", __func__); + goto error; + } + buf->dmabuf = dmabuf; + } + rc = vb2_buffer_to_driver(vb2, buf); + if (rc) + goto error; + + if (!found) + list_add_tail(&buf->list, &buffers->list); + + rc = msm_vidc_map_driver_buf(inst, buf); + if (rc) + goto error; + + return buf; + +error: + if (!found) + kfree(buf); + return NULL; +} + +struct msm_vidc_buffer *get_meta_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf) +{ + struct msm_vidc_buffer *mbuf; + struct msm_vidc_buffers *meta; + bool found = false; + + if (!inst || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return NULL; + } + + if (buf->type == MSM_VIDC_BUF_INPUT) { + meta = &inst->buffers.input_meta; + } else if (buf->type == MSM_VIDC_BUF_OUTPUT) { + meta = &inst->buffers.output_meta; + } else { + s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + __func__, buf->type); + return NULL; + } + list_for_each_entry(mbuf, &meta->list, list) { + if (!mbuf->valid) + continue; + if (mbuf->type == buf->type && + mbuf->index == buf->index) { + found = true; + break; + } + } + if (!found) + return NULL; + + return mbuf; +} + +int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) +{ + int rc = 0; + struct msm_vidc_buffer *buf; + int port; + + if (!inst || !vb2) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + buf = msm_vidc_get_driver_buf(inst, vb2); + if (!buf) + return -EINVAL; + + /* meta buffer will be queued along with actual buffer */ + if (buf->type == MSM_VIDC_BUF_INPUT_META || + buf->type == MSM_VIDC_BUF_OUTPUT_META) + return 0; + + /* skip queuing if streamon not completed */ + port = v4l2_type_to_driver_port(inst, vb2->type, __func__); + if (port < 0) + return -EINVAL; + if (!inst->vb2q[port].streaming) { + buf->attr |= MSM_VIDC_ATTR_DEFERRED; + print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, buf); + return 0; + } + + print_vidc_buffer(VIDC_HIGH, "qbuf", inst, buf); + rc = venus_hfi_queue_buffer(inst, buf, get_meta_buffer(inst, buf)); + if (rc) + return rc; + + return rc; +} + int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type) { int rc = 0; - struct msm_vidc_buffer_info *buffer_info; - struct msm_vidc_alloc_info *alloc_info; - struct msm_vidc_map_info *map_info; + struct msm_vidc_buffers *buffers; + struct msm_vidc_allocations *allocations; + struct msm_vidc_mappings *mappings; int i; d_vpr_h("%s()\n", __func__); @@ -388,22 +778,22 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); - if (!buffer_info) + buffers = msm_vidc_get_buffers(inst, buffer_type, __func__); + if (!buffers) return -EINVAL; - alloc_info = msm_vidc_get_alloc_info(inst, buffer_type, __func__); - if (!alloc_info) + allocations = msm_vidc_get_allocations(inst, buffer_type, __func__); + if (!allocations) return -EINVAL; - map_info = msm_vidc_get_map_info(inst, buffer_type, __func__); - if (!alloc_info) + mappings = msm_vidc_get_mappings(inst, buffer_type, __func__); + if (!mappings) return -EINVAL; - for (i = 0; i < buffer_info->min_count; i++) { + for (i = 0; i < buffers->min_count; i++) { struct msm_vidc_buffer *buffer; struct msm_vidc_alloc *alloc; struct msm_vidc_map *map; - if (!buffer_info->size) { + if (!buffers->size) { s_vpr_e(inst->sid, "%s: invalid buffer %#x\n", __func__, buffer_type); return -EINVAL; @@ -417,8 +807,8 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, buffer->valid = true; buffer->type = buffer_type; buffer->index = i; - buffer->buffer_size = buffer_info->size; - list_add_tail(&buffer->list, &buffer_info->list); + buffer->buffer_size = buffers->size; + list_add_tail(&buffer->list, &buffers->list); alloc = kzalloc(sizeof(struct msm_vidc_alloc), GFP_KERNEL); if (!alloc) { @@ -426,14 +816,14 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return -ENOMEM; } INIT_LIST_HEAD(&alloc->list); - alloc->buffer_type = buffer_type; - alloc->region = msm_vidc_get_buffer_region(inst, + alloc->type = buffer_type; + alloc->region = msm_vidc_get_buffer_region(inst, buffer_type, __func__); - alloc->size = buffer->buffer_size; + alloc->size = buffer->buffer_size; rc = msm_vidc_memory_alloc(inst->core, alloc); if (rc) return -ENOMEM; - list_add_tail(&alloc->list, &alloc_info->list); + list_add_tail(&alloc->list, &allocations->list); map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL); if (!map) { @@ -441,16 +831,16 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return -ENOMEM; } INIT_LIST_HEAD(&map->list); - map->buffer_type = alloc->buffer_type; - map->region = alloc->region; - map->dmabuf = alloc->dmabuf; + map->type = alloc->type; + map->region = alloc->region; + map->dmabuf = alloc->dmabuf; rc = msm_vidc_memory_map(inst->core, map); if (rc) return -ENOMEM; - list_add_tail(&map->list, &map_info->list); + list_add_tail(&map->list, &mappings->list); s_vpr_e(inst->sid, "%s: created buffer_type %#x, size %d\n", - __func__, buffer_type, buffer_info->size); + __func__, buffer_type, buffers->size); } return 0; @@ -460,7 +850,7 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type) { int rc = 0; - struct msm_vidc_buffer_info *buffer_info; + struct msm_vidc_buffers *buffers; struct msm_vidc_buffer *buffer, *dummy; d_vpr_h("%s()\n", __func__); @@ -474,11 +864,11 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); - if (!buffer_info) + buffers = msm_vidc_get_buffers(inst, buffer_type, __func__); + if (!buffers) return -EINVAL; - list_for_each_entry_safe(buffer, dummy, &buffer_info->list, list) { + list_for_each_entry_safe(buffer, dummy, &buffers->list, list) { /* do not queue pending release buffers */ if (buffer->flags & MSM_VIDC_ATTR_PENDING_RELEASE) continue; @@ -492,7 +882,7 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, buffer->attr |= MSM_VIDC_ATTR_QUEUED; s_vpr_h(inst->sid, "%s: queued buffer_type %#x, size %d\n", - __func__, buffer_type, buffer_info->size); + __func__, buffer_type, buffers->size); } return 0; @@ -502,7 +892,7 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type) { int rc = 0; - struct msm_vidc_buffer_info *buffer_info; + struct msm_vidc_buffers *buffers; struct msm_vidc_buffer *buffer, *dummy; d_vpr_h("%s()\n", __func__); @@ -516,11 +906,11 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); - if (!buffer_info) + buffers = msm_vidc_get_buffers(inst, buffer_type, __func__); + if (!buffers) return -EINVAL; - list_for_each_entry_safe(buffer, dummy, &buffer_info->list, list) { + list_for_each_entry_safe(buffer, dummy, &buffers->list, list) { /* do not release already pending release buffers */ if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE) continue; @@ -534,7 +924,7 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, buffer->attr |= MSM_VIDC_ATTR_PENDING_RELEASE; s_vpr_e(inst->sid, "%s: released buffer_type %#x, size %d\n", - __func__, buffer_type, buffer_info->size); + __func__, buffer_type, buffers->size); } return 0; @@ -918,13 +1308,16 @@ int msm_vidc_core_init(struct msm_vidc_core *core) mutex_unlock(&core->lock); /*TODO: acquire lock or not */ + d_vpr_h("%s(): waiting for sys init done, %d ms\n", __func__, + core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value); rc = wait_for_completion_timeout(&core->init_done, msecs_to_jiffies( - core->platform->data.core_data[DEBUG_TIMEOUT].value)); + core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value)); if (!rc) { d_vpr_e("%s: system init timed out\n", __func__); //msm_comm_kill_session(inst); - rc = -EIO; + //rc = -EIO; } else { + d_vpr_h("%s: system init wait completed\n", __func__); rc = 0; } mutex_lock(&core->lock); diff --git a/driver/vidc/src/msm_vidc_memory.c b/driver/vidc/src/msm_vidc_memory.c index 59f63f9fc0..5c95f0d598 100644 --- a/driver/vidc/src/msm_vidc_memory.c +++ b/driver/vidc/src/msm_vidc_memory.c @@ -248,8 +248,7 @@ int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem d_vpr_h( "%s: dmabuf = %pK, size = %d, kvaddr = %pK, buffer_type = %#x\n", - __func__, mem->dmabuf, mem->size, - mem->kvaddr, mem->buffer_type); + __func__, mem->dmabuf, mem->size, mem->kvaddr, mem->type); return 0; error: @@ -268,8 +267,7 @@ int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem) d_vpr_h( "%s: dmabuf = %pK, size = %d, kvaddr = %pK, buffer_type = %#x\n", - __func__, mem->dmabuf, mem->size, - mem->kvaddr, mem->buffer_type); + __func__, mem->dmabuf, mem->size, mem->kvaddr, mem->type); if (mem->kvaddr) { dma_buf_vunmap(mem->dmabuf, mem->kvaddr); diff --git a/driver/vidc/src/msm_vidc_platform.c b/driver/vidc/src/msm_vidc_platform.c index 3492e601f2..9c2955cab4 100644 --- a/driver/vidc/src/msm_vidc_platform.c +++ b/driver/vidc/src/msm_vidc_platform.c @@ -29,8 +29,12 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_out = msm_v4l2_s_fmt, + .vidioc_s_fmt_meta_out = msm_v4l2_s_fmt, + .vidioc_s_fmt_meta_cap = msm_v4l2_s_fmt, .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt, .vidioc_g_fmt_vid_out = msm_v4l2_g_fmt, + .vidioc_g_fmt_meta_out = msm_v4l2_g_fmt, + .vidioc_g_fmt_meta_cap = msm_v4l2_g_fmt, .vidioc_reqbufs = msm_v4l2_reqbufs, .vidioc_qbuf = msm_v4l2_qbuf, .vidioc_dqbuf = msm_v4l2_dqbuf, diff --git a/driver/vidc/src/msm_vidc_vb2.c b/driver/vidc/src/msm_vidc_vb2.c index 055e0c4777..3830346d80 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -46,7 +46,7 @@ int msm_vidc_queue_setup(struct vb2_queue *q, return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(inst, q->type, __func__); + port = v4l2_type_to_driver_port(inst, q->type, __func__); if (port < 0) return -EINVAL; @@ -69,8 +69,11 @@ int msm_vidc_queue_setup(struct vb2_queue *q, inst->buffers.input.extra_count) *num_buffers = inst->buffers.input.min_count + inst->buffers.input.extra_count; - sizes[0] = inst->fmts[port].fmt.pix.sizeimage; inst->buffers.input.actual_count = *num_buffers; + if (port == INPUT_PORT || port == OUTPUT_PORT) + sizes[0] = inst->fmts[port].fmt.pix.sizeimage; + else if (port == INPUT_META_PORT || port == OUTPUT_META_PORT) + sizes[0] = inst->fmts[port].fmt.meta.buffersize; s_vpr_h(inst->sid, "queue_setup: type %d num_buffers %d sizes[0] %d\n", @@ -151,8 +154,29 @@ void msm_vidc_stop_streaming(struct vb2_queue *q) void msm_vidc_buf_queue(struct vb2_buffer *vb2) { + int rc = 0; + struct msm_vidc_inst *inst; + + inst = vb2_get_drv_priv(vb2->vb2_queue); + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + + if (is_decode_session(inst)) + rc = msm_vdec_qbuf(inst, vb2); + else if (is_encode_session(inst)) + rc = msm_vdec_qbuf(inst, vb2); + else + rc = -EINVAL; + + if (rc) { + print_vb2_buffer("failed vb2-qbuf", inst, vb2); + msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); + vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR); + } } void msm_vidc_buf_cleanup(struct vb2_buffer *vb) { -} \ No newline at end of file +} diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index 8e01bbc3e0..5a62ef2c41 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -144,7 +144,7 @@ static void __dump_packet(u8 *packet) static void __fatal_error(struct msm_vidc_core *core, bool fatal) { return; - fatal &= core->platform->data.core_data[DEBUG_TIMEOUT].value; + fatal &= core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value; MSM_VIDC_ERROR(fatal); } @@ -2082,7 +2082,7 @@ static int __interface_queues_init(struct msm_vidc_core *core) q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; memset(&alloc, 0, sizeof(alloc)); - alloc.buffer_type = MSM_VIDC_BUF_QUEUE; + alloc.type = MSM_VIDC_BUF_QUEUE; alloc.region = MSM_VIDC_NON_SECURE; alloc.size = q_size; alloc.cached = false; @@ -2095,7 +2095,7 @@ static int __interface_queues_init(struct msm_vidc_core *core) } memset(&map, 0, sizeof(map)); - map.buffer_type = alloc.buffer_type; + map.type = alloc.type; map.region = alloc.region; map.dmabuf = alloc.dmabuf; rc = msm_vidc_memory_map(core, &map); @@ -2155,7 +2155,7 @@ static int __interface_queues_init(struct msm_vidc_core *core) /* sfr buffer */ memset(&alloc, 0, sizeof(alloc)); - alloc.buffer_type = MSM_VIDC_BUF_QUEUE; + alloc.type = MSM_VIDC_BUF_QUEUE; alloc.region = MSM_VIDC_NON_SECURE; alloc.size = ALIGNED_SFR_SIZE; alloc.cached = false; @@ -2167,7 +2167,7 @@ static int __interface_queues_init(struct msm_vidc_core *core) goto fail_alloc_queue; } memset(&map, 0, sizeof(map)); - map.buffer_type = alloc.buffer_type; + map.type = alloc.type; map.region = alloc.region; map.dmabuf = alloc.dmabuf; rc = msm_vidc_memory_map(core, &map); diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 2cc570f88c..f5ab05e0ff 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -27,19 +27,6 @@ /* vendor controls start */ #define V4L2_CID_MPEG_MSM_VIDC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) -#define V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x1) -#define V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x2) -#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x3) -#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x4) -#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x5) -#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x6) - #define V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0x1) #define V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE \