Merge tag 'v5.15.57' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / drivers / staging / media / rpivid / rpivid_dec.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Raspberry Pi HEVC driver
4  *
5  * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
6  *
7  * Based on the Cedrus VPU driver, that is:
8  *
9  * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
10  * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
11  * Copyright (C) 2018 Bootlin
12  */
13
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-ioctl.h>
16 #include <media/v4l2-event.h>
17 #include <media/v4l2-mem2mem.h>
18
19 #include "rpivid.h"
20 #include "rpivid_dec.h"
21
22 void rpivid_device_run(void *priv)
23 {
24         struct rpivid_ctx *const ctx = priv;
25         struct rpivid_dev *const dev = ctx->dev;
26         struct rpivid_run run = {};
27         struct media_request *src_req;
28
29         run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
30         run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
31
32         if (!run.src || !run.dst) {
33                 v4l2_err(&dev->v4l2_dev, "%s: Missing buffer: src=%p, dst=%p\n",
34                          __func__, run.src, run.dst);
35                 goto fail;
36         }
37
38         /* Apply request(s) controls */
39         src_req = run.src->vb2_buf.req_obj.req;
40         if (!src_req) {
41                 v4l2_err(&dev->v4l2_dev, "%s: Missing request\n", __func__);
42                 goto fail;
43         }
44
45         v4l2_ctrl_request_setup(src_req, &ctx->hdl);
46
47         switch (ctx->src_fmt.pixelformat) {
48         case V4L2_PIX_FMT_HEVC_SLICE:
49         {
50                 const struct v4l2_ctrl *ctrl;
51
52                 run.h265.sps =
53                         rpivid_find_control_data(ctx,
54                                                  V4L2_CID_MPEG_VIDEO_HEVC_SPS);
55                 run.h265.pps =
56                         rpivid_find_control_data(ctx,
57                                                  V4L2_CID_MPEG_VIDEO_HEVC_PPS);
58                 run.h265.dec =
59                         rpivid_find_control_data(ctx,
60                                                  V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
61
62                 ctrl = rpivid_find_ctrl(ctx,
63                                         V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
64                 if (!ctrl || !ctrl->elems) {
65                         v4l2_err(&dev->v4l2_dev, "%s: Missing slice params\n",
66                                  __func__);
67                         goto fail;
68                 }
69                 run.h265.slice_ents = ctrl->elems;
70                 run.h265.slice_params = ctrl->p_cur.p;
71
72                 run.h265.scaling_matrix =
73                         rpivid_find_control_data(ctx,
74                                                  V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
75                 break;
76         }
77
78         default:
79                 break;
80         }
81
82         v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
83
84         dev->dec_ops->setup(ctx, &run);
85
86         /* Complete request(s) controls */
87         v4l2_ctrl_request_complete(src_req, &ctx->hdl);
88
89         dev->dec_ops->trigger(ctx);
90         return;
91
92 fail:
93         /* We really shouldn't get here but tidy up what we can */
94         v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx,
95                                          VB2_BUF_STATE_ERROR);
96 }