.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * |
---|
7 | 8 | * Jeongtae Park <jtp.park@samsung.com> |
---|
8 | 9 | * Kamil Debski <k.debski@samsung.com> |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - * (at your option) any later version. |
---|
14 | 10 | */ |
---|
15 | 11 | |
---|
16 | 12 | #include <linux/clk.h> |
---|
.. | .. |
---|
36 | 32 | |
---|
37 | 33 | static struct s5p_mfc_fmt formats[] = { |
---|
38 | 34 | { |
---|
39 | | - .name = "4:2:0 2 Planes 16x16 Tiles", |
---|
40 | 35 | .fourcc = V4L2_PIX_FMT_NV12MT_16X16, |
---|
41 | 36 | .codec_mode = S5P_MFC_CODEC_NONE, |
---|
42 | 37 | .type = MFC_FMT_RAW, |
---|
.. | .. |
---|
44 | 39 | .versions = MFC_V6_BIT | MFC_V7_BIT, |
---|
45 | 40 | }, |
---|
46 | 41 | { |
---|
47 | | - .name = "4:2:0 2 Planes 64x32 Tiles", |
---|
48 | 42 | .fourcc = V4L2_PIX_FMT_NV12MT, |
---|
49 | 43 | .codec_mode = S5P_MFC_CODEC_NONE, |
---|
50 | 44 | .type = MFC_FMT_RAW, |
---|
.. | .. |
---|
52 | 46 | .versions = MFC_V5_BIT, |
---|
53 | 47 | }, |
---|
54 | 48 | { |
---|
55 | | - .name = "4:2:0 2 Planes Y/CbCr", |
---|
56 | 49 | .fourcc = V4L2_PIX_FMT_NV12M, |
---|
57 | 50 | .codec_mode = S5P_MFC_CODEC_NONE, |
---|
58 | 51 | .type = MFC_FMT_RAW, |
---|
.. | .. |
---|
60 | 53 | .versions = MFC_V5PLUS_BITS, |
---|
61 | 54 | }, |
---|
62 | 55 | { |
---|
63 | | - .name = "4:2:0 2 Planes Y/CrCb", |
---|
64 | 56 | .fourcc = V4L2_PIX_FMT_NV21M, |
---|
65 | 57 | .codec_mode = S5P_MFC_CODEC_NONE, |
---|
66 | 58 | .type = MFC_FMT_RAW, |
---|
.. | .. |
---|
68 | 60 | .versions = MFC_V6PLUS_BITS, |
---|
69 | 61 | }, |
---|
70 | 62 | { |
---|
71 | | - .name = "H264 Encoded Stream", |
---|
72 | 63 | .fourcc = V4L2_PIX_FMT_H264, |
---|
73 | 64 | .codec_mode = S5P_MFC_CODEC_H264_ENC, |
---|
74 | 65 | .type = MFC_FMT_ENC, |
---|
.. | .. |
---|
76 | 67 | .versions = MFC_V5PLUS_BITS, |
---|
77 | 68 | }, |
---|
78 | 69 | { |
---|
79 | | - .name = "MPEG4 Encoded Stream", |
---|
80 | 70 | .fourcc = V4L2_PIX_FMT_MPEG4, |
---|
81 | 71 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, |
---|
82 | 72 | .type = MFC_FMT_ENC, |
---|
.. | .. |
---|
84 | 74 | .versions = MFC_V5PLUS_BITS, |
---|
85 | 75 | }, |
---|
86 | 76 | { |
---|
87 | | - .name = "H263 Encoded Stream", |
---|
88 | 77 | .fourcc = V4L2_PIX_FMT_H263, |
---|
89 | 78 | .codec_mode = S5P_MFC_CODEC_H263_ENC, |
---|
90 | 79 | .type = MFC_FMT_ENC, |
---|
.. | .. |
---|
92 | 81 | .versions = MFC_V5PLUS_BITS, |
---|
93 | 82 | }, |
---|
94 | 83 | { |
---|
95 | | - .name = "VP8 Encoded Stream", |
---|
96 | 84 | .fourcc = V4L2_PIX_FMT_VP8, |
---|
97 | 85 | .codec_mode = S5P_MFC_CODEC_VP8_ENC, |
---|
98 | 86 | .type = MFC_FMT_ENC, |
---|
.. | .. |
---|
134 | 122 | .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, |
---|
135 | 123 | .type = V4L2_CTRL_TYPE_MENU, |
---|
136 | 124 | .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, |
---|
137 | | - .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, |
---|
| 125 | + .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES, |
---|
138 | 126 | .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, |
---|
139 | 127 | .menu_skip_mask = 0, |
---|
140 | 128 | }, |
---|
.. | .. |
---|
272 | 260 | .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, |
---|
273 | 261 | .menu_skip_mask = 0, |
---|
274 | 262 | .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED, |
---|
| 263 | + }, |
---|
| 264 | + { |
---|
| 265 | + .id = V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE, |
---|
| 266 | + .type = V4L2_CTRL_TYPE_MENU, |
---|
| 267 | + .maximum = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, |
---|
| 268 | + .default_value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED, |
---|
275 | 269 | }, |
---|
276 | 270 | { |
---|
277 | 271 | .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT, |
---|
.. | .. |
---|
1224 | 1218 | unsigned long mb_y_addr, mb_c_addr; |
---|
1225 | 1219 | int slice_type; |
---|
1226 | 1220 | unsigned int strm_size; |
---|
| 1221 | + bool src_ready; |
---|
1227 | 1222 | |
---|
1228 | 1223 | slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); |
---|
1229 | 1224 | strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); |
---|
.. | .. |
---|
1263 | 1258 | } |
---|
1264 | 1259 | } |
---|
1265 | 1260 | } |
---|
1266 | | - if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) { |
---|
| 1261 | + if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING || |
---|
| 1262 | + ctx->state == MFCINST_FINISHING)) { |
---|
1267 | 1263 | mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, |
---|
1268 | 1264 | list); |
---|
1269 | 1265 | if (mb_entry->flags & MFC_BUF_FLAG_USED) { |
---|
.. | .. |
---|
1294 | 1290 | vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size); |
---|
1295 | 1291 | vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE); |
---|
1296 | 1292 | } |
---|
1297 | | - if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) |
---|
| 1293 | + |
---|
| 1294 | + src_ready = true; |
---|
| 1295 | + if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0) |
---|
| 1296 | + src_ready = false; |
---|
| 1297 | + if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0) |
---|
| 1298 | + src_ready = false; |
---|
| 1299 | + if (!src_ready || ctx->dst_queue_cnt == 0) |
---|
1298 | 1300 | clear_work_bit(ctx); |
---|
1299 | 1301 | |
---|
1300 | 1302 | return 0; |
---|
.. | .. |
---|
1313 | 1315 | { |
---|
1314 | 1316 | struct s5p_mfc_dev *dev = video_drvdata(file); |
---|
1315 | 1317 | |
---|
1316 | | - strlcpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); |
---|
1317 | | - strlcpy(cap->card, dev->vfd_enc->name, sizeof(cap->card)); |
---|
| 1318 | + strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); |
---|
| 1319 | + strscpy(cap->card, dev->vfd_enc->name, sizeof(cap->card)); |
---|
1318 | 1320 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
---|
1319 | 1321 | dev_name(&dev->plat_dev->dev)); |
---|
1320 | | - /* |
---|
1321 | | - * This is only a mem-to-mem video device. The capture and output |
---|
1322 | | - * device capability flags are left only for backward compatibility |
---|
1323 | | - * and are scheduled for removal. |
---|
1324 | | - */ |
---|
1325 | | - cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
---|
1326 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
---|
1327 | 1322 | return 0; |
---|
1328 | 1323 | } |
---|
1329 | 1324 | |
---|
.. | .. |
---|
1331 | 1326 | bool out) |
---|
1332 | 1327 | { |
---|
1333 | 1328 | struct s5p_mfc_dev *dev = video_drvdata(file); |
---|
1334 | | - struct s5p_mfc_fmt *fmt; |
---|
1335 | 1329 | int i, j = 0; |
---|
1336 | 1330 | |
---|
1337 | 1331 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { |
---|
.. | .. |
---|
1343 | 1337 | continue; |
---|
1344 | 1338 | |
---|
1345 | 1339 | if (j == f->index) { |
---|
1346 | | - fmt = &formats[i]; |
---|
1347 | | - strlcpy(f->description, fmt->name, |
---|
1348 | | - sizeof(f->description)); |
---|
1349 | | - f->pixelformat = fmt->fourcc; |
---|
| 1340 | + f->pixelformat = formats[i].fourcc; |
---|
1350 | 1341 | return 0; |
---|
1351 | 1342 | } |
---|
1352 | 1343 | ++j; |
---|
.. | .. |
---|
1354 | 1345 | return -EINVAL; |
---|
1355 | 1346 | } |
---|
1356 | 1347 | |
---|
1357 | | -static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, |
---|
1358 | | - struct v4l2_fmtdesc *f) |
---|
| 1348 | +static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, |
---|
| 1349 | + struct v4l2_fmtdesc *f) |
---|
1359 | 1350 | { |
---|
1360 | 1351 | return vidioc_enum_fmt(file, f, false); |
---|
1361 | 1352 | } |
---|
1362 | 1353 | |
---|
1363 | | -static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, |
---|
1364 | | - struct v4l2_fmtdesc *f) |
---|
| 1354 | +static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, |
---|
| 1355 | + struct v4l2_fmtdesc *f) |
---|
1365 | 1356 | { |
---|
1366 | 1357 | return vidioc_enum_fmt(file, f, true); |
---|
1367 | 1358 | } |
---|
.. | .. |
---|
1621 | 1612 | mfc_err("Call on QBUF after EOS command\n"); |
---|
1622 | 1613 | return -EIO; |
---|
1623 | 1614 | } |
---|
1624 | | - return vb2_qbuf(&ctx->vq_src, buf); |
---|
| 1615 | + return vb2_qbuf(&ctx->vq_src, NULL, buf); |
---|
1625 | 1616 | } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
---|
1626 | | - return vb2_qbuf(&ctx->vq_dst, buf); |
---|
| 1617 | + return vb2_qbuf(&ctx->vq_dst, NULL, buf); |
---|
1627 | 1618 | } |
---|
1628 | 1619 | return -EINVAL; |
---|
1629 | 1620 | } |
---|
.. | .. |
---|
1872 | 1863 | p->seq_hdr_mode = ctrl->val; |
---|
1873 | 1864 | break; |
---|
1874 | 1865 | case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE: |
---|
| 1866 | + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: |
---|
1875 | 1867 | p->frame_skip_mode = ctrl->val; |
---|
1876 | 1868 | break; |
---|
1877 | 1869 | case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT: |
---|
.. | .. |
---|
2343 | 2335 | |
---|
2344 | 2336 | static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { |
---|
2345 | 2337 | .vidioc_querycap = vidioc_querycap, |
---|
2346 | | - .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, |
---|
2347 | | - .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, |
---|
| 2338 | + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
---|
| 2339 | + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, |
---|
2348 | 2340 | .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, |
---|
2349 | 2341 | .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, |
---|
2350 | 2342 | .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, |
---|