]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c
7c7c20ab27331222e57c0301c28835a31fca2ac8
[linux.git] / drivers / staging / media / rockchip / vpu / rockchip_vpu_enc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip VPU codec driver
4  *
5  * Copyright (C) 2018 Collabora, Ltd.
6  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
7  *      Alpha Lin <Alpha.Lin@rock-chips.com>
8  *      Jeffy Chen <jeffy.chen@rock-chips.com>
9  *
10  * Copyright 2018 Google LLC.
11  *      Tomasz Figa <tfiga@chromium.org>
12  *
13  * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
14  * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
15  */
16
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/videodev2.h>
22 #include <linux/workqueue.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-event.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/videobuf2-core.h>
27 #include <media/videobuf2-dma-sg.h>
28
29 #include "rockchip_vpu.h"
30 #include "rockchip_vpu_hw.h"
31 #include "rockchip_vpu_common.h"
32
33 static const struct rockchip_vpu_fmt *
34 rockchip_vpu_find_format(struct rockchip_vpu_ctx *ctx, u32 fourcc)
35 {
36         struct rockchip_vpu_dev *dev = ctx->dev;
37         const struct rockchip_vpu_fmt *formats;
38         unsigned int num_fmts, i;
39
40         formats = dev->variant->enc_fmts;
41         num_fmts = dev->variant->num_enc_fmts;
42         for (i = 0; i < num_fmts; i++)
43                 if (formats[i].fourcc == fourcc)
44                         return &formats[i];
45         return NULL;
46 }
47
48 static const struct rockchip_vpu_fmt *
49 rockchip_vpu_get_default_fmt(struct rockchip_vpu_ctx *ctx, bool bitstream)
50 {
51         struct rockchip_vpu_dev *dev = ctx->dev;
52         const struct rockchip_vpu_fmt *formats;
53         unsigned int num_fmts, i;
54
55         formats = dev->variant->enc_fmts;
56         num_fmts = dev->variant->num_enc_fmts;
57         for (i = 0; i < num_fmts; i++) {
58                 if (bitstream == (formats[i].codec_mode != RK_VPU_MODE_NONE))
59                         return &formats[i];
60         }
61         return NULL;
62 }
63
64 static int vidioc_querycap(struct file *file, void *priv,
65                            struct v4l2_capability *cap)
66 {
67         struct rockchip_vpu_dev *vpu = video_drvdata(file);
68         struct video_device *vdev = video_devdata(file);
69
70         strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver));
71         strscpy(cap->card, vdev->name, sizeof(cap->card));
72         snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
73                  vpu->dev->driver->name);
74         return 0;
75 }
76
77 static int vidioc_enum_framesizes(struct file *file, void *priv,
78                                   struct v4l2_frmsizeenum *fsize)
79 {
80         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
81         const struct rockchip_vpu_fmt *fmt;
82
83         if (fsize->index != 0) {
84                 vpu_debug(0, "invalid frame size index (expected 0, got %d)\n",
85                           fsize->index);
86                 return -EINVAL;
87         }
88
89         fmt = rockchip_vpu_find_format(ctx, fsize->pixel_format);
90         if (!fmt) {
91                 vpu_debug(0, "unsupported bitstream format (%08x)\n",
92                           fsize->pixel_format);
93                 return -EINVAL;
94         }
95
96         /* This only makes sense for coded formats */
97         if (fmt->codec_mode == RK_VPU_MODE_NONE)
98                 return -EINVAL;
99
100         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
101         fsize->stepwise = fmt->frmsize;
102
103         return 0;
104 }
105
106 static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
107                                           struct v4l2_fmtdesc *f)
108 {
109         struct rockchip_vpu_dev *dev = video_drvdata(file);
110         const struct rockchip_vpu_fmt *fmt;
111         const struct rockchip_vpu_fmt *formats;
112         int num_fmts, i, j = 0;
113
114         formats = dev->variant->enc_fmts;
115         num_fmts = dev->variant->num_enc_fmts;
116         for (i = 0; i < num_fmts; i++) {
117                 /* Skip uncompressed formats */
118                 if (formats[i].codec_mode == RK_VPU_MODE_NONE)
119                         continue;
120                 if (j == f->index) {
121                         fmt = &formats[i];
122                         f->pixelformat = fmt->fourcc;
123                         return 0;
124                 }
125                 ++j;
126         }
127         return -EINVAL;
128 }
129
130 static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *priv,
131                                           struct v4l2_fmtdesc *f)
132 {
133         struct rockchip_vpu_dev *dev = video_drvdata(file);
134         const struct rockchip_vpu_fmt *formats;
135         const struct rockchip_vpu_fmt *fmt;
136         int num_fmts, i, j = 0;
137
138         formats = dev->variant->enc_fmts;
139         num_fmts = dev->variant->num_enc_fmts;
140         for (i = 0; i < num_fmts; i++) {
141                 if (formats[i].codec_mode != RK_VPU_MODE_NONE)
142                         continue;
143                 if (j == f->index) {
144                         fmt = &formats[i];
145                         f->pixelformat = fmt->fourcc;
146                         return 0;
147                 }
148                 ++j;
149         }
150         return -EINVAL;
151 }
152
153 static int vidioc_g_fmt_out_mplane(struct file *file, void *priv,
154                                    struct v4l2_format *f)
155 {
156         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
157         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
158
159         vpu_debug(4, "f->type = %d\n", f->type);
160
161         *pix_mp = ctx->src_fmt;
162
163         return 0;
164 }
165
166 static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
167                                    struct v4l2_format *f)
168 {
169         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
170         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
171
172         vpu_debug(4, "f->type = %d\n", f->type);
173
174         *pix_mp = ctx->dst_fmt;
175
176         return 0;
177 }
178
179 static int
180 vidioc_try_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
181 {
182         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
183         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
184         const struct rockchip_vpu_fmt *fmt;
185
186         vpu_debug(4, "%c%c%c%c\n",
187                   (pix_mp->pixelformat & 0x7f),
188                   (pix_mp->pixelformat >> 8) & 0x7f,
189                   (pix_mp->pixelformat >> 16) & 0x7f,
190                   (pix_mp->pixelformat >> 24) & 0x7f);
191
192         fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat);
193         if (!fmt) {
194                 fmt = rockchip_vpu_get_default_fmt(ctx, true);
195                 f->fmt.pix.pixelformat = fmt->fourcc;
196         }
197
198         pix_mp->num_planes = 1;
199         pix_mp->field = V4L2_FIELD_NONE;
200         pix_mp->width = clamp(pix_mp->width,
201                               fmt->frmsize.min_width,
202                               fmt->frmsize.max_width);
203         pix_mp->height = clamp(pix_mp->height,
204                                fmt->frmsize.min_height,
205                                fmt->frmsize.max_height);
206         /* Round up to macroblocks. */
207         pix_mp->width = round_up(pix_mp->width, fmt->frmsize.step_width);
208         pix_mp->height = round_up(pix_mp->height, fmt->frmsize.step_height);
209
210         /*
211          * For compressed formats the application can specify
212          * sizeimage. If the application passes a zero sizeimage,
213          * let's default to the maximum frame size.
214          */
215         if (!pix_mp->plane_fmt[0].sizeimage)
216                 pix_mp->plane_fmt[0].sizeimage = fmt->header_size +
217                         pix_mp->width * pix_mp->height * fmt->max_depth;
218         memset(pix_mp->plane_fmt[0].reserved, 0,
219                sizeof(pix_mp->plane_fmt[0].reserved));
220         return 0;
221 }
222
223 static int
224 vidioc_try_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
225 {
226         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
227         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
228         const struct rockchip_vpu_fmt *fmt;
229         unsigned int width, height;
230         int i;
231
232         vpu_debug(4, "%c%c%c%c\n",
233                   (pix_mp->pixelformat & 0x7f),
234                   (pix_mp->pixelformat >> 8) & 0x7f,
235                   (pix_mp->pixelformat >> 16) & 0x7f,
236                   (pix_mp->pixelformat >> 24) & 0x7f);
237
238         fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat);
239         if (!fmt) {
240                 fmt = rockchip_vpu_get_default_fmt(ctx, false);
241                 f->fmt.pix.pixelformat = fmt->fourcc;
242         }
243
244         pix_mp->field = V4L2_FIELD_NONE;
245         width = clamp(pix_mp->width,
246                       ctx->vpu_dst_fmt->frmsize.min_width,
247                       ctx->vpu_dst_fmt->frmsize.max_width);
248         height = clamp(pix_mp->height,
249                        ctx->vpu_dst_fmt->frmsize.min_height,
250                        ctx->vpu_dst_fmt->frmsize.max_height);
251         /* Round up to macroblocks. */
252         width = round_up(width, ctx->vpu_dst_fmt->frmsize.step_width);
253         height = round_up(height, ctx->vpu_dst_fmt->frmsize.step_height);
254
255         /* Fill remaining fields */
256         v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, width, height);
257
258         for (i = 0; i < pix_mp->num_planes; i++) {
259                 memset(pix_mp->plane_fmt[i].reserved, 0,
260                        sizeof(pix_mp->plane_fmt[i].reserved));
261         }
262         return 0;
263 }
264
265 void rockchip_vpu_enc_reset_dst_fmt(struct rockchip_vpu_dev *vpu,
266                                     struct rockchip_vpu_ctx *ctx)
267 {
268         struct v4l2_pix_format_mplane *fmt = &ctx->dst_fmt;
269
270         ctx->vpu_dst_fmt = rockchip_vpu_get_default_fmt(ctx, true);
271
272         memset(fmt, 0, sizeof(*fmt));
273
274         fmt->num_planes = 1;
275         fmt->width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width,
276                            ctx->vpu_dst_fmt->frmsize.max_width);
277         fmt->height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height,
278                             ctx->vpu_dst_fmt->frmsize.max_height);
279         fmt->pixelformat = ctx->vpu_dst_fmt->fourcc;
280         fmt->field = V4L2_FIELD_NONE;
281         fmt->colorspace = V4L2_COLORSPACE_JPEG,
282         fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
283         fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
284         fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
285
286         fmt->plane_fmt[0].sizeimage = ctx->vpu_dst_fmt->header_size +
287                 fmt->width * fmt->height * ctx->vpu_dst_fmt->max_depth;
288 }
289
290 void rockchip_vpu_enc_reset_src_fmt(struct rockchip_vpu_dev *vpu,
291                                     struct rockchip_vpu_ctx *ctx)
292 {
293         struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt;
294         unsigned int width, height;
295
296         ctx->vpu_src_fmt = rockchip_vpu_get_default_fmt(ctx, false);
297
298         memset(fmt, 0, sizeof(*fmt));
299
300         width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width,
301                       ctx->vpu_dst_fmt->frmsize.max_width);
302         height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height,
303                        ctx->vpu_dst_fmt->frmsize.max_height);
304         fmt->field = V4L2_FIELD_NONE;
305         fmt->colorspace = V4L2_COLORSPACE_JPEG,
306         fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
307         fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
308         fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
309
310         v4l2_fill_pixfmt_mp(fmt, ctx->vpu_src_fmt->fourcc, width, height);
311 }
312
313 static int
314 vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
315 {
316         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
317         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
318         struct vb2_queue *vq;
319         int ret;
320
321         /* Change not allowed if queue is streaming. */
322         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
323         if (vb2_is_streaming(vq))
324                 return -EBUSY;
325
326         ret = vidioc_try_fmt_out_mplane(file, priv, f);
327         if (ret)
328                 return ret;
329
330         ctx->vpu_src_fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat);
331         ctx->src_fmt = *pix_mp;
332
333         /* Propagate to the CAPTURE format */
334         ctx->dst_fmt.colorspace = pix_mp->colorspace;
335         ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc;
336         ctx->dst_fmt.xfer_func = pix_mp->xfer_func;
337         ctx->dst_fmt.quantization = pix_mp->quantization;
338         ctx->dst_fmt.width = pix_mp->width;
339         ctx->dst_fmt.height = pix_mp->height;
340
341         vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode);
342         vpu_debug(0, "fmt - w: %d, h: %d\n",
343                   pix_mp->width, pix_mp->height);
344         return 0;
345 }
346
347 static int
348 vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
349 {
350         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
351         struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
352         struct rockchip_vpu_dev *vpu = ctx->dev;
353         struct vb2_queue *vq, *peer_vq;
354         int ret;
355
356         /* Change not allowed if queue is streaming. */
357         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
358         if (vb2_is_streaming(vq))
359                 return -EBUSY;
360
361         /*
362          * Since format change on the CAPTURE queue will reset
363          * the OUTPUT queue, we can't allow doing so
364          * when the OUTPUT queue has buffers allocated.
365          */
366         peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
367                                   V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
368         if (vb2_is_busy(peer_vq) &&
369             (pix_mp->pixelformat != ctx->dst_fmt.pixelformat ||
370              pix_mp->height != ctx->dst_fmt.height ||
371              pix_mp->width != ctx->dst_fmt.width))
372                 return -EBUSY;
373
374         ret = vidioc_try_fmt_cap_mplane(file, priv, f);
375         if (ret)
376                 return ret;
377
378         ctx->vpu_dst_fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat);
379         ctx->dst_fmt = *pix_mp;
380
381         vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode);
382         vpu_debug(0, "fmt - w: %d, h: %d\n",
383                   pix_mp->width, pix_mp->height);
384
385         /*
386          * Current raw format might have become invalid with newly
387          * selected codec, so reset it to default just to be safe and
388          * keep internal driver state sane. User is mandated to set
389          * the raw format again after we return, so we don't need
390          * anything smarter.
391          */
392         rockchip_vpu_enc_reset_src_fmt(vpu, ctx);
393         return 0;
394 }
395
396 const struct v4l2_ioctl_ops rockchip_vpu_enc_ioctl_ops = {
397         .vidioc_querycap = vidioc_querycap,
398         .vidioc_enum_framesizes = vidioc_enum_framesizes,
399
400         .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane,
401         .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane,
402         .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_out_mplane,
403         .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_cap_mplane,
404         .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_out_mplane,
405         .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_cap_mplane,
406         .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
407         .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
408
409         .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
410         .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
411         .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
412         .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
413         .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
414         .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
415         .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
416
417         .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
418         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
419
420         .vidioc_streamon = v4l2_m2m_ioctl_streamon,
421         .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
422 };
423
424 static int
425 rockchip_vpu_queue_setup(struct vb2_queue *vq,
426                          unsigned int *num_buffers,
427                          unsigned int *num_planes,
428                          unsigned int sizes[],
429                          struct device *alloc_devs[])
430 {
431         struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vq);
432         struct v4l2_pix_format_mplane *pixfmt;
433         int i;
434
435         switch (vq->type) {
436         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
437                 pixfmt = &ctx->dst_fmt;
438                 break;
439         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
440                 pixfmt = &ctx->src_fmt;
441                 break;
442         default:
443                 vpu_err("invalid queue type: %d\n", vq->type);
444                 return -EINVAL;
445         }
446
447         if (*num_planes) {
448                 if (*num_planes != pixfmt->num_planes)
449                         return -EINVAL;
450                 for (i = 0; i < pixfmt->num_planes; ++i)
451                         if (sizes[i] < pixfmt->plane_fmt[i].sizeimage)
452                                 return -EINVAL;
453                 return 0;
454         }
455
456         *num_planes = pixfmt->num_planes;
457         for (i = 0; i < pixfmt->num_planes; ++i)
458                 sizes[i] = pixfmt->plane_fmt[i].sizeimage;
459         return 0;
460 }
461
462 static int rockchip_vpu_buf_prepare(struct vb2_buffer *vb)
463 {
464         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
465         struct vb2_queue *vq = vb->vb2_queue;
466         struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vq);
467         struct v4l2_pix_format_mplane *pixfmt;
468         unsigned int sz;
469         int ret = 0;
470         int i;
471
472         switch (vq->type) {
473         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
474                 pixfmt = &ctx->dst_fmt;
475                 break;
476         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
477                 pixfmt = &ctx->src_fmt;
478
479                 if (vbuf->field == V4L2_FIELD_ANY)
480                         vbuf->field = V4L2_FIELD_NONE;
481                 if (vbuf->field != V4L2_FIELD_NONE) {
482                         vpu_debug(4, "field %d not supported\n",
483                                   vbuf->field);
484                         return -EINVAL;
485                 }
486                 break;
487         default:
488                 vpu_err("invalid queue type: %d\n", vq->type);
489                 return -EINVAL;
490         }
491
492         for (i = 0; i < pixfmt->num_planes; ++i) {
493                 sz = pixfmt->plane_fmt[i].sizeimage;
494                 vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n",
495                           i, vb2_plane_size(vb, i), sz);
496                 if (vb2_plane_size(vb, i) < sz) {
497                         vpu_err("plane %d is too small\n", i);
498                         ret = -EINVAL;
499                         break;
500                 }
501         }
502
503         return ret;
504 }
505
506 static void rockchip_vpu_buf_queue(struct vb2_buffer *vb)
507 {
508         struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
509         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
510
511         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
512 }
513
514 static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count)
515 {
516         struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q);
517         enum rockchip_vpu_codec_mode codec_mode;
518         int ret = 0;
519
520         if (V4L2_TYPE_IS_OUTPUT(q->type))
521                 ctx->sequence_out = 0;
522         else
523                 ctx->sequence_cap = 0;
524
525         /* Set codec_ops for the chosen destination format */
526         codec_mode = ctx->vpu_dst_fmt->codec_mode;
527
528         vpu_debug(4, "Codec mode = %d\n", codec_mode);
529         ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode];
530
531         if (!V4L2_TYPE_IS_OUTPUT(q->type))
532                 if (ctx->codec_ops && ctx->codec_ops->init)
533                         ret = ctx->codec_ops->init(ctx);
534         return ret;
535 }
536
537 static void rockchip_vpu_stop_streaming(struct vb2_queue *q)
538 {
539         struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q);
540
541         if (!V4L2_TYPE_IS_OUTPUT(q->type))
542                 if (ctx->codec_ops && ctx->codec_ops->exit)
543                         ctx->codec_ops->exit(ctx);
544
545         /*
546          * The mem2mem framework calls v4l2_m2m_cancel_job before
547          * .stop_streaming, so there isn't any job running and
548          * it is safe to return all the buffers.
549          */
550         for (;;) {
551                 struct vb2_v4l2_buffer *vbuf;
552
553                 if (V4L2_TYPE_IS_OUTPUT(q->type))
554                         vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
555                 else
556                         vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
557                 if (!vbuf)
558                         break;
559                 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
560         }
561 }
562
563 const struct vb2_ops rockchip_vpu_enc_queue_ops = {
564         .queue_setup = rockchip_vpu_queue_setup,
565         .buf_prepare = rockchip_vpu_buf_prepare,
566         .buf_queue = rockchip_vpu_buf_queue,
567         .start_streaming = rockchip_vpu_start_streaming,
568         .stop_streaming = rockchip_vpu_stop_streaming,
569         .wait_prepare = vb2_ops_wait_prepare,
570         .wait_finish = vb2_ops_wait_finish,
571 };