1 /*
2 * Copyright (c) 2022 Shenzhen Kaihong DID Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "codec_service.h"
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <securec.h>
20 #include <stdio.h>
21 #include <sys/mman.h>
22 #include <unistd.h>
23 #include "ashmem_wrapper.h"
24 #ifndef CODEC_HAL_PASSTHROUGH
25 #include "codec_config_parser.h"
26 #endif
27 #include "hdf_log.h"
28 #include "osal_mem.h"
29
30 #define HDF_LOG_TAG codec_hdi_service
31 #define VIDEO_HARDWARE_ENCODER_INDEX 0
32 #define VIDEO_HARDWARE_DECODER_INDEX 1
33 #define AUDIO_HARDWARE_ENCODER_INDEX 4
34 #define AUDIO_HARDWARE_DECODER_INDEX 5
35
36 struct CodecInstance *g_codecInstance = NULL;
37 #ifdef CODEC_HAL_PASSTHROUGH
38 const CodecCallback *g_codecCallback = NULL;
39 UINTPTR g_userData;
40 #endif
41
DefaultCbOnEvent(UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])42 static int32_t DefaultCbOnEvent(UINTPTR userData, EventType event, uint32_t length, int32_t eventData[])
43 {
44 #ifdef CODEC_HAL_PASSTHROUGH
45 g_codecCallback->OnEvent(g_userData, event, length, eventData);
46 #endif
47 return HDF_SUCCESS;
48 }
49
DefaultCbInputBufferAvailable(UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)50 static int32_t DefaultCbInputBufferAvailable(UINTPTR userData, CodecBuffer *inBuf, int32_t *acquireFd)
51 {
52 if (inBuf == NULL || inBuf->bufferCnt == 0) {
53 HDF_LOGE("%{public}s: inBuf Nullpoint or buf not assigned", __func__);
54 return HDF_FAILURE;
55 }
56 CodecBuffer *inputInfo = GetInputInfo(g_codecInstance, inBuf->bufferId);
57 if (inputInfo == NULL || inputInfo->bufferCnt == 0) {
58 HDF_LOGE("%{public}s: inputInfo Nullpoint or buf not assigned", __func__);
59 return HDF_FAILURE;
60 }
61 CopyCodecBufferWithTypeSwitch(g_codecInstance, inputInfo, inBuf, true);
62 EmptyCodecBuffer(inputInfo);
63 g_codecInstance->bufferManagerWrapper->PutUsedInputDataBuffer(g_codecInstance->bufferManagerWrapper, inputInfo);
64 #ifdef CODEC_HAL_PASSTHROUGH
65 g_codecCallback->InputBufferAvailable(g_userData, inBuf, acquireFd);
66 #endif
67 return HDF_SUCCESS;
68 }
69
DefaultCbOutputBufferAvailable(UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)70 static int32_t DefaultCbOutputBufferAvailable(UINTPTR userData, CodecBuffer *outBuf, int32_t *acquireFd)
71 {
72 if (outBuf == NULL || outBuf->bufferCnt == 0) {
73 HDF_LOGE("%{public}s: outBuf Nullpoint or buf not assigned", __func__);
74 return HDF_FAILURE;
75 }
76 struct BufferManagerWrapper *bmWrapper = g_codecInstance->bufferManagerWrapper;
77 CodecBuffer *outputInfo = GetOutputInfo(g_codecInstance, outBuf->bufferId);
78 if (outputInfo == NULL || outputInfo->bufferCnt == 0) {
79 HDF_LOGE("%{public}s: outputInfo Nullpoint or buf not assigned", __func__);
80 return HDF_FAILURE;
81 }
82 CopyCodecBufferWithTypeSwitch(g_codecInstance, outputInfo, outBuf, true);
83 bmWrapper->PutOutputDataBuffer(bmWrapper, outputInfo);
84 #ifdef CODEC_HAL_PASSTHROUGH
85 g_codecCallback->OutputBufferAvailable(g_userData, outputInfo, acquireFd);
86 #endif
87 // get a new OutputBuffer
88 CodecBuffer *output = NULL;
89 while (output == NULL && g_codecInstance->codecStatus == CODEC_STATUS_STARTED) {
90 output = bmWrapper->GetUsedOutputDataBuffer(bmWrapper, QUEUE_TIME_OUT);
91 }
92 if (output == NULL) {
93 HDF_LOGE("%{public}s: output is NULL", __func__);
94 return HDF_FAILURE;
95 }
96 SetOemCodecBufferType(outBuf, output);
97 CopyCodecBufferWithTypeSwitch(g_codecInstance, outBuf, output, false);
98
99 return HDF_SUCCESS;
100 }
101
CodecInit()102 int32_t CodecInit()
103 {
104 g_codecInstance = GetCodecInstance();
105 if (g_codecInstance == NULL) {
106 HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__);
107 return HDF_FAILURE;
108 }
109 int32_t ret = InitCodecInstance(g_codecInstance);
110 if (ret != HDF_SUCCESS) {
111 HDF_LOGE("%{public}s: InitCodecInstance failed!", __func__);
112 return ret;
113 }
114
115 if (g_codecInstance->codecOemIface == NULL) {
116 HDF_LOGE("%{public}s: oemIface is NULL!", __func__);
117 return HDF_FAILURE;
118 }
119 return g_codecInstance->codecOemIface->codecInit();
120 }
121
CodecDeinit()122 int32_t CodecDeinit()
123 {
124 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
125 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
126 return HDF_FAILURE;
127 }
128 g_codecInstance->codecOemIface->codecDeinit();
129 int32_t ret = DestroyCodecInstance(g_codecInstance);
130 if (ret != HDF_SUCCESS) {
131 HDF_LOGE("%{public}s: CodecDeinit failed!", __func__);
132 return ret;
133 }
134 g_codecInstance = NULL;
135 return HDF_SUCCESS;
136 }
137
CodecEnumerateCapability(uint32_t index,CodecCapability * cap)138 int32_t CodecEnumerateCapability(uint32_t index, CodecCapability *cap)
139 {
140 #ifndef CODEC_HAL_PASSTHROUGH
141 int32_t loopIndex;
142 uint32_t cursor = index;
143 CodecCapablityGroup *group = NULL;
144 if (cursor + 1 < cursor) {
145 HDF_LOGE("%{public}s: the index out of bounds!", __func__);
146 return HDF_FAILURE;
147 }
148 for (loopIndex = 0; loopIndex < CODEC_CAPABLITY_GROUP_NUM; loopIndex++) {
149 group = GetCapablityGroup(loopIndex);
150 if (group == NULL) {
151 continue;
152 }
153 if (cursor + 1 <= (uint32_t)group->num) {
154 *cap = group->capablitis[cursor];
155 return HDF_SUCCESS;
156 } else {
157 cursor -= group->num;
158 }
159 }
160 #endif
161 return HDF_FAILURE;
162 }
163
CodecGetCapability(AvCodecMime mime,CodecType type,uint32_t flags,CodecCapability * cap)164 int32_t CodecGetCapability(AvCodecMime mime, CodecType type, uint32_t flags, CodecCapability *cap)
165 {
166 #ifndef CODEC_HAL_PASSTHROUGH
167 int32_t groupIndex;
168 int32_t capIndex;
169 CodecCapablityGroup *group = NULL;
170 CodecCapability *capItem;
171 bool inputHardwareFlag = flags == 0;
172
173 for (groupIndex = 0; groupIndex < CODEC_CAPABLITY_GROUP_NUM; groupIndex++) {
174 group = GetCapablityGroup(groupIndex);
175 if (group == NULL) {
176 continue;
177 }
178 bool curHardwareFlag = (groupIndex == VIDEO_HARDWARE_ENCODER_INDEX)
179 || (groupIndex == VIDEO_HARDWARE_DECODER_INDEX) || (groupIndex == AUDIO_HARDWARE_ENCODER_INDEX)
180 || (groupIndex == AUDIO_HARDWARE_DECODER_INDEX);
181 if (inputHardwareFlag != curHardwareFlag) {
182 continue;
183 }
184 for (capIndex = 0; capIndex < group->num; capIndex++) {
185 capItem = &group->capablitis[capIndex];
186 if (mime == capItem->mime && type == capItem->type) {
187 *cap = group->capablitis[capIndex];
188 return HDF_SUCCESS;
189 }
190 }
191 }
192 #endif
193 return HDF_FAILURE;
194 }
195
CodecCreate(const char * name,CODEC_HANDLETYPE * handle)196 int32_t CodecCreate(const char* name, CODEC_HANDLETYPE *handle)
197 {
198 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
199 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
200 return HDF_FAILURE;
201 }
202 int32_t ret = g_codecInstance->codecOemIface->codecCreate(name, handle);
203 if (ret != HDF_SUCCESS) {
204 return ret;
205 }
206 g_codecInstance->handle = *handle;
207 HDF_LOGI("%{public}s codec created", __func__);
208 return HDF_SUCCESS;
209 }
210
CodecCreateByType(CodecType type,AvCodecMime mime,CODEC_HANDLETYPE * handle)211 int32_t CodecCreateByType(CodecType type, AvCodecMime mime, CODEC_HANDLETYPE *handle)
212 {
213 (void)type;
214 (void)mime;
215 (void)handle;
216 return HDF_ERR_NOT_SUPPORT;
217 }
218
CodecDestroy(CODEC_HANDLETYPE handle)219 int32_t CodecDestroy(CODEC_HANDLETYPE handle)
220 {
221 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
222 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
223 return HDF_FAILURE;
224 }
225 return g_codecInstance->codecOemIface->codecDestroy(handle);
226 }
227
CodecSetPortMode(CODEC_HANDLETYPE handle,DirectionType direct,AllocateBufferMode mode,BufferType type)228 int32_t CodecSetPortMode(CODEC_HANDLETYPE handle, DirectionType direct, AllocateBufferMode mode, BufferType type)
229 {
230 (void)handle;
231 (void)direct;
232 (void)mode;
233 (void)type;
234 return HDF_ERR_NOT_SUPPORT;
235 }
236
CodecGetPortMode(CODEC_HANDLETYPE handle,DirectionType direct,AllocateBufferMode * mode,BufferType * type)237 int32_t CodecGetPortMode(CODEC_HANDLETYPE handle, DirectionType direct, AllocateBufferMode *mode, BufferType *type)
238 {
239 (void)handle;
240 (void)direct;
241 (void)mode;
242 (void)type;
243 return HDF_ERR_NOT_SUPPORT;
244 }
245
CodecSetParameter(CODEC_HANDLETYPE handle,const Param * params,int32_t paramCnt)246 int32_t CodecSetParameter(CODEC_HANDLETYPE handle, const Param *params, int32_t paramCnt)
247 {
248 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
249 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
250 return HDF_FAILURE;
251 }
252 if (params == NULL || paramCnt <= 0) {
253 HDF_LOGE("%{public}s: params empty!", __func__);
254 return HDF_FAILURE;
255 }
256 for (int32_t i = 0; i < paramCnt; i++) {
257 if (params[i].key == KEY_CODEC_TYPE) {
258 int32_t codecType = 0;
259 memcpy_s(&codecType, sizeof(codecType), params[i].val, params[i].size);
260 g_codecInstance->codecType = codecType;
261 }
262 }
263 return g_codecInstance->codecOemIface->codecSetParameter(handle, params, paramCnt);
264 }
265
CodecGetParameter(CODEC_HANDLETYPE handle,Param * params,int32_t paramCnt)266 int32_t CodecGetParameter(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt)
267 {
268 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
269 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
270 return HDF_FAILURE;
271 }
272 if (params == NULL || paramCnt <= 0) {
273 HDF_LOGE("%{public}s: params empty!", __func__);
274 return HDF_FAILURE;
275 }
276 return g_codecInstance->codecOemIface->codecGetParameter(handle, params, paramCnt);
277 }
278
CodecStart(CODEC_HANDLETYPE handle)279 int32_t CodecStart(CODEC_HANDLETYPE handle)
280 {
281 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
282 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
283 return HDF_FAILURE;
284 }
285 if (!g_codecInstance->hasCallback) {
286 g_codecInstance->defaultCb.OnEvent = DefaultCbOnEvent;
287 g_codecInstance->defaultCb.InputBufferAvailable = DefaultCbInputBufferAvailable;
288 g_codecInstance->defaultCb.OutputBufferAvailable = DefaultCbOutputBufferAvailable;
289 g_codecInstance->codecOemIface->codecSetCallback(handle, &(g_codecInstance->defaultCb), 0);
290 }
291 return RunCodecInstance(g_codecInstance);
292 }
293
CodecStop(CODEC_HANDLETYPE handle)294 int32_t CodecStop(CODEC_HANDLETYPE handle)
295 {
296 if (g_codecInstance == NULL) {
297 HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__);
298 return HDF_FAILURE;
299 }
300 return StopCodecInstance(g_codecInstance);
301 }
302
CodecReset(CODEC_HANDLETYPE handle)303 int32_t CodecReset(CODEC_HANDLETYPE handle)
304 {
305 (void)handle;
306 return HDF_ERR_NOT_SUPPORT;
307 }
308
CodecFlush(CODEC_HANDLETYPE handle,DirectionType directType)309 int32_t CodecFlush(CODEC_HANDLETYPE handle, DirectionType directType)
310 {
311 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
312 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
313 return HDF_FAILURE;
314 }
315 return g_codecInstance->codecOemIface->codecFlush(handle, directType);
316 }
317
CodecQueueInput(CODEC_HANDLETYPE handle,const CodecBuffer * inputData,uint32_t timeoutMs,int releaseFenceFd)318 int32_t CodecQueueInput(CODEC_HANDLETYPE handle, const CodecBuffer *inputData, uint32_t timeoutMs, int releaseFenceFd)
319 {
320 if (g_codecInstance == NULL) {
321 HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__);
322 return HDF_FAILURE;
323 }
324
325 if (g_codecInstance->codecStatus == CODEC_STATUS_IDLE) {
326 if (g_codecInstance->codecType != VIDEO_DECODER && g_codecInstance->codecType != AUDIO_DECODER &&
327 g_codecInstance->codecType != VIDEO_ENCODER && g_codecInstance->codecType != AUDIO_ENCODER) {
328 HDF_LOGE("%{public}s: codecType invalid, queue input buffer failed!", __func__);
329 return HDF_FAILURE;
330 }
331 for (uint32_t i = 0; i < inputData->bufferCnt; i++) {
332 if (AddInputShm(g_codecInstance, &inputData->buffer[i], inputData->bufferId) != HDF_SUCCESS) {
333 HDF_LOGE("%{public}s: AddInputShm failed, queue input buffer failed!", __func__);
334 return HDF_FAILURE;
335 }
336 }
337 CodecBuffer *dup = DupCodecBuffer(inputData);
338 if (AddInputInfo(g_codecInstance, dup) != HDF_SUCCESS) {
339 HDF_LOGE("%{public}s: AddInputInfo failed, queue input buffer failed!", __func__);
340 return HDF_FAILURE;
341 }
342 g_codecInstance->bufferManagerWrapper->PutUsedInputDataBuffer(g_codecInstance->bufferManagerWrapper, dup);
343 return HDF_SUCCESS;
344 } else if (g_codecInstance->codecStatus == CODEC_STATUS_STARTED) {
345 CodecBuffer *info = GetInputInfo(g_codecInstance, inputData->bufferId);
346 CopyCodecBufferWithTypeSwitch(g_codecInstance, info, inputData, true);
347 g_codecInstance->bufferManagerWrapper->PutInputDataBuffer(g_codecInstance->bufferManagerWrapper, info);
348 return HDF_SUCCESS;
349 }
350 return HDF_SUCCESS;
351 }
352
CodecDequeueInput(CODEC_HANDLETYPE handle,uint32_t timeoutMs,int32_t * acquireFd,CodecBuffer * inputData)353 int32_t CodecDequeueInput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int32_t *acquireFd, CodecBuffer *inputData)
354 {
355 if (g_codecInstance == NULL) {
356 HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__);
357 return HDF_FAILURE;
358 }
359
360 CodecBuffer *info = g_codecInstance->bufferManagerWrapper->GetUsedInputDataBuffer(
361 g_codecInstance->bufferManagerWrapper, timeoutMs);
362 if (info != NULL) {
363 *acquireFd = -1;
364 inputData->buffer[0].type = info->buffer[0].type;
365 CopyCodecBufferWithTypeSwitch(g_codecInstance, inputData, info, false);
366 } else {
367 return HDF_ERR_TIMEOUT;
368 }
369
370 return HDF_SUCCESS;
371 }
372
CodecQueueOutput(CODEC_HANDLETYPE handle,CodecBuffer * outInfo,uint32_t timeoutMs,int releaseFenceFd)373 int32_t CodecQueueOutput(CODEC_HANDLETYPE handle, CodecBuffer *outInfo, uint32_t timeoutMs, int releaseFenceFd)
374 {
375 if (g_codecInstance == NULL || g_codecInstance->bufferManagerWrapper == NULL) {
376 HDF_LOGE("%{public}s: g_codecInstance or buffermanager is NULL!", __func__);
377 return HDF_FAILURE;
378 }
379
380 if (g_codecInstance->codecStatus == CODEC_STATUS_IDLE) {
381 if (g_codecInstance->codecType != VIDEO_DECODER && g_codecInstance->codecType != AUDIO_DECODER &&
382 g_codecInstance->codecType != VIDEO_ENCODER && g_codecInstance->codecType != AUDIO_ENCODER) {
383 HDF_LOGE("%{public}s: codecType invalid, queue output buffer failed!", __func__);
384 return HDF_FAILURE;
385 }
386 for (uint32_t i = 0; i < outInfo->bufferCnt; i++) {
387 if (AddOutputShm(g_codecInstance, &outInfo->buffer[i], outInfo->bufferId) != HDF_SUCCESS) {
388 HDF_LOGE("%{public}s: AddOutputShm failed, queue output buffer failed!", __func__);
389 }
390 }
391 CodecBuffer *dup = DupCodecBuffer(outInfo);
392 if (AddOutputInfo(g_codecInstance, dup) != HDF_SUCCESS) {
393 HDF_LOGE("%{public}s: AddOutputInfo failed, queue output buffer failed!", __func__);
394 return HDF_FAILURE;
395 }
396 g_codecInstance->bufferManagerWrapper->PutUsedOutputDataBuffer(g_codecInstance->bufferManagerWrapper, dup);
397 return HDF_SUCCESS;
398 } else if (g_codecInstance->codecStatus == CODEC_STATUS_STARTED) {
399 CodecBuffer *info = GetOutputInfo(g_codecInstance, outInfo->bufferId);
400 CopyCodecBufferWithTypeSwitch(g_codecInstance, info, outInfo, true);
401 EmptyCodecBuffer(info);
402 g_codecInstance->bufferManagerWrapper->PutUsedOutputDataBuffer(g_codecInstance->bufferManagerWrapper, info);
403 return HDF_SUCCESS;
404 } else if (g_codecInstance->codecStatus == CODEC_STATUS_STOPED) {
405 CodecBuffer *dup = DupCodecBuffer(outInfo);
406 g_codecInstance->bufferManagerWrapper->PutOutputDataBuffer(g_codecInstance->bufferManagerWrapper, dup);
407 }
408 return HDF_SUCCESS;
409 }
410
CodecDequeueOutput(CODEC_HANDLETYPE handle,uint32_t timeoutMs,int32_t * acquireFd,CodecBuffer * outInfo)411 int32_t CodecDequeueOutput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int32_t *acquireFd, CodecBuffer *outInfo)
412 {
413 if (g_codecInstance == NULL || g_codecInstance->bufferManagerWrapper == NULL) {
414 HDF_LOGE("%{public}s: g_codecInstance or buffermanager is NULL!", __func__);
415 return HDF_FAILURE;
416 }
417
418 CodecBuffer *info = g_codecInstance->bufferManagerWrapper->GetOutputDataBuffer(
419 g_codecInstance->bufferManagerWrapper, timeoutMs);
420 if (info != NULL) {
421 *acquireFd = -1;
422 outInfo->buffer[0].type = info->buffer[0].type;
423 CopyCodecBufferWithTypeSwitch(g_codecInstance, outInfo, info, false);
424 } else {
425 return HDF_ERR_TIMEOUT;
426 }
427
428 return HDF_SUCCESS;
429 }
430
CodecSetCallback(CODEC_HANDLETYPE handle,const CodecCallback * cb,UINTPTR instance)431 int32_t CodecSetCallback(CODEC_HANDLETYPE handle, const CodecCallback *cb, UINTPTR instance)
432 {
433 if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) {
434 HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__);
435 return HDF_FAILURE;
436 }
437 #ifndef CODEC_HAL_PASSTHROUGH
438 int32_t ret = g_codecInstance->codecOemIface->codecSetCallback(handle, cb, instance);
439 #else
440 g_codecInstance->defaultCb.OnEvent = DefaultCbOnEvent;
441 g_codecInstance->defaultCb.InputBufferAvailable = DefaultCbInputBufferAvailable;
442 g_codecInstance->defaultCb.OutputBufferAvailable = DefaultCbOutputBufferAvailable;
443 int32_t ret = g_codecInstance->codecOemIface->codecSetCallback(handle, &(g_codecInstance->defaultCb), 0);
444 g_codecCallback = cb;
445 g_userData = instance;
446 #endif
447 if (ret == HDF_SUCCESS) {
448 g_codecInstance->hasCallback = true;
449 }
450 return ret;
451 }
452