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