• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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