xref: /rockchip-linux_mpp/mpp/hal/mpp_enc_hal.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define  MODULE_TAG "mpp_enc_hal"
7 
8 #include "mpp_mem.h"
9 #include "mpp_log.h"
10 #include "mpp_common.h"
11 
12 #include "mpp.h"
13 #include "mpp_enc_hal.h"
14 #include "mpp_frame_impl.h"
15 
16 #include "hal_h264e_api_v2.h"
17 #include "hal_h265e_api_v2.h"
18 #include "hal_jpege_api_v2.h"
19 #include "hal_vp8e_api_v2.h"
20 
21 static const MppEncHalApi *hw_enc_apis[] = {
22 #if HAVE_H264E
23     &hal_api_h264e_v2,
24 #endif
25 #if HAVE_H265E
26     &hal_api_h265e_v2,
27 #endif
28 #if HAVE_JPEGE
29     &hal_api_jpege_v2,
30 #endif
31 #if HAVE_VP8E
32     &hal_api_vp8e_v2,
33 #endif
34 };
35 
36 typedef struct MppEncHalImpl_t {
37     MppCodingType       coding;
38 
39     void                *ctx;
40     const MppEncHalApi  *api;
41 
42     HalTaskGroup        tasks;
43 } MppEncHalImpl;
44 
mpp_enc_hal_init(MppEncHal * ctx,MppEncHalCfg * cfg)45 MPP_RET mpp_enc_hal_init(MppEncHal *ctx, MppEncHalCfg *cfg)
46 {
47     if (NULL == ctx || NULL == cfg) {
48         mpp_err_f("found NULL input ctx %p cfg %p\n", ctx, cfg);
49         return MPP_ERR_NULL_PTR;
50     }
51     *ctx = NULL;
52 
53     MppEncHalImpl *p = mpp_calloc(MppEncHalImpl, 1);
54     if (NULL == p) {
55         mpp_err_f("malloc failed\n");
56         return MPP_ERR_MALLOC;
57     }
58 
59     RK_U32 i;
60     for (i = 0; i < MPP_ARRAY_ELEMS(hw_enc_apis); i++) {
61         if (cfg->coding == hw_enc_apis[i]->coding) {
62             p->coding       = cfg->coding;
63             p->api          = hw_enc_apis[i];
64             p->ctx          = mpp_calloc_size(void, p->api->ctx_size);
65 
66             MPP_RET ret = p->api->init(p->ctx, cfg);
67             if (ret) {
68                 mpp_err_f("hal %s init failed ret %d\n", hw_enc_apis[i]->name, ret);
69                 break;
70             }
71 
72             ret = hal_task_group_init(&p->tasks, TASK_BUTT, cfg->task_cnt,
73                                       sizeof(EncAsyncTaskInfo));
74             if (ret) {
75                 mpp_err_f("hal_task_group_init failed ret %d\n", ret);
76                 break;
77             }
78 
79             cfg->tasks = p->tasks;
80             *ctx = p;
81             return MPP_OK;
82         }
83     }
84 
85     mpp_err_f("could not found coding type %d\n", cfg->coding);
86     mpp_free(p->ctx);
87     mpp_free(p);
88 
89     return MPP_NOK;
90 }
91 
mpp_enc_hal_deinit(MppEncHal ctx)92 MPP_RET mpp_enc_hal_deinit(MppEncHal ctx)
93 {
94     if (NULL == ctx) {
95         mpp_err_f("found NULL input\n");
96         return MPP_ERR_NULL_PTR;
97     }
98 
99     MppEncHalImpl *p = (MppEncHalImpl*)ctx;
100     p->api->deinit(p->ctx);
101     mpp_free(p->ctx);
102     if (p->tasks)
103         hal_task_group_deinit(p->tasks);
104     mpp_free(p);
105     return MPP_OK;
106 }
107 
mpp_enc_hal_prepare(void * hal)108 MPP_RET mpp_enc_hal_prepare(void *hal)
109 {
110     if (NULL == hal) {
111         mpp_err_f("found NULL input ctx %p\n", hal);
112         return MPP_ERR_NULL_PTR;
113     }
114 
115     MppEncHalImpl *p = (MppEncHalImpl*)hal;
116     if (!p->api || !p->api->prepare)
117         return MPP_OK;
118 
119     return p->api->prepare(p->ctx);
120 }
121 
mpp_enc_hal_check_part_mode(MppEncHal ctx)122 MPP_RET mpp_enc_hal_check_part_mode(MppEncHal ctx)
123 {
124     MppEncHalImpl *p = (MppEncHalImpl*)ctx;
125 
126     if (p && p->api && p->api->part_start && p->api->part_wait)
127         return MPP_OK;
128 
129     return MPP_NOK;
130 }
131 
mpp_enc_hal_start(void * hal,HalEncTask * task)132 MPP_RET mpp_enc_hal_start(void *hal, HalEncTask *task)
133 {
134     if (NULL == hal || NULL == task) {
135         mpp_err_f("found NULL input ctx %p task %p\n", hal, task);
136         return MPP_ERR_NULL_PTR;
137     }
138 
139     MppEncHalImpl *p = (MppEncHalImpl*)hal;
140     if (!p->api || !p->api->start)
141         return MPP_OK;
142 
143     /* Add buffer sync process */
144     mpp_buffer_sync_partial_end(task->output, 0, task->length);
145 
146     return p->api->start(p->ctx, task);
147 }
148 
149 #define MPP_ENC_HAL_TASK_FUNC(func) \
150     MPP_RET mpp_enc_hal_##func(void *hal, HalEncTask *task)             \
151     {                                                                   \
152         if (NULL == hal || NULL == task) {                              \
153             mpp_err_f("found NULL input ctx %p task %p\n", hal, task);  \
154             return MPP_ERR_NULL_PTR;                                    \
155         }                                                               \
156                                                                         \
157         MppEncHalImpl *p = (MppEncHalImpl*)hal;                         \
158         if (!p->api || !p->api->func)                                   \
159             return MPP_OK;                                              \
160                                                                         \
161         return p->api->func(p->ctx, task);                              \
162     }
163 
164 MPP_ENC_HAL_TASK_FUNC(get_task)
165 MPP_ENC_HAL_TASK_FUNC(gen_regs)
166 MPP_ENC_HAL_TASK_FUNC(wait)
167 MPP_ENC_HAL_TASK_FUNC(part_start)
168 MPP_ENC_HAL_TASK_FUNC(part_wait)
169 MPP_ENC_HAL_TASK_FUNC(ret_task)
170