xref: /rockchip-linux_mpp/mpp/legacy/vpu_api_mlvec.cpp (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2020 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_mlvec"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include "string.h"
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_mem.h"
22*437bfbebSnyanmisaka #include "mpp_debug.h"
23*437bfbebSnyanmisaka #include "mpp_common.h"
24*437bfbebSnyanmisaka 
25*437bfbebSnyanmisaka #include "vpu_api_mlvec.h"
26*437bfbebSnyanmisaka #include "vpu_api_legacy.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka #define VPU_API_DBG_MLVEC_FUNC      (0x00010000)
29*437bfbebSnyanmisaka #define VPU_API_DBG_MLVEC_FLOW      (0x00020000)
30*437bfbebSnyanmisaka 
31*437bfbebSnyanmisaka #define mlvec_dbg_func(fmt, ...)    vpu_api_dbg_f(VPU_API_DBG_MLVEC_FUNC, fmt, ## __VA_ARGS__)
32*437bfbebSnyanmisaka #define mlvec_dbg_flow(fmt, ...)    vpu_api_dbg_f(VPU_API_DBG_MLVEC_FLOW, fmt, ## __VA_ARGS__)
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka typedef struct VpuApiMlvecImpl_t {
35*437bfbebSnyanmisaka     MppCtx      mpp;
36*437bfbebSnyanmisaka     MppApi      *mpi;
37*437bfbebSnyanmisaka     MppEncCfg   enc_cfg;
38*437bfbebSnyanmisaka 
39*437bfbebSnyanmisaka     VpuApiMlvecStaticCfg    st_cfg;
40*437bfbebSnyanmisaka     VpuApiMlvecDynamicCfg   dy_cfg;
41*437bfbebSnyanmisaka } VpuApiMlvecImpl;
42*437bfbebSnyanmisaka 
vpu_api_mlvec_init(VpuApiMlvec * ctx)43*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_init(VpuApiMlvec *ctx)
44*437bfbebSnyanmisaka {
45*437bfbebSnyanmisaka     if (NULL == ctx) {
46*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
47*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
48*437bfbebSnyanmisaka     }
49*437bfbebSnyanmisaka 
50*437bfbebSnyanmisaka     mlvec_dbg_func("enter %p\n", ctx);
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     VpuApiMlvecImpl *impl = mpp_calloc(VpuApiMlvecImpl, 1);
53*437bfbebSnyanmisaka     if (NULL == impl)
54*437bfbebSnyanmisaka         mpp_err_f("failed to create MLVEC context\n");
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     mpp_assert(sizeof(VpuApiMlvecStaticCfg) == sizeof(EncParameter_t));
57*437bfbebSnyanmisaka     /* default disable frame_qp setup */
58*437bfbebSnyanmisaka     impl->dy_cfg.frame_qp = -1;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     *ctx = impl;
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     mlvec_dbg_func("leave %p %p\n", ctx, impl);
63*437bfbebSnyanmisaka     return (impl) ? (MPP_OK) : (MPP_NOK);
64*437bfbebSnyanmisaka }
65*437bfbebSnyanmisaka 
vpu_api_mlvec_deinit(VpuApiMlvec ctx)66*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_deinit(VpuApiMlvec ctx)
67*437bfbebSnyanmisaka {
68*437bfbebSnyanmisaka     mlvec_dbg_func("enter %p\n", ctx);
69*437bfbebSnyanmisaka     MPP_FREE(ctx);
70*437bfbebSnyanmisaka     mlvec_dbg_func("leave %p\n", ctx);
71*437bfbebSnyanmisaka     return MPP_OK;
72*437bfbebSnyanmisaka }
73*437bfbebSnyanmisaka 
vpu_api_mlvec_setup(VpuApiMlvec ctx,MppCtx mpp,MppApi * mpi,MppEncCfg enc_cfg)74*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_setup(VpuApiMlvec ctx, MppCtx mpp, MppApi *mpi, MppEncCfg enc_cfg)
75*437bfbebSnyanmisaka {
76*437bfbebSnyanmisaka     if (NULL == ctx || NULL == mpp || NULL == mpi || NULL == enc_cfg) {
77*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input ctx %p mpp %p mpi %p cfg %p\n",
78*437bfbebSnyanmisaka                   ctx, mpp, mpi, enc_cfg);
79*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
80*437bfbebSnyanmisaka     }
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka     mlvec_dbg_func("enter %p\n", ctx);
83*437bfbebSnyanmisaka 
84*437bfbebSnyanmisaka     VpuApiMlvecImpl *impl = (VpuApiMlvecImpl *)ctx;
85*437bfbebSnyanmisaka     impl->mpp = mpp;
86*437bfbebSnyanmisaka     impl->mpi = mpi;
87*437bfbebSnyanmisaka     impl->enc_cfg = enc_cfg;
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka     mlvec_dbg_func("leave %p\n", ctx);
90*437bfbebSnyanmisaka 
91*437bfbebSnyanmisaka     return MPP_OK;
92*437bfbebSnyanmisaka }
93*437bfbebSnyanmisaka 
vpu_api_mlvec_check_cfg(void * p)94*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_check_cfg(void *p)
95*437bfbebSnyanmisaka {
96*437bfbebSnyanmisaka     if (NULL == p) {
97*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
98*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
99*437bfbebSnyanmisaka     }
100*437bfbebSnyanmisaka 
101*437bfbebSnyanmisaka     VpuApiMlvecStaticCfg *cfg = (VpuApiMlvecStaticCfg *)p;
102*437bfbebSnyanmisaka     RK_U32 magic = cfg->magic;
103*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
104*437bfbebSnyanmisaka 
105*437bfbebSnyanmisaka     if ((((magic >> 24) & 0xff) != MLVEC_MAGIC) ||
106*437bfbebSnyanmisaka         (((magic >> 16) & 0xff) != MLVEC_VERSION))
107*437bfbebSnyanmisaka         ret = MPP_NOK;
108*437bfbebSnyanmisaka 
109*437bfbebSnyanmisaka     mlvec_dbg_flow("check mlvec cfg magic %08x %s\n", magic,
110*437bfbebSnyanmisaka                    (ret == MPP_OK) ? "success" : "failed");
111*437bfbebSnyanmisaka 
112*437bfbebSnyanmisaka     return ret;
113*437bfbebSnyanmisaka }
114*437bfbebSnyanmisaka 
vpu_api_mlvec_set_st_cfg(VpuApiMlvec ctx,VpuApiMlvecStaticCfg * cfg)115*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_set_st_cfg(VpuApiMlvec ctx, VpuApiMlvecStaticCfg *cfg)
116*437bfbebSnyanmisaka {
117*437bfbebSnyanmisaka     if (NULL == ctx || NULL == cfg) {
118*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input ctx %p cfg %p\n");
119*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
120*437bfbebSnyanmisaka     }
121*437bfbebSnyanmisaka 
122*437bfbebSnyanmisaka     mlvec_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
123*437bfbebSnyanmisaka 
124*437bfbebSnyanmisaka     /* check mlvec magic word */
125*437bfbebSnyanmisaka     if (vpu_api_mlvec_check_cfg(cfg))
126*437bfbebSnyanmisaka         return MPP_NOK;
127*437bfbebSnyanmisaka 
128*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
129*437bfbebSnyanmisaka     /* update static configure */
130*437bfbebSnyanmisaka     VpuApiMlvecImpl *impl = (VpuApiMlvecImpl *)ctx;
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka     memcpy(&impl->st_cfg, cfg, sizeof(impl->st_cfg));
133*437bfbebSnyanmisaka     cfg = &impl->st_cfg;
134*437bfbebSnyanmisaka 
135*437bfbebSnyanmisaka     /* get mpp context and check */
136*437bfbebSnyanmisaka     MppCtx mpp_ctx = impl->mpp;
137*437bfbebSnyanmisaka     MppApi *mpi = impl->mpi;
138*437bfbebSnyanmisaka     MppEncCfg enc_cfg = impl->enc_cfg;
139*437bfbebSnyanmisaka 
140*437bfbebSnyanmisaka     mpp_assert(mpp_ctx);
141*437bfbebSnyanmisaka     mpp_assert(mpi);
142*437bfbebSnyanmisaka     mpp_assert(enc_cfg);
143*437bfbebSnyanmisaka 
144*437bfbebSnyanmisaka     /* start control mpp */
145*437bfbebSnyanmisaka     mlvec_dbg_flow("hdr_on_idr %d\n", cfg->hdr_on_idr);
146*437bfbebSnyanmisaka     MppEncHeaderMode mode = cfg->hdr_on_idr ?
147*437bfbebSnyanmisaka                             MPP_ENC_HEADER_MODE_EACH_IDR :
148*437bfbebSnyanmisaka                             MPP_ENC_HEADER_MODE_DEFAULT;
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     ret = mpi->control(mpp_ctx, MPP_ENC_SET_HEADER_MODE, &mode);
151*437bfbebSnyanmisaka     if (ret)
152*437bfbebSnyanmisaka         mpp_err("setup enc header mode %d failed ret %d\n", mode, ret);
153*437bfbebSnyanmisaka 
154*437bfbebSnyanmisaka     mlvec_dbg_flow("add_prefix %d\n", cfg->add_prefix);
155*437bfbebSnyanmisaka     mpp_enc_cfg_set_s32(enc_cfg, "h264:prefix_mode", cfg->add_prefix);
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka     mlvec_dbg_flow("slice_mbs  %d\n", cfg->slice_mbs);
158*437bfbebSnyanmisaka     if (cfg->slice_mbs) {
159*437bfbebSnyanmisaka         mpp_enc_cfg_set_u32(enc_cfg, "split:mode", MPP_ENC_SPLIT_BY_CTU);
160*437bfbebSnyanmisaka         mpp_enc_cfg_set_u32(enc_cfg, "split:arg", cfg->slice_mbs);
161*437bfbebSnyanmisaka     } else
162*437bfbebSnyanmisaka         mpp_enc_cfg_set_u32(enc_cfg, "split:mode", MPP_ENC_SPLIT_NONE);
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka     /* NOTE: ltr_frames is already configured */
165*437bfbebSnyanmisaka     vpu_api_mlvec_set_dy_max_tid(ctx, cfg->max_tid);
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     mlvec_dbg_func("leave ctx %p ret %d\n", ctx, ret);
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka     return ret;
170*437bfbebSnyanmisaka }
171*437bfbebSnyanmisaka 
vpu_api_mlvec_set_dy_cfg(VpuApiMlvec ctx,VpuApiMlvecDynamicCfg * cfg,MppMeta meta)172*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_set_dy_cfg(VpuApiMlvec ctx, VpuApiMlvecDynamicCfg *cfg, MppMeta meta)
173*437bfbebSnyanmisaka {
174*437bfbebSnyanmisaka     if (NULL == ctx || NULL == cfg || NULL == meta) {
175*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input ctx %p cfg %p meta %p\n",
176*437bfbebSnyanmisaka                   ctx, cfg, meta);
177*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
178*437bfbebSnyanmisaka     }
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka     mlvec_dbg_func("enter ctx %p cfg %p meta %p\n", ctx, cfg, meta);
181*437bfbebSnyanmisaka 
182*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
183*437bfbebSnyanmisaka     VpuApiMlvecImpl *impl = (VpuApiMlvecImpl *)ctx;
184*437bfbebSnyanmisaka     VpuApiMlvecDynamicCfg *dst = &impl->dy_cfg;
185*437bfbebSnyanmisaka 
186*437bfbebSnyanmisaka     /* clear non-sticky flag first */
187*437bfbebSnyanmisaka     dst->mark_ltr   = -1;
188*437bfbebSnyanmisaka     dst->use_ltr    = -1;
189*437bfbebSnyanmisaka     /* frame qp and base layer pid is sticky flag */
190*437bfbebSnyanmisaka 
191*437bfbebSnyanmisaka     /* update flags */
192*437bfbebSnyanmisaka     if (cfg->updated) {
193*437bfbebSnyanmisaka         if (cfg->updated & VPU_API_ENC_MARK_LTR_UPDATED)
194*437bfbebSnyanmisaka             dst->mark_ltr = cfg->mark_ltr;
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka         if (cfg->updated & VPU_API_ENC_USE_LTR_UPDATED)
197*437bfbebSnyanmisaka             dst->use_ltr = cfg->use_ltr;
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka         if (cfg->updated & VPU_API_ENC_FRAME_QP_UPDATED)
200*437bfbebSnyanmisaka             dst->frame_qp = cfg->frame_qp;
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka         if (cfg->updated & VPU_API_ENC_BASE_PID_UPDATED)
203*437bfbebSnyanmisaka             dst->base_layer_pid = cfg->base_layer_pid;
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka         /* dynamic max temporal layer count updated go through mpp ref cfg */
206*437bfbebSnyanmisaka         cfg->updated = 0;
207*437bfbebSnyanmisaka     }
208*437bfbebSnyanmisaka 
209*437bfbebSnyanmisaka     mlvec_dbg_flow("ltr mark %2d use %2d frm qp %2d blpid %d\n", dst->mark_ltr,
210*437bfbebSnyanmisaka                    dst->use_ltr, dst->frame_qp, dst->base_layer_pid);
211*437bfbebSnyanmisaka 
212*437bfbebSnyanmisaka     /* setup next frame configure */
213*437bfbebSnyanmisaka     if (dst->mark_ltr >= 0)
214*437bfbebSnyanmisaka         mpp_meta_set_s32(meta, KEY_ENC_MARK_LTR, dst->mark_ltr);
215*437bfbebSnyanmisaka 
216*437bfbebSnyanmisaka     if (dst->use_ltr >= 0)
217*437bfbebSnyanmisaka         mpp_meta_set_s32(meta, KEY_ENC_USE_LTR, dst->use_ltr);
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka     if (dst->frame_qp >= 0)
220*437bfbebSnyanmisaka         mpp_meta_set_s32(meta, KEY_ENC_FRAME_QP, dst->frame_qp);
221*437bfbebSnyanmisaka 
222*437bfbebSnyanmisaka     if (dst->base_layer_pid >= 0)
223*437bfbebSnyanmisaka         mpp_meta_set_s32(meta, KEY_ENC_BASE_LAYER_PID, dst->base_layer_pid);
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka     mlvec_dbg_func("leave ctx %p ret %d\n", ctx, ret);
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka     return ret;
228*437bfbebSnyanmisaka }
229*437bfbebSnyanmisaka 
vpu_api_mlvec_set_dy_max_tid(VpuApiMlvec ctx,RK_S32 max_tid)230*437bfbebSnyanmisaka MPP_RET vpu_api_mlvec_set_dy_max_tid(VpuApiMlvec ctx, RK_S32 max_tid)
231*437bfbebSnyanmisaka {
232*437bfbebSnyanmisaka     if (NULL == ctx) {
233*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
234*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
235*437bfbebSnyanmisaka     }
236*437bfbebSnyanmisaka 
237*437bfbebSnyanmisaka     mlvec_dbg_func("enter ctx %p max_tid %d\n", ctx, max_tid);
238*437bfbebSnyanmisaka 
239*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
240*437bfbebSnyanmisaka     VpuApiMlvecImpl *impl = (VpuApiMlvecImpl *)ctx;
241*437bfbebSnyanmisaka     MppCtx mpp_ctx = impl->mpp;
242*437bfbebSnyanmisaka     MppApi *mpi = impl->mpi;
243*437bfbebSnyanmisaka     MppEncCfg enc_cfg = impl->enc_cfg;
244*437bfbebSnyanmisaka 
245*437bfbebSnyanmisaka     mpp_assert(mpp_ctx);
246*437bfbebSnyanmisaka     mpp_assert(mpi);
247*437bfbebSnyanmisaka     mpp_assert(enc_cfg);
248*437bfbebSnyanmisaka 
249*437bfbebSnyanmisaka     MppEncRefLtFrmCfg lt_ref[16];
250*437bfbebSnyanmisaka     MppEncRefStFrmCfg st_ref[16];
251*437bfbebSnyanmisaka     RK_S32 lt_cfg_cnt = 0;
252*437bfbebSnyanmisaka     RK_S32 st_cfg_cnt = 0;
253*437bfbebSnyanmisaka     RK_S32 tid0_loop = 0;
254*437bfbebSnyanmisaka     RK_S32 ltr_frames = impl->st_cfg.ltr_frames;
255*437bfbebSnyanmisaka 
256*437bfbebSnyanmisaka     memset(lt_ref, 0, sizeof(lt_ref));
257*437bfbebSnyanmisaka     memset(st_ref, 0, sizeof(st_ref));
258*437bfbebSnyanmisaka 
259*437bfbebSnyanmisaka     mlvec_dbg_flow("ltr_frames %d\n", ltr_frames);
260*437bfbebSnyanmisaka     mlvec_dbg_flow("max_tid    %d\n", max_tid);
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka     switch (max_tid) {
263*437bfbebSnyanmisaka     case 0 : {
264*437bfbebSnyanmisaka         st_ref[0].is_non_ref    = 0;
265*437bfbebSnyanmisaka         st_ref[0].temporal_id   = 0;
266*437bfbebSnyanmisaka         st_ref[0].ref_mode      = REF_TO_PREV_REF_FRM;
267*437bfbebSnyanmisaka         st_ref[0].ref_arg       = 0;
268*437bfbebSnyanmisaka         st_ref[0].repeat        = 0;
269*437bfbebSnyanmisaka 
270*437bfbebSnyanmisaka         st_cfg_cnt = 1;
271*437bfbebSnyanmisaka         tid0_loop = 1;
272*437bfbebSnyanmisaka         mlvec_dbg_flow("no tsvc\n");
273*437bfbebSnyanmisaka     } break;
274*437bfbebSnyanmisaka     case 1 : {
275*437bfbebSnyanmisaka         /* set tsvc2 st-ref struct */
276*437bfbebSnyanmisaka         /* st 0 layer 0 - ref */
277*437bfbebSnyanmisaka         st_ref[0].is_non_ref    = 0;
278*437bfbebSnyanmisaka         st_ref[0].temporal_id   = 0;
279*437bfbebSnyanmisaka         st_ref[0].ref_mode      = REF_TO_PREV_REF_FRM;
280*437bfbebSnyanmisaka         st_ref[0].ref_arg       = 0;
281*437bfbebSnyanmisaka         st_ref[0].repeat        = 0;
282*437bfbebSnyanmisaka         /* st 1 layer 1 - non-ref */
283*437bfbebSnyanmisaka         st_ref[1].is_non_ref    = 1;
284*437bfbebSnyanmisaka         st_ref[1].temporal_id   = 1;
285*437bfbebSnyanmisaka         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
286*437bfbebSnyanmisaka         st_ref[1].ref_arg       = 0;
287*437bfbebSnyanmisaka         st_ref[1].repeat        = 0;
288*437bfbebSnyanmisaka         /* st 2 layer 0 - ref */
289*437bfbebSnyanmisaka         st_ref[2].is_non_ref    = 0;
290*437bfbebSnyanmisaka         st_ref[2].temporal_id   = 0;
291*437bfbebSnyanmisaka         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
292*437bfbebSnyanmisaka         st_ref[2].ref_arg       = 0;
293*437bfbebSnyanmisaka         st_ref[2].repeat        = 0;
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka         st_cfg_cnt = 3;
296*437bfbebSnyanmisaka         tid0_loop = 2;
297*437bfbebSnyanmisaka         mlvec_dbg_flow("tsvc2\n");
298*437bfbebSnyanmisaka     } break;
299*437bfbebSnyanmisaka     case 2 : {
300*437bfbebSnyanmisaka         /* set tsvc3 st-ref struct */
301*437bfbebSnyanmisaka         /* st 0 layer 0 - ref */
302*437bfbebSnyanmisaka         st_ref[0].is_non_ref    = 0;
303*437bfbebSnyanmisaka         st_ref[0].temporal_id   = 0;
304*437bfbebSnyanmisaka         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
305*437bfbebSnyanmisaka         st_ref[0].ref_arg       = 0;
306*437bfbebSnyanmisaka         st_ref[0].repeat        = 0;
307*437bfbebSnyanmisaka         /* st 1 layer 2 - non-ref */
308*437bfbebSnyanmisaka         st_ref[1].is_non_ref    = 0;
309*437bfbebSnyanmisaka         st_ref[1].temporal_id   = 2;
310*437bfbebSnyanmisaka         st_ref[1].ref_mode      = REF_TO_TEMPORAL_LAYER;
311*437bfbebSnyanmisaka         st_ref[1].ref_arg       = 0;
312*437bfbebSnyanmisaka         st_ref[1].repeat        = 0;
313*437bfbebSnyanmisaka         /* st 2 layer 1 - ref */
314*437bfbebSnyanmisaka         st_ref[2].is_non_ref    = 0;
315*437bfbebSnyanmisaka         st_ref[2].temporal_id   = 1;
316*437bfbebSnyanmisaka         st_ref[2].ref_mode      = REF_TO_TEMPORAL_LAYER;
317*437bfbebSnyanmisaka         st_ref[2].ref_arg       = 0;
318*437bfbebSnyanmisaka         st_ref[2].repeat        = 0;
319*437bfbebSnyanmisaka         /* st 3 layer 2 - non-ref */
320*437bfbebSnyanmisaka         st_ref[3].is_non_ref    = 0;
321*437bfbebSnyanmisaka         st_ref[3].temporal_id   = 2;
322*437bfbebSnyanmisaka         st_ref[3].ref_mode      = REF_TO_TEMPORAL_LAYER;
323*437bfbebSnyanmisaka         st_ref[3].ref_arg       = 1;
324*437bfbebSnyanmisaka         st_ref[3].repeat        = 0;
325*437bfbebSnyanmisaka         /* st 4 layer 0 - ref */
326*437bfbebSnyanmisaka         st_ref[4].is_non_ref    = 0;
327*437bfbebSnyanmisaka         st_ref[4].temporal_id   = 0;
328*437bfbebSnyanmisaka         st_ref[4].ref_mode      = REF_TO_TEMPORAL_LAYER;
329*437bfbebSnyanmisaka         st_ref[4].ref_arg       = 0;
330*437bfbebSnyanmisaka         st_ref[4].repeat        = 0;
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka         st_cfg_cnt = 5;
333*437bfbebSnyanmisaka         tid0_loop = 4;
334*437bfbebSnyanmisaka         mlvec_dbg_flow("tsvc3\n");
335*437bfbebSnyanmisaka     } break;
336*437bfbebSnyanmisaka     case 3 : {
337*437bfbebSnyanmisaka         /* set tsvc3 st-ref struct */
338*437bfbebSnyanmisaka         /* st 0 layer 0 - ref */
339*437bfbebSnyanmisaka         st_ref[0].is_non_ref    = 0;
340*437bfbebSnyanmisaka         st_ref[0].temporal_id   = 0;
341*437bfbebSnyanmisaka         st_ref[0].ref_mode      = REF_TO_TEMPORAL_LAYER;
342*437bfbebSnyanmisaka         st_ref[0].ref_arg       = 0;
343*437bfbebSnyanmisaka         st_ref[0].repeat        = 0;
344*437bfbebSnyanmisaka         /* st 1 layer 3 - non-ref */
345*437bfbebSnyanmisaka         st_ref[1].is_non_ref    = 1;
346*437bfbebSnyanmisaka         st_ref[1].temporal_id   = 3;
347*437bfbebSnyanmisaka         st_ref[1].ref_mode      = REF_TO_PREV_REF_FRM;
348*437bfbebSnyanmisaka         st_ref[1].ref_arg       = 0;
349*437bfbebSnyanmisaka         st_ref[1].repeat        = 0;
350*437bfbebSnyanmisaka         /* st 2 layer 2 - ref */
351*437bfbebSnyanmisaka         st_ref[2].is_non_ref    = 0;
352*437bfbebSnyanmisaka         st_ref[2].temporal_id   = 2;
353*437bfbebSnyanmisaka         st_ref[2].ref_mode      = REF_TO_PREV_REF_FRM;
354*437bfbebSnyanmisaka         st_ref[2].ref_arg       = 0;
355*437bfbebSnyanmisaka         st_ref[2].repeat        = 0;
356*437bfbebSnyanmisaka         /* st 3 layer 3 - non-ref */
357*437bfbebSnyanmisaka         st_ref[3].is_non_ref    = 1;
358*437bfbebSnyanmisaka         st_ref[3].temporal_id   = 3;
359*437bfbebSnyanmisaka         st_ref[3].ref_mode      = REF_TO_PREV_REF_FRM;
360*437bfbebSnyanmisaka         st_ref[3].ref_arg       = 0;
361*437bfbebSnyanmisaka         st_ref[3].repeat        = 0;
362*437bfbebSnyanmisaka         /* st 4 layer 1 - ref */
363*437bfbebSnyanmisaka         st_ref[4].is_non_ref    = 0;
364*437bfbebSnyanmisaka         st_ref[4].temporal_id   = 1;
365*437bfbebSnyanmisaka         st_ref[4].ref_mode      = REF_TO_TEMPORAL_LAYER;
366*437bfbebSnyanmisaka         st_ref[4].ref_arg       = 0;
367*437bfbebSnyanmisaka         st_ref[4].repeat        = 0;
368*437bfbebSnyanmisaka         /* st 5 layer 3 - non-ref */
369*437bfbebSnyanmisaka         st_ref[5].is_non_ref    = 1;
370*437bfbebSnyanmisaka         st_ref[5].temporal_id   = 3;
371*437bfbebSnyanmisaka         st_ref[5].ref_mode      = REF_TO_PREV_REF_FRM;
372*437bfbebSnyanmisaka         st_ref[5].ref_arg       = 0;
373*437bfbebSnyanmisaka         st_ref[5].repeat        = 0;
374*437bfbebSnyanmisaka         /* st 6 layer 2 - ref */
375*437bfbebSnyanmisaka         st_ref[6].is_non_ref    = 0;
376*437bfbebSnyanmisaka         st_ref[6].temporal_id   = 2;
377*437bfbebSnyanmisaka         st_ref[6].ref_mode      = REF_TO_PREV_REF_FRM;
378*437bfbebSnyanmisaka         st_ref[6].ref_arg       = 0;
379*437bfbebSnyanmisaka         st_ref[6].repeat        = 0;
380*437bfbebSnyanmisaka         /* st 7 layer 3 - non-ref */
381*437bfbebSnyanmisaka         st_ref[7].is_non_ref    = 1;
382*437bfbebSnyanmisaka         st_ref[7].temporal_id   = 3;
383*437bfbebSnyanmisaka         st_ref[7].ref_mode      = REF_TO_PREV_REF_FRM;
384*437bfbebSnyanmisaka         st_ref[7].ref_arg       = 0;
385*437bfbebSnyanmisaka         st_ref[7].repeat        = 0;
386*437bfbebSnyanmisaka         /* st 8 layer 0 - ref */
387*437bfbebSnyanmisaka         st_ref[8].is_non_ref    = 0;
388*437bfbebSnyanmisaka         st_ref[8].temporal_id   = 0;
389*437bfbebSnyanmisaka         st_ref[8].ref_mode      = REF_TO_PREV_REF_FRM;
390*437bfbebSnyanmisaka         st_ref[8].ref_arg       = 0;
391*437bfbebSnyanmisaka         st_ref[8].repeat        = 0;
392*437bfbebSnyanmisaka 
393*437bfbebSnyanmisaka         st_cfg_cnt = 9;
394*437bfbebSnyanmisaka         tid0_loop = 8;
395*437bfbebSnyanmisaka         mlvec_dbg_flow("tsvc4\n");
396*437bfbebSnyanmisaka     } break;
397*437bfbebSnyanmisaka     default : {
398*437bfbebSnyanmisaka         mpp_err("invalid max temporal layer id %d\n", max_tid);
399*437bfbebSnyanmisaka     } break;
400*437bfbebSnyanmisaka     }
401*437bfbebSnyanmisaka 
402*437bfbebSnyanmisaka     if (ltr_frames) {
403*437bfbebSnyanmisaka         RK_S32 i;
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka         lt_cfg_cnt = ltr_frames;
406*437bfbebSnyanmisaka         mpp_assert(ltr_frames <= MPP_ENC_MAX_LT_REF_NUM);
407*437bfbebSnyanmisaka         for (i = 0; i < ltr_frames; i++) {
408*437bfbebSnyanmisaka             lt_ref[i].lt_idx        = i;
409*437bfbebSnyanmisaka             lt_ref[i].temporal_id   = 0;
410*437bfbebSnyanmisaka             lt_ref[i].ref_mode      = REF_TO_PREV_LT_REF;
411*437bfbebSnyanmisaka             lt_ref[i].lt_gap        = 0;
412*437bfbebSnyanmisaka             lt_ref[i].lt_delay      = tid0_loop * i;
413*437bfbebSnyanmisaka         }
414*437bfbebSnyanmisaka     }
415*437bfbebSnyanmisaka 
416*437bfbebSnyanmisaka     if (lt_cfg_cnt)
417*437bfbebSnyanmisaka         mpp_assert(st_cfg_cnt);
418*437bfbebSnyanmisaka 
419*437bfbebSnyanmisaka     mlvec_dbg_flow("lt_cfg_cnt %d st_cfg_cnt %d\n", lt_cfg_cnt, st_cfg_cnt);
420*437bfbebSnyanmisaka     if (lt_cfg_cnt || st_cfg_cnt) {
421*437bfbebSnyanmisaka         MppEncRefCfg ref = NULL;
422*437bfbebSnyanmisaka 
423*437bfbebSnyanmisaka         mpp_enc_ref_cfg_init(&ref);
424*437bfbebSnyanmisaka 
425*437bfbebSnyanmisaka         ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cfg_cnt, st_cfg_cnt);
426*437bfbebSnyanmisaka         ret = mpp_enc_ref_cfg_add_lt_cfg(ref, lt_cfg_cnt, lt_ref);
427*437bfbebSnyanmisaka         ret = mpp_enc_ref_cfg_add_st_cfg(ref, st_cfg_cnt, st_ref);
428*437bfbebSnyanmisaka         ret = mpp_enc_ref_cfg_set_keep_cpb(ref, 1);
429*437bfbebSnyanmisaka         ret = mpp_enc_ref_cfg_check(ref);
430*437bfbebSnyanmisaka 
431*437bfbebSnyanmisaka         ret = mpi->control(mpp_ctx, MPP_ENC_SET_REF_CFG, ref);
432*437bfbebSnyanmisaka         if (ret)
433*437bfbebSnyanmisaka             mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka         mpp_enc_ref_cfg_deinit(&ref);
436*437bfbebSnyanmisaka     } else {
437*437bfbebSnyanmisaka         ret = mpi->control(mpp_ctx, MPP_ENC_SET_REF_CFG, NULL);
438*437bfbebSnyanmisaka         if (ret)
439*437bfbebSnyanmisaka             mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
440*437bfbebSnyanmisaka     }
441*437bfbebSnyanmisaka 
442*437bfbebSnyanmisaka     mlvec_dbg_func("leave ctx %p ret %d\n", ctx, ret);
443*437bfbebSnyanmisaka 
444*437bfbebSnyanmisaka     return ret;
445*437bfbebSnyanmisaka }
446