video: driver: implement TRY_FMT for encoder and decoder
Any video device which supports capture multiplanar buf type should implement VIDIOC_TRY_FMT. Fixes: v4l2-compliance: testTryFormats (VIDIOC_TRY_FMT). Change-Id: Id7ec171115c9374c6173fcf74a609382c3acf2d0 Signed-off-by: Dikshita Agarwal <dikshita@codeaurora.org>
This commit is contained in:
@@ -14,6 +14,7 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_streamoff_output(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_streamon_output(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
|
||||
int msm_vdec_try_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
|
||||
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_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s);
|
||||
|
@@ -15,6 +15,7 @@ int msm_venc_streamoff_output(struct msm_vidc_inst *inst);
|
||||
int msm_venc_streamon_output(struct msm_vidc_inst *inst);
|
||||
int msm_venc_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
|
||||
int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
|
||||
int msm_venc_try_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
|
||||
int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
|
||||
int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f);
|
||||
int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
|
||||
|
@@ -19,6 +19,7 @@ int msm_vidc_close(void *instance);
|
||||
int msm_vidc_suspend(int core_id);
|
||||
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap);
|
||||
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
|
||||
int msm_vidc_try_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vidc_s_selection(void* instance, struct v4l2_selection* s);
|
||||
|
@@ -18,6 +18,8 @@ int msm_v4l2_querycap(struct file *filp, void *fh,
|
||||
struct v4l2_capability *cap);
|
||||
int msm_v4l2_enum_fmt(struct file *file, void *fh,
|
||||
struct v4l2_fmtdesc *f);
|
||||
int msm_v4l2_try_fmt(struct file *file, void *fh,
|
||||
struct v4l2_format *f);
|
||||
int msm_v4l2_s_fmt(struct file *file, void *fh,
|
||||
struct v4l2_format *f);
|
||||
int msm_v4l2_g_fmt(struct file *file, void *fh,
|
||||
@@ -62,4 +64,5 @@ int msm_v4l2_querymenu(struct file *file, void *fh,
|
||||
struct v4l2_querymenu *qmenu);
|
||||
unsigned int msm_v4l2_poll(struct file *filp,
|
||||
struct poll_table_struct *pt);
|
||||
|
||||
#endif // _MSM_VIDC_V4L2_H_
|
@@ -2090,6 +2090,56 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vdec_try_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
|
||||
u32 pix_fmt;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
|
||||
if (f->type == INPUT_MPLANE) {
|
||||
pix_fmt = v4l2_codec_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
if (!pix_fmt) {
|
||||
i_vpr_h(inst, "%s: unsupported codec, set default params\n", __func__);
|
||||
f->fmt.pix_mp.width = DEFAULT_WIDTH;
|
||||
f->fmt.pix_mp.height = DEFAULT_HEIGHT;
|
||||
f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
|
||||
pix_fmt = v4l2_codec_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
}
|
||||
} else if (f->type == OUTPUT_MPLANE) {
|
||||
if (inst->vb2q[INPUT_PORT].streaming) {
|
||||
f->fmt.pix_mp.height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
|
||||
f->fmt.pix_mp.width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
|
||||
}
|
||||
pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
if (!pix_fmt) {
|
||||
i_vpr_h(inst, "%s: unsupported format, set default params\n", __func__);
|
||||
f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VIDC_NV12C;
|
||||
f->fmt.pix_mp.width = VIDEO_Y_STRIDE_PIX(f->fmt.pix_mp.pixelformat,
|
||||
DEFAULT_WIDTH);
|
||||
f->fmt.pix_mp.height = VIDEO_Y_SCANLINES(f->fmt.pix_mp.pixelformat,
|
||||
DEFAULT_HEIGHT);
|
||||
pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
}
|
||||
} else {
|
||||
i_vpr_e(inst, "%s: invalid type %d\n", __func__, f->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pixmp->field == V4L2_FIELD_ANY)
|
||||
pixmp->field = V4L2_FIELD_NONE;
|
||||
|
||||
pixmp->num_planes = 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@@ -1036,6 +1036,52 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_venc_try_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
|
||||
u32 pix_fmt;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
|
||||
|
||||
if (f->type == INPUT_MPLANE) {
|
||||
pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
if (!pix_fmt) {
|
||||
i_vpr_h(inst, "%s: unsupported format, set default params\n", __func__);
|
||||
f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VIDC_NV12C;
|
||||
f->fmt.pix_mp.width = VIDEO_Y_STRIDE_PIX(f->fmt.pix_mp.pixelformat,
|
||||
DEFAULT_WIDTH);
|
||||
f->fmt.pix_mp.height = VIDEO_Y_SCANLINES(f->fmt.pix_mp.pixelformat,
|
||||
DEFAULT_HEIGHT);
|
||||
}
|
||||
} else if (f->type == OUTPUT_MPLANE) {
|
||||
pix_fmt = v4l2_codec_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
if (!pix_fmt) {
|
||||
i_vpr_h(inst, "%s: unsupported codec, set default params\n", __func__);
|
||||
f->fmt.pix_mp.width = DEFAULT_WIDTH;
|
||||
f->fmt.pix_mp.height = DEFAULT_HEIGHT;
|
||||
f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
|
||||
pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
|
||||
}
|
||||
} else {
|
||||
i_vpr_e(inst, "%s: invalid type %d\n", __func__, f->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pixmp->field == V4L2_FIELD_ANY)
|
||||
pixmp->field = V4L2_FIELD_NONE;
|
||||
pixmp->num_planes = 1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@@ -210,6 +210,31 @@ int msm_vidc_query_menu(void *instance, struct v4l2_querymenu *qmenu)
|
||||
}
|
||||
EXPORT_SYMBOL(msm_vidc_query_menu);
|
||||
|
||||
int msm_vidc_try_fmt(void *instance, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *inst = instance;
|
||||
|
||||
if (!inst || !f) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!msm_vidc_allow_s_fmt(inst, f->type))
|
||||
return -EBUSY;
|
||||
|
||||
if (inst->domain == MSM_VIDC_DECODER)
|
||||
rc = msm_vdec_try_fmt(inst, f);
|
||||
if (inst->domain == MSM_VIDC_ENCODER)
|
||||
rc = msm_venc_try_fmt(inst, f);
|
||||
|
||||
if (rc)
|
||||
i_vpr_e(inst, "%s: try_fmt(%d) failed %d\n",
|
||||
__func__, f->type, rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_vidc_try_fmt);
|
||||
|
||||
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@@ -26,6 +26,8 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
|
||||
.vidioc_enum_fmt_vid_out = msm_v4l2_enum_fmt,
|
||||
.vidioc_enum_framesizes = msm_v4l2_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = msm_v4l2_enum_frameintervals,
|
||||
.vidioc_try_fmt_vid_cap_mplane = msm_v4l2_try_fmt,
|
||||
.vidioc_try_fmt_vid_out_mplane = msm_v4l2_try_fmt,
|
||||
.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,
|
||||
|
@@ -107,6 +107,34 @@ unlock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
|
||||
{
|
||||
struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
|
||||
int rc = 0;
|
||||
|
||||
inst = get_inst_ref(g_core, inst);
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid instance\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inst_lock(inst, __func__);
|
||||
if (is_session_error(inst)) {
|
||||
i_vpr_e(inst, "%s: inst in error state\n", __func__);
|
||||
rc = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
rc = msm_vidc_try_fmt((void *)inst, f);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
unlock:
|
||||
inst_unlock(inst, __func__);
|
||||
put_inst(inst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_v4l2_s_fmt(struct file *filp, void *fh,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
|
Reference in New Issue
Block a user