1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "vcodec_service"
7
8 #include <sys/ioctl.h>
9 #include <fcntl.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "mpp_env.h"
15 #include "mpp_mem.h"
16 #include "mpp_time.h"
17 #include "mpp_list.h"
18 #include "mpp_debug.h"
19 #include "mpp_common.h"
20
21 #include "vpu.h"
22 #include "mpp_soc.h"
23 #include "mpp_platform.h"
24 #include "vcodec_service.h"
25 #include "vcodec_service_api.h"
26
27 #define MAX_REGS_COUNT 3
28 #define MPX_EXTRA_INFO_NUM 16
29 #define MAX_INFO_COUNT 16
30 #define INFO_FORMAT_TYPE 3
31
32 typedef struct MppReq_t {
33 RK_U32 *req;
34 RK_U32 size;
35 } MppReq;
36
37 typedef struct VcodecExtraSlot_t {
38 RK_U32 reg_idx;
39 RK_U32 offset;
40 } VcodecExtraSlot;
41
42 typedef struct VcodecExtraInfo_t {
43 RK_U32 magic; // Fix magic value 0x4C4A46
44 RK_U32 count; // valid patch info count
45 VcodecExtraSlot slots[MPX_EXTRA_INFO_NUM];
46 } VcodecExtraInfo;
47
48 typedef struct VcodecRegCfg_t {
49 RK_U32 reg_size;
50 VcodecExtraInfo extra_info;
51
52 void *reg_set;
53 void *reg_get;
54 } VcodecRegCfg;
55
56 typedef struct MppDevVcodecService_t {
57 RK_S32 client_type;
58 RK_U64 fmt;
59 RK_S32 fd;
60 RK_S32 max_regs;
61 RK_U32 reg_size;
62
63 RK_S32 reg_send_idx;
64 RK_S32 reg_poll_idx;
65
66 VcodecRegCfg regs[MAX_REGS_COUNT];
67
68 RK_S32 info_count;
69 MppDevInfoCfg info[MAX_INFO_COUNT];
70 } MppDevVcodecService;
71
72 /* For vpu1 / vpu2 */
73 static const char *mpp_vpu_dev[] = {
74 "/dev/vpu_service",
75 "/dev/vpu-service",
76 "/dev/mpp_service",
77 };
78
79 /* For hevc 4K decoder */
80 static const char *mpp_hevc_dev[] = {
81 "/dev/hevc_service",
82 "/dev/hevc-service",
83 "/dev/mpp_service",
84 };
85
86 /* For H.264/H.265/VP9 4K decoder */
87 static const char *mpp_rkvdec_dev[] = {
88 "/dev/rkvdec",
89 "/dev/mpp_service",
90 };
91
92 /* For H.264 4K encoder */
93 static const char *mpp_rkvenc_dev[] = {
94 "/dev/rkvenc",
95 "/dev/mpp_service",
96 };
97
98 /* For avs+ decoder */
99 static const char *mpp_avsd_dev[] = {
100 "/dev/avsd",
101 "/dev/mpp_service",
102 };
103
104 /* For H.264 / jpeg encoder */
105 static const char *mpp_vepu_dev[] = {
106 "/dev/vepu",
107 "/dev/mpp_service",
108 };
109
110 /* For H.265 encoder */
111 static const char *mpp_h265e_dev[] = {
112 "/dev/h265e",
113 "/dev/mpp_service",
114 };
115
116 /* For jpeg decoder */
117 static const char *mpp_jpegd_dev[] = {
118 "/dev/mpp_service",
119 };
120
121 static const char *mpp_jpege_dev[] = {
122 "/dev/mpp_service",
123 };
124
125 #define mpp_find_device(dev) _mpp_find_device(dev, MPP_ARRAY_ELEMS(dev))
126
_mpp_find_device(const char ** dev,RK_U32 size)127 static const char *_mpp_find_device(const char **dev, RK_U32 size)
128 {
129 RK_U32 i;
130
131 for (i = 0; i < size; i++)
132 if (!access(dev[i], F_OK))
133 return dev[i];
134
135 return NULL;
136 }
137
mpp_get_platform_dev_name(MppCtxType type,MppCodingType coding,RK_U32 platform)138 const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform)
139 {
140 const char *dev = NULL;
141
142 if ((platform & HAVE_RKVDEC) && (type == MPP_CTX_DEC) &&
143 (coding == MPP_VIDEO_CodingAVC ||
144 coding == MPP_VIDEO_CodingHEVC ||
145 coding == MPP_VIDEO_CodingAVS2 ||
146 coding == MPP_VIDEO_CodingVP9)) {
147 dev = mpp_find_device(mpp_rkvdec_dev);
148 } else if ((platform & HAVE_HEVC_DEC) && (type == MPP_CTX_DEC) &&
149 (coding == MPP_VIDEO_CodingHEVC)) {
150 dev = mpp_find_device(mpp_hevc_dev);
151 } else if ((platform & HAVE_AVSDEC) && (type == MPP_CTX_DEC) &&
152 (coding == MPP_VIDEO_CodingAVS)) {
153 dev = mpp_find_device(mpp_avsd_dev);
154 } else if ((platform & HAVE_RKVENC) && (type == MPP_CTX_ENC) &&
155 (coding == MPP_VIDEO_CodingAVC)) {
156 dev = mpp_find_device(mpp_rkvenc_dev);
157 } else if ((platform & HAVE_VEPU22) && (type == MPP_CTX_ENC) &&
158 (coding == MPP_VIDEO_CodingHEVC)) {
159 dev = mpp_find_device(mpp_h265e_dev);
160 } else {
161 if (type == MPP_CTX_ENC)
162 dev = mpp_find_device(mpp_vepu_dev);
163
164 if (dev == NULL)
165 dev = mpp_find_device(mpp_vpu_dev);
166 }
167
168 return dev;
169 }
170
mpp_get_vcodec_dev_name(MppCtxType type,MppCodingType coding)171 const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding)
172 {
173 const char *dev = NULL;
174 RockchipSocType soc_type = mpp_get_soc_type();
175
176 switch (soc_type) {
177 case ROCKCHIP_SOC_RK3036 : {
178 /* rk3036 do NOT have encoder */
179 if (type == MPP_CTX_ENC)
180 dev = NULL;
181 else if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
182 dev = mpp_find_device(mpp_hevc_dev);
183 else
184 dev = mpp_find_device(mpp_vpu_dev);
185 } break;
186 case ROCKCHIP_SOC_RK3066 :
187 case ROCKCHIP_SOC_RK3188 : {
188 /* rk3066/rk3188 have vpu1 only */
189 dev = mpp_find_device(mpp_vpu_dev);
190 } break;
191 case ROCKCHIP_SOC_RK3288 :
192 case ROCKCHIP_SOC_RK312X :
193 case ROCKCHIP_SOC_RK3368 :
194 case ROCKCHIP_SOC_RK3326 :
195 case ROCKCHIP_SOC_PX30 : {
196 /*
197 * rk3288/rk312x/rk3368 have codec:
198 * 1 - vpu1
199 * 2 - RK hevc decoder
200 */
201 if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
202 dev = mpp_find_device(mpp_hevc_dev);
203 else
204 dev = mpp_find_device(mpp_vpu_dev);
205 } break;
206 case ROCKCHIP_SOC_RK3128H : {
207 /*
208 * rk3128H have codec:
209 * 1 - vpu2
210 * 2 - RK H.264/H.265 1080p@60fps decoder
211 * NOTE: rk3128H do NOT have jpeg encoder
212 */
213 if (type == MPP_CTX_DEC &&
214 (coding == MPP_VIDEO_CodingAVC ||
215 coding == MPP_VIDEO_CodingHEVC))
216 dev = mpp_find_device(mpp_rkvdec_dev);
217 else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
218 dev = NULL;
219 else if (type == MPP_CTX_DEC && coding == MPP_VIDEO_CodingVP9)
220 dev = NULL;
221 else
222 dev = mpp_find_device(mpp_vpu_dev);
223 } break;
224 case ROCKCHIP_SOC_RK3399 :
225 case ROCKCHIP_SOC_RK3229 : {
226 /*
227 * rk3399/rk3229 have codec:
228 * 1 - vpu2
229 * 2 - RK H.264/H.265/VP9 4K decoder
230 */
231 if (type == MPP_CTX_DEC &&
232 (coding == MPP_VIDEO_CodingAVC ||
233 coding == MPP_VIDEO_CodingHEVC ||
234 coding == MPP_VIDEO_CodingVP9))
235 dev = mpp_find_device(mpp_rkvdec_dev);
236 else
237 dev = mpp_find_device(mpp_vpu_dev);
238 } break;
239 case ROCKCHIP_SOC_RK3228 : {
240 /*
241 * rk3228 have codec:
242 * 1 - vpu2
243 * 2 - RK H.264/H.265 4K decoder
244 * NOTE: rk3228 do NOT have jpeg encoder
245 */
246 if (type == MPP_CTX_DEC &&
247 (coding == MPP_VIDEO_CodingAVC ||
248 coding == MPP_VIDEO_CodingHEVC))
249 dev = mpp_find_device(mpp_rkvdec_dev);
250 else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
251 dev = NULL;
252 else
253 dev = mpp_find_device(mpp_vpu_dev);
254 } break;
255 case ROCKCHIP_SOC_RK3228H : {
256 /*
257 * rk3228h has codec:
258 * 1 - vpu2
259 * 2 - RK H.264/H.265 4K decoder
260 * 3 - avs+ decoder
261 * 4 - H.265 encoder
262 */
263 if (type == MPP_CTX_ENC) {
264 if (coding == MPP_VIDEO_CodingHEVC)
265 dev = mpp_find_device(mpp_h265e_dev);
266 else
267 dev = mpp_find_device(mpp_vepu_dev);
268 } else if (type == MPP_CTX_DEC) {
269 if (coding == MPP_VIDEO_CodingAVS)
270 dev = mpp_find_device(mpp_avsd_dev);
271 else if (coding == MPP_VIDEO_CodingAVC ||
272 coding == MPP_VIDEO_CodingHEVC)
273 dev = mpp_find_device(mpp_rkvdec_dev);
274 else
275 dev = mpp_find_device(mpp_vpu_dev);
276 }
277 } break;
278 case ROCKCHIP_SOC_RK3328 : {
279 /*
280 * rk3228 has codec:
281 * 1 - vpu2
282 * 2 - RK H.264/H.265/VP9 4K decoder
283 * 4 - H.265 encoder
284 */
285 if (type == MPP_CTX_ENC) {
286 if (coding == MPP_VIDEO_CodingHEVC)
287 dev = mpp_find_device(mpp_h265e_dev);
288 else
289 dev = mpp_find_device(mpp_vepu_dev);
290 } else if (type == MPP_CTX_DEC) {
291 if (coding == MPP_VIDEO_CodingAVC ||
292 coding == MPP_VIDEO_CodingHEVC ||
293 coding == MPP_VIDEO_CodingVP9) {
294 dev = mpp_find_device(mpp_rkvdec_dev);
295 } else
296 dev = mpp_find_device(mpp_vpu_dev);
297 }
298 } break;
299 case ROCKCHIP_SOC_RV1108 : {
300 /*
301 * rv1108 has codec:
302 * 1 - vpu2
303 * 2 - RK H.264 4K decoder
304 * 3 - RK H.264 4K encoder
305 */
306 if (coding == MPP_VIDEO_CodingAVC) {
307 if (type == MPP_CTX_ENC)
308 dev = mpp_find_device(mpp_rkvenc_dev);
309 else
310 dev = mpp_find_device(mpp_rkvdec_dev);
311 } else if (coding == MPP_VIDEO_CodingMJPEG)
312 dev = mpp_find_device(mpp_vpu_dev);
313 } break;
314 case ROCKCHIP_SOC_RV1109 :
315 case ROCKCHIP_SOC_RV1126 : {
316 /*
317 * rv1108 has codec:
318 * 1 - vpu2 for jpeg encoder and decoder
319 * 2 - RK H.264/H.265 4K decoder
320 * 3 - RK H.264/H.265 4K encoder
321 */
322 if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) {
323 if (type == MPP_CTX_ENC)
324 dev = mpp_find_device(mpp_rkvenc_dev);
325 else
326 dev = mpp_find_device(mpp_rkvdec_dev);
327 } else if (coding == MPP_VIDEO_CodingMJPEG)
328 dev = mpp_find_device(mpp_vpu_dev);
329 } break;
330 case ROCKCHIP_SOC_RK3566 :
331 case ROCKCHIP_SOC_RK3567 :
332 case ROCKCHIP_SOC_RK3568 : {
333 /*
334 * rk3566/rk3568 has codec:
335 * 1 - vpu2 for jpeg/vp8 encoder and decoder
336 * 2 - RK H.264/H.265/VP9 4K decoder
337 * 3 - RK H.264/H.265 4K encoder
338 * 3 - RK jpeg decoder
339 */
340 if (type == MPP_CTX_DEC) {
341 if (coding == MPP_VIDEO_CodingAVC ||
342 coding == MPP_VIDEO_CodingHEVC ||
343 coding == MPP_VIDEO_CodingVP9)
344 dev = mpp_find_device(mpp_rkvdec_dev);
345 else if (coding == MPP_VIDEO_CodingMJPEG)
346 dev = mpp_find_device(mpp_jpegd_dev);
347 else
348 dev = mpp_find_device(mpp_vpu_dev);
349 } else if (type == MPP_CTX_ENC) {
350 if (coding == MPP_VIDEO_CodingAVC ||
351 coding == MPP_VIDEO_CodingHEVC)
352 dev = mpp_find_device(mpp_rkvenc_dev);
353 else if (coding == MPP_VIDEO_CodingMJPEG ||
354 coding == MPP_VIDEO_CodingVP8)
355 dev = mpp_find_device(mpp_vpu_dev);
356 else
357 dev = NULL;
358 }
359 } break;
360 case ROCKCHIP_SOC_RK3588 : {
361 /*
362 * rk3588 has codec:
363 * 1 - RK H.264/H.265/VP9/AVS2 8K decoder
364 * 2 - RK H.264/H.265 8K encoder
365 * 3 - vpu2 for jpeg/vp8 encoder and decoder
366 * 4 - RK jpeg decoder
367 */
368 if (type == MPP_CTX_DEC) {
369 if (coding == MPP_VIDEO_CodingAVC ||
370 coding == MPP_VIDEO_CodingHEVC ||
371 coding == MPP_VIDEO_CodingAVS2 ||
372 coding == MPP_VIDEO_CodingVP9)
373 dev = mpp_find_device(mpp_rkvdec_dev);
374 else if (coding == MPP_VIDEO_CodingMJPEG)
375 dev = mpp_find_device(mpp_jpegd_dev);
376 else
377 dev = mpp_find_device(mpp_vpu_dev);
378 } else if (type == MPP_CTX_ENC) {
379 if (coding == MPP_VIDEO_CodingAVC ||
380 coding == MPP_VIDEO_CodingHEVC)
381 dev = mpp_find_device(mpp_rkvenc_dev);
382 else if (coding == MPP_VIDEO_CodingMJPEG ||
383 coding == MPP_VIDEO_CodingVP8)
384 dev = mpp_find_device(mpp_vpu_dev);
385 else
386 dev = NULL;
387 }
388 } break;
389 case ROCKCHIP_SOC_RK3576 :
390 case ROCKCHIP_SOC_RV1126B : {
391 if (type == MPP_CTX_DEC) {
392 if (coding == MPP_VIDEO_CodingMJPEG)
393 dev = mpp_find_device(mpp_jpegd_dev);
394 else
395 dev = mpp_find_device(mpp_rkvdec_dev);
396 } else if (type == MPP_CTX_ENC) {
397 if (coding == MPP_VIDEO_CodingMJPEG)
398 dev = mpp_find_device(mpp_jpege_dev);
399 else
400 dev = mpp_find_device(mpp_rkvenc_dev);
401 }
402 } break;
403 default : {
404 /* default case for unknown compatible */
405 RK_U32 vcodec_type = mpp_get_vcodec_type();
406
407 dev = mpp_get_platform_dev_name(type, coding, vcodec_type);
408 } break;
409 }
410
411 return dev;
412 }
413
vcodec_service_ioctl(RK_S32 fd,RK_S32 cmd,void * regs,RK_S32 size)414 static RK_S32 vcodec_service_ioctl(RK_S32 fd, RK_S32 cmd, void *regs, RK_S32 size)
415 {
416 MppReq req;
417
418 req.req = regs;
419 req.size = size;
420
421 return (RK_S32)ioctl(fd, cmd, &req);
422 }
423
extra_info_init(VcodecExtraInfo * info)424 static void extra_info_init(VcodecExtraInfo *info)
425 {
426 info->magic = EXTRA_INFO_MAGIC;
427 info->count = 0;
428 }
429
update_extra_info(VcodecExtraInfo * info,char * fmt,VcodecRegCfg * send_cfg)430 static void update_extra_info(VcodecExtraInfo *info, char* fmt, VcodecRegCfg* send_cfg)
431 {
432 void *reg_set = send_cfg->reg_set;
433 RK_U32 reg_size = send_cfg->reg_size;
434
435 if (info->count) {
436 if (!strstr(fmt, "mjpeg")) {
437 RK_U32 *reg = (RK_U32*)reg_set;
438 RK_U32 i = 0;
439
440 for (i = 0; i < info->count; i++) {
441 VcodecExtraSlot *slot = &info->slots[i];
442
443 reg[slot->reg_idx] |= (slot->offset << 10);
444 }
445 info->count = 0;
446 } else {
447 void *extra_data = reg_set + reg_size;
448 RK_S32 extra_size = sizeof(send_cfg->extra_info);
449
450 memcpy(extra_data, info, extra_size);
451 send_cfg->reg_size += extra_size;
452 extra_info_init(info);
453 }
454 }
455 }
456
vcodec_service_init(void * ctx,MppClientType type)457 MPP_RET vcodec_service_init(void *ctx, MppClientType type)
458 {
459 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
460 static RK_S32 vcodec_ioctl_version = -1;
461 VPU_CLIENT_TYPE client_type;
462 const char *name = NULL;
463 RK_U32 reg_size = 0;
464 RK_S32 max_regs = 2;
465 MPP_RET ret = MPP_NOK;
466
467 switch (type) {
468 case VPU_CLIENT_VDPU1 : {
469 name = mpp_find_device(mpp_vpu_dev);
470 client_type = VPU_DEC;
471 reg_size = VDPU1_REGISTERS;
472 } break;
473 case VPU_CLIENT_VDPU2 : {
474 name = mpp_find_device(mpp_vpu_dev);
475 client_type = VPU_DEC;
476 reg_size = VDPU2_REGISTERS;
477 } break;
478 case VPU_CLIENT_VDPU1_PP : {
479 name = mpp_find_device(mpp_vpu_dev);
480 client_type = VPU_DEC_PP;
481 if (ROCKCHIP_SOC_RK3036 == mpp_get_soc_type())
482 reg_size = VDPU1_REGISTERS;
483 else
484 reg_size = VDPU1_PP_REGISTERS;
485 } break;
486 case VPU_CLIENT_VDPU2_PP : {
487 name = mpp_find_device(mpp_vpu_dev);
488 client_type = VPU_DEC_PP;
489 reg_size = VDPU2_PP_REGISTERS;
490 } break;
491 case VPU_CLIENT_HEVC_DEC : {
492 name = mpp_find_device(mpp_hevc_dev);
493 client_type = VPU_DEC;
494 reg_size = RKHEVC_REGISTERS;
495 max_regs = 3;
496 } break;
497 case VPU_CLIENT_RKVDEC : {
498 name = mpp_find_device(mpp_rkvdec_dev);
499 client_type = VPU_DEC;
500 reg_size = RKVDEC_REGISTERS;
501 max_regs = 3;
502 } break;
503 case VPU_CLIENT_AVSPLUS_DEC : {
504 name = mpp_find_device(mpp_avsd_dev);
505 client_type = VPU_DEC;
506 reg_size = AVSD_REGISTERS;
507 } break;
508 case VPU_CLIENT_RKVENC : {
509 name = mpp_find_device(mpp_rkvenc_dev);
510 client_type = VPU_ENC;
511 reg_size = AVSD_REGISTERS;
512 } break;
513 case VPU_CLIENT_VEPU1 : {
514 name = mpp_find_device(mpp_vpu_dev);
515 client_type = VPU_ENC;
516 reg_size = VEPU1_REGISTERS;
517 } break;
518 case VPU_CLIENT_VEPU2 : {
519 name = mpp_find_device(mpp_vepu_dev);
520 if (NULL == name)
521 name = mpp_find_device(mpp_vpu_dev);
522 client_type = VPU_ENC;
523 reg_size = VEPU2_REGISTERS;
524 } break;
525 default : {
526 mpp_err_f("unsupported client type %d\n", type);
527 return ret;
528 } break;
529 }
530
531 p->fd = open(name, O_RDWR | O_CLOEXEC);
532 if (p->fd < 0) {
533 mpp_err("open vcodec_service %s failed\n", name);
534 return ret;
535 }
536
537 if (vcodec_ioctl_version < 0) {
538 ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE, (unsigned long)client_type);
539 if (!ret) {
540 vcodec_ioctl_version = 0;
541 } else {
542 ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE_U32, (RK_U32)client_type);
543 if (!ret)
544 vcodec_ioctl_version = 1;
545 }
546 mpp_assert(ret == MPP_OK);
547 } else {
548 RK_U32 cmd = (vcodec_ioctl_version == 0) ?
549 (VPU_IOC_SET_CLIENT_TYPE) :
550 (VPU_IOC_SET_CLIENT_TYPE_U32);
551
552 ret = (RK_S32)ioctl(p->fd, cmd, client_type);
553 }
554
555 p->max_regs = max_regs;
556 p->reg_size = reg_size * sizeof(RK_U32);
557 {
558 RK_S32 i;
559
560 for (i = 0; i < max_regs; i++) {
561 VcodecRegCfg *reg = &p->regs[i];
562
563 reg->reg_size = p->reg_size;
564 extra_info_init(®->extra_info);
565 }
566 }
567
568 return ret;
569 }
570
vcodec_service_deinit(void * ctx)571 MPP_RET vcodec_service_deinit(void *ctx)
572 {
573 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
574
575 if (p->fd)
576 close(p->fd);
577
578 return MPP_OK;
579 }
580
vcodec_service_reg_wr(void * ctx,MppDevRegWrCfg * cfg)581 MPP_RET vcodec_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
582 {
583 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
584 VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
585
586 mpp_assert(cfg->offset == 0);
587 send_cfg->reg_set = cfg->reg;
588 send_cfg->reg_size = cfg->size;
589
590 if (p->reg_size != cfg->size)
591 mpp_err_f("reg size mismatch wr %d rd %d\n",
592 p->reg_size, cfg->size);
593
594 return MPP_OK;
595 }
596
vcodec_service_reg_rd(void * ctx,MppDevRegRdCfg * cfg)597 MPP_RET vcodec_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
598 {
599 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
600 VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
601
602 mpp_assert(cfg->offset == 0);
603 send_cfg->reg_get = cfg->reg;
604 if (send_cfg->reg_size != cfg->size)
605 mpp_err_f("reg size mismatch rd %d rd %d\n",
606 send_cfg->reg_size, cfg->size);
607
608 return MPP_OK;
609 }
610
vcodec_service_reg_offset(void * ctx,MppDevRegOffsetCfg * cfg)611 MPP_RET vcodec_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg)
612 {
613 if (cfg->offset) {
614 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
615 VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
616 VcodecExtraInfo *extra = &send_cfg->extra_info;
617 VcodecExtraSlot *slot;
618 RK_U32 i;
619
620 for (i = 0; i < extra->count; i++) {
621 slot = &extra->slots[i];
622
623 if (slot->reg_idx == cfg->reg_idx) {
624 mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
625 slot->reg_idx, slot->offset, cfg->offset);
626 slot->offset = cfg->offset;
627 return MPP_OK;
628 }
629 }
630
631 slot = &extra->slots[extra->count];
632 slot->reg_idx = cfg->reg_idx;
633 slot->offset = cfg->offset;
634 extra->count++;
635 }
636
637 return MPP_OK;
638 }
639
vcodec_service_cmd_send(void * ctx)640 MPP_RET vcodec_service_cmd_send(void *ctx)
641 {
642 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
643 VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
644 VcodecExtraInfo *extra = &send_cfg->extra_info;
645 void *reg_set = send_cfg->reg_set;
646 char *fmt = (char*)&p->fmt;
647
648 update_extra_info(extra, fmt, send_cfg);
649
650 MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_SET_REG,
651 reg_set, send_cfg->reg_size);
652 if (ret) {
653 mpp_err_f("ioctl VPU_IOC_SET_REG failed ret %d errno %d %s\n",
654 ret, errno, strerror(errno));
655 ret = errno;
656 }
657
658 p->reg_send_idx++;
659 if (p->reg_send_idx >= p->max_regs)
660 p->reg_send_idx = 0;
661 p->info_count = 0;
662
663 return ret;
664 }
665
vcodec_service_cmd_poll(void * ctx,MppDevPollCfg * cfg)666 MPP_RET vcodec_service_cmd_poll(void *ctx, MppDevPollCfg *cfg)
667 {
668 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
669 VcodecRegCfg *poll_cfg = &p->regs[p->reg_poll_idx];
670 void *reg_get = poll_cfg->reg_get;
671 RK_S32 reg_size = poll_cfg->reg_size;
672 MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_GET_REG,
673 reg_get, reg_size);
674 if (ret) {
675 mpp_err_f("ioctl VPU_IOC_GET_REG failed ret %d errno %d %s\n",
676 ret, errno, strerror(errno));
677 ret = errno;
678 }
679
680 p->reg_poll_idx++;
681 if (p->reg_poll_idx >= p->max_regs)
682 p->reg_poll_idx = 0;
683
684 (void)cfg;
685 return ret;
686 }
687
vcodec_service_set_info(void * ctx,MppDevInfoCfg * cfg)688 MPP_RET vcodec_service_set_info(void *ctx, MppDevInfoCfg *cfg)
689 {
690 MppDevVcodecService *p = (MppDevVcodecService *)ctx;
691
692 if (!p->info_count)
693 memset(p->info, 0, sizeof(p->info));
694
695 if (p->info_count >= MAX_INFO_COUNT) {
696 mpp_err("info count reach max\n");
697 return MPP_NOK;
698 }
699
700 memcpy(&p->info[p->info_count], cfg, sizeof(MppDevInfoCfg));
701 p->info_count++;
702
703 if (cfg->type == INFO_FORMAT_TYPE) {
704 p->fmt = cfg->data;
705 }
706 return MPP_OK;
707 }
708
709 const MppDevApi vcodec_service_api = {
710 "vcodec_service",
711 sizeof(MppDevVcodecService),
712 vcodec_service_init,
713 vcodec_service_deinit,
714 NULL,
715 NULL,
716 NULL,
717 NULL,
718 vcodec_service_reg_wr,
719 vcodec_service_reg_rd,
720 vcodec_service_reg_offset,
721 NULL,
722 NULL,
723 vcodec_service_set_info,
724 NULL,
725 NULL,
726 NULL,
727 NULL,
728 NULL,
729 vcodec_service_cmd_send,
730 vcodec_service_cmd_poll,
731 };
732