[media] s5p-mfc: don't close instance after free OUTPUT buffers
authorayaka <ayaka@soulik.info>
Fri, 6 May 2016 22:11:22 +0000 (19:11 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 7 Jun 2016 13:45:37 +0000 (10:45 -0300)
User-space applications can use the VIDIOC_REQBUFS ioctl to determine if a
memory mapped, user pointer or DMABUF based I/O is supported by the driver.

So a set of VIDIOC_REQBUFS ioctl calls will be made with count 0 and then
the real VIDIOC_REQBUFS call with count == n. But for count 0, the driver
not only frees the buffer but also closes the MFC instance and s5p_mfc_ctx
state is set to MFCINST_FREE.

The VIDIOC_REQBUFS handler for the output device checks if the s5p_mfc_ctx
state is set to MFCINST_INIT (which happens on an VIDIOC_S_FMT) and fails
otherwise. So after a VIDIOC_REQBUFS(n), future VIDIOC_REQBUFS(n) calls
will fails unless a VIDIOC_S_FMT ioctl calls happens before the reqbufs.

But applications may first set the format and then attempt to determine
the I/O methods supported by the driver (for example Gstramer does it) so
the state won't be set to MFCINST_INIT again and VIDIOC_REQBUFS will fail.

To avoid this issue, only free the buffers on VIDIOC_REQBUFS(0) but don't
close the MFC instance to allow future VIDIOC_REQBUFS(n) calls to succeed.

[javier: Rewrote changelog to explain the problem more detailed]

Signed-off-by: ayaka <ayaka@soulik.info>
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Nicolas Dufresne <nicolas@collabora.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/platform/s5p-mfc/s5p_mfc_dec.c

index f2d6376ce618b24d82b9a3743a4179f9d98259df..8b9467de2d6aff877376300ed5acf7c1d90807c3 100644 (file)
@@ -474,7 +474,6 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
                ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
                if (ret)
                        goto out;
-               s5p_mfc_close_mfc_inst(dev, ctx);
                ctx->src_bufs_cnt = 0;
                ctx->output_state = QUEUE_FREE;
        } else if (ctx->output_state == QUEUE_FREE) {