xref: /rockchip-linux_mpp/mpp/legacy/vpu_api.cpp (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "vpu_api"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka #include <dlfcn.h>
21*437bfbebSnyanmisaka #include <unistd.h>
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_env.h"
25*437bfbebSnyanmisaka #include "mpp_debug.h"
26*437bfbebSnyanmisaka #include "mpp_common.h"
27*437bfbebSnyanmisaka #include "mpp_soc.h"
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka #include "vpu_api.h"
30*437bfbebSnyanmisaka #include "vpu_api_legacy.h"
31*437bfbebSnyanmisaka #include "vpu_mem_legacy.h"
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka static RK_S32
vpu_api_init(VpuCodecContext * ctx,RK_U8 * extraData,RK_U32 extra_size)34*437bfbebSnyanmisaka vpu_api_init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size)
35*437bfbebSnyanmisaka {
36*437bfbebSnyanmisaka     vpu_api_dbg_func("vpu_api_init in, extra_size: %d", extra_size);
37*437bfbebSnyanmisaka 
38*437bfbebSnyanmisaka     if (ctx == NULL) {
39*437bfbebSnyanmisaka         mpp_log("vpu_api_init fail, input invalid");
40*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
41*437bfbebSnyanmisaka     }
42*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
43*437bfbebSnyanmisaka     if (api == NULL) {
44*437bfbebSnyanmisaka         mpp_log("vpu_api_init fail, vpu api invalid");
45*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
46*437bfbebSnyanmisaka     }
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     return api->init(ctx, extraData, extra_size);
49*437bfbebSnyanmisaka }
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka static RK_S32
vpu_api_decode(VpuCodecContext * ctx,VideoPacket_t * pkt,DecoderOut_t * aDecOut)52*437bfbebSnyanmisaka vpu_api_decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut)
53*437bfbebSnyanmisaka {
54*437bfbebSnyanmisaka     if (ctx == NULL) {
55*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
56*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
57*437bfbebSnyanmisaka     }
58*437bfbebSnyanmisaka 
59*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
60*437bfbebSnyanmisaka     if (api == NULL) {
61*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, vpu api invalid");
62*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
63*437bfbebSnyanmisaka     }
64*437bfbebSnyanmisaka 
65*437bfbebSnyanmisaka     return api->decode(ctx, pkt, aDecOut);
66*437bfbebSnyanmisaka }
vpu_api_sendstream(VpuCodecContext * ctx,VideoPacket_t * pkt)67*437bfbebSnyanmisaka static RK_S32 vpu_api_sendstream(VpuCodecContext *ctx, VideoPacket_t *pkt)
68*437bfbebSnyanmisaka {
69*437bfbebSnyanmisaka     if (ctx == NULL) {
70*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
71*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
72*437bfbebSnyanmisaka     }
73*437bfbebSnyanmisaka 
74*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
75*437bfbebSnyanmisaka     if (api == NULL) {
76*437bfbebSnyanmisaka         mpp_log("vpu_api_sendstream fail, vpu api invalid");
77*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
78*437bfbebSnyanmisaka     }
79*437bfbebSnyanmisaka 
80*437bfbebSnyanmisaka     return api->decode_sendstream(pkt);
81*437bfbebSnyanmisaka }
82*437bfbebSnyanmisaka 
vpu_api_getframe(VpuCodecContext * ctx,DecoderOut_t * aDecOut)83*437bfbebSnyanmisaka static RK_S32 vpu_api_getframe(VpuCodecContext *ctx, DecoderOut_t *aDecOut)
84*437bfbebSnyanmisaka {
85*437bfbebSnyanmisaka     if (ctx == NULL) {
86*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
87*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
88*437bfbebSnyanmisaka     }
89*437bfbebSnyanmisaka 
90*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
91*437bfbebSnyanmisaka     if (api == NULL) {
92*437bfbebSnyanmisaka         mpp_log("vpu_api_getframe fail, vpu api invalid");
93*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
94*437bfbebSnyanmisaka     }
95*437bfbebSnyanmisaka 
96*437bfbebSnyanmisaka     return api->decode_getoutframe(ctx, aDecOut);
97*437bfbebSnyanmisaka }
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka static RK_S32
vpu_api_sendframe(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm)100*437bfbebSnyanmisaka vpu_api_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm)
101*437bfbebSnyanmisaka {
102*437bfbebSnyanmisaka     if (ctx == NULL) {
103*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
104*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
105*437bfbebSnyanmisaka     }
106*437bfbebSnyanmisaka 
107*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
108*437bfbebSnyanmisaka     if (api == NULL) {
109*437bfbebSnyanmisaka         mpp_log("vpu_api_sendframe fail, vpu api invalid");
110*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
111*437bfbebSnyanmisaka     }
112*437bfbebSnyanmisaka 
113*437bfbebSnyanmisaka     return api->encoder_sendframe(ctx, aEncInStrm);
114*437bfbebSnyanmisaka }
115*437bfbebSnyanmisaka 
vpu_api_getstream(VpuCodecContext * ctx,EncoderOut_t * aEncOut)116*437bfbebSnyanmisaka static RK_S32 vpu_api_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut)
117*437bfbebSnyanmisaka {
118*437bfbebSnyanmisaka     if (ctx == NULL) {
119*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
120*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
121*437bfbebSnyanmisaka     }
122*437bfbebSnyanmisaka 
123*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
124*437bfbebSnyanmisaka     if (api == NULL) {
125*437bfbebSnyanmisaka         mpp_log("vpu_api_getframe fail, vpu api invalid");
126*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
127*437bfbebSnyanmisaka     }
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     return api->encoder_getstream(ctx, aEncOut);
130*437bfbebSnyanmisaka }
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka static RK_S32
vpu_api_encode(VpuCodecContext * ctx,EncInputStream_t * aEncInStrm,EncoderOut_t * aEncOut)133*437bfbebSnyanmisaka vpu_api_encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm,
134*437bfbebSnyanmisaka                EncoderOut_t *aEncOut)
135*437bfbebSnyanmisaka {
136*437bfbebSnyanmisaka     if (ctx == NULL) {
137*437bfbebSnyanmisaka         mpp_log("vpu_api_encode fail, input invalid");
138*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
139*437bfbebSnyanmisaka     }
140*437bfbebSnyanmisaka 
141*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
142*437bfbebSnyanmisaka     if (api == NULL) {
143*437bfbebSnyanmisaka         mpp_log("vpu_api_encode fail, vpu api invalid");
144*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
145*437bfbebSnyanmisaka     }
146*437bfbebSnyanmisaka 
147*437bfbebSnyanmisaka     return api->encode(ctx, aEncInStrm, aEncOut);
148*437bfbebSnyanmisaka }
149*437bfbebSnyanmisaka 
vpu_api_flush(VpuCodecContext * ctx)150*437bfbebSnyanmisaka static RK_S32 vpu_api_flush(VpuCodecContext *ctx)
151*437bfbebSnyanmisaka {
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     if (ctx == NULL) {
154*437bfbebSnyanmisaka         mpp_log("vpu_api_encode fail, input invalid");
155*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
156*437bfbebSnyanmisaka     }
157*437bfbebSnyanmisaka 
158*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
159*437bfbebSnyanmisaka     if (api == NULL) {
160*437bfbebSnyanmisaka         mpp_log("vpu_api_flush fail, vpu api invalid");
161*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
162*437bfbebSnyanmisaka     }
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka     return api->flush(ctx);
165*437bfbebSnyanmisaka }
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka static RK_S32
vpu_api_control(VpuCodecContext * ctx,VPU_API_CMD cmdType,void * param)168*437bfbebSnyanmisaka vpu_api_control(VpuCodecContext *ctx, VPU_API_CMD cmdType, void *param)
169*437bfbebSnyanmisaka {
170*437bfbebSnyanmisaka     if (ctx == NULL) {
171*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, input invalid");
172*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
173*437bfbebSnyanmisaka     }
174*437bfbebSnyanmisaka 
175*437bfbebSnyanmisaka     VpuApiLegacy* api = (VpuApiLegacy*)(ctx->vpuApiObj);
176*437bfbebSnyanmisaka     if (api == NULL) {
177*437bfbebSnyanmisaka         mpp_log("vpu_api_decode fail, vpu api invalid");
178*437bfbebSnyanmisaka         return VPU_API_ERR_UNKNOW;
179*437bfbebSnyanmisaka     }
180*437bfbebSnyanmisaka 
181*437bfbebSnyanmisaka     vpu_api_dbg_func("enter\n");
182*437bfbebSnyanmisaka     switch (cmdType) {
183*437bfbebSnyanmisaka     case VPU_API_SET_VPUMEM_CONTEXT: {
184*437bfbebSnyanmisaka         vpu_display_mem_pool_impl *p_mempool =
185*437bfbebSnyanmisaka             (vpu_display_mem_pool_impl *)param;
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka         param = (void*)p_mempool->group;
188*437bfbebSnyanmisaka         break;
189*437bfbebSnyanmisaka     }
190*437bfbebSnyanmisaka     default: {
191*437bfbebSnyanmisaka         break;
192*437bfbebSnyanmisaka     }
193*437bfbebSnyanmisaka     }
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     vpu_api_dbg_func("pass to mpi\n");
196*437bfbebSnyanmisaka     return api->control(ctx, cmdType, param);
197*437bfbebSnyanmisaka }
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka static const char *codec_paths[] = {
200*437bfbebSnyanmisaka     "/vendor/lib/librk_vpuapi.so",
201*437bfbebSnyanmisaka     "/system/lib/librk_vpuapi.so",
202*437bfbebSnyanmisaka     "/system/lib/librk_on2.so",
203*437bfbebSnyanmisaka     "/usr/lib/librk_codec.so",
204*437bfbebSnyanmisaka };
205*437bfbebSnyanmisaka 
206*437bfbebSnyanmisaka class VpulibDlsym
207*437bfbebSnyanmisaka {
208*437bfbebSnyanmisaka public:
209*437bfbebSnyanmisaka     void *rkapi_hdl;
210*437bfbebSnyanmisaka     RK_S32 (*rkvpu_open_cxt)(VpuCodecContext **ctx);
211*437bfbebSnyanmisaka     RK_S32 (*rkvpu_close_cxt)(VpuCodecContext **ctx);
VpulibDlsym()212*437bfbebSnyanmisaka     VpulibDlsym() :
213*437bfbebSnyanmisaka         rkapi_hdl(NULL),
214*437bfbebSnyanmisaka         rkvpu_open_cxt(NULL),
215*437bfbebSnyanmisaka         rkvpu_close_cxt(NULL) {
216*437bfbebSnyanmisaka         RK_U32 i;
217*437bfbebSnyanmisaka 
218*437bfbebSnyanmisaka         for (i = 0; i < MPP_ARRAY_ELEMS(codec_paths); i++) {
219*437bfbebSnyanmisaka             rkapi_hdl = dlopen(codec_paths[i], RTLD_LAZY | RTLD_GLOBAL);
220*437bfbebSnyanmisaka             if (rkapi_hdl)
221*437bfbebSnyanmisaka                 break;
222*437bfbebSnyanmisaka         }
223*437bfbebSnyanmisaka 
224*437bfbebSnyanmisaka         if (rkapi_hdl) {
225*437bfbebSnyanmisaka             rkvpu_open_cxt  = (RK_S32 (*)(VpuCodecContext **ctx))
226*437bfbebSnyanmisaka                               dlsym(rkapi_hdl, "vpu_open_context");
227*437bfbebSnyanmisaka             rkvpu_close_cxt = (RK_S32 (*)(VpuCodecContext **ctx))
228*437bfbebSnyanmisaka                               dlsym(rkapi_hdl, "vpu_close_context");
229*437bfbebSnyanmisaka             mpp_log("dlopen vpu lib %s success\n", codec_paths[i]);
230*437bfbebSnyanmisaka         }
231*437bfbebSnyanmisaka     }
232*437bfbebSnyanmisaka 
~VpulibDlsym()233*437bfbebSnyanmisaka     ~VpulibDlsym() {
234*437bfbebSnyanmisaka         if (rkapi_hdl) {
235*437bfbebSnyanmisaka             dlclose(rkapi_hdl);
236*437bfbebSnyanmisaka             rkapi_hdl = NULL;
237*437bfbebSnyanmisaka         }
238*437bfbebSnyanmisaka     }
239*437bfbebSnyanmisaka };
240*437bfbebSnyanmisaka 
241*437bfbebSnyanmisaka static VpulibDlsym gVpulib;
242*437bfbebSnyanmisaka 
check_orign_vpu()243*437bfbebSnyanmisaka static RK_S32 check_orign_vpu()
244*437bfbebSnyanmisaka {
245*437bfbebSnyanmisaka     return (gVpulib.rkapi_hdl) ? (MPP_OK) : (MPP_NOK);
246*437bfbebSnyanmisaka }
247*437bfbebSnyanmisaka 
open_orign_vpu(VpuCodecContext ** ctx)248*437bfbebSnyanmisaka static RK_S32 open_orign_vpu(VpuCodecContext **ctx)
249*437bfbebSnyanmisaka {
250*437bfbebSnyanmisaka     if (gVpulib.rkvpu_open_cxt && ctx) {
251*437bfbebSnyanmisaka         return (gVpulib.rkvpu_open_cxt)(ctx);
252*437bfbebSnyanmisaka     }
253*437bfbebSnyanmisaka     return MPP_NOK;
254*437bfbebSnyanmisaka }
255*437bfbebSnyanmisaka 
close_orign_vpu(VpuCodecContext ** ctx)256*437bfbebSnyanmisaka static RK_S32 close_orign_vpu(VpuCodecContext **ctx)
257*437bfbebSnyanmisaka {
258*437bfbebSnyanmisaka     if (gVpulib.rkvpu_close_cxt && ctx) {
259*437bfbebSnyanmisaka         return (gVpulib.rkvpu_close_cxt)(ctx);
260*437bfbebSnyanmisaka     }
261*437bfbebSnyanmisaka     return MPP_NOK;
262*437bfbebSnyanmisaka }
263*437bfbebSnyanmisaka 
264*437bfbebSnyanmisaka /*
265*437bfbebSnyanmisaka  * old libvpu path will input a NULL pointer in *ctx
266*437bfbebSnyanmisaka  * new libvpu path will input non-NULL pointer in *ctx
267*437bfbebSnyanmisaka  */
vpu_open_context(VpuCodecContext ** ctx)268*437bfbebSnyanmisaka RK_S32 vpu_open_context(VpuCodecContext **ctx)
269*437bfbebSnyanmisaka {
270*437bfbebSnyanmisaka     VpuCodecContext *s = *ctx;
271*437bfbebSnyanmisaka     RK_S32 ret = -1;
272*437bfbebSnyanmisaka     RK_U32 force_original = 0;
273*437bfbebSnyanmisaka     RK_U32 force_mpp_mode = 0;
274*437bfbebSnyanmisaka     RK_U32 use_mpp = 0;
275*437bfbebSnyanmisaka 
276*437bfbebSnyanmisaka     CODEC_TYPE codecType = CODEC_NONE;
277*437bfbebSnyanmisaka     OMX_RK_VIDEO_CODINGTYPE videoCoding = OMX_RK_VIDEO_CodingUnused;
278*437bfbebSnyanmisaka     RK_U32 width = 0;
279*437bfbebSnyanmisaka     RK_U32 height = 0;
280*437bfbebSnyanmisaka     void  *extradata = NULL;
281*437bfbebSnyanmisaka     RK_S32 extradata_size = 0;
282*437bfbebSnyanmisaka     EXtraCfg_t extra_cfg;
283*437bfbebSnyanmisaka     memset(&extra_cfg, 0, sizeof(EXtraCfg_t));
284*437bfbebSnyanmisaka 
285*437bfbebSnyanmisaka     mpp_env_get_u32("vpu_api_debug", &vpu_api_debug, 0);
286*437bfbebSnyanmisaka     vpu_api_dbg_func("enter\n");
287*437bfbebSnyanmisaka 
288*437bfbebSnyanmisaka     mpp_env_get_u32("use_original", &force_original, 0);
289*437bfbebSnyanmisaka     mpp_env_get_u32("use_mpp_mode", &force_mpp_mode, 0);
290*437bfbebSnyanmisaka 
291*437bfbebSnyanmisaka     /* if there is no original vpuapi library force to mpp path */
292*437bfbebSnyanmisaka     if (check_orign_vpu())
293*437bfbebSnyanmisaka         force_mpp_mode = 1;
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka     if (force_original) {
296*437bfbebSnyanmisaka         /* force mpp mode here */
297*437bfbebSnyanmisaka         use_mpp = 0;
298*437bfbebSnyanmisaka     } else if (force_mpp_mode) {
299*437bfbebSnyanmisaka         /* force mpp mode here */
300*437bfbebSnyanmisaka         use_mpp = 1;
301*437bfbebSnyanmisaka     } else if (!access("/dev/mpp_service", F_OK)) {
302*437bfbebSnyanmisaka         /* if mpp_service exist, force mpp mode */
303*437bfbebSnyanmisaka         use_mpp = 1;
304*437bfbebSnyanmisaka     } else if (!!access("/dev/rkvdec", F_OK)) {
305*437bfbebSnyanmisaka         /* if there is no rkvdec it means the platform must be vpu1 */
306*437bfbebSnyanmisaka         if (s && s->videoCoding == OMX_RK_VIDEO_CodingHEVC &&
307*437bfbebSnyanmisaka             (!access("/dev/hevc-service", F_OK)
308*437bfbebSnyanmisaka              || !access("/dev/hevc_service", F_OK))) {
309*437bfbebSnyanmisaka             /* if this is a hevc request and exist hevc_service for decoding use mpp */
310*437bfbebSnyanmisaka             use_mpp = 1;
311*437bfbebSnyanmisaka         } else {
312*437bfbebSnyanmisaka             /* otherwise use original vpuapi path */
313*437bfbebSnyanmisaka             use_mpp = 0;
314*437bfbebSnyanmisaka         }
315*437bfbebSnyanmisaka     } else if (NULL == s) {
316*437bfbebSnyanmisaka         /* caller is original vpuapi path. Force use original vpuapi path */
317*437bfbebSnyanmisaka         use_mpp = 0;
318*437bfbebSnyanmisaka     } else {
319*437bfbebSnyanmisaka         if (s->videoCoding == OMX_RK_VIDEO_CodingAVC
320*437bfbebSnyanmisaka             && s->codecType == CODEC_DECODER && s->width <= 1920
321*437bfbebSnyanmisaka             && s->height <= 1088 && !s->extra_cfg.mpp_mode
322*437bfbebSnyanmisaka             && mpp_get_soc_type() != ROCKCHIP_SOC_RK3399) {
323*437bfbebSnyanmisaka             /* H.264 smaller than 1080p use original vpuapi library for better error process */
324*437bfbebSnyanmisaka             // NOTE: rk3399 need better performance
325*437bfbebSnyanmisaka             use_mpp = 0;
326*437bfbebSnyanmisaka         } else {
327*437bfbebSnyanmisaka             MppCtxType type = (s->codecType == CODEC_DECODER) ? (MPP_CTX_DEC) :
328*437bfbebSnyanmisaka                               (s->codecType == CODEC_ENCODER)
329*437bfbebSnyanmisaka                               ? (MPP_CTX_ENC) : (MPP_CTX_BUTT);
330*437bfbebSnyanmisaka             MppCodingType coding = (MppCodingType)s->videoCoding;
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka             if (MPP_OK == mpp_check_support_format(type, coding)) {
333*437bfbebSnyanmisaka                 /* If current mpp can support this format use mpp */
334*437bfbebSnyanmisaka                 use_mpp = 1;
335*437bfbebSnyanmisaka             } else {
336*437bfbebSnyanmisaka                 /* unsupport format use vpuapi library */
337*437bfbebSnyanmisaka                 use_mpp = 0;
338*437bfbebSnyanmisaka             }
339*437bfbebSnyanmisaka         }
340*437bfbebSnyanmisaka     }
341*437bfbebSnyanmisaka 
342*437bfbebSnyanmisaka     /*
343*437bfbebSnyanmisaka      * No matter what is the old context just release it.
344*437bfbebSnyanmisaka      * But we need to save to pre-configured parameter
345*437bfbebSnyanmisaka      */
346*437bfbebSnyanmisaka     if (s) {
347*437bfbebSnyanmisaka         codecType       = s->codecType;
348*437bfbebSnyanmisaka         videoCoding     = s->videoCoding;
349*437bfbebSnyanmisaka         width           = s->width;
350*437bfbebSnyanmisaka         height          = s->height;
351*437bfbebSnyanmisaka         extradata       = s->extradata;
352*437bfbebSnyanmisaka         extradata_size  = s->extradata_size;
353*437bfbebSnyanmisaka         extra_cfg       = s->extra_cfg;
354*437bfbebSnyanmisaka 
355*437bfbebSnyanmisaka         free(s);
356*437bfbebSnyanmisaka         s = NULL;
357*437bfbebSnyanmisaka     }
358*437bfbebSnyanmisaka 
359*437bfbebSnyanmisaka     if (!use_mpp) {
360*437bfbebSnyanmisaka         vpu_api_dbg_func("use vpuapi path\n");
361*437bfbebSnyanmisaka 
362*437bfbebSnyanmisaka         ret = open_orign_vpu(&s);
363*437bfbebSnyanmisaka         if (!ret && s) {
364*437bfbebSnyanmisaka             // for safety
365*437bfbebSnyanmisaka             s->extra_cfg.ori_vpu = 1;
366*437bfbebSnyanmisaka             extra_cfg.ori_vpu = 1;
367*437bfbebSnyanmisaka         }
368*437bfbebSnyanmisaka     } else {
369*437bfbebSnyanmisaka         vpu_api_dbg_func("use mpp path\n");
370*437bfbebSnyanmisaka 
371*437bfbebSnyanmisaka         s = mpp_calloc(VpuCodecContext, 1);
372*437bfbebSnyanmisaka         if (s) {
373*437bfbebSnyanmisaka             s->enableparsing = 1;
374*437bfbebSnyanmisaka 
375*437bfbebSnyanmisaka             VpuApiLegacy* api = new VpuApiLegacy();
376*437bfbebSnyanmisaka 
377*437bfbebSnyanmisaka             if (api) {
378*437bfbebSnyanmisaka                 s->vpuApiObj = (void*)api;
379*437bfbebSnyanmisaka                 s->init = vpu_api_init;
380*437bfbebSnyanmisaka                 s->decode = vpu_api_decode;
381*437bfbebSnyanmisaka                 s->encode = vpu_api_encode;
382*437bfbebSnyanmisaka                 s->flush = vpu_api_flush;
383*437bfbebSnyanmisaka                 s->control = vpu_api_control;
384*437bfbebSnyanmisaka                 s->decode_sendstream = vpu_api_sendstream;
385*437bfbebSnyanmisaka                 s->decode_getframe = vpu_api_getframe;
386*437bfbebSnyanmisaka                 s->encoder_sendframe = vpu_api_sendframe;
387*437bfbebSnyanmisaka                 s->encoder_getstream = vpu_api_getstream;
388*437bfbebSnyanmisaka 
389*437bfbebSnyanmisaka                 s->extra_cfg.ori_vpu = 0;
390*437bfbebSnyanmisaka                 extra_cfg.ori_vpu = 0;
391*437bfbebSnyanmisaka 
392*437bfbebSnyanmisaka                 ret = 0;
393*437bfbebSnyanmisaka             } else {
394*437bfbebSnyanmisaka                 mpp_err("Vpu api object has not been properly allocated");
395*437bfbebSnyanmisaka                 mpp_free(s);
396*437bfbebSnyanmisaka                 s = NULL;
397*437bfbebSnyanmisaka             }
398*437bfbebSnyanmisaka         } else {
399*437bfbebSnyanmisaka             mpp_err("Input context has not been properly allocated");
400*437bfbebSnyanmisaka         }
401*437bfbebSnyanmisaka     }
402*437bfbebSnyanmisaka 
403*437bfbebSnyanmisaka     if (s) {
404*437bfbebSnyanmisaka         s->codecType        = codecType;
405*437bfbebSnyanmisaka         s->videoCoding      = videoCoding;
406*437bfbebSnyanmisaka         s->width            = width;
407*437bfbebSnyanmisaka         s->height           = height;
408*437bfbebSnyanmisaka         s->extradata        = extradata;
409*437bfbebSnyanmisaka         s->extradata_size   = extradata_size;
410*437bfbebSnyanmisaka         s->extra_cfg        = extra_cfg;
411*437bfbebSnyanmisaka     }
412*437bfbebSnyanmisaka     *ctx = s;
413*437bfbebSnyanmisaka 
414*437bfbebSnyanmisaka     vpu_api_dbg_func("leave\n");
415*437bfbebSnyanmisaka     return ret;
416*437bfbebSnyanmisaka }
417*437bfbebSnyanmisaka 
vpu_close_context(VpuCodecContext ** ctx)418*437bfbebSnyanmisaka RK_S32 vpu_close_context(VpuCodecContext **ctx)
419*437bfbebSnyanmisaka {
420*437bfbebSnyanmisaka     vpu_api_dbg_func("enter\n");
421*437bfbebSnyanmisaka     VpuCodecContext *s = *ctx;
422*437bfbebSnyanmisaka     RK_S32 ret = -1;
423*437bfbebSnyanmisaka     RK_U32 force_original = 0;
424*437bfbebSnyanmisaka 
425*437bfbebSnyanmisaka     mpp_env_get_u32("force_original", &force_original, 0);
426*437bfbebSnyanmisaka 
427*437bfbebSnyanmisaka     if (s) {
428*437bfbebSnyanmisaka         if (s->extra_cfg.ori_vpu) {
429*437bfbebSnyanmisaka             ret = close_orign_vpu(ctx);
430*437bfbebSnyanmisaka             mpp_log("org vpu_close_context ok");
431*437bfbebSnyanmisaka         } else {
432*437bfbebSnyanmisaka             if (s->flush)
433*437bfbebSnyanmisaka                 s->flush(s);
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka             VpuApiLegacy* api = (VpuApiLegacy*)(s->vpuApiObj);
436*437bfbebSnyanmisaka             if (s->vpuApiObj) {
437*437bfbebSnyanmisaka                 delete api;
438*437bfbebSnyanmisaka                 s->vpuApiObj = NULL;
439*437bfbebSnyanmisaka             }
440*437bfbebSnyanmisaka 
441*437bfbebSnyanmisaka             if (s->extradata_size > 0) {
442*437bfbebSnyanmisaka                 s->extradata_size = 0;
443*437bfbebSnyanmisaka                 s->extradata = NULL;
444*437bfbebSnyanmisaka             }
445*437bfbebSnyanmisaka 
446*437bfbebSnyanmisaka             if (s->private_data)
447*437bfbebSnyanmisaka                 mpp_free(s->private_data);
448*437bfbebSnyanmisaka 
449*437bfbebSnyanmisaka             mpp_free(s);
450*437bfbebSnyanmisaka             ret = 0;
451*437bfbebSnyanmisaka         }
452*437bfbebSnyanmisaka 
453*437bfbebSnyanmisaka         *ctx = s = NULL;
454*437bfbebSnyanmisaka     }
455*437bfbebSnyanmisaka 
456*437bfbebSnyanmisaka     vpu_api_dbg_func("leave\n");
457*437bfbebSnyanmisaka 
458*437bfbebSnyanmisaka     return ret;
459*437bfbebSnyanmisaka }
460