1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define MODULE_TAG "vp8e_api_v2"
17
18 #include <string.h>
19 #include <limits.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_debug.h"
24 #include "mpp_common.h"
25 #include "mpp_rc.h"
26 #include "mpp_enc_cfg.h"
27
28 #include "vp8e_api_v2.h"
29 #include "vp8e_syntax.h"
30
31 #define VP8E_DBG_FUNCTION (0x00000001)
32 #define VP8E_DBG_CFG (0x00000002)
33
34 #define vp8e_dbg_cfg(fmt, ...) _mpp_dbg_f(vp8e_debug, VP8E_DBG_CFG, fmt, ## __VA_ARGS__)
35 #define vp8e_dbg_fun(fmt, ...) _mpp_dbg_f(vp8e_debug, VP8E_DBG_FUNCTION, fmt, ## __VA_ARGS__)
36
37 RK_U32 vp8e_debug = 0;
38 #define VP8E_SYN_BUTT 2
39
40 typedef struct {
41 /* config from mpp_enc */
42 MppEncCfgSet *cfg;
43
44 /* internal rate control config*/
45 Vp8eRc *rc;
46
47 Vp8eSyntax vp8e_syntax[VP8E_SYN_BUTT];
48 } Vp8eCtx;
49
vp8e_init(void * ctx,EncImplCfg * ctrl_cfg)50 static MPP_RET vp8e_init(void *ctx, EncImplCfg *ctrl_cfg)
51 {
52 MPP_RET ret = MPP_OK;
53 Vp8eCtx *p = (Vp8eCtx *)ctx;
54
55 MppEncRcCfg *rc_cfg = &ctrl_cfg->cfg->rc;
56 MppEncPrepCfg *prep = &ctrl_cfg->cfg->prep;
57
58 vp8e_dbg_fun("enter\n");
59 if (NULL == ctx || NULL == ctrl_cfg) {
60 mpp_err_f("Init failed, contex or controller cfg is null!\n");
61 ret = MPP_NOK;
62 goto __ERR_RET;
63 }
64
65 p->cfg = ctrl_cfg->cfg;
66
67 /*
68 * default prep:
69 * 720p
70 * YUV420SP
71 */
72 prep->width = 1280;
73 prep->height = 720;
74 prep->hor_stride = 1280;
75 prep->ver_stride = 720;
76 prep->format = MPP_FMT_YUV420SP;
77 prep->rotation = MPP_ENC_ROT_0;
78 prep->rotation_ext = MPP_ENC_ROT_0;
79 prep->mirroring = 0;
80 prep->mirroring_ext = 0;
81 prep->denoise = 0;
82
83 /*
84 * default rc_cfg:
85 * CBR
86 * 2Mbps +-25%
87 * 30fps
88 * gop 60
89 */
90 rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR;
91 rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM;
92 rc_cfg->bps_target = 2000 * 1000;
93 rc_cfg->bps_max = rc_cfg->bps_target * 5 / 4;
94 rc_cfg->bps_min = rc_cfg->bps_target * 3 / 4;
95 rc_cfg->fps_in_flex = 0;
96 rc_cfg->fps_in_num = 30;
97 rc_cfg->fps_in_denom = 1;
98 rc_cfg->fps_out_flex = 0;
99 rc_cfg->fps_out_num = 30;
100 rc_cfg->fps_out_denom = 1;
101 rc_cfg->gop = 60;
102 rc_cfg->max_reenc_times = 1;
103 rc_cfg->fqp_min_i = INT_MAX;
104 rc_cfg->fqp_min_p = INT_MAX;
105 rc_cfg->fqp_max_i = INT_MAX;
106 rc_cfg->fqp_max_p = INT_MAX;
107
108 p->rc = mpp_calloc(Vp8eRc, 1);
109 memset(p->rc, 0, sizeof(Vp8eRc));
110 p->rc->frame_coded = 1;
111 if (NULL == p->rc) {
112 mpp_err_f("failed to malloc vp8_rc\n");
113 ret = MPP_ERR_MALLOC;
114 goto __ERR_RET;
115 }
116
117 mpp_env_get_u32("vp8e_debug", &vp8e_debug, 0);
118
119 vp8e_dbg_fun("leave ret %d\n", ret);
120 return ret;
121
122 __ERR_RET:
123 vp8e_dbg_fun("leave ret %d\n", ret);
124 return ret;
125 }
126
vp8e_deinit(void * ctx)127 static MPP_RET vp8e_deinit(void *ctx)
128 {
129 Vp8eCtx *p = (Vp8eCtx *)ctx;
130
131 vp8e_dbg_fun("enter\n");
132
133 if (p->rc)
134 mpp_free(p->rc);
135
136 vp8e_dbg_fun("leave\n");
137 return MPP_OK;
138 }
139
vp8e_start(void * ctx,HalEncTask * task)140 static MPP_RET vp8e_start(void *ctx, HalEncTask *task)
141 {
142 (void)ctx;
143 (void)task;
144
145 return MPP_OK;
146 }
147
vp8e_proc_dpb(void * ctx,HalEncTask * task)148 static MPP_RET vp8e_proc_dpb(void *ctx, HalEncTask *task)
149 {
150 (void)ctx;
151 EncRcTask *rc_task = task->rc_task;
152 EncCpbStatus *cpb = &task->rc_task->cpb;
153 rc_task->frm.val = cpb->curr.val;
154 return MPP_OK;
155 }
156
vp8e_proc_cfg(void * ctx,MpiCmd cmd,void * param)157 static MPP_RET vp8e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
158 {
159 MPP_RET ret = MPP_OK;
160
161 vp8e_dbg_fun("enter ctx %p cmd %x param %p\n", ctx, cmd, param);
162 switch (cmd) {
163 case MPP_ENC_SET_CFG : {
164 } break;
165 default: {
166 mpp_err("No correspond cmd found, and can not config!");
167 ret = MPP_NOK;
168 } break;
169 }
170
171 vp8e_dbg_fun("leave ret %d\n", ret);
172 return ret;
173 }
174
vp8e_proc_hal(void * ctx,HalEncTask * task)175 static MPP_RET vp8e_proc_hal(void *ctx, HalEncTask *task)
176 {
177 Vp8eCtx *p = (Vp8eCtx *)ctx;
178 Vp8eSyntax *syntax = &p->vp8e_syntax[0];
179 RK_U32 syn_num = 0;
180
181 syntax[syn_num].type = VP8E_SYN_CFG;
182 syntax[syn_num].data = p->cfg;
183 syn_num++;
184 syntax[syn_num].type = VP8E_SYN_RC;
185 syntax[syn_num].data = p->rc;
186 syn_num++;
187 task->syntax.data = syntax;
188 task->syntax.number = syn_num;
189
190 task->valid = 1;
191 return MPP_OK;
192 }
193
194 const EncImplApi api_vp8e = {
195 .name = "vp8_control",
196 .coding = MPP_VIDEO_CodingVP8,
197 .ctx_size = sizeof(Vp8eCtx),
198 .flag = 0,
199 .init = vp8e_init,
200 .deinit = vp8e_deinit,
201 .proc_cfg = vp8e_proc_cfg,
202 .gen_hdr = NULL,
203 .start = vp8e_start,
204 .proc_dpb = vp8e_proc_dpb,
205 .proc_hal = vp8e_proc_hal,
206 .add_prefix = NULL,
207 .sw_enc = NULL,
208 };
209