1 /*
2 * Copyright (c) 2022-2023 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 <dlfcn.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <securec.h>
21 #include <stdio.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include "ashmem_wrapper.h"
25 #ifndef CODEC_HAL_PASSTHROUGH
26 #include "codec_callback_proxy.h"
27 #include "codec_config_parser.h"
28 #endif
29 #include "codec_instance_manager.h"
30 #include "hdf_log.h"
31 #include "osal_mem.h"
32 #include "osal_mutex.h"
33
34 #define HDF_LOG_TAG codec_hdi_service
35 #define VIDEO_HARDWARE_ENCODER_INDEX 0
36 #define VIDEO_HARDWARE_DECODER_INDEX 1
37 #define AUDIO_HARDWARE_ENCODER_INDEX 4
38 #define AUDIO_HARDWARE_DECODER_INDEX 5
39 #define CODEC_OEM_INTERFACE_LIB_NAME "libcodec_oem_interface.z.so"
40
41 struct CodecOemIf *g_codecOemIface = NULL;
42 void *g_oemLibHandle = NULL;
43 #ifndef CODEC_HAL_PASSTHROUGH
44 struct OsalMutex g_oemIfaceLock;
45 int g_oemIfaceRefCount = 0; /** Client process reference count. */
46 #endif
47
CodecOnEvent(UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])48 static int32_t CodecOnEvent(UINTPTR userData, EventType event, uint32_t length, int32_t eventData[])
49 {
50 struct CodecInstance *instance = FindInCodecInstanceManager((CODEC_HANDLETYPE)userData);
51 if (instance == NULL) {
52 HDF_LOGE("%{public}s: instance is NULL!", __func__);
53 return HDF_FAILURE;
54 }
55 #ifdef CODEC_HAL_PASSTHROUGH
56 if (instance->hasCustomerCallback && instance->codecCallback != NULL) {
57 instance->codecCallback->OnEvent(instance->callbackUserData, event, length, eventData);
58 }
59 #else
60 if (instance->hasCustomerCallback && instance->callbackProxy != NULL) {
61 instance->callbackProxy->OnEvent(instance->callbackProxy, instance->callbackUserData,
62 event, length, eventData);
63 }
64 #endif
65 return HDF_SUCCESS;
66 }
67
CodecInputBufferAvailable(UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)68 static int32_t CodecInputBufferAvailable(UINTPTR userData, CodecBuffer *inBuf, int32_t *acquireFd)
69 {
70 struct CodecInstance *instance = FindInCodecInstanceManager((CODEC_HANDLETYPE)userData);
71 if (instance == NULL) {
72 HDF_LOGE("%{public}s: instance is NULL!", __func__);
73 return HDF_FAILURE;
74 }
75 if (inBuf == NULL || inBuf->bufferCnt == 0) {
76 HDF_LOGE("%{public}s: inBuf Nullpoint or buf not assigned", __func__);
77 return HDF_FAILURE;
78 }
79 CodecBuffer *inputInfo = GetInputInfo(instance, inBuf->bufferId);
80 if (inputInfo == NULL || inputInfo->bufferCnt == 0) {
81 HDF_LOGE("%{public}s: inputInfo Nullpoint or buf not assigned", __func__);
82 return HDF_FAILURE;
83 }
84 CopyCodecBufferWithTypeSwitch(instance, inputInfo, inBuf, true);
85 EmptyCodecBuffer(inputInfo);
86 instance->bufferManagerWrapper->PutUsedInputDataBuffer(instance->bufferManagerWrapper, inputInfo);
87 return HDF_SUCCESS;
88 }
89
CodecOutputBufferAvailable(UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)90 static int32_t CodecOutputBufferAvailable(UINTPTR userData, CodecBuffer *outBuf, int32_t *acquireFd)
91 {
92 struct CodecInstance *instance = FindInCodecInstanceManager((CODEC_HANDLETYPE)userData);
93 if (instance == NULL) {
94 HDF_LOGE("%{public}s: instance is NULL!", __func__);
95 return HDF_FAILURE;
96 }
97 if (outBuf == NULL || outBuf->bufferCnt == 0) {
98 HDF_LOGE("%{public}s: outBuf Nullpoint or buf not assigned", __func__);
99 return HDF_FAILURE;
100 }
101 CodecBuffer *outputInfo = GetOutputInfo(instance, outBuf->bufferId);
102 if (outputInfo == NULL || outputInfo->bufferCnt == 0) {
103 HDF_LOGE("%{public}s: outputInfo Nullpoint or buf not assigned", __func__);
104 return HDF_FAILURE;
105 }
106 CopyCodecBufferWithTypeSwitch(instance, outputInfo, outBuf, true);
107 instance->bufferManagerWrapper->PutOutputDataBuffer(instance->bufferManagerWrapper, outputInfo);
108 // get a new OutputBuffer
109 CodecBuffer *output = NULL;
110 while (output == NULL && instance->codecStatus == CODEC_STATUS_STARTED) {
111 output = instance->bufferManagerWrapper->GetUsedOutputDataBuffer(
112 instance->bufferManagerWrapper, QUEUE_TIME_OUT);
113 }
114 if (output == NULL) {
115 HDF_LOGE("%{public}s: output is NULL", __func__);
116 return HDF_FAILURE;
117 }
118 SetOemCodecBufferType(outBuf, output);
119 CopyCodecBufferWithTypeSwitch(instance, outBuf, output, false);
120
121 return HDF_SUCCESS;
122 }
123
124 #ifndef CODEC_HAL_PASSTHROUGH
InitOemIfaceLock(void)125 void InitOemIfaceLock(void)
126 {
127 OsalMutexInit(&g_oemIfaceLock);
128 }
129
DeinitOemIfaceLock(void)130 void DeinitOemIfaceLock(void)
131 {
132 OsalMutexDestroy(&g_oemIfaceLock);
133 }
134 #endif
135
InitCodecOemIf(struct CodecOemIf ** codecOemIface)136 static int32_t InitCodecOemIf(struct CodecOemIf **codecOemIface)
137 {
138 *codecOemIface = (struct CodecOemIf *)OsalMemCalloc(sizeof(struct CodecOemIf));
139 if (*codecOemIface == NULL) {
140 HDF_LOGE("%{public}s: g_codecOemIface mem alloc failed", __func__);
141 return HDF_FAILURE;
142 }
143 g_oemLibHandle = dlopen(CODEC_OEM_INTERFACE_LIB_NAME, RTLD_NOW);
144 if (g_oemLibHandle == NULL) {
145 HDF_LOGE("%{public}s: lib %{public}s dlopen failed, error code[%{public}s]",
146 __func__, CODEC_OEM_INTERFACE_LIB_NAME, dlerror());
147 OsalMemFree(*codecOemIface);
148 *codecOemIface = NULL;
149 return HDF_FAILURE;
150 }
151
152 (*codecOemIface)->codecInit = (CodecInitType)dlsym(g_oemLibHandle, "CodecInit");
153 (*codecOemIface)->codecDeinit = (CodecDeinitType)dlsym(g_oemLibHandle, "CodecDeinit");
154 (*codecOemIface)->codecCreate = (CodecCreateType)dlsym(g_oemLibHandle, "CodecCreate");
155 (*codecOemIface)->codecDestroy = (CodecDestroyType)dlsym(g_oemLibHandle, "CodecDestroy");
156 (*codecOemIface)->codecSetParameter = (CodecSetParameterType)dlsym(g_oemLibHandle, "CodecSetParameter");
157 (*codecOemIface)->codecGetParameter = (CodecGetParameterType)dlsym(g_oemLibHandle, "CodecGetParameter");
158 (*codecOemIface)->codecStart = (CodecStartType)dlsym(g_oemLibHandle, "CodecStart");
159 (*codecOemIface)->codecStop = (CodecStopType)dlsym(g_oemLibHandle, "CodecStop");
160 (*codecOemIface)->codecFlush = (CodecFlushType)dlsym(g_oemLibHandle, "CodecFlush");
161 (*codecOemIface)->codecSetCallback = (CodecSetCallbackType)dlsym(g_oemLibHandle, "CodecSetCallback");
162 (*codecOemIface)->codecDecode = (CodecDecodeType)dlsym(g_oemLibHandle, "CodecDecode");
163 (*codecOemIface)->codecEncode = (CodecEncodeType)dlsym(g_oemLibHandle, "CodecEncode");
164 (*codecOemIface)->codecEncodeHeader = (CodecEncodeHeaderType)dlsym(g_oemLibHandle, "CodecEncodeHeader");
165
166 return HDF_SUCCESS;
167 }
168
DeinitCodecOemIf(void)169 static void DeinitCodecOemIf(void)
170 {
171 if (g_codecOemIface != NULL) {
172 OsalMemFree(g_codecOemIface);
173 g_codecOemIface = NULL;
174 }
175 }
176
CodecInit(void)177 int32_t CodecInit(void)
178 {
179 #ifndef CODEC_HAL_PASSTHROUGH
180 OsalMutexLock(&g_oemIfaceLock);
181 #endif
182 if (g_codecOemIface == NULL) {
183 HDF_LOGI("%{public}s: g_codecOemIface is NULL, do init!", __func__);
184 if (InitCodecOemIf(&g_codecOemIface) != HDF_SUCCESS) {
185 HDF_LOGE("%{public}s: InitCodecOemIf failed!", __func__);
186 #ifndef CODEC_HAL_PASSTHROUGH
187 OsalMutexUnlock(&g_oemIfaceLock);
188 #endif
189 return HDF_FAILURE;
190 }
191 }
192 #ifndef CODEC_HAL_PASSTHROUGH
193 g_oemIfaceRefCount++;
194 HDF_LOGI("%{public}s: oemIface ref increased to: %{public}d", __func__, g_oemIfaceRefCount);
195 OsalMutexUnlock(&g_oemIfaceLock);
196 #endif
197 return g_codecOemIface->codecInit();
198 }
199
CodecDeinit(void)200 int32_t CodecDeinit(void)
201 {
202 if (g_codecOemIface == NULL) {
203 HDF_LOGE("%{public}s: g_codecOemIface is NULL!", __func__);
204 return HDF_FAILURE;
205 }
206
207 int32_t ret = g_codecOemIface->codecDeinit();
208 #ifndef CODEC_HAL_PASSTHROUGH
209 OsalMutexLock(&g_oemIfaceLock);
210 g_oemIfaceRefCount--;
211 HDF_LOGI("%{public}s: oemIface ref decreased to: %{public}d", __func__, g_oemIfaceRefCount);
212 if (g_oemIfaceRefCount <= 0) {
213 #endif
214 DeinitCodecOemIf();
215 HDF_LOGI("%{public}s: call DeinitCodecOemIf", __func__);
216 #ifndef CODEC_HAL_PASSTHROUGH
217 g_oemIfaceRefCount = 0;
218 }
219 OsalMutexUnlock(&g_oemIfaceLock);
220 #endif
221
222 return ret;
223 }
224
CodecEnumerateCapability(uint32_t index,CodecCapability * cap)225 int32_t CodecEnumerateCapability(uint32_t index, CodecCapability *cap)
226 {
227 #ifndef CODEC_HAL_PASSTHROUGH
228 int32_t loopIndex;
229 uint32_t cursor = index;
230 CodecCapablityGroup *group = NULL;
231 if (cursor + 1 < cursor) {
232 HDF_LOGE("%{public}s: the index out of bounds!", __func__);
233 return HDF_FAILURE;
234 }
235 for (loopIndex = 0; loopIndex < CODEC_CAPABLITY_GROUP_NUM; loopIndex++) {
236 group = GetCapablityGroup(loopIndex);
237 if (group == NULL) {
238 continue;
239 }
240 if (cursor + 1 <= (uint32_t)group->num) {
241 *cap = group->capablitis[cursor];
242 return HDF_SUCCESS;
243 } else {
244 cursor -= group->num;
245 }
246 }
247 #endif
248 return HDF_FAILURE;
249 }
250
CodecGetCapability(AvCodecMime mime,CodecType type,uint32_t flags,CodecCapability * cap)251 int32_t CodecGetCapability(AvCodecMime mime, CodecType type, uint32_t flags, CodecCapability *cap)
252 {
253 #ifndef CODEC_HAL_PASSTHROUGH
254 int32_t groupIndex;
255 int32_t capIndex;
256 CodecCapablityGroup *group = NULL;
257 CodecCapability *capItem;
258 bool inputHardwareFlag = flags == 0;
259
260 for (groupIndex = 0; groupIndex < CODEC_CAPABLITY_GROUP_NUM; groupIndex++) {
261 group = GetCapablityGroup(groupIndex);
262 if (group == NULL) {
263 continue;
264 }
265 bool curHardwareFlag = (groupIndex == VIDEO_HARDWARE_ENCODER_INDEX)
266 || (groupIndex == VIDEO_HARDWARE_DECODER_INDEX) || (groupIndex == AUDIO_HARDWARE_ENCODER_INDEX)
267 || (groupIndex == AUDIO_HARDWARE_DECODER_INDEX);
268 if (inputHardwareFlag != curHardwareFlag) {
269 continue;
270 }
271 for (capIndex = 0; capIndex < group->num; capIndex++) {
272 capItem = &group->capablitis[capIndex];
273 if (mime == capItem->mime && type == capItem->type) {
274 *cap = group->capablitis[capIndex];
275 return HDF_SUCCESS;
276 }
277 }
278 }
279 #endif
280 return HDF_FAILURE;
281 }
282
CodecCreate(const char * name,CODEC_HANDLETYPE * handle)283 int32_t CodecCreate(const char* name, CODEC_HANDLETYPE *handle)
284 {
285 struct CodecInstance *instance = GetCodecInstance();
286 if (instance == NULL || g_codecOemIface == NULL) {
287 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
288 return HDF_FAILURE;
289 }
290 int32_t ret = InitCodecInstance(instance, g_codecOemIface);
291 if (ret != HDF_SUCCESS) {
292 HDF_LOGE("%{public}s: InitCodecInstance failed!", __func__);
293 return ret;
294 }
295 ret = g_codecOemIface->codecCreate(name, handle);
296 if (ret != HDF_SUCCESS) {
297 HDF_LOGE("%{public}s: g_codecOemIface->codecCreate failed!", __func__);
298 return ret;
299 }
300 instance->handle = *handle;
301 HDF_LOGI("%{public}s codec created", __func__);
302 if (!AddToCodecInstanceManager(*handle, instance)) {
303 HDF_LOGE("%{public}s: AddToCodecInstanceManager failed!", __func__);
304 return HDF_FAILURE;
305 }
306 return HDF_SUCCESS;
307 }
308
CodecCreateByType(CodecType type,AvCodecMime mime,CODEC_HANDLETYPE * handle)309 int32_t CodecCreateByType(CodecType type, AvCodecMime mime, CODEC_HANDLETYPE *handle)
310 {
311 (void)type;
312 (void)mime;
313 (void)handle;
314 return HDF_ERR_NOT_SUPPORT;
315 }
316
CodecDestroy(CODEC_HANDLETYPE handle)317 int32_t CodecDestroy(CODEC_HANDLETYPE handle)
318 {
319 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
320 int32_t destroyInstanceResult;
321 if (instance != NULL) {
322 #ifndef CODEC_HAL_PASSTHROUGH
323 CodecProxyCallbackRelease(instance->callbackProxy);
324 #endif
325 destroyInstanceResult = DestroyCodecInstance(instance);
326 RemoveFromCodecInstanceManager(handle);
327 OsalMemFree(instance);
328 } else {
329 HDF_LOGE("%{public}s: instance is NULL!", __func__);
330 destroyInstanceResult = HDF_FAILURE;
331 }
332
333 int32_t destroyIfaceResult;
334 if (g_codecOemIface != NULL) {
335 destroyIfaceResult = g_codecOemIface->codecDestroy(handle);
336 } else {
337 HDF_LOGE("%{public}s: g_codecOemIface is NULL!", __func__);
338 destroyIfaceResult = HDF_FAILURE;
339 }
340
341 if (destroyInstanceResult != HDF_SUCCESS || destroyIfaceResult != HDF_SUCCESS) {
342 HDF_LOGE("%{public}s: destroyInstanceResult or destroyIfaceResult not HDF_SUCCESS!", __func__);
343 return HDF_FAILURE;
344 }
345 return HDF_SUCCESS;
346 }
347
CodecSetPortMode(CODEC_HANDLETYPE handle,DirectionType direct,AllocateBufferMode mode,BufferType type)348 int32_t CodecSetPortMode(CODEC_HANDLETYPE handle, DirectionType direct, AllocateBufferMode mode, BufferType type)
349 {
350 (void)handle;
351 (void)direct;
352 (void)mode;
353 (void)type;
354 return HDF_ERR_NOT_SUPPORT;
355 }
356
CodecGetPortMode(CODEC_HANDLETYPE handle,DirectionType direct,AllocateBufferMode * mode,BufferType * type)357 int32_t CodecGetPortMode(CODEC_HANDLETYPE handle, DirectionType direct, AllocateBufferMode *mode, BufferType *type)
358 {
359 (void)handle;
360 (void)direct;
361 (void)mode;
362 (void)type;
363 return HDF_ERR_NOT_SUPPORT;
364 }
365
CodecSetParameter(CODEC_HANDLETYPE handle,const Param * params,int32_t paramCnt)366 int32_t CodecSetParameter(CODEC_HANDLETYPE handle, const Param *params, int32_t paramCnt)
367 {
368 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
369 if (instance == NULL || g_codecOemIface == NULL) {
370 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
371 return HDF_FAILURE;
372 }
373 if (params == NULL || paramCnt <= 0) {
374 HDF_LOGE("%{public}s: params empty!", __func__);
375 return HDF_FAILURE;
376 }
377 for (int32_t i = 0; i < paramCnt; i++) {
378 if (params[i].key != KEY_CODEC_TYPE) {
379 continue;
380 }
381 int32_t codecType = 0;
382 if (memcpy_s(&codecType, sizeof(codecType), params[i].val, params[i].size) != EOK) {
383 HDF_LOGE("%{public}s: memcpy_s params failed!", __func__);
384 return HDF_FAILURE;
385 }
386 instance->codecType = codecType;
387 }
388 return g_codecOemIface->codecSetParameter(handle, params, paramCnt);
389 }
390
CodecGetParameter(CODEC_HANDLETYPE handle,Param * params,int32_t paramCnt)391 int32_t CodecGetParameter(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt)
392 {
393 if (g_codecOemIface == NULL) {
394 HDF_LOGE("%{public}s: g_codecOemIface is NULL!", __func__);
395 return HDF_FAILURE;
396 }
397 if (params == NULL || paramCnt <= 0) {
398 HDF_LOGE("%{public}s: params empty!", __func__);
399 return HDF_FAILURE;
400 }
401 return g_codecOemIface->codecGetParameter(handle, params, paramCnt);
402 }
403
CodecStart(CODEC_HANDLETYPE handle)404 int32_t CodecStart(CODEC_HANDLETYPE handle)
405 {
406 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
407 if (instance == NULL || g_codecOemIface == NULL) {
408 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
409 return HDF_FAILURE;
410 }
411
412 if (!instance->hasCustomerCallback) {
413 instance->defaultCb.OnEvent = CodecOnEvent;
414 instance->defaultCb.InputBufferAvailable = CodecInputBufferAvailable;
415 instance->defaultCb.OutputBufferAvailable = CodecOutputBufferAvailable;
416 if (g_codecOemIface->codecSetCallback(handle, &(instance->defaultCb), 0) != HDF_SUCCESS) {
417 HDF_LOGE("%{public}s: call oem codecSetCallback failed!", __func__);
418 return HDF_FAILURE;
419 }
420 }
421
422 if (g_codecOemIface->codecStart(handle) != HDF_SUCCESS) {
423 HDF_LOGE("%{public}s: call oem codecStart failed!", __func__);
424 return HDF_FAILURE;
425 }
426 return RunCodecInstance(instance);
427 }
428
CodecStop(CODEC_HANDLETYPE handle)429 int32_t CodecStop(CODEC_HANDLETYPE handle)
430 {
431 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
432 if (instance == NULL) {
433 HDF_LOGE("%{public}s: instance is NULL!", __func__);
434 return HDF_FAILURE;
435 }
436 return StopCodecInstance(instance);
437 }
438
CodecReset(CODEC_HANDLETYPE handle)439 int32_t CodecReset(CODEC_HANDLETYPE handle)
440 {
441 (void)handle;
442 return HDF_ERR_NOT_SUPPORT;
443 }
444
CodecFlush(CODEC_HANDLETYPE handle,DirectionType directType)445 int32_t CodecFlush(CODEC_HANDLETYPE handle, DirectionType directType)
446 {
447 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
448 if (instance == NULL || g_codecOemIface == NULL) {
449 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
450 return HDF_FAILURE;
451 }
452 return g_codecOemIface->codecFlush(handle, directType);
453 }
454
CodecQueueInput(CODEC_HANDLETYPE handle,const CodecBuffer * inputData,uint32_t timeoutMs,int releaseFenceFd)455 int32_t CodecQueueInput(CODEC_HANDLETYPE handle, const CodecBuffer *inputData, uint32_t timeoutMs, int releaseFenceFd)
456 {
457 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
458 if (instance == NULL || instance->bufferManagerWrapper == NULL) {
459 HDF_LOGE("%{public}s: instance or buffermanager is NULL!", __func__);
460 return HDF_FAILURE;
461 }
462
463 if (instance->codecStatus == CODEC_STATUS_IDLE) {
464 if (instance->codecType != VIDEO_DECODER && instance->codecType != AUDIO_DECODER &&
465 instance->codecType != VIDEO_ENCODER && instance->codecType != AUDIO_ENCODER) {
466 HDF_LOGE("%{public}s: codecType invalid, queue input buffer failed!", __func__);
467 return HDF_FAILURE;
468 }
469 for (uint32_t i = 0; i < inputData->bufferCnt; i++) {
470 if (AddInputShm(instance, &inputData->buffer[i], inputData->bufferId) != HDF_SUCCESS) {
471 HDF_LOGE("%{public}s: AddInputShm failed, queue input buffer failed!", __func__);
472 return HDF_FAILURE;
473 }
474 }
475 CodecBuffer *dup = DupCodecBuffer(inputData);
476 if (AddInputInfo(instance, dup) != HDF_SUCCESS) {
477 ReleaseCodecBuffer(dup);
478 HDF_LOGE("%{public}s: AddInputInfo failed, queue input buffer failed!", __func__);
479 return HDF_FAILURE;
480 }
481 instance->bufferManagerWrapper->PutUsedInputDataBuffer(instance->bufferManagerWrapper, dup);
482 return HDF_SUCCESS;
483 } else if (instance->codecStatus == CODEC_STATUS_STARTED) {
484 CodecBuffer *info = GetInputInfo(instance, inputData->bufferId);
485 CopyCodecBufferWithTypeSwitch(instance, info, inputData, true);
486 instance->bufferManagerWrapper->PutInputDataBuffer(instance->bufferManagerWrapper, info);
487 if ((inputData->flag & STREAM_FLAG_EOS) != 0) {
488 instance->inputEos = true;
489 HDF_LOGI("%{public}s: input reach STREAM_FLAG_EOS!", __func__);
490 }
491 return HDF_SUCCESS;
492 }
493 return HDF_SUCCESS;
494 }
495
CodecDequeueInput(CODEC_HANDLETYPE handle,uint32_t timeoutMs,int32_t * acquireFd,CodecBuffer * inputData)496 int32_t CodecDequeueInput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int32_t *acquireFd, CodecBuffer *inputData)
497 {
498 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
499 if (instance == NULL || instance->bufferManagerWrapper == NULL) {
500 HDF_LOGE("%{public}s: instance or buffermanager is NULL!", __func__);
501 return HDF_FAILURE;
502 }
503
504 CodecBuffer *info = instance->bufferManagerWrapper->GetUsedInputDataBuffer(
505 instance->bufferManagerWrapper, timeoutMs);
506 if (info != NULL) {
507 *acquireFd = -1;
508 inputData->buffer[0].type = info->buffer[0].type;
509 CopyCodecBufferWithTypeSwitch(instance, inputData, info, false);
510 // fd has been transmitted at the initial time, here set invalid to avoid being transmitted again
511 if (inputData->buffer[0].type == BUFFER_TYPE_FD) {
512 inputData->buffer[0].buf = NO_TRANSMIT_FD;
513 } else if (inputData->buffer[0].type == BUFFER_TYPE_HANDLE) {
514 inputData->buffer[0].buf = NO_TRANSMIT_BUFFERHANDLE;
515 }
516 } else {
517 return HDF_ERR_TIMEOUT;
518 }
519
520 return HDF_SUCCESS;
521 }
522
CodecQueueOutput(CODEC_HANDLETYPE handle,CodecBuffer * outInfo,uint32_t timeoutMs,int releaseFenceFd)523 int32_t CodecQueueOutput(CODEC_HANDLETYPE handle, CodecBuffer *outInfo, uint32_t timeoutMs, int releaseFenceFd)
524 {
525 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
526 if (instance == NULL || instance->bufferManagerWrapper == NULL) {
527 HDF_LOGE("%{public}s: instance or buffermanager is NULL!", __func__);
528 return HDF_FAILURE;
529 }
530
531 if (instance->codecStatus == CODEC_STATUS_IDLE) {
532 if (instance->codecType != VIDEO_DECODER && instance->codecType != AUDIO_DECODER &&
533 instance->codecType != VIDEO_ENCODER && instance->codecType != AUDIO_ENCODER) {
534 HDF_LOGE("%{public}s: codecType invalid, queue output buffer failed!", __func__);
535 return HDF_FAILURE;
536 }
537 for (uint32_t i = 0; i < outInfo->bufferCnt; i++) {
538 if (AddOutputShm(instance, &outInfo->buffer[i], outInfo->bufferId) != HDF_SUCCESS) {
539 HDF_LOGE("%{public}s: AddOutputShm failed, queue output buffer failed!", __func__);
540 }
541 }
542 CodecBuffer *dup = DupCodecBuffer(outInfo);
543 if (AddOutputInfo(instance, dup) != HDF_SUCCESS) {
544 ReleaseCodecBuffer(dup);
545 HDF_LOGE("%{public}s: AddOutputInfo failed, queue output buffer failed!", __func__);
546 return HDF_FAILURE;
547 }
548 instance->bufferManagerWrapper->PutUsedOutputDataBuffer(instance->bufferManagerWrapper, dup);
549 return HDF_SUCCESS;
550 } else if (instance->codecStatus == CODEC_STATUS_STARTED ||
551 instance->codecCallbackStatus == CODEC_STATUS_STARTED) {
552 CodecBuffer *info = GetOutputInfo(instance, outInfo->bufferId);
553 CopyCodecBufferWithTypeSwitch(instance, info, outInfo, true);
554 EmptyCodecBuffer(info);
555 instance->bufferManagerWrapper->PutUsedOutputDataBuffer(instance->bufferManagerWrapper, info);
556 return HDF_SUCCESS;
557 } else if (instance->codecStatus == CODEC_STATUS_STOPPED || instance->codecStatus == CODEC_STATUS_STOPPING) {
558 CodecBuffer *dup = DupCodecBuffer(outInfo);
559 instance->bufferManagerWrapper->PutOutputDataBuffer(instance->bufferManagerWrapper, dup);
560 }
561 return HDF_SUCCESS;
562 }
563
CodecDequeueOutput(CODEC_HANDLETYPE handle,uint32_t timeoutMs,int32_t * acquireFd,CodecBuffer * outInfo)564 int32_t CodecDequeueOutput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int32_t *acquireFd, CodecBuffer *outInfo)
565 {
566 struct CodecInstance *instance = FindInCodecInstanceManager(handle);
567 if (instance == NULL || instance->bufferManagerWrapper == NULL) {
568 HDF_LOGE("%{public}s: instance or buffermanager is NULL!", __func__);
569 return HDF_FAILURE;
570 }
571
572 CodecBuffer *info = instance->bufferManagerWrapper->GetOutputDataBuffer(
573 instance->bufferManagerWrapper, timeoutMs);
574 if (info != NULL) {
575 *acquireFd = -1;
576 outInfo->buffer[0].type = info->buffer[0].type;
577 CopyCodecBufferWithTypeSwitch(instance, outInfo, info, false);
578 // fd has been transmitted at the initial time, here set invalid to avoid being transmitted again
579 if (outInfo->buffer[0].type == BUFFER_TYPE_FD) {
580 outInfo->buffer[0].buf = NO_TRANSMIT_FD;
581 } else if (outInfo->buffer[0].type == BUFFER_TYPE_HANDLE) {
582 outInfo->buffer[0].buf = NO_TRANSMIT_BUFFERHANDLE;
583 }
584 } else {
585 return HDF_ERR_TIMEOUT;
586 }
587
588 return HDF_SUCCESS;
589 }
590
591 #ifndef CODEC_HAL_PASSTHROUGH
CodecSetCallbackProxy(CODEC_HANDLETYPE handle,struct ICodecCallbackProxy * cb,UINTPTR instance)592 int32_t CodecSetCallbackProxy(CODEC_HANDLETYPE handle, struct ICodecCallbackProxy *cb, UINTPTR instance)
593 {
594 struct CodecInstance *codecInstance = FindInCodecInstanceManager(handle);
595 if (codecInstance == NULL || g_codecOemIface == NULL) {
596 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
597 return HDF_FAILURE;
598 }
599
600 codecInstance->callbackUserData = instance;
601 codecInstance->callbackProxy = cb;
602 codecInstance->hasCustomerCallback = true;
603
604 codecInstance->defaultCb.OnEvent = CodecOnEvent;
605 codecInstance->defaultCb.InputBufferAvailable = CodecInputBufferAvailable;
606 codecInstance->defaultCb.OutputBufferAvailable = CodecOutputBufferAvailable;
607 if (g_codecOemIface->codecSetCallback(handle, &(codecInstance->defaultCb), 0) != HDF_SUCCESS) {
608 HDF_LOGE("%{public}s: call oem codecSetCallback failed!", __func__);
609 return HDF_FAILURE;
610 }
611
612 return HDF_SUCCESS;
613 }
614 #else
CodecSetCallback(CODEC_HANDLETYPE handle,CodecCallback * cb,UINTPTR instance)615 int32_t CodecSetCallback(CODEC_HANDLETYPE handle, CodecCallback *cb, UINTPTR instance)
616 {
617 struct CodecInstance *codecInstance = FindInCodecInstanceManager(handle);
618 if (codecInstance == NULL || g_codecOemIface == NULL) {
619 HDF_LOGE("%{public}s: instance or g_codecOemIface is NULL!", __func__);
620 return HDF_FAILURE;
621 }
622
623 codecInstance->callbackUserData = instance;
624 codecInstance->codecCallback = cb;
625 codecInstance->hasCustomerCallback = true;
626
627 codecInstance->defaultCb.OnEvent = CodecOnEvent;
628 codecInstance->defaultCb.InputBufferAvailable = CodecInputBufferAvailable;
629 codecInstance->defaultCb.OutputBufferAvailable = CodecOutputBufferAvailable;
630 if (g_codecOemIface->codecSetCallback(handle, &(codecInstance->defaultCb), 0) != HDF_SUCCESS) {
631 HDF_LOGE("%{public}s: call oem codecSetCallback failed!", __func__);
632 return HDF_FAILURE;
633 }
634
635 return HDF_SUCCESS;
636 }
637 #endif
638
639