xref: /rockchip-linux_mpp/osal/driver/vcodec_service.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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(&reg->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