瀏覽代碼

video: driver: add frame interval enum support.

Added support for VIDIOC_ENUM_FRAMEINTERVALS to provide
supported frame intervals range for a given resolution.

Change-Id: I51174634739dd1141d308ba9bfd1cf3720b6ca42
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 4 年之前
父節點
當前提交
c446124753

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

@@ -49,4 +49,5 @@ int msm_vidc_unsubscribe_event(void *instance,
 int msm_vidc_dqevent(void *instance, struct v4l2_event *event);
 int msm_vidc_g_crop(void *instance, struct v4l2_crop *a);
 int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize);
+int msm_vidc_enum_frameintervals(void *instance, struct v4l2_frmivalenum *fival);
 #endif

+ 2 - 0
driver/vidc/inc/msm_vidc_v4l2.h

@@ -54,6 +54,8 @@ int msm_v4l2_encoder_cmd(struct file *file, void *fh,
 		struct v4l2_encoder_cmd *enc);
 int msm_v4l2_enum_framesizes(struct file *file, void *fh,
 		struct v4l2_frmsizeenum *fsize);
+int msm_v4l2_enum_frameintervals(struct file *file, void *fh,
+		struct v4l2_frmivalenum *fival);
 int msm_v4l2_queryctrl(struct file *file, void *fh,
 		struct v4l2_queryctrl *ctrl);
 int msm_v4l2_querymenu(struct file *file, void *fh,

+ 71 - 0
driver/vidc/src/msm_vidc.c

@@ -603,6 +603,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
 {
 	struct msm_vidc_inst *inst = instance;
 	struct msm_vidc_inst_capability *capability;
+	enum msm_vidc_colorformat_type colorfmt;
 
 	if (!inst || !fsize) {
 		d_vpr_e("%s: invalid params: %pK %pK\n",
@@ -614,6 +615,18 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
 		return -EINVAL;
 	}
 	capability = inst->capabilities;
+
+	/* only index 0 allowed as per v4l2 spec */
+	if (fsize->index)
+		return -EINVAL;
+
+	/* validate pixel format */
+	colorfmt = v4l2_colorformat_to_driver(fsize->pixel_format, __func__);
+	if (colorfmt == MSM_VIDC_FMT_NONE) {
+		i_vpr_e(inst, "%s: unsupported pix fmt %#x\n", __func__, fsize->pixel_format);
+		return -EINVAL;
+	}
+
 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 	fsize->stepwise.min_width = capability->cap[FRAME_WIDTH].min;
 	fsize->stepwise.max_width = capability->cap[FRAME_WIDTH].max;
@@ -628,6 +641,64 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
 }
 EXPORT_SYMBOL(msm_vidc_enum_framesizes);
 
+int msm_vidc_enum_frameintervals(void *instance, struct v4l2_frmivalenum *fival)
+{
+	struct msm_vidc_inst *inst = instance;
+	struct msm_vidc_core *core;
+	struct msm_vidc_inst_capability *capability;
+	enum msm_vidc_colorformat_type colorfmt;
+	u32 fps, mbpf;
+
+	if (!inst || !fival) {
+		d_vpr_e("%s: invalid params: %pK %pK\n",
+				__func__, inst, fival);
+		return -EINVAL;
+	}
+	core = inst->core;
+
+	if (!inst->capabilities || !core->capabilities) {
+		i_vpr_e(inst, "capabilities not available\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	/* only index 0 allowed as per v4l2 spec */
+	if (fival->index)
+		return -EINVAL;
+
+	/* validate pixel format */
+	colorfmt = v4l2_colorformat_to_driver(fival->pixel_format, __func__);
+	if (colorfmt == MSM_VIDC_FMT_NONE) {
+		i_vpr_e(inst, "%s: unsupported pix fmt %#x\n", __func__, fival->pixel_format);
+		return -EINVAL;
+	}
+
+	/* validate resolution */
+	if (fival->width > capability->cap[FRAME_WIDTH].max ||
+		fival->width < capability->cap[FRAME_WIDTH].min ||
+		fival->height > capability->cap[FRAME_HEIGHT].max ||
+		fival->height < capability->cap[FRAME_HEIGHT].min) {
+		i_vpr_e(inst, "%s: unsupported resolution %u x %u\n", __func__,
+			fival->width, fival->height);
+		return -EINVAL;
+	}
+
+	/* calculate max supported fps for a given resolution */
+	mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
+	fps = core->capabilities[MAX_MBPS].value / mbpf;
+
+	fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = min_t(u32, fps, MAXIMUM_FPS);
+	fival->stepwise.max.numerator = 1;
+	fival->stepwise.max.denominator = 1;
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = MAXIMUM_FPS;
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_vidc_enum_frameintervals);
+
 int msm_vidc_subscribe_event(void *instance,
 		const struct v4l2_event_subscription *sub)
 {

+ 1 - 0
driver/vidc/src/msm_vidc_platform.c

@@ -27,6 +27,7 @@ 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_enum_frameintervals     = msm_v4l2_enum_frameintervals,
 	.vidioc_s_fmt_vid_cap           = msm_v4l2_s_fmt,
 	.vidioc_s_fmt_vid_out           = msm_v4l2_s_fmt,
 	.vidioc_s_fmt_vid_cap_mplane    = msm_v4l2_s_fmt,

+ 8 - 0
driver/vidc/src/msm_vidc_v4l2.c

@@ -215,6 +215,14 @@ int msm_v4l2_enum_framesizes(struct file *file, void *fh,
 	return msm_vidc_enum_framesizes((void *)vidc_inst, fsize);
 }
 
+int msm_v4l2_enum_frameintervals(struct file *file, void *fh,
+				struct v4l2_frmivalenum *fival)
+{
+	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+
+	return msm_vidc_enum_frameintervals((void *)vidc_inst, fival);
+}
+
 int msm_v4l2_queryctrl(struct file *file, void *fh,
 	struct v4l2_queryctrl *ctrl)
 {