diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 593c52ec7c..b9028c146d 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -108,6 +108,26 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { MSM_VIDC_FMT_NV12_P010_UBWC | MSM_VIDC_FMT_NV12_TP10_UBWC | MSM_VIDC_FMT_RGBA8888_UBWC | MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, MSM_VIDC_FMT_NV12_UBWC}, + {MIN_BUFFERS_INPUT, ENC|DEC, CODECS_ALL, 0, 64, 1, 4, + V4L2_CID_MIN_BUFFERS_FOR_OUTPUT}, + {MIN_BUFFERS_OUTPUT, ENC|DEC, CODECS_ALL, 0, 64, 1, 4, + V4L2_CID_MIN_BUFFERS_FOR_CAPTURE}, + {DECODE_ORDER, DEC, CODECS_ALL, 0, 1, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER, + HFI_PROP_DECODE_ORDER_OUTPUT}, + {THUMBNAIL_MODE, DEC, CODECS_ALL, 0, 1, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE, + HFI_PROP_THUMBNAIL_MODE}, + {SECURE_MODE, ENC|DEC, CODECS_ALL, 0, 1, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_SECURE, + HFI_PROP_SECURE}, + {LOWLATENCY_MODE, ENC|DEC, CODECS_ALL, 0, 1, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE}, + {LOWLATENCY_HINT, DEC, CODECS_ALL, 0, 1, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT}, + {BUF_SIZE_LIMIT, ENC|DEC, CODECS_ALL, 0, 0x0fffffff, 1, 0, + V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT}, + /* (8192 * 4320) / 256 */ {MBPF, ENC|DEC, CODECS_ALL, 64, 138240, 1, 138240}, /* ((1920 * 1088) / 256) * 960 fps */ diff --git a/driver/vidc/inc/hfi_packet.h b/driver/vidc/inc/hfi_packet.h index 29cbf473cf..fb867d6e5a 100644 --- a/driver/vidc/inc/hfi_packet.h +++ b/driver/vidc/inc/hfi_packet.h @@ -14,6 +14,8 @@ #include "hfi_definition.h" u32 get_hfi_port(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port); +u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type); u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain, enum msm_vidc_buffer_type buffer_type); diff --git a/driver/vidc/inc/msm_vidc_control.h b/driver/vidc/inc/msm_vidc_control.h index 1cce5cd5aa..d438d2fc1a 100644 --- a/driver/vidc/inc/msm_vidc_control.h +++ b/driver/vidc/inc/msm_vidc_control.h @@ -6,6 +6,7 @@ #ifndef _MSM_VIDC_CONTROL_H_ #define _MSM_VIDC_CONTROL_H_ +#include #include "msm_vidc_inst.h" #include "msm_vidc_internal.h" diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 73aacd64ee..6c8865fa54 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -72,7 +72,7 @@ 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); int msm_vidc_change_inst_state(struct msm_vidc_inst *inst, - enum msm_vidc_inst_state state); + enum msm_vidc_inst_state state, const char *func); int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type); int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, @@ -94,15 +94,16 @@ 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(u32 type); +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); + 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, - enum msm_vidc_buffer_type buffer_type); + 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); + 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, - enum msm_vidc_buffer_type buffer_type); + enum msm_vidc_buffer_type buffer_type, const char *func); struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, u32 session_id); void put_inst(struct msm_vidc_inst *inst); @@ -110,6 +111,5 @@ void core_lock(struct msm_vidc_core *core, const char *function); void core_unlock(struct msm_vidc_core *core, const char *function); void inst_lock(struct msm_vidc_inst *inst, const char *function); void inst_unlock(struct msm_vidc_inst *inst, const char *function); - #endif // _MSM_VIDC_DRIVER_H_ diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index c0775a2f46..39cf7d950d 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -99,7 +99,12 @@ struct msm_vidc_inst { struct msm_vidc_buffers buffers; struct msm_vidc_maps maps; struct msm_vidc_allocations allocations; - struct msm_vidc_port_settings port_settings[MAX_PORT]; + bool subscribed_input_psc; + bool subscribed_output_psc; + bool subscribed_input_prop; + bool subscribed_output_prop; + struct msm_vidc_subscription_params vidc_subcr[MAX_PORT]; + struct msm_vidc_subscription_params hfi_subcr[MAX_PORT]; struct msm_vidc_decode_batch decode_batch; struct msm_vidc_decode_vpp_delay decode_vpp_delay; struct msm_vidc_session_idle session_idle; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index efe5d84e34..ba8f6a69fd 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -174,6 +174,14 @@ enum msm_vidc_inst_capability_type { FRAME_WIDTH, FRAME_HEIGHT, PIX_FMTS, + MIN_BUFFERS_INPUT, + MIN_BUFFERS_OUTPUT, + DECODE_ORDER, + THUMBNAIL_MODE, + SECURE_MODE, + LOWLATENCY_MODE, + LOWLATENCY_HINT, + BUF_SIZE_LIMIT, MBPF, MBPS, FRAME_RATE, @@ -413,13 +421,41 @@ struct msm_vidc_session_idle { u64 last_activity_time_ns; }; -struct msm_vidc_port_settings { - u32 aligned_width; - u32 aligned_height; - u32 crop_width; - u32 crop_height; +struct msm_vidc_color_info { + u32 colorspace; + u32 ycbcr_enc; + u32 xfer_func; + u32 quantization; +}; + +struct msm_vidc_crop { + u32 x; + u32 y; + u32 width; + u32 height; +}; + +struct msm_vidc_properties { + u32 frame_rate; + u32 operating_rate; + u32 bit_rate; + u32 profile; + u32 level; + u32 entropy_mode; + u32 rc_type; +}; + +struct msm_vidc_subscription_params { + u32 align_width; + u32 align_height; + struct msm_vidc_crop crop; + struct msm_vidc_color_info color_info; + u32 bit_depth; + u32 cabac; + u32 interlace; u32 min_count; - u32 poc; + u32 pic_order_cnt; + u32 profile; }; struct msm_vidc_decode_vpp_delay { @@ -503,23 +539,6 @@ struct msm_vidc_buffer_info { u32 size; }; -struct msm_vidc_crop { - u32 x; - u32 y; - u32 width; - u32 height; -}; - -struct msm_vidc_properties { - u32 frame_rate; - u32 operating_rate; - u32 bit_rate; - u32 profile; - u32 level; - u32 entropy_mode; - u32 rc_type; -}; - struct msm_vidc_ssr { bool trigger; enum msm_vidc_ssr_trigger_type ssr_type; diff --git a/driver/vidc/inc/venus_hfi.h b/driver/vidc/inc/venus_hfi.h index 2660cb8e2a..5a816236ac 100644 --- a/driver/vidc/inc/venus_hfi.h +++ b/driver/vidc/inc/venus_hfi.h @@ -50,10 +50,8 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf); int venus_hfi_release_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer); -int venus_hfi_start_input(struct msm_vidc_inst *inst); -int venus_hfi_stop_input(struct msm_vidc_inst *inst); -int venus_hfi_start_output(struct msm_vidc_inst *inst); -int venus_hfi_stop_output(struct msm_vidc_inst *inst); +int venus_hfi_start(struct msm_vidc_inst *inst, enum msm_vidc_port_type port); +int venus_hfi_stop(struct msm_vidc_inst *inst, enum msm_vidc_port_type port); int venus_hfi_session_close(struct msm_vidc_inst *inst); int venus_hfi_session_open(struct msm_vidc_inst *inst); int venus_hfi_core_init(struct msm_vidc_core *core); diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index 87ce3356b5..afe81e3ca8 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -11,6 +11,49 @@ #include "msm_vidc_platform.h" u32 get_hfi_port(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + u32 hfi_port = HFI_PORT_NONE; + + if (is_decode_session(inst)) { + switch(port) { + case INPUT_PORT: + case INPUT_META_PORT: + hfi_port = HFI_PORT_BITSTREAM; + break; + case OUTPUT_PORT: + case OUTPUT_META_PORT: + hfi_port = HFI_PORT_RAW; + break; + default: + s_vpr_e(inst->sid, "%s: invalid port type %d\n", + __func__, port); + break; + } + } else if (is_encode_session(inst)) { + switch (port) { + case INPUT_PORT: + case INPUT_META_PORT: + hfi_port = HFI_PORT_RAW; + break; + case OUTPUT_PORT: + case OUTPUT_META_PORT: + hfi_port = HFI_PORT_BITSTREAM; + break; + default: + s_vpr_e(inst->sid, "%s: invalid port type %d\n", + __func__, port); + break; + } + } else { + s_vpr_e(inst->sid, "%s: invalid domain %#x\n", + __func__, inst->domain); + } + + return hfi_port; +} + +u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type) { u32 hfi_port = HFI_PORT_NONE; diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index bcc5aa820e..ed01898d29 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -14,6 +14,7 @@ #include "msm_vidc_platform.h" #include "msm_vidc_debug.h" #include "venus_hfi.h" +#include "hfi_packet.h" static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec) { @@ -136,15 +137,153 @@ static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst) return 0; } */ + +static int msm_vdec_port_settings_subscription(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core; + u32 payload[32] = {0}; + u32 i; + u32 subscribe_psc[] = { + HFI_PROP_ALIGN_RESOLUTION, + HFI_PROP_CROP_RESOLUTION, + HFI_PROP_CROP_COORDINATE_TOP_LEFT, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_PROP_CABAC_SESSION, + HFI_PROP_CODED_FRAMES, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_PROP_PIC_ORDER_CNT_TYPE, + HFI_PROP_SIGNAL_COLOR_INFO, + }; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + d_vpr_h("%s()\n", __func__); + + payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; + for (i = 0; i < ARRAY_SIZE(subscribe_psc); i++) + payload[i + 1] = subscribe_psc[i]; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, + core->header_id++); + if (rc) + return rc; + + rc = hfi_create_packet(inst->packet, inst->packet_size, + HFI_CMD_SUBSCRIBE_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(subscribe_psc) + 1) * sizeof(u32)); + if (rc) + return rc; + + return rc; +} + +static int msm_vdec_property_subscription(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core; + u32 payload[32] = {0}; + u32 i; + u32 subscribe_properties[] = { + HFI_PROP_TAG_NOT_PROPAGATED_TO_OUTPUT, + }; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + d_vpr_h("%s()\n", __func__); + + payload[0] = HFI_MODE_PROPERTY; + for (i = 0; i < ARRAY_SIZE(subscribe_properties); i++) + payload[i + 1] = subscribe_properties[i]; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, + core->header_id++); + if (rc) + return rc; + + rc = hfi_create_packet(inst->packet, inst->packet_size, + HFI_CMD_SUBSCRIBE_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(subscribe_properties) + 1) * sizeof(u32)); + if (rc) + return rc; + + return rc; +} + +static int msm_vdec_metadata_delivery(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core; + u32 payload[32] = {0}; + u32 i; + u32 metadata_delivery[] = { + HFI_PROP_BUFFER_TAG, + }; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + d_vpr_h("%s()\n", __func__); + + payload[0] = HFI_MODE_METADATA; + for (i = 0; i < ARRAY_SIZE(metadata_delivery); i++) + payload[i + 1] = metadata_delivery[i]; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, + core->header_id++); + if (rc) + return rc; + + rc = hfi_create_packet(inst->packet, inst->packet_size, + HFI_CMD_DELIVERY_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(metadata_delivery) + 1) * sizeof(u32)); + if (rc) + return rc; + + return rc; +} + int msm_vdec_stop_input(struct msm_vidc_inst *inst) { int rc = 0; - d_vpr_h("%s()\n", __func__); if (!inst) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + d_vpr_h("%s()\n", __func__); return rc; } @@ -154,11 +293,11 @@ int msm_vdec_start_input(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; } + d_vpr_h("%s()\n", __func__); core = inst->core; //rc = msm_vidc_check_session_supported(inst); @@ -199,11 +338,23 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) if (rc) goto error; - rc = venus_hfi_start_input(inst); + rc = msm_vdec_port_settings_subscription(inst, INPUT_PORT); if (rc) goto error; - rc = msm_vidc_change_inst_state(inst, MSM_VIDC_START_INPUT); + rc = msm_vdec_property_subscription(inst, INPUT_PORT); + if (rc) + goto error; + + rc = msm_vdec_metadata_delivery(inst, INPUT_PORT); + if (rc) + goto error; + + rc = venus_hfi_start(inst, INPUT_PORT); + if (rc) + goto error; + + rc = msm_vidc_change_inst_state(inst, MSM_VIDC_START_INPUT, __func__); if (rc) goto error; @@ -238,6 +389,23 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst) return -EINVAL; } + rc = msm_vdec_port_settings_subscription(inst, OUTPUT_PORT); + if (rc) + goto error; + + rc = msm_vdec_metadata_delivery(inst, OUTPUT_PORT); + if (rc) + goto error; + + rc = venus_hfi_start(inst, OUTPUT_PORT); + if (rc) + goto error; + + d_vpr_h("%s: done\n", __func__); + return 0; + +error: + msm_vdec_stop_output(inst); return rc; } @@ -394,7 +562,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.output.actual_count; inst->buffers.output_meta.size = fmt->fmt.meta.buffersize; s_vpr_h(inst->sid, - "%s: input meta: size %d min_count %d extra_count %d\n", + "%s: output meta: size %d min_count %d extra_count %d\n", __func__, fmt->fmt.meta.buffersize, inst->buffers.output_meta.min_count, inst->buffers.output_meta.extra_count); @@ -419,11 +587,10 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(f->type); - if (port < 0) { - d_vpr_e("%s: invalid format type %d\n", __func__, f->type); + port = msm_vidc_get_port_from_v4l2_type(inst, f->type, __func__); + if (port < 0) return -EINVAL; - } + memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format)); return rc; @@ -432,9 +599,9 @@ 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) { int rc = 0; - enum msm_vidc_codec_type codec; - enum msm_vidc_colorformat_type colorformat; struct msm_vidc_core *core; + u32 array[32] = {0}; + u32 i = 0, idx = 0; if (!inst || !inst->core || !inst->capabilities || !f) { d_vpr_e("%s: invalid params\n", __func__); @@ -442,24 +609,38 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) } core = inst->core; - if (f->index >= - sizeof(inst->capabilities->cap[PIX_FMTS].step_or_mask) * 8) { - d_vpr_e("%s: invalid index %d\n", __func__, f->index); - return -EINVAL; - } - memset(f->reserved, 0, sizeof(f->reserved)); - if (f->type == INPUT_PLANE) { - codec = core->capabilities[DEC_CODECS].value & f->index; - f->pixelformat = get_v4l2_codec_from_vidc(codec); + u32 codecs = core->capabilities[DEC_CODECS].value; + + while (codecs) { + if (idx > 31) + break; + if (codecs & BIT(i)) { + array[idx] = codecs & BIT(i); + idx++; + } + i++; + codecs >>= 1; + } + f->pixelformat = get_v4l2_codec_from_vidc(array[f->index]); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; strlcpy(f->description, "codec", sizeof(f->description)); } else if (f->type == OUTPUT_PLANE) { - colorformat = f->index & - inst->capabilities->cap[PIX_FMTS].step_or_mask; - f->pixelformat = get_v4l2_colorformat_from_vidc(colorformat); + u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask; + + while (formats) { + if (idx > 31) + break; + if (formats & BIT(i)) { + array[idx] = formats & BIT(i); + idx++; + } + i++; + formats >>= 1; + } + f->pixelformat = get_v4l2_colorformat_from_vidc(array[f->index]); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -471,7 +652,10 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) return -EINVAL; } } + memset(f->reserved, 0, sizeof(f->reserved)); + s_vpr_h(inst->sid, "%s: index %d, %s : %#x, flags %#x\n", + __func__, f->index, f->description, f->pixelformat, f->flags); return rc; } diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index a8da10cf04..e9b655608f 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -179,7 +179,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.output.actual_count; inst->buffers.output_meta.size = fmt->fmt.meta.buffersize; s_vpr_h(inst->sid, - "%s: input meta: size %d min_count %d extra_count %d\n", + "%s: output meta: size %d min_count %d extra_count %d\n", __func__, fmt->fmt.meta.buffersize, inst->buffers.output_meta.min_count, inst->buffers.output_meta.extra_count); @@ -204,11 +204,10 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(f->type); - if (port < 0) { - d_vpr_e("%s: invalid format type %d\n", __func__, f->type); + port = msm_vidc_get_port_from_v4l2_type(inst, f->type, __func__); + if (port < 0) return -EINVAL; - } + memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format)); return rc; @@ -217,9 +216,9 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) { int rc = 0; - enum msm_vidc_codec_type codec; - enum msm_vidc_colorformat_type colorformat; struct msm_vidc_core *core; + u32 array[32] = {0}; + u32 i = 0, idx = 0; if (!inst || !inst->core || !inst->capabilities || !f) { d_vpr_e("%s: invalid params\n", __func__); @@ -227,24 +226,38 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) } core = inst->core; - if (f->index >= - sizeof(inst->capabilities->cap[PIX_FMTS].step_or_mask) * 8) { - d_vpr_e("%s: invalid index %d\n", __func__, f->index); - return -EINVAL; - } - memset(f->reserved, 0, sizeof(f->reserved)); - if (f->type == OUTPUT_PLANE) { - codec = core->capabilities[DEC_CODECS].value & f->index; - f->pixelformat = get_v4l2_codec_from_vidc(codec); + u32 codecs = core->capabilities[DEC_CODECS].value; + + while (codecs) { + if (idx > 31) + break; + if (codecs & BIT(i)) { + array[idx] = codecs & BIT(i); + idx++; + } + i++; + codecs >>= 1; + } + f->pixelformat = get_v4l2_codec_from_vidc(array[f->index]); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; strlcpy(f->description, "codec", sizeof(f->description)); } else if (f->type == INPUT_PLANE) { - colorformat = f->index & - inst->capabilities->cap[PIX_FMTS].step_or_mask; - f->pixelformat = get_v4l2_colorformat_from_vidc(colorformat); + u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask; + + while (formats) { + if (idx > 31) + break; + if (formats & BIT(i)) { + array[idx] = formats & BIT(i); + idx++; + } + i++; + formats >>= 1; + } + f->pixelformat = get_v4l2_colorformat_from_vidc(array[f->index]); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -256,7 +269,10 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) return -EINVAL; } } + memset(f->reserved, 0, sizeof(f->reserved)); + s_vpr_h(inst->sid, "%s: index %d, %s : %#x, flags %#x\n", + __func__, f->index, f->description, f->pixelformat, f->flags); return rc; } diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index bb41bd304c..ffa0d9a4f1 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -237,6 +237,9 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) if (inst->domain == MSM_VIDC_ENCODER) rc = msm_venc_s_fmt(inst, f); + if (rc) + s_vpr_e(inst->sid, "%s: s_fmt(%d) failed %d\n", + __func__, f->type, rc); return rc; } EXPORT_SYMBOL(msm_vidc_s_fmt); @@ -287,7 +290,12 @@ int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control) if (!rc) control->value = ctrl->val; } - + if (rc) + s_vpr_e(inst->sid, "%s: failed for control id %#x\n", + __func__, control->id); + else + s_vpr_h(inst->sid, "%s: control id %#x, value %d\n", + __func__, control->id, control->value); return rc; } EXPORT_SYMBOL(msm_vidc_g_ctrl); @@ -324,11 +332,10 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) } } - port = msm_vidc_get_port_from_v4l2_type(b->type); - if (port < 0) { - d_vpr_e("%s: invalid queue type %d\n", __func__, b->type); + port = msm_vidc_get_port_from_v4l2_type(inst, b->type, __func__); + if (port < 0) return -EINVAL; - } + rc = vb2_reqbufs(&inst->vb2q[port], b); if (rc) { s_vpr_e(inst->sid, "%s: vb2_reqbufs(%d) failed, %d\n", @@ -390,9 +397,8 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) } } - port = msm_vidc_get_port_from_v4l2_type(type); + port = msm_vidc_get_port_from_v4l2_type(inst, type, __func__); if (port < 0) { - d_vpr_e("%s: invalid buf type %d\n", __func__, type); rc = -EINVAL; goto unlock; } @@ -410,7 +416,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) } else if (inst->state == MSM_VIDC_START_OUTPUT) { new_state = MSM_VIDC_START; } - rc = msm_vidc_change_inst_state(inst, new_state); + rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; } else if (type == OUTPUT_PLANE) { @@ -424,7 +430,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) else new_state = MSM_VIDC_DRAIN; } - rc = msm_vidc_change_inst_state(inst, new_state); + rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; } @@ -469,9 +475,8 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) } } - port = msm_vidc_get_port_from_v4l2_type(type); + port = msm_vidc_get_port_from_v4l2_type(inst, type, __func__); if (port < 0) { - d_vpr_e("%s: invalid buf type %d\n", __func__, type); rc = -EINVAL; goto unlock; } @@ -498,7 +503,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) new_state = MSM_VIDC_START_OUTPUT; /* discard pending port settings change if any */ } - rc = msm_vidc_change_inst_state(inst, new_state); + rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; } else if (type == OUTPUT_PLANE) { @@ -514,7 +519,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) } else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) { new_state = MSM_VIDC_DRAIN_START_INPUT; } - rc = msm_vidc_change_inst_state(inst, new_state); + rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; } @@ -533,6 +538,29 @@ EXPORT_SYMBOL(msm_vidc_cmd); int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) { + struct msm_vidc_inst *inst = instance; + struct msm_vidc_inst_capability *capability; + + if (!inst || !fsize) { + d_vpr_e("%s: invalid params: %pK %pK\n", + __func__, inst, fsize); + return -EINVAL; + } + if (!inst->capabilities) { + s_vpr_e(inst->sid, "capabilities not available\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width = capability->cap[FRAME_WIDTH].min; + fsize->stepwise.max_width = capability->cap[FRAME_WIDTH].max; + fsize->stepwise.step_width = + capability->cap[FRAME_WIDTH].step_or_mask; + fsize->stepwise.min_height = capability->cap[FRAME_HEIGHT].min; + fsize->stepwise.max_height = capability->cap[FRAME_HEIGHT].max; + fsize->stepwise.step_height = + capability->cap[FRAME_HEIGHT].step_or_mask; + return 0; } EXPORT_SYMBOL(msm_vidc_enum_framesizes); @@ -550,6 +578,9 @@ int msm_vidc_subscribe_event(void *instance, s_vpr_h(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id); rc = v4l2_event_subscribe(&inst->event_handler, sub, MAX_EVENTS, NULL); + if (rc) + s_vpr_e(inst->sid, "%s: fialed, type %d id %d\n", + __func__, sub->type, sub->id); return rc; } EXPORT_SYMBOL(msm_vidc_subscribe_event); @@ -566,6 +597,9 @@ int msm_vidc_unsubscribe_event(void *instance, } s_vpr_h(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id); rc = v4l2_event_unsubscribe(&inst->event_handler, sub); + if (rc) + s_vpr_e(inst->sid, "%s: fialed, type %d id %d\n", + __func__, sub->type, sub->id); return rc; } EXPORT_SYMBOL(msm_vidc_unsubscribe_event); @@ -580,6 +614,8 @@ int msm_vidc_dqevent(void *instance, struct v4l2_event *event) return -EINVAL; } rc = v4l2_event_dequeue(&inst->event_handler, event, false); + if (rc) + s_vpr_e(inst->sid, "%s: fialed\n", __func__); return rc; } EXPORT_SYMBOL(msm_vidc_dqevent); @@ -708,6 +744,14 @@ EXPORT_SYMBOL(msm_vidc_open); int msm_vidc_close(void *instance) { + struct msm_vidc_inst *inst = instance; + + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + s_vpr_h(inst->sid, "%s()\n", __func__); + return 0; } EXPORT_SYMBOL(msm_vidc_close); diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index f3646c105f..5b78475a8b 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -61,11 +61,6 @@ static const char * const * msm_vidc_get_qmenu_type( return mpeg_video_rate_control; case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return mpeg_video_stream_format; - /* - * TODO(AS) - * case V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE: - * return roi_map_type; - */ default: s_vpr_e(inst->sid, "%s: No available qmenu for ctrl %#x", __func__, control_id); @@ -76,15 +71,22 @@ static const char * const * msm_vidc_get_qmenu_type( static const char *msm_vidc_get_priv_ctrl_name(u32 sid, u32 control_id) { switch (control_id) { + case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: + return "Decode Order"; + case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE: + return "Sync Frame Decode"; + case V4L2_CID_MPEG_VIDC_VIDEO_SECURE: + return "Secure Mode"; + case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: + return "Low Latency Mode"; + case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT: + return "Low Latency Hint"; + case V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT: + return "Buffer Size Limit"; case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Control"; case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "NAL Format"; - /* - * TODO(AS) - * case V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE: - * return "ROI Type"; - */ default: s_vpr_e(sid, "%s: ctrl name not available for ctrl id %#x", __func__, control_id); @@ -109,6 +111,11 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst) core = inst->core; capability = inst->capabilities; + 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++) { if (capability->cap[idx].v4l2_id) num_ctrls++; @@ -131,17 +138,36 @@ 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; + if (!capability->cap[idx].v4l2_id) + continue; + if (ctrl_idx >= num_ctrls) { s_vpr_e(inst->sid, - "invalid ctrl_idx, max allowed %d\n", + "%s: invalid ctrl %#x, max allowed %d\n", + __func__, capability->cap[idx].v4l2_id, num_ctrls); return -EINVAL; } - if (!capability->cap[idx].v4l2_id) - continue; + s_vpr_h(inst->sid, + "%s: cap idx %d, value %d min %d max %d step_or_mask %#x flags %#x v4l2_id %#x hfi_id %#x\n", + __func__, idx, + capability->cap[idx].value, + capability->cap[idx].min, + capability->cap[idx].max, + capability->cap[idx].step_or_mask, + capability->cap[idx].flags, + capability->cap[idx].v4l2_id, + capability->cap[idx].hfi_id); + + memset(&ctrl_cfg, 0, sizeof(struct v4l2_ctrl_config)); if (is_priv_ctrl(capability->cap[idx].v4l2_id)) { /* add private control */ @@ -150,20 +176,24 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst) ctrl_cfg.id = capability->cap[idx].v4l2_id; ctrl_cfg.max = capability->cap[idx].max; ctrl_cfg.min = capability->cap[idx].min; - ctrl_cfg.menu_skip_mask = - ~(capability->cap[idx].step_or_mask); ctrl_cfg.ops = core->v4l2_ctrl_ops; - ctrl_cfg.step = capability->cap[idx].step_or_mask; ctrl_cfg.type = (capability->cap[idx].flags & CAP_FLAG_MENU) ? V4L2_CTRL_TYPE_MENU : V4L2_CTRL_TYPE_INTEGER; - ctrl_cfg.qmenu = msm_vidc_get_qmenu_type(inst, + if (ctrl_cfg.type == V4L2_CTRL_TYPE_MENU) { + ctrl_cfg.menu_skip_mask = + ~(capability->cap[idx].step_or_mask); + ctrl_cfg.qmenu = msm_vidc_get_qmenu_type(inst, capability->cap[idx].v4l2_id); + } else { + ctrl_cfg.step = + capability->cap[idx].step_or_mask; + } ctrl_cfg.name = msm_vidc_get_priv_ctrl_name(inst->sid, capability->cap[idx].v4l2_id); - if (!ctrl_cfg.name || !ctrl_cfg.ops) { - s_vpr_e(inst->sid, "%s: invalid control, %d\n", + if (!ctrl_cfg.name) { + s_vpr_e(inst->sid, "%s: invalid control, %#x\n", __func__, ctrl_cfg.id); return -EINVAL; } @@ -189,8 +219,8 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst) } } if (!ctrl) { - s_vpr_e(inst->sid, "%s: invalid ctrl %s\n", __func__, - ctrl->name); + s_vpr_e(inst->sid, "%s: invalid ctrl %#x\n", __func__, + capability->cap[idx].v4l2_id); return -EINVAL; } diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index ab1ac2376e..9dc5119f3a 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -166,7 +166,8 @@ u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt) } } -int msm_vidc_get_port_from_v4l2_type(u32 type) +int msm_vidc_get_port_from_v4l2_type(struct msm_vidc_inst *inst, u32 type, + const char *func) { int port; @@ -179,7 +180,7 @@ int msm_vidc_get_port_from_v4l2_type(u32 type) } else if (type == OUTPUT_META_PLANE) { port = OUTPUT_META_PORT; } else { - d_vpr_e("%s: invalid type %d\n", __func__, type); + s_vpr_e(inst->sid, "%s: invalid type %d\n", func, type); port = -EINVAL; } @@ -187,7 +188,7 @@ int msm_vidc_get_port_from_v4l2_type(u32 type) } u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) + enum msm_vidc_buffer_type buffer_type, const char *func) { u32 region = MSM_VIDC_NON_SECURE; @@ -231,13 +232,13 @@ u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, break; default: s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", - __func__, buffer_type); + func, buffer_type); } return region; } struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) + enum msm_vidc_buffer_type buffer_type, const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_INPUT: @@ -266,7 +267,7 @@ struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst } struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) + enum msm_vidc_buffer_type buffer_type, const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_INPUT: @@ -295,7 +296,7 @@ struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst, } struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) + enum msm_vidc_buffer_type buffer_type, const char *func) { switch (buffer_type) { case MSM_VIDC_BUF_SCRATCH: @@ -316,26 +317,26 @@ struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst, } int msm_vidc_change_inst_state(struct msm_vidc_inst *inst, - enum msm_vidc_inst_state request_state) + enum msm_vidc_inst_state request_state, const char *func) { if (!inst) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } if (!request_state) { - d_vpr_e("%s: invalid request state\n", __func__); + s_vpr_e(inst->sid, "%s: invalid request state\n", func); return -EINVAL; } if (inst->state == MSM_VIDC_ERROR) { s_vpr_h(inst->sid, - "inst is in bad state, can not change state to %d\n", - request_state); + "%s: inst is in bad state, can not change state to %d\n", + func, request_state); return 0; } - s_vpr_h(inst->sid, "state changed from %d to %d\n", - inst->state, request_state); + s_vpr_h(inst->sid, "%s: state changed from %d to %d\n", + func, inst->state, request_state); inst->state = request_state; return 0; } @@ -382,18 +383,18 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return -EINVAL; } if (!is_internal_buffer(buffer_type)) { - s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n", + s_vpr_e(inst->sid, "%s: buffer type %#x is not internal\n", __func__, buffer_type); return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type); + buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); if (!buffer_info) return -EINVAL; - alloc_info = msm_vidc_get_alloc_info(inst, buffer_type); + alloc_info = msm_vidc_get_alloc_info(inst, buffer_type, __func__); if (!alloc_info) return -EINVAL; - map_info = msm_vidc_get_map_info(inst, buffer_type); + map_info = msm_vidc_get_map_info(inst, buffer_type, __func__); if (!alloc_info) return -EINVAL; @@ -403,12 +404,13 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, struct msm_vidc_map *map; if (!buffer_info->size) { - d_vpr_e("%s: invalid buffer %#x\n", __func__, buffer_type); + s_vpr_e(inst->sid, "%s: invalid buffer %#x\n", + __func__, buffer_type); return -EINVAL; } buffer = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL); if (!buffer) { - s_vpr_e(inst->sid, "%s: msm_vidc_buffer alloc failed\n", __func__); + s_vpr_e(inst->sid, "%s: buf alloc failed\n", __func__); return -ENOMEM; } INIT_LIST_HEAD(&buffer->list); @@ -420,12 +422,13 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, alloc = kzalloc(sizeof(struct msm_vidc_alloc), GFP_KERNEL); if (!alloc) { - s_vpr_e(inst->sid, "%s: msm_vidc_alloc alloc failed\n", __func__); + s_vpr_e(inst->sid, "%s: alloc failed\n", __func__); return -ENOMEM; } INIT_LIST_HEAD(&alloc->list); alloc->buffer_type = buffer_type; - alloc->region = msm_vidc_get_buffer_region(inst, buffer_type); + alloc->region = msm_vidc_get_buffer_region(inst, + buffer_type, __func__); alloc->size = buffer->buffer_size; rc = msm_vidc_memory_alloc(inst->core, alloc); if (rc) @@ -434,7 +437,7 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL); if (!map) { - s_vpr_e(inst->sid, "%s: msm_vidc_map alloc failed\n", __func__); + s_vpr_e(inst->sid, "%s: map alloc failed\n", __func__); return -ENOMEM; } INIT_LIST_HEAD(&map->list); @@ -446,7 +449,7 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return -ENOMEM; list_add_tail(&map->list, &map_info->list); - s_vpr_e(inst->sid, "%s: created buffer_type %d, size %d\n", + s_vpr_e(inst->sid, "%s: created buffer_type %#x, size %d\n", __func__, buffer_type, buffer_info->size); } @@ -466,12 +469,12 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, return -EINVAL; } if (!is_internal_buffer(buffer_type)) { - s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n", + s_vpr_e(inst->sid, "%s: buffer type %#x is not internal\n", __func__, buffer_type); return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type); + buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); if (!buffer_info) return -EINVAL; @@ -488,7 +491,7 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, /* mark queued */ buffer->attr |= MSM_VIDC_ATTR_QUEUED; - s_vpr_e(inst->sid, "%s: queued buffer_type %d, size %d\n", + s_vpr_h(inst->sid, "%s: queued buffer_type %#x, size %d\n", __func__, buffer_type, buffer_info->size); } @@ -508,12 +511,12 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, return -EINVAL; } if (!is_internal_buffer(buffer_type)) { - s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n", + s_vpr_e(inst->sid, "%s: buffer type %#x is not internal\n", __func__, buffer_type); return 0; } - buffer_info = msm_vidc_get_buffer_info(inst, buffer_type); + buffer_info = msm_vidc_get_buffer_info(inst, buffer_type, __func__); if (!buffer_info) return -EINVAL; @@ -530,7 +533,7 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, /* mark pending release */ buffer->attr |= MSM_VIDC_ATTR_PENDING_RELEASE; - s_vpr_e(inst->sid, "%s: released buffer_type %d, size %d\n", + s_vpr_e(inst->sid, "%s: released buffer_type %#x, size %d\n", __func__, buffer_type, buffer_info->size); } @@ -632,7 +635,7 @@ int msm_vidc_add_session(struct msm_vidc_inst *inst) list_for_each_entry(i, &core->instances, list) count++; - if (count < MAX_SUPPORTED_INSTANCES) { + if (count < 0xffffff /*TODO: MAX_SUPPORTED_INSTANCES*/) { list_add_tail(&inst->list, &core->instances); } else { d_vpr_e("%s: total sessions %d exceeded max limit %d\n", diff --git a/driver/vidc/src/msm_vidc_platform.c b/driver/vidc/src/msm_vidc_platform.c index 69cda2acaa..3492e601f2 100644 --- a/driver/vidc/src/msm_vidc_platform.c +++ b/driver/vidc/src/msm_vidc_platform.c @@ -27,10 +27,10 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt, .vidioc_enum_fmt_vid_out = msm_v4l2_enum_fmt, .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, - .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, - .vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt, - .vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt, - .vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt, + .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt, + .vidioc_s_fmt_vid_out = msm_v4l2_s_fmt, + .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt, + .vidioc_g_fmt_vid_out = 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 64f323bb9c..b95d046728 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -46,11 +46,10 @@ int msm_vidc_queue_setup(struct vb2_queue *q, return -EINVAL; } - port = msm_vidc_get_port_from_v4l2_type(q->type); - if (port < 0) { - d_vpr_e("%s: invalid queue type %d\n", __func__, q->type); + port = msm_vidc_get_port_from_v4l2_type(inst, q->type, __func__); + if (port < 0) return -EINVAL; - } + if (port == INPUT_PORT || port == INPUT_META_PORT) { if (inst->state == MSM_VIDC_START_INPUT) { d_vpr_e("%s: input invalid state %d\n", diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index f400132ae2..8e01bbc3e0 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -2543,24 +2543,24 @@ int venus_hfi_session_close(struct msm_vidc_inst *inst) return rc; } -int venus_hfi_start_input(struct msm_vidc_inst *inst) +int venus_hfi_start(struct msm_vidc_inst *inst, enum msm_vidc_port_type port) { int rc = 0; - u32 port; - - d_vpr_h("%s(): inst %p\n", __func__, inst); if (!inst) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } - port = is_decode_session(inst) ? HFI_PORT_BITSTREAM : HFI_PORT_RAW; rc = hfi_packet_session_command(inst, HFI_CMD_START, (HFI_HOST_FLAGS_RESPONSE_REQUIRED | HFI_HOST_FLAGS_INTR_REQUIRED), - port, + get_hfi_port(inst, port), inst->session_id, HFI_PAYLOAD_NONE, NULL, @@ -2575,90 +2575,25 @@ int venus_hfi_start_input(struct msm_vidc_inst *inst) return rc; } -int venus_hfi_stop_input(struct msm_vidc_inst *inst) +int venus_hfi_stop(struct msm_vidc_inst *inst, enum msm_vidc_port_type port) { int rc = 0; - u32 port; - - d_vpr_h("%s(): inst %p\n", __func__, inst); if (!inst) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } - port = is_decode_session(inst) ? HFI_PORT_BITSTREAM : HFI_PORT_RAW; rc = hfi_packet_session_command(inst, HFI_CMD_STOP, (HFI_HOST_FLAGS_RESPONSE_REQUIRED | HFI_HOST_FLAGS_INTR_REQUIRED | HFI_HOST_FLAGS_NON_DISCARDABLE), - port, - inst->session_id, - HFI_PAYLOAD_NONE, - NULL, - 0); - if (rc) - return rc; - - rc = __iface_cmdq_write(inst->core, inst->packet); - if (rc) - return rc; - - return rc; -} - -int venus_hfi_start_output(struct msm_vidc_inst *inst) -{ - int rc = 0; - u32 port; - - d_vpr_h("%s(): inst %p\n", __func__, inst); - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - port = is_decode_session(inst) ? HFI_PORT_RAW : HFI_PORT_BITSTREAM; - rc = hfi_packet_session_command(inst, - HFI_CMD_START, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - port, - inst->session_id, - HFI_PAYLOAD_NONE, - NULL, - 0); - if (rc) - return rc; - - rc = __iface_cmdq_write(inst->core, inst->packet); - if (rc) - return rc; - - return rc; -} - -int venus_hfi_stop_output(struct msm_vidc_inst *inst) -{ - int rc = 0; - u32 port; - - d_vpr_h("%s(): inst %p\n", __func__, inst); - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - port = is_decode_session(inst) ? HFI_PORT_RAW : HFI_PORT_BITSTREAM; - rc = hfi_packet_session_command(inst, - HFI_CMD_STOP, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED | - HFI_HOST_FLAGS_NON_DISCARDABLE), - port, + get_hfi_port(inst, port), inst->session_id, HFI_PAYLOAD_NONE, NULL, @@ -2697,15 +2632,15 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, return rc; rc = hfi_create_packet(inst->packet, - inst->packet_size, - HFI_CMD_BUFFER, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_STRUCTURE, - get_hfi_port(inst, buffer->type), - core->packet_id++, - &hfi_buffer, - sizeof(hfi_buffer)); + inst->packet_size, + HFI_CMD_BUFFER, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_STRUCTURE, + get_hfi_port_from_buffer_type(inst, buffer->type), + core->packet_id++, + &hfi_buffer, + sizeof(hfi_buffer)); if (rc) return rc; @@ -2714,14 +2649,14 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, if (rc) return rc; rc = hfi_create_packet(inst->packet, - inst->packet_size, - HFI_CMD_BUFFER, - HFI_HOST_FLAGS_NONE, - HFI_PAYLOAD_STRUCTURE, - get_hfi_port(inst, metabuf->type), - core->packet_id++, - &hfi_buffer, - sizeof(hfi_buffer)); + inst->packet_size, + HFI_CMD_BUFFER, + HFI_HOST_FLAGS_NONE, + HFI_PAYLOAD_STRUCTURE, + get_hfi_port_from_buffer_type(inst, metabuf->type), + core->packet_id++, + &hfi_buffer, + sizeof(hfi_buffer)); if (rc) return rc; } @@ -2765,15 +2700,15 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst, return rc; rc = hfi_create_packet(inst->packet, - inst->packet_size, - HFI_CMD_BUFFER, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_STRUCTURE, - get_hfi_port(inst, buffer->type), - core->packet_id++, - &hfi_buffer, - sizeof(hfi_buffer)); + inst->packet_size, + HFI_CMD_BUFFER, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_STRUCTURE, + get_hfi_port_from_buffer_type(inst, buffer->type), + core->packet_id++, + &hfi_buffer, + sizeof(hfi_buffer)); if (rc) return rc; diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 8c08ced070..2cc570f88c 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -27,6 +27,32 @@ /* 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 \ + (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) + /* vendor controls end */ #endif