Browse Source

video: driver: add enumerate format support

Add below configuration
- format enumeration
- set format for encoder
- get inst capabilities based on codec from core

Change-Id: I2484056ae688cf7b634c5137631197a83c382950
Signed-off-by: Maheshwar Ajja <[email protected]>
Maheshwar Ajja 4 years ago
parent
commit
cd536c944c

+ 15 - 1
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -82,9 +82,23 @@ static struct msm_platform_core_capability core_data_waipio[] = {
 };
 
 static struct msm_platform_inst_capability instance_data_waipio[] = {
-	/* {type, domains, codecs, min, max, step_or_menu, value} */
+	/* {type, domains, codecs, min, max, step_or_mask, value} */
 	{FRAME_WIDTH, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1920},
 	{FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080},
+	{PIX_FMTS, ENC, CODECS_ALL,
+		MSM_VIDC_FMT_NV12,
+		MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
+		MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC |
+		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},
+	{PIX_FMTS, DEC, CODECS_ALL,
+		MSM_VIDC_FMT_NV12,
+		MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS,
+		MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC |
+		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},
 	/* (8192 * 4320) / 256 */
 	{MBPF, ENC|DEC, CODECS_ALL, 64, 138240, 1, 138240},
 	/* ((1920 * 1088) / 256) * 960 fps */

+ 1 - 0
driver/vidc/inc/msm_vdec.h

@@ -15,6 +15,7 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst);
 int msm_vdec_start_output(struct msm_vidc_inst *inst);
 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);
 int msm_vdec_inst_init(struct msm_vidc_inst *inst);
 int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
 

+ 3 - 0
driver/vidc/inc/msm_venc.h

@@ -9,6 +9,9 @@
 #include "msm_vidc_core.h"
 #include "msm_vidc_inst.h"
 
+int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
+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 msm_venc_inst_init(struct msm_vidc_inst *inst);
 int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
 

+ 1 - 0
driver/vidc/inc/msm_vidc_core.h

@@ -76,6 +76,7 @@ struct msm_vidc_core {
 	u32                                    spur_count;
 	u32                                    reg_count;
 	bool                                   power_enabled;
+	u32                                    codecs_count;
 	struct msm_vidc_core_capability       *capabilities;
 	struct msm_vidc_inst_capability       *inst_caps;
 	struct msm_vidc_mem_addr               sfr;

+ 5 - 1
driver/vidc/inc/msm_vidc_driver.h

@@ -66,6 +66,11 @@ 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);
 int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
 		enum msm_vidc_inst_state state);
 int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
@@ -87,7 +92,6 @@ void msm_vidc_fw_unload_handler(struct work_struct *work);
 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);
-u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt);
 int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl);
 int msm_vidc_get_port_from_v4l2_type(u32 type);
 u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,

+ 2 - 1
driver/vidc/inc/msm_vidc_internal.h

@@ -169,6 +169,7 @@ enum msm_vidc_inst_capability_type {
 	INST_CAP_NONE = 0,
 	FRAME_WIDTH,
 	FRAME_HEIGHT,
+	PIX_FMTS,
 	MBPF,
 	MBPS,
 	FRAME_RATE,
@@ -223,7 +224,7 @@ struct msm_vidc_inst_cap {
 	enum msm_vidc_inst_capability_type cap;
 	s32 min;
 	s32 max;
-	u32 step_or_menu;
+	u32 step_or_mask;
 	s32 value;
 	enum msm_vidc_inst_capability_flags flags;
 	u32 v4l2_id;

+ 1 - 1
driver/vidc/inc/msm_vidc_platform.h

@@ -21,7 +21,7 @@ struct msm_platform_inst_capability {
 	enum msm_vidc_codec_type codec;
 	s32 min;
 	s32 max;
-	u32 step_or_menu;
+	u32 step_or_mask;
 	s32 value;
 	enum msm_vidc_inst_capability_flags flags;
 	u32 v4l2_id;

+ 91 - 17
driver/vidc/src/msm_vdec.c

@@ -18,6 +18,7 @@
 static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
 {
 	int rc = 0;
+	int i;
 	struct msm_vidc_core *core;
 
 	d_vpr_h("%s()\n", __func__);
@@ -27,6 +28,20 @@ static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
 	}
 	core = inst->core;
 
+	inst->capabilities = NULL;
+	for (i = 0; i < core->codecs_count; i++) {
+		if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
+		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
+				inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
+			s_vpr_h(inst->sid, "%s: changed capabilities to %#x caps\n",
+				__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
+			inst->capabilities = &core->inst_caps[i];
+		}
+	}
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
+		return -EINVAL;
+	}
 	return rc;
 }
 
@@ -300,7 +315,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
 		}
 		inst->buffers.input.size = fmt->fmt.pix.sizeimage;
 
-		// update crop dimensions
+		/* update crop dimensions */
 		inst->crop.x = inst->crop.y = 0;
 		inst->crop.width = f->fmt.pix.width;
 		inst->crop.height = f->fmt.pix.height;
@@ -351,10 +366,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(
-			msm_vidc_convert_color_fmt(fmt->fmt.pix.pixelformat),
+			get_media_colorformat_from_v4l2(fmt->fmt.pix.pixelformat),
 			f->fmt.pix.width);
 		fmt->fmt.pix.height = VENUS_Y_SCANLINES(
-			msm_vidc_convert_color_fmt(fmt->fmt.pix.pixelformat),
+			get_media_colorformat_from_v4l2(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,
@@ -416,7 +431,7 @@ err_invalid_fmt:
 int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
 {
 	int rc = 0;
-	u32 index;
+	int port;
 
 	d_vpr_h("%s()\n", __func__);
 	if (!inst) {
@@ -424,19 +439,58 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
 		return -EINVAL;
 	}
 
-	if (f->type == OUTPUT_PLANE) {
-		index = OUTPUT_PORT;
-	} else if (f->type == INPUT_PLANE) {
-		index = OUTPUT_PORT;
-	} else if (f->type == OUTPUT_META_PLANE) {
-		index = OUTPUT_PORT;
-	} else if (f->type == OUTPUT_META_PLANE) {
-		index = OUTPUT_PORT;
-	} else {
-		d_vpr_e("%s: invalid type %d\n", __func__, f->type);
+	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);
+		return -EINVAL;
+	}
+	memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
+
+	return rc;
+}
+
+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;
+
+	if (!inst || !inst->core || !inst->capabilities || !f) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 	}
-	memcpy(f, &inst->fmts[index], sizeof(struct v4l2_format));
+	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);
+		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);
+		if (!f->pixelformat)
+			return -EINVAL;
+		strlcpy(f->description, "colorformat", sizeof(f->description));
+	} else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
+		if (!f->index) {
+			f->pixelformat = V4L2_PIX_FMT_VIDC_META;
+			strlcpy(f->description, "metadata", sizeof(f->description));
+		} else {
+			return -EINVAL;
+		}
+	}
 
 	return rc;
 }
@@ -444,6 +498,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
 int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
+	int i;
 	struct msm_vidc_core *core;
 	struct v4l2_format *f;
 
@@ -473,6 +528,10 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 			inst->buffers.input.extra_count;
 	inst->buffers.input.size = f->fmt.pix.sizeimage;
 
+	inst->crop.x = inst->crop.y = 0;
+	inst->crop.width = f->fmt.pix.width;
+	inst->crop.height = f->fmt.pix.height;
+
 	f = &inst->fmts[INPUT_META_PORT];
 	f->type = INPUT_META_PLANE;
 	f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
@@ -487,9 +546,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(
-		msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
+		get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
 	f->fmt.pix.height = VENUS_Y_SCANLINES(
-		msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
+		get_media_colorformat_from_v4l2(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);
@@ -515,6 +574,21 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 
+	inst->capabilities = NULL;
+	for (i = 0; i < core->codecs_count; i++) {
+		if (core->inst_caps[i].domain == MSM_VIDC_DECODER &&
+		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
+				inst->fmts[INPUT_PORT].fmt.pix.pixelformat)) {
+			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
+				__func__, inst->fmts[INPUT_PORT].fmt.pix.pixelformat);
+			inst->capabilities = &core->inst_caps[i];
+		}
+	}
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
+		return -EINVAL;
+	}
+
 	return rc;
 }
 

+ 288 - 2
driver/vidc/src/msm_venc.c

@@ -14,10 +14,277 @@
 #include "msm_vidc_platform.h"
 #include "msm_vidc_debug.h"
 
+static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec)
+{
+	int rc = 0;
+	int i;
+	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;
+	}
+	core = inst->core;
+
+	inst->capabilities = NULL;
+	for (i = 0; i < core->codecs_count; i++) {
+		if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
+		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
+				inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
+			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
+				__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
+			inst->capabilities = &core->inst_caps[i];
+		}
+	}
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
+int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+	struct v4l2_format *fmt;
+
+	d_vpr_h("%s()\n", __func__);
+	if (!inst || !inst->core) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	core = inst->core;
+
+	if (inst->state == MSM_VIDC_START) {
+		d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
+		return -EINVAL;
+	}
+
+	if (f->type == INPUT_PLANE) {
+		if (inst->state == MSM_VIDC_START_INPUT) {
+			d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
+			return -EINVAL;
+		}
+		fmt = &inst->fmts[INPUT_PORT];
+		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),
+			f->fmt.pix.width);
+		fmt->fmt.pix.height = VENUS_Y_SCANLINES(
+			get_media_colorformat_from_v4l2(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,
+				inst, MSM_VIDC_BUF_INPUT);
+		inst->buffers.input.min_count =
+			call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT);
+		inst->buffers.input.extra_count =
+			call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT);
+		if (inst->buffers.input.actual_count <
+			inst->buffers.input.min_count +
+			inst->buffers.input.extra_count) {
+			inst->buffers.input.actual_count =
+				inst->buffers.input.min_count +
+				inst->buffers.input.extra_count;
+		}
+		inst->buffers.input.size = fmt->fmt.pix.sizeimage;
+
+		//rc = msm_vidc_check_session_supported(inst);
+		if (rc)
+			goto err_invalid_fmt;
+		//update_log_ctxt(inst->sid, inst->session_type,
+		//	mplane->pixelformat);
+		s_vpr_h(inst->sid,
+			"%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
+			__func__, f->fmt.pix.pixelformat, f->fmt.pix.width,
+			f->fmt.pix.height, fmt->fmt.pix.sizeimage,
+			inst->buffers.input.min_count,
+			inst->buffers.input.extra_count);
+
+		//msm_vidc_update_dcvs(inst);
+		//msm_vidc_update_batching(inst);
+
+	} else if (f->type == INPUT_META_PLANE) {
+		if (inst->state == MSM_VIDC_START_INPUT) {
+			d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
+			return -EINVAL;
+		}
+		fmt = &inst->fmts[INPUT_META_PORT];
+		fmt->type = INPUT_META_PLANE;
+		fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
+		fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
+				inst, MSM_VIDC_BUF_INPUT_META);
+		inst->buffers.input_meta.min_count =
+				inst->buffers.input.min_count;
+		inst->buffers.input_meta.extra_count =
+				inst->buffers.input.extra_count;
+		inst->buffers.input_meta.actual_count =
+				inst->buffers.input.actual_count;
+		inst->buffers.input_meta.size = fmt->fmt.meta.buffersize;
+		s_vpr_h(inst->sid,
+			"%s: input meta: size %d min_count %d extra_count %d\n",
+			__func__, fmt->fmt.meta.buffersize,
+			inst->buffers.input_meta.min_count,
+			inst->buffers.input_meta.extra_count);
+	} else if (f->type == OUTPUT_PLANE) {
+		if (inst->state == MSM_VIDC_START_OUTPUT) {
+			d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
+			return -EINVAL;
+		}
+		fmt = &inst->fmts[OUTPUT_PORT];
+		if (fmt->fmt.pix.pixelformat != f->fmt.pix.pixelformat) {
+			s_vpr_e(inst->sid,
+				"%s: codec changed from %#x to %#x\n", __func__,
+				fmt->fmt.pix.pixelformat, f->fmt.pix.pixelformat);
+			rc = msm_venc_codec_change(inst, f->fmt.pix.pixelformat);
+			if (rc)
+				goto err_invalid_fmt;
+		}
+		fmt->type = OUTPUT_PLANE;
+		fmt->fmt.pix.width = ALIGN(f->fmt.pix.width, 16);
+		fmt->fmt.pix.height = ALIGN(f->fmt.pix.height, 16);
+		fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat;
+		fmt->fmt.pix.bytesperline = 0;
+		fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
+				inst, MSM_VIDC_BUF_OUTPUT);
+		inst->buffers.output.min_count =
+			call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT);
+		inst->buffers.output.extra_count =
+			call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT);
+		if (inst->buffers.output.actual_count <
+			inst->buffers.output.min_count +
+			inst->buffers.output.extra_count) {
+			inst->buffers.output.actual_count =
+				inst->buffers.output.min_count +
+				inst->buffers.output.extra_count;
+		}
+		inst->buffers.output.size = fmt->fmt.pix.sizeimage;
+
+		//rc = msm_vidc_check_session_supported(inst);
+		if (rc)
+			goto err_invalid_fmt;
+
+		/* update crop dimensions */
+		inst->crop.x = inst->crop.y = 0;
+		inst->crop.width = f->fmt.pix.width;
+		inst->crop.height = f->fmt.pix.height;
+
+		//update_log_ctxt(inst->sid, inst->session_type,
+		//	mplane->pixelformat);
+
+		s_vpr_h(inst->sid,
+			"%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n",
+			__func__, fmt->fmt.pix.pixelformat, fmt->fmt.pix.width,
+			fmt->fmt.pix.height, fmt->fmt.pix.sizeimage,
+			inst->buffers.output.min_count,
+			inst->buffers.output.extra_count);
+	} else if (f->type == OUTPUT_META_PLANE) {
+		if (inst->state == MSM_VIDC_START_OUTPUT) {
+			d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
+			return -EINVAL;
+		}
+		fmt = &inst->fmts[OUTPUT_META_PORT];
+		fmt->type = OUTPUT_META_PLANE;
+		fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
+		fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
+				inst, MSM_VIDC_BUF_OUTPUT_META);
+		inst->buffers.output_meta.min_count =
+				inst->buffers.output.min_count;
+		inst->buffers.output_meta.extra_count =
+				inst->buffers.output.extra_count;
+		inst->buffers.output_meta.actual_count =
+				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",
+			__func__, fmt->fmt.meta.buffersize,
+			inst->buffers.output_meta.min_count,
+			inst->buffers.output_meta.extra_count);
+	} else {
+		s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, f->type);
+		goto err_invalid_fmt;
+	}
+	memcpy(f, fmt, sizeof(struct v4l2_format));
+
+err_invalid_fmt:
+	return rc;
+}
+
+int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
+{
+	int rc = 0;
+	int port;
+
+	d_vpr_h("%s()\n", __func__);
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		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);
+		return -EINVAL;
+	}
+	memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
+
+	return rc;
+}
+
+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;
+
+	if (!inst || !inst->core || !inst->capabilities || !f) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	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);
+		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);
+		if (!f->pixelformat)
+			return -EINVAL;
+		strlcpy(f->description, "colorformat", sizeof(f->description));
+	} else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
+		if (!f->index) {
+			f->pixelformat = V4L2_PIX_FMT_VIDC_META;
+			strlcpy(f->description, "metadata", sizeof(f->description));
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return rc;
+}
 
 int msm_venc_inst_init(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
+	int i;
 	struct msm_vidc_core *core;
 	struct v4l2_format *f;
 
@@ -45,6 +312,10 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
 			inst->buffers.output.extra_count;
 	inst->buffers.output.size = f->fmt.pix.sizeimage;
 
+	inst->crop.x = inst->crop.y = 0;
+	inst->crop.width = f->fmt.pix.width;
+	inst->crop.height = f->fmt.pix.height;
+
 	f = &inst->fmts[OUTPUT_META_PORT];
 	f->type = OUTPUT_META_PLANE;
 	f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
@@ -59,9 +330,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(
-		msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
+		get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat), DEFAULT_WIDTH);
 	f->fmt.pix.height = VENUS_Y_SCANLINES(
-		msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
+		get_media_colorformat_from_v4l2(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);
@@ -87,6 +358,21 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
 	inst->prop.frame_rate = DEFAULT_FPS << 16;
 	inst->prop.operating_rate = DEFAULT_FPS << 16;
 
+	inst->capabilities = NULL;
+	for (i = 0; i < core->codecs_count; i++) {
+		if (core->inst_caps[i].domain == MSM_VIDC_ENCODER &&
+		    core->inst_caps[i].codec == get_vidc_codec_from_v4l2(
+				inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat)) {
+			s_vpr_h(inst->sid, "%s: assigned capabilities with %#x caps\n",
+				__func__, inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat);
+			inst->capabilities = &core->inst_caps[i];
+		}
+	}
+	if (!inst->capabilities) {
+		s_vpr_e(inst->sid, "%s: capabilities not found\n", __func__);
+		return -EINVAL;
+	}
+
 	return rc;
 }
 

+ 86 - 65
driver/vidc/src/msm_vidc.c

@@ -25,61 +25,63 @@ bool valid_v4l2_buffer(struct v4l2_buffer *b,
 {
 	return true;
 }
-/*
-static int get_poll_flags(struct msm_vidc_inst *inst)
+
+static int get_poll_flags(struct msm_vidc_inst *inst, u32 port)
 {
-	int rc = 0;
-	struct vb2_queue *outq = &inst->bufq[PORT_INPUT].vb2_bufq;
-	struct vb2_queue *capq = &inst->bufq[PORT_OUTPUT].vb2_bufq;
-	struct vb2_buffer *out_vb = NULL;
-	struct vb2_buffer *cap_vb = NULL;
+	int poll = 0;
+	struct vb2_queue *q = NULL;
+	struct vb2_buffer *vb = NULL;
 	unsigned long flags = 0;
 
-	if (v4l2_event_pending(&inst->event_handler))
-		rc |= POLLPRI;
-
-	spin_lock_irqsave(&capq->done_lock, flags);
-	if (!list_empty(&capq->done_list))
-		cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
-								done_entry);
-	if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
-				|| cap_vb->state == VB2_BUF_STATE_ERROR))
-		rc |= POLLIN | POLLRDNORM;
-	spin_unlock_irqrestore(&capq->done_lock, flags);
-
-	spin_lock_irqsave(&outq->done_lock, flags);
-	if (!list_empty(&outq->done_list))
-		out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
-								done_entry);
-	if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
-				|| out_vb->state == VB2_BUF_STATE_ERROR))
-		rc |= POLLOUT | POLLWRNORM;
-	spin_unlock_irqrestore(&outq->done_lock, flags);
+	if (!inst || port >= MAX_PORT) {
+		d_vpr_e("%s: invalid params, inst %pK, port %d\n",
+			__func__, inst, port);
+		return poll;
+	}
+	q = &inst->vb2q[port];
+
+	spin_lock_irqsave(&q->done_lock, flags);
+	if (!list_empty(&q->done_list))
+		vb = list_first_entry(&q->done_list, struct vb2_buffer,
+							  done_entry);
+	if (vb && (vb->state == VB2_BUF_STATE_DONE ||
+			   vb->state == VB2_BUF_STATE_ERROR)) {
+		if (port == OUTPUT_PORT || port == OUTPUT_META_PORT)
+			poll |= POLLIN | POLLRDNORM;
+		else if (port == INPUT_PORT || port == INPUT_META_PORT)
+			poll |= POLLOUT | POLLWRNORM;
+	}
+	spin_unlock_irqrestore(&q->done_lock, flags);
 
-	return rc;
+	return poll;
 }
-*/
 
 int msm_vidc_poll(void *instance, struct file *filp,
 		struct poll_table_struct *wait)
 {
-/*
+	int poll = 0;
 	struct msm_vidc_inst *inst = instance;
-	struct vb2_queue *outq = NULL;
-	struct vb2_queue *capq = NULL;
 
-	if (!inst)
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
-
-	outq = &inst->bufq[PORT_INPUT].vb2_bufq;
-	capq = &inst->bufq[PORT_OUTPUT].vb2_bufq;
+	}
 
 	poll_wait(filp, &inst->event_handler.wait, wait);
-	poll_wait(filp, &capq->done_wq, wait);
-	poll_wait(filp, &outq->done_wq, wait);
-	return get_poll_flags(inst);
-*/
-	return 0;
+	poll_wait(filp, &inst->vb2q[INPUT_META_PORT].done_wq, wait);
+	poll_wait(filp, &inst->vb2q[OUTPUT_META_PORT].done_wq, wait);
+	poll_wait(filp, &inst->vb2q[INPUT_PORT].done_wq, wait);
+	poll_wait(filp, &inst->vb2q[OUTPUT_PORT].done_wq, wait);
+
+	if (v4l2_event_pending(&inst->event_handler))
+		poll |= POLLPRI;
+
+	poll |= get_poll_flags(inst, INPUT_META_PORT);
+	poll |= get_poll_flags(inst, OUTPUT_META_PORT);
+	poll |= get_poll_flags(inst, INPUT_PORT);
+	poll |= get_poll_flags(inst, OUTPUT_PORT);
+
+	return poll;
 }
 EXPORT_SYMBOL(msm_vidc_poll);
 
@@ -87,14 +89,16 @@ int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
 {
 	struct msm_vidc_inst *inst = instance;
 
-	if (!inst || !cap)
+	if (!inst || !cap) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
 	cap->bus_info[0] = 0;
 	cap->version = MSM_VIDC_VERSION;
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
-		V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE |
+		V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT |
 		V4L2_CAP_STREAMING;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
@@ -115,13 +119,16 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
 {
 	struct msm_vidc_inst *inst = instance;
 
-	if (!inst || !f)
+	if (!inst || !f) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	if (inst->domain == MSM_VIDC_DECODER)
-		return -EINVAL;//msm_vdec_enum_fmt(instance, f);
-	else if (inst->domain == MSM_VIDC_ENCODER)
-		return -EINVAL;//msm_venc_enum_fmt(instance, f);
+		return msm_vdec_enum_fmt(inst, f);
+	if (inst->domain == MSM_VIDC_ENCODER)
+		return msm_venc_enum_fmt(inst, f);
+
 	return -EINVAL;
 }
 EXPORT_SYMBOL(msm_vidc_enum_fmt);
@@ -200,8 +207,10 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
 	int rc = 0;
 	struct msm_vidc_inst *inst = instance;
 
-	if (!inst || !f)
+	if (!inst || !f) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	if (f->type == INPUT_PLANE) {
 		if (inst->state != MSM_VIDC_OPEN &&
@@ -225,7 +234,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
 	if (inst->domain == MSM_VIDC_DECODER)
 		rc = msm_vdec_s_fmt(inst, f);
 	if (inst->domain == MSM_VIDC_ENCODER)
-		rc = 0;//msm_venc_s_fmt(instance, f);
+		rc = msm_venc_s_fmt(inst, f);
 
 	return rc;
 }
@@ -236,13 +245,15 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
 	int rc = 0;
 	struct msm_vidc_inst *inst = instance;
 
-	if (!inst || !f)
+	if (!inst || !f) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	if (inst->domain == MSM_VIDC_DECODER)
 		rc = msm_vdec_g_fmt(inst, f);
 	if (inst->domain == MSM_VIDC_ENCODER)
-		rc = 0;//msm_venc_g_fmt(instance, f);
+		rc = msm_venc_g_fmt(inst, f);
 
 	return rc;
 }
@@ -265,9 +276,10 @@ int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
 	struct v4l2_ctrl *ctrl = NULL;
 	int rc = 0;
 
-	if (!inst || !control)
+	if (!inst || !control) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
-
+	}
 	ctrl = v4l2_ctrl_find(&inst->ctrl_handler, control->id);
 	if (ctrl) {
 		rc = msm_vidc_get_control(inst, ctrl);
@@ -285,8 +297,10 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
 	struct msm_vidc_inst *inst = instance;
 	int port;
 
-	if (!inst || !b)
+	if (!inst || !b) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	mutex_lock(&inst->lock);
 
@@ -347,8 +361,10 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
 	enum msm_vidc_inst_state new_state = 0;
 	int port;
 
-	if (!inst)
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	mutex_lock(&inst->lock);
 
@@ -425,8 +441,10 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
 	enum msm_vidc_inst_state new_state = 0;
 	int port;
 
-	if (!inst)
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
+	}
 
 	mutex_lock(&inst->lock);
 
@@ -524,10 +542,11 @@ int msm_vidc_subscribe_event(void *instance,
 	int rc = 0;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
 
-	if (!inst || !sub)
+	if (!inst || !sub) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
-
-	s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
+	}
+	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);
 	return rc;
@@ -540,10 +559,11 @@ int msm_vidc_unsubscribe_event(void *instance,
 	int rc = 0;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
 
-	if (!inst || !sub)
+	if (!inst || !sub) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
-
-	s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
+	}
+	s_vpr_h(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
 	rc = v4l2_event_unsubscribe(&inst->event_handler, sub);
 	return rc;
 }
@@ -554,9 +574,10 @@ int msm_vidc_dqevent(void *instance, struct v4l2_event *event)
 	int rc = 0;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
 
-	if (!inst || !event)
+	if (!inst || !event) {
+		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
-
+	}
 	rc = v4l2_event_dequeue(&inst->event_handler, event, false);
 	return rc;
 }

+ 2 - 2
driver/vidc/src/msm_vidc_buffer.c

@@ -148,7 +148,7 @@ u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst)
 	struct v4l2_format *f;
 
 	f = &inst->fmts[OUTPUT_PORT];
-	format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
+	format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat);
 	return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
 			f->fmt.pix.height);
 }
@@ -169,7 +169,7 @@ u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst)
 	struct v4l2_format *f;
 
 	f = &inst->fmts[INPUT_PORT];
-	format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
+	format = get_media_colorformat_from_v4l2(f->fmt.pix.pixelformat);
 	return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
 			f->fmt.pix.height);
 }

+ 142 - 26
driver/vidc/src/msm_vidc_driver.c

@@ -26,6 +26,145 @@ void print_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *b)
 {
 }
 
+enum msm_vidc_codec_type get_vidc_codec_from_v4l2(u32 v4l2_codec)
+{
+	enum msm_vidc_codec_type codec = 0;
+
+	switch (v4l2_codec) {
+	case V4L2_PIX_FMT_H264:
+		codec = MSM_VIDC_H264;
+		break;
+	case V4L2_PIX_FMT_HEVC:
+		codec = MSM_VIDC_HEVC;
+		break;
+	case V4L2_PIX_FMT_VP9:
+		codec = MSM_VIDC_VP9;
+		break;
+	case V4L2_PIX_FMT_MPEG2:
+		codec = MSM_VIDC_MPEG2;
+		break;
+	default:
+		d_vpr_e("%s: vidc codec not found for %#x\n", __func__, v4l2_codec);
+		break;
+	}
+	return codec;
+}
+
+u32 get_v4l2_codec_from_vidc(enum msm_vidc_codec_type codec)
+{
+	u32 v4l2_codec = 0;
+
+	switch (codec) {
+	case MSM_VIDC_H264:
+		v4l2_codec = V4L2_PIX_FMT_H264;
+		break;
+	case MSM_VIDC_HEVC:
+		v4l2_codec = V4L2_PIX_FMT_HEVC;
+		break;
+	case MSM_VIDC_VP9:
+		v4l2_codec = V4L2_PIX_FMT_VP9;
+		break;
+	case MSM_VIDC_MPEG2:
+		v4l2_codec = V4L2_PIX_FMT_MPEG2;
+		break;
+	default:
+		d_vpr_e("%s: v4l2 codec not found for %#x\n", __func__, codec);
+		break;
+	}
+	return v4l2_codec;
+}
+
+enum msm_vidc_colorformat_type get_vidc_colorformat_from_v4l2(u32 v4l2_colorformat)
+{
+	enum msm_vidc_colorformat_type colorformat = 0;
+
+	switch (v4l2_colorformat) {
+	case V4L2_PIX_FMT_NV12:
+		colorformat = MSM_VIDC_FMT_NV12;
+		break;
+	case V4L2_PIX_FMT_NV21:
+		colorformat = MSM_VIDC_FMT_NV21;
+		break;
+	case V4L2_PIX_FMT_NV12_UBWC:
+		colorformat = MSM_VIDC_FMT_NV12_UBWC;
+		break;
+	case V4L2_PIX_FMT_NV12_TP10_UBWC:
+		colorformat = MSM_VIDC_FMT_NV12_TP10_UBWC;
+		break;
+	case V4L2_PIX_FMT_RGBA8888_UBWC:
+		colorformat = MSM_VIDC_FMT_RGBA8888_UBWC;
+		break;
+	case V4L2_PIX_FMT_NV12_P010_UBWC:
+		colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
+		break;
+	case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
+		colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
+		break;
+	default:
+		d_vpr_e("%s: vidc format not found for %#x\n", __func__, v4l2_colorformat);
+		break;
+	}
+	return colorformat;
+}
+
+u32 get_v4l2_colorformat_from_vidc(enum msm_vidc_colorformat_type colorformat)
+{
+	u32 v4l2_colorformat = 0;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12:
+		v4l2_colorformat = V4L2_PIX_FMT_NV12;
+		break;
+	case MSM_VIDC_FMT_NV21:
+		v4l2_colorformat = V4L2_PIX_FMT_NV21;
+		break;
+	case MSM_VIDC_FMT_NV12_UBWC:
+		v4l2_colorformat = V4L2_PIX_FMT_NV12_UBWC;
+		break;
+	case MSM_VIDC_FMT_NV12_TP10_UBWC:
+		v4l2_colorformat = V4L2_PIX_FMT_NV12_TP10_UBWC;
+		break;
+	case MSM_VIDC_FMT_RGBA8888_UBWC:
+		v4l2_colorformat = V4L2_PIX_FMT_RGBA8888_UBWC;
+		break;
+	case MSM_VIDC_FMT_NV12_P010_UBWC:
+		v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
+		break;
+	case MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
+		v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
+		break;
+	default:
+		d_vpr_e("%s: v4l2 format not found for %#x\n", __func__, colorformat);
+		break;
+	}
+	return v4l2_colorformat;
+}
+
+u32 get_media_colorformat_from_v4l2(u32 v4l2_fmt)
+{
+	switch (v4l2_fmt) {
+	case V4L2_PIX_FMT_NV12:
+		return COLOR_FMT_NV12;
+	case V4L2_PIX_FMT_NV21:
+		return COLOR_FMT_NV21;
+	case V4L2_PIX_FMT_NV12_512:
+		return COLOR_FMT_NV12_512;
+	case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
+		return COLOR_FMT_P010;
+	case V4L2_PIX_FMT_NV12_UBWC:
+		return COLOR_FMT_NV12_UBWC;
+	case V4L2_PIX_FMT_NV12_TP10_UBWC:
+		return COLOR_FMT_NV12_BPP10_UBWC;
+	case V4L2_PIX_FMT_RGBA8888_UBWC:
+		return COLOR_FMT_RGBA8888_UBWC;
+	default:
+		d_vpr_e(
+			"Invalid v4l2 color fmt FMT : %x, Set default(NV12)",
+			v4l2_fmt);
+		return COLOR_FMT_NV12;
+	}
+}
+
 int msm_vidc_get_port_from_v4l2_type(u32 type)
 {
 	int port;
@@ -227,31 +366,6 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 	return rc;
 }
 
-u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt)
-{
-	switch (v4l2_fmt) {
-	case V4L2_PIX_FMT_NV12:
-		return COLOR_FMT_NV12;
-	case V4L2_PIX_FMT_NV21:
-		return COLOR_FMT_NV21;
-	case V4L2_PIX_FMT_NV12_512:
-		return COLOR_FMT_NV12_512;
-	case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
-		return COLOR_FMT_P010;
-	case V4L2_PIX_FMT_NV12_UBWC:
-		return COLOR_FMT_NV12_UBWC;
-	case V4L2_PIX_FMT_NV12_TP10_UBWC:
-		return COLOR_FMT_NV12_BPP10_UBWC;
-	case V4L2_PIX_FMT_RGBA8888_UBWC:
-		return COLOR_FMT_RGBA8888_UBWC;
-	default:
-		d_vpr_e(
-			"Invalid v4l2 color fmt FMT : %x, Set default(NV12)",
-			v4l2_fmt);
-		return COLOR_FMT_NV12;
-	}
-}
-
 int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
 		enum msm_vidc_buffer_type buffer_type)
 {
@@ -609,7 +723,7 @@ static void update_inst_capability(struct msm_platform_inst_capability *in,
 		capability->cap[in->cap].cap = in->cap;
 		capability->cap[in->cap].min = in->min;
 		capability->cap[in->cap].max = in->max;
-		capability->cap[in->cap].step_or_menu = in->step_or_menu;
+		capability->cap[in->cap].step_or_mask = in->step_or_mask;
 		capability->cap[in->cap].value = in->value;
 		capability->cap[in->cap].flags = in->flags;
 		capability->cap[in->cap].v4l2_id = in->v4l2_id;
@@ -658,6 +772,8 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
 	count_bits = dec_valid_codecs;
 	COUNT_BITS(count_bits, codecs_count);
 
+	core->codecs_count = codecs_count;
+
 	if (!core->inst_caps) {
 		core->inst_caps = kcalloc(codecs_count,
 			sizeof(struct msm_vidc_inst_capability),

+ 2 - 1
driver/vidc/src/msm_vidc_probe.c

@@ -118,7 +118,8 @@ static int msm_vidc_register_video_device(struct msm_vidc_core *core,
 	core->vdev[index].type = type;
 	core->vdev[index].vdev.v4l2_dev = &core->v4l2_dev;
 	core->vdev[index].vdev.device_caps =
-		V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+		V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE |
+		V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT |
 		V4L2_CAP_STREAMING;
 	rc = video_register_device(&core->vdev[index].vdev,
 					VFL_TYPE_GRABBER, nr);