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_instance.h"
17 #include <buffer_handle_utils.h>
18 #include <dlfcn.h>
19 #include <securec.h>
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22
23 #define HDF_LOG_TAG codec_hdi_instance
24
25 #define CODEC_OEM_INTERFACE_LIB_NAME "libcodec_oem_interface.z.so"
26 #define BUFFER_COUNT 1
27
InitData(CodecBuffer ** inputData,CodecBuffer ** outputData)28 static bool InitData(CodecBuffer **inputData, CodecBuffer **outputData)
29 {
30 if (inputData == NULL || outputData == NULL) {
31 HDF_LOGE("%{public}s: inputData or outputData NULL!", __func__);
32 return false;
33 }
34 int32_t codecBufferSize = sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * BUFFER_COUNT;
35 *inputData = (CodecBuffer *)OsalMemCalloc(codecBufferSize);
36 if (*inputData == NULL) {
37 HDF_LOGE("%{public}s: inputData is NULL!", __func__);
38 return false;
39 }
40 *outputData = (CodecBuffer *)OsalMemCalloc(codecBufferSize);
41 if (*outputData == NULL) {
42 OsalMemFree(*inputData);
43 *inputData = NULL;
44 HDF_LOGE("%{public}s: outputData is NULL!", __func__);
45 return false;
46 }
47 return true;
48 }
49
WaitForOutputDataBuffer(struct CodecInstance * instance,CodecBuffer * outputData)50 static int32_t WaitForOutputDataBuffer(struct CodecInstance *instance, CodecBuffer *outputData)
51 {
52 struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper;
53 CodecBuffer *output = NULL;
54 while (instance->codecStatus == CODEC_STATUS_STARTED) {
55 if (bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)
56 && bmWrapper->IsUsedOutputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) {
57 output = bmWrapper->GetUsedOutputDataBuffer(bmWrapper, QUEUE_TIME_OUT);
58 if (output == NULL) {
59 continue;
60 }
61 if (!SetOemCodecBufferType(outputData, output)) {
62 HDF_LOGE("%{public}s: SetOemCodecBufferType failed!", __func__);
63 return HDF_FAILURE;
64 }
65 if (!CopyCodecBufferWithTypeSwitch(instance, outputData, output, false)) {
66 HDF_LOGE("%{public}s: CopyCodecBuffer failed!", __func__);
67 return HDF_FAILURE;
68 }
69 break;
70 }
71 }
72 return HDF_SUCCESS;
73 }
74
PrepareInputDataBuffer(struct BufferManagerWrapper * bmWrapper,struct CodecInstance * instance,CodecBuffer * bufferToOemCodec)75 static int32_t PrepareInputDataBuffer(struct BufferManagerWrapper *bmWrapper,
76 struct CodecInstance *instance, CodecBuffer *bufferToOemCodec)
77 {
78 if (!bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) {
79 return HDF_ERR_TIMEOUT;
80 }
81 CodecBuffer *bufferInQueue = bmWrapper->GetInputDataBuffer(bmWrapper, QUEUE_TIME_OUT);
82 if (bufferInQueue == NULL) {
83 return HDF_ERR_TIMEOUT;
84 }
85
86 if (!SetOemCodecBufferType(bufferToOemCodec, bufferInQueue)) {
87 HDF_LOGE("%{public}s: SetOemCodecBufferType failed!", __func__);
88 return HDF_FAILURE;
89 }
90 if (!CopyCodecBufferWithTypeSwitch(instance, bufferToOemCodec, bufferInQueue, false)) {
91 HDF_LOGE("%{public}s: CopyCodecBuffer failed!", __func__);
92 return HDF_FAILURE;
93 }
94 return HDF_SUCCESS;
95 }
96
CodecTaskThread(void * arg)97 static void *CodecTaskThread(void *arg)
98 {
99 if (arg == NULL) {
100 HDF_LOGE("%{public}s: Invalid arg, exit CodecTaskThread!", __func__);
101 return NULL;
102 }
103 struct CodecInstance *instance = (struct CodecInstance *)arg;
104 struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper;
105 if (bmWrapper == NULL) {
106 HDF_LOGE("%{public}s: BufferManager not ready!", __func__);
107 return NULL;
108 }
109 HDF_LOGI("%{public}s: codec task thread started!", __func__);
110
111 CodecBuffer *inputData = NULL;
112 CodecBuffer *outputData = NULL;
113 int32_t ret = HDF_FAILURE;
114 if (!InitData(&inputData, &outputData)) {
115 HDF_LOGE("%{public}s: InitData failed!", __func__);
116 return NULL;
117 }
118
119 inputData->bufferCnt = BUFFER_COUNT;
120 outputData->bufferCnt = BUFFER_COUNT;
121 if (WaitForOutputDataBuffer(instance, outputData) != HDF_SUCCESS) {
122 OsalMemFree(inputData);
123 OsalMemFree(outputData);
124 HDF_LOGE("%{public}s: WaitForOutputDataBuffer failed!", __func__);
125 return NULL;
126 }
127 while (instance->codecStatus == CODEC_STATUS_STARTED) {
128 if (PrepareInputDataBuffer(bmWrapper, instance, inputData) != HDF_SUCCESS) {
129 continue;
130 }
131
132 if (instance->codecType == VIDEO_DECODER) {
133 ret = instance->codecOemIface->codecDecode(instance->handle, inputData, outputData, QUEUE_TIME_OUT);
134 } else if (instance->codecType == VIDEO_ENCODER) {
135 ret = instance->codecOemIface->codecEncode(instance->handle, inputData, outputData, QUEUE_TIME_OUT);
136 }
137 if (ret == HDF_SUCCESS || (outputData->flag & STREAM_FLAG_EOS)) {
138 HDF_LOGI("%{public}s: output reach STREAM_FLAG_EOS!", __func__);
139 break;
140 }
141 }
142 OsalMutexLock(&instance->codecStatusLock);
143 instance->codecStatus = CODEC_STATUS_STOPPED;
144 pthread_cond_signal(&instance->codecStatusCond);
145 OsalMutexUnlock(&instance->codecStatusLock);
146
147 OsalMemFree(inputData);
148 OsalMemFree(outputData);
149 HDF_LOGI("%{public}s: codec task thread finished!", __func__);
150 return NULL;
151 }
152
GetUsedInputInfo(struct CodecInstance * instance,CodecBuffer * inputInfoSendToClient)153 static int32_t GetUsedInputInfo(struct CodecInstance *instance, CodecBuffer *inputInfoSendToClient)
154 {
155 if (instance == NULL || instance->bufferManagerWrapper == NULL || inputInfoSendToClient == NULL) {
156 HDF_LOGE("%{public}s failed: invalid parameter!", __func__);
157 return HDF_FAILURE;
158 }
159
160 CodecBuffer *inputInfo = instance->bufferManagerWrapper->GetUsedInputDataBuffer(
161 instance->bufferManagerWrapper, QUEUE_TIME_OUT);
162 if (inputInfo == NULL) {
163 return HDF_ERR_TIMEOUT;
164 }
165
166 inputInfoSendToClient->bufferCnt = inputInfo->bufferCnt;
167 inputInfoSendToClient->buffer[0].type = inputInfo->buffer[0].type;
168 if (!CopyCodecBufferWithTypeSwitch(instance, inputInfoSendToClient, inputInfo, false)) {
169 HDF_LOGE("%{public}s: copy CodecBuffer failed!", __func__);
170 return HDF_FAILURE;
171 }
172 // fd has been transmitted at the initial time, here set invalid to avoid being transmitted again
173 if (inputInfoSendToClient->buffer[0].type == BUFFER_TYPE_FD) {
174 inputInfoSendToClient->buffer[0].buf = NO_TRANSMIT_FD;
175 } else if (inputInfoSendToClient->buffer[0].type == BUFFER_TYPE_HANDLE) {
176 inputInfoSendToClient->buffer[0].buf = NO_TRANSMIT_BUFFERHANDLE;
177 }
178 return HDF_SUCCESS;
179 }
180
GetFilledOutputInfo(struct CodecInstance * instance,CodecBuffer * outputInfoSendToClient)181 static int32_t GetFilledOutputInfo(struct CodecInstance *instance, CodecBuffer *outputInfoSendToClient)
182 {
183 if (instance == NULL || instance->bufferManagerWrapper == NULL || outputInfoSendToClient == NULL) {
184 HDF_LOGE("%{public}s failed: invalid parameter!", __func__);
185 return HDF_FAILURE;
186 }
187
188 CodecBuffer *outputInfo = instance->bufferManagerWrapper->GetOutputDataBuffer(
189 instance->bufferManagerWrapper, QUEUE_TIME_OUT);
190 if (outputInfo == NULL) {
191 return HDF_ERR_TIMEOUT;
192 }
193
194 outputInfoSendToClient->bufferCnt = outputInfo->bufferCnt;
195 outputInfoSendToClient->buffer[0].type = outputInfo->buffer[0].type;
196 if (!CopyCodecBufferWithTypeSwitch(instance, outputInfoSendToClient, outputInfo, false)) {
197 HDF_LOGE("%{public}s: copy CodecBuffer failed!", __func__);
198 return HDF_FAILURE;
199 }
200 // fd has been transmitted at the initial time, here set invalid to avoid being transmitted again
201 if (outputInfoSendToClient->buffer[0].type == BUFFER_TYPE_FD) {
202 outputInfoSendToClient->buffer[0].buf = NO_TRANSMIT_FD;
203 } else if (outputInfoSendToClient->buffer[0].type == BUFFER_TYPE_HANDLE) {
204 outputInfoSendToClient->buffer[0].buf = NO_TRANSMIT_BUFFERHANDLE;
205 }
206 return HDF_SUCCESS;
207 }
208
CallbackTaskLoop(struct CodecInstance * instance,CodecBuffer * inputInfoSendToClient,CodecBuffer * outputInfoSendToClient)209 static void CallbackTaskLoop(struct CodecInstance *instance, CodecBuffer *inputInfoSendToClient,
210 CodecBuffer *outputInfoSendToClient)
211 {
212 int32_t acquireFd = 1;
213 bool codecTaskFinished = false;
214 int32_t getResult;
215 if (instance == NULL || inputInfoSendToClient == NULL || outputInfoSendToClient == NULL) {
216 HDF_LOGE("%{public}s failed: invalid parameter!", __func__);
217 return;
218 }
219 while (instance->codecCallbackStatus == CODEC_STATUS_STARTED) {
220 if (instance->codecStatus != CODEC_STATUS_STARTED) {
221 codecTaskFinished = true;
222 }
223 if (!instance->inputEos && GetUsedInputInfo(instance, inputInfoSendToClient) == HDF_SUCCESS) {
224 #ifndef CODEC_HAL_PASSTHROUGH
225 instance->callbackProxy->InputBufferAvailable(instance->callbackProxy, instance->callbackUserData,
226 inputInfoSendToClient, &acquireFd);
227 #else
228 instance->codecCallback->InputBufferAvailable(instance->callbackUserData,
229 inputInfoSendToClient, &acquireFd);
230 #endif
231 }
232 getResult = GetFilledOutputInfo(instance, outputInfoSendToClient);
233 if (getResult == HDF_SUCCESS) {
234 #ifndef CODEC_HAL_PASSTHROUGH
235 instance->callbackProxy->OutputBufferAvailable(instance->callbackProxy, instance->callbackUserData,
236 outputInfoSendToClient, &acquireFd);
237 #else
238 instance->codecCallback->OutputBufferAvailable(instance->callbackUserData,
239 outputInfoSendToClient, &acquireFd);
240 #endif
241 } else if (getResult == HDF_ERR_TIMEOUT && codecTaskFinished) {
242 HDF_LOGI("%{public}s: no output any more!", __func__);
243 EmptyCodecBuffer(outputInfoSendToClient);
244 outputInfoSendToClient->flag = STREAM_FLAG_EOS;
245 #ifndef CODEC_HAL_PASSTHROUGH
246 instance->callbackProxy->OutputBufferAvailable(instance->callbackProxy, instance->callbackUserData,
247 outputInfoSendToClient, &acquireFd);
248 #else
249 instance->codecCallback->OutputBufferAvailable(instance->callbackUserData,
250 outputInfoSendToClient, &acquireFd);
251 #endif
252 break;
253 }
254 if (outputInfoSendToClient->flag & STREAM_FLAG_EOS) {
255 HDF_LOGI("%{public}s: output reach STREAM_FLAG_EOS!", __func__);
256 break;
257 }
258 }
259 }
260
CodecCallbackTaskThread(void * arg)261 static void *CodecCallbackTaskThread(void *arg)
262 {
263 HDF_LOGI("%{public}s: codec callback task thread started!", __func__);
264 if (arg == NULL) {
265 HDF_LOGE("%{public}s: Invalid arg, exit CodecTaskThread!", __func__);
266 return NULL;
267 }
268 struct CodecInstance *instance = (struct CodecInstance *)arg;
269
270 CodecBuffer *inputInfoSendToClient = NULL;
271 CodecBuffer *outputInfoSendToClient = NULL;
272 if (!InitData(&inputInfoSendToClient, &outputInfoSendToClient)) {
273 HDF_LOGE("%{public}s: InitData failed!", __func__);
274 return NULL;
275 }
276
277 CallbackTaskLoop(instance, inputInfoSendToClient, outputInfoSendToClient);
278
279 OsalMutexLock(&instance->codecCallbackStatusLock);
280 instance->codecCallbackStatus = CODEC_STATUS_STOPPED;
281 pthread_cond_signal(&instance->codecCallbackStatusCond);
282 OsalMutexUnlock(&instance->codecCallbackStatusLock);
283
284 OsalMemFree(inputInfoSendToClient);
285 OsalMemFree(outputInfoSendToClient);
286 HDF_LOGI("%{public}s: codec callback task thread finished!", __func__);
287 return NULL;
288 }
289
GetCodecInstance(void)290 struct CodecInstance* GetCodecInstance(void)
291 {
292 struct CodecInstance *instance = (struct CodecInstance *)OsalMemCalloc(sizeof(struct CodecInstance));
293 if (instance == NULL) {
294 HDF_LOGE("%{public}s: instance mem alloc failed", __func__);
295 return NULL;
296 }
297
298 instance->codecStatus = CODEC_STATUS_IDLE;
299 instance->codecCallbackStatus = CODEC_STATUS_IDLE;
300 instance->inputEos = false;
301 instance->hasCustomerCallback = false;
302 return instance;
303 }
304
InitCodecInstance(struct CodecInstance * instance,struct CodecOemIf * oemIf)305 int32_t InitCodecInstance(struct CodecInstance *instance, struct CodecOemIf *oemIf)
306 {
307 if (instance == NULL || oemIf == NULL) {
308 HDF_LOGE("%{public}s: Invalid param!", __func__);
309 return HDF_FAILURE;
310 }
311 instance->codecOemIface = oemIf;
312 instance->bufferManagerWrapper = GetBufferManager();
313 if (instance->bufferManagerWrapper == NULL) {
314 HDF_LOGE("%{public}s: GetBufferManager failed", __func__);
315 return HDF_FAILURE;
316 }
317
318 int32_t ret = OsalMutexInit(&instance->codecStatusLock);
319 if (ret != HDF_SUCCESS) {
320 HDF_LOGE("%{public}s: OsalMutexInit failed, ret:%{public}d", __func__, ret);
321 return HDF_FAILURE;
322 }
323 ret = pthread_cond_init(&instance->codecStatusCond, NULL);
324 if (ret != 0) {
325 HDF_LOGE("%{public}s: pthread_cond_init failed, ret:%{public}d", __func__, ret);
326 return HDF_FAILURE;
327 }
328 ret = OsalMutexInit(&instance->codecCallbackStatusLock);
329 if (ret != HDF_SUCCESS) {
330 HDF_LOGE("%{public}s: OsalMutexInit failed, ret:%{public}d", __func__, ret);
331 return HDF_FAILURE;
332 }
333 ret = pthread_cond_init(&instance->codecCallbackStatusCond, NULL);
334 if (ret != 0) {
335 HDF_LOGE("%{public}s: pthread_cond_init failed, ret:%{public}d", __func__, ret);
336 return HDF_FAILURE;
337 }
338
339 return HDF_SUCCESS;
340 }
341
RunCodecInstance(struct CodecInstance * instance)342 int32_t RunCodecInstance(struct CodecInstance *instance)
343 {
344 if (instance == NULL) {
345 HDF_LOGE("%{public}s: Invalid param!", __func__);
346 return HDF_FAILURE;
347 }
348
349 instance->codecStatus = CODEC_STATUS_STARTED;
350 pthread_attr_init(&instance->codecTaskAttr);
351 pthread_attr_setdetachstate(&instance->codecTaskAttr, PTHREAD_CREATE_JOINABLE);
352 int32_t ret = pthread_create(&instance->codecTask, NULL, CodecTaskThread, instance);
353 if (ret != 0) {
354 HDF_LOGE("%{public}s: run codec task thread failed!", __func__);
355 instance->codecStatus = CODEC_STATUS_STOPPED;
356 return HDF_FAILURE;
357 }
358
359 if (instance->hasCustomerCallback) {
360 instance->codecCallbackStatus = CODEC_STATUS_STARTED;
361 pthread_attr_init(&instance->codecCallbackTaskAttr);
362 pthread_attr_setdetachstate(&instance->codecCallbackTaskAttr, PTHREAD_CREATE_JOINABLE);
363 ret = pthread_create(&instance->codecCallbackTask, NULL, CodecCallbackTaskThread, instance);
364 if (ret != 0) {
365 HDF_LOGE("%{public}s: run codec callback task thread failed!", __func__);
366 instance->codecStatus = CODEC_STATUS_STOPPING;
367 instance->codecCallbackStatus = CODEC_STATUS_STOPPED;
368 return HDF_FAILURE;
369 }
370 }
371 return HDF_SUCCESS;
372 }
373
StopCodecInstance(struct CodecInstance * instance)374 int32_t StopCodecInstance(struct CodecInstance *instance)
375 {
376 if (instance == NULL) {
377 HDF_LOGE("%{public}s: Invalid param!", __func__);
378 return HDF_FAILURE;
379 }
380
381 OsalMutexLock(&instance->codecStatusLock);
382 if (instance->codecStatus == CODEC_STATUS_STARTED) {
383 instance->codecStatus = CODEC_STATUS_STOPPING;
384 } else {
385 instance->codecStatus = CODEC_STATUS_STOPPED;
386 }
387 OsalMutexUnlock(&instance->codecStatusLock);
388
389 OsalMutexLock(&instance->codecCallbackStatusLock);
390 if (instance->codecCallbackStatus == CODEC_STATUS_STARTED) {
391 instance->codecCallbackStatus = CODEC_STATUS_STOPPING;
392 } else {
393 instance->codecCallbackStatus = CODEC_STATUS_STOPPED;
394 }
395 OsalMutexUnlock(&instance->codecCallbackStatusLock);
396
397 return HDF_SUCCESS;
398 }
399
DestroyCodecInstance(struct CodecInstance * instance)400 int32_t DestroyCodecInstance(struct CodecInstance *instance)
401 {
402 if (instance == NULL) {
403 HDF_LOGE("%{public}s: Invalid param!", __func__);
404 return HDF_FAILURE;
405 }
406
407 OsalMutexLock(&instance->codecStatusLock);
408 if (instance->codecStatus == CODEC_STATUS_STARTED ||
409 instance->codecStatus == CODEC_STATUS_STOPPING) {
410 HDF_LOGI("%{public}s: wait codec task stop!", __func__);
411 if (instance->codecStatusLock.realMutex != NULL) {
412 pthread_cond_wait(&instance->codecStatusCond,
413 (pthread_mutex_t *)instance->codecStatusLock.realMutex);
414 }
415 }
416 OsalMutexUnlock(&instance->codecStatusLock);
417 pthread_cond_destroy(&instance->codecStatusCond);
418 OsalMutexDestroy(&instance->codecStatusLock);
419 pthread_attr_destroy(&instance->codecTaskAttr);
420
421 OsalMutexLock(&instance->codecCallbackStatusLock);
422 if (instance->codecCallbackStatus == CODEC_STATUS_STARTED ||
423 instance->codecCallbackStatus == CODEC_STATUS_STOPPING) {
424 HDF_LOGI("%{public}s: wait codec callback task stop!", __func__);
425 if (instance->codecStatusLock.realMutex != NULL) {
426 pthread_cond_wait(&instance->codecCallbackStatusCond,
427 (pthread_mutex_t *)instance->codecCallbackStatusLock.realMutex);
428 }
429 }
430 OsalMutexUnlock(&instance->codecCallbackStatusLock);
431 pthread_cond_destroy(&instance->codecCallbackStatusCond);
432 OsalMutexDestroy(&instance->codecCallbackStatusLock);
433 pthread_attr_destroy(&instance->codecCallbackTaskAttr);
434
435 ReleaseInputShm(instance);
436 ReleaseOutputShm(instance);
437 ReleaseInputInfo(instance);
438 ReleaseOutputInfo(instance);
439
440 DeleteBufferManager(&(instance->bufferManagerWrapper));
441 return HDF_SUCCESS;
442 }
443
SetOemCodecBufferType(CodecBuffer * bufferToOemCodec,CodecBuffer * bufferInQueue)444 bool SetOemCodecBufferType(CodecBuffer *bufferToOemCodec, CodecBuffer *bufferInQueue)
445 {
446 if (bufferToOemCodec == NULL || bufferInQueue == NULL) {
447 HDF_LOGE("%{public}s: Invalid params!", __func__);
448 return false;
449 }
450 if (bufferInQueue->buffer[0].type == BUFFER_TYPE_HANDLE) {
451 bufferToOemCodec->buffer[0].type = BUFFER_TYPE_HANDLE;
452 } else {
453 bufferToOemCodec->buffer[0].type = BUFFER_TYPE_VIRTUAL;
454 }
455 return true;
456 }
457
AddInputShm(struct CodecInstance * instance,const CodecBufferInfo * bufferInfo,int32_t bufferId)458 int32_t AddInputShm(struct CodecInstance *instance, const CodecBufferInfo *bufferInfo, int32_t bufferId)
459 {
460 if (instance == NULL || bufferInfo == NULL) {
461 HDF_LOGE("%{public}s: Invalid param!", __func__);
462 return HDF_FAILURE;
463 }
464 int32_t count = instance->inputBuffersCount;
465 if (count >= MAX_BUFFER_NUM) {
466 HDF_LOGE("%{public}s: ShareMemory buffer array full!", __func__);
467 return HDF_FAILURE;
468 }
469 instance->inputBuffers[count].id = bufferId;
470 instance->inputBuffers[count].size = bufferInfo->capacity;
471 instance->inputBuffers[count].type = bufferInfo->type;
472 if (bufferInfo->type == BUFFER_TYPE_HANDLE) {
473 BufferHandle *bufferHandle = (BufferHandle *)bufferInfo->buf;
474 if (bufferHandle == NULL) {
475 HDF_LOGE("%{public}s: null bufferHandle!", __func__);
476 return HDF_FAILURE;
477 }
478 instance->inputBuffers[count].fd = bufferHandle->fd;
479 } else if (bufferInfo->type == BUFFER_TYPE_FD) {
480 instance->inputBuffers[count].fd = (int32_t)bufferInfo->buf;
481 if (OpenFdShareMemory(&instance->inputBuffers[count]) != HDF_SUCCESS) {
482 return HDF_FAILURE;
483 }
484 }
485 instance->inputBuffersCount++;
486 return HDF_SUCCESS;
487 }
488
AddOutputShm(struct CodecInstance * instance,const CodecBufferInfo * bufferInfo,int32_t bufferId)489 int32_t AddOutputShm(struct CodecInstance *instance, const CodecBufferInfo *bufferInfo, int32_t bufferId)
490 {
491 if (instance == NULL || bufferInfo == NULL) {
492 HDF_LOGE("%{public}s: Invalid param!", __func__);
493 return HDF_FAILURE;
494 }
495 int32_t count = instance->outputBuffersCount;
496 if (count >= MAX_BUFFER_NUM) {
497 HDF_LOGE("%{public}s: ShareMemory buffer array full!", __func__);
498 return HDF_FAILURE;
499 }
500 instance->outputBuffers[count].id = bufferId;
501 instance->outputBuffers[count].size = bufferInfo->capacity;
502 instance->outputBuffers[count].type = bufferInfo->type;
503 if (bufferInfo->type == BUFFER_TYPE_HANDLE) {
504 BufferHandle *bufferHandle = (BufferHandle *)bufferInfo->buf;
505 if (bufferHandle == NULL) {
506 HDF_LOGE("%{public}s: null bufferHandle!", __func__);
507 return HDF_FAILURE;
508 }
509 instance->outputBuffers[count].fd = bufferHandle->fd;
510 } else if (bufferInfo->type == BUFFER_TYPE_FD) {
511 instance->outputBuffers[count].fd = (int32_t)bufferInfo->buf;
512 if (OpenFdShareMemory(&instance->outputBuffers[count]) != HDF_SUCCESS) {
513 return HDF_FAILURE;
514 }
515 }
516 instance->outputBuffersCount++;
517 return HDF_SUCCESS;
518 }
519
GetShmById(struct CodecInstance * instance,int32_t id)520 static ShareMemory* GetShmById(struct CodecInstance *instance, int32_t id)
521 {
522 int32_t i;
523 if (instance == NULL) {
524 HDF_LOGE("%{public}s: Invalid param!", __func__);
525 return NULL;
526 }
527 for (i = 0; i < instance->inputBuffersCount; i++) {
528 if (instance->inputBuffers[i].id == id) {
529 return &(instance->inputBuffers[i]);
530 }
531 }
532 for (i = 0; i < instance->outputBuffersCount; i++) {
533 if (instance->outputBuffers[i].id == id) {
534 return &(instance->outputBuffers[i]);
535 }
536 }
537 HDF_LOGE("%{public}s: not found for bufferId:%{public}d!", __func__, id);
538 return NULL;
539 }
540
GetFdById(struct CodecInstance * instance,int32_t id)541 int32_t GetFdById(struct CodecInstance *instance, int32_t id)
542 {
543 if (instance == NULL) {
544 HDF_LOGE("%{public}s: Invalid param!", __func__);
545 return HDF_FAILURE;
546 }
547 int32_t i;
548 for (i = 0; i < instance->inputBuffersCount; i++) {
549 if (instance->inputBuffers[i].id == id) {
550 return instance->inputBuffers[i].fd;
551 }
552 }
553 for (i = 0; i < instance->outputBuffersCount; i++) {
554 if (instance->outputBuffers[i].id == id) {
555 return instance->outputBuffers[i].fd;
556 }
557 }
558 HDF_LOGE("%{public}s: not found bufferId:%{public}d!", __func__, id);
559 return HDF_FAILURE;
560 }
561
ReleaseInputShm(struct CodecInstance * instance)562 void ReleaseInputShm(struct CodecInstance *instance)
563 {
564 if (instance == NULL) {
565 HDF_LOGE("%{public}s: Invalid param!", __func__);
566 return;
567 }
568 for (int32_t i = 0; i < instance->inputBuffersCount; i++) {
569 if (instance->inputBuffers[i].type == BUFFER_TYPE_FD) {
570 ReleaseFdShareMemory(&instance->inputBuffers[i]);
571 }
572 }
573 }
ReleaseOutputShm(struct CodecInstance * instance)574 void ReleaseOutputShm(struct CodecInstance *instance)
575 {
576 if (instance == NULL) {
577 HDF_LOGE("%{public}s: Invalid param!", __func__);
578 return;
579 }
580 for (int32_t i = 0; i < instance->outputBuffersCount; i++) {
581 if (instance->outputBuffers[i].type == BUFFER_TYPE_FD) {
582 ReleaseFdShareMemory(&instance->outputBuffers[i]);
583 }
584 }
585 }
586
AddInputInfo(struct CodecInstance * instance,CodecBuffer * info)587 int32_t AddInputInfo(struct CodecInstance *instance, CodecBuffer *info)
588 {
589 if (instance == NULL || info == NULL) {
590 HDF_LOGE("%{public}s: Invalid param!", __func__);
591 return HDF_FAILURE;
592 }
593 if (instance->inputInfoCount >= MAX_BUFFER_NUM) {
594 HDF_LOGE("%{public}s: CodecBuffer array full!", __func__);
595 return HDF_FAILURE;
596 }
597 instance->inputInfos[instance->inputInfoCount] = info;
598 instance->inputInfoCount++;
599 return HDF_SUCCESS;
600 }
601
AddOutputInfo(struct CodecInstance * instance,CodecBuffer * info)602 int32_t AddOutputInfo(struct CodecInstance *instance, CodecBuffer *info)
603 {
604 if (instance == NULL || info == NULL) {
605 HDF_LOGE("%{public}s: Invalid param!", __func__);
606 return HDF_FAILURE;
607 }
608 if (instance->outputInfoCount >= MAX_BUFFER_NUM) {
609 HDF_LOGE("%{public}s: CodecBuffer array full!", __func__);
610 return HDF_FAILURE;
611 }
612 instance->outputInfos[instance->outputInfoCount] = info;
613 instance->outputInfoCount++;
614 return HDF_SUCCESS;
615 }
616
GetInputInfo(struct CodecInstance * instance,uint32_t id)617 CodecBuffer* GetInputInfo(struct CodecInstance *instance, uint32_t id)
618 {
619 if (instance == NULL) {
620 HDF_LOGE("%{public}s: Invalid param!", __func__);
621 return NULL;
622 }
623 for (int32_t i = 0; i < instance->inputInfoCount; i++) {
624 if (instance->inputInfos[i]->bufferId == id) {
625 return instance->inputInfos[i];
626 }
627 }
628 HDF_LOGE("%{public}s: not found bufferId:%{public}d!", __func__, id);
629 return NULL;
630 }
631
GetOutputInfo(struct CodecInstance * instance,uint32_t id)632 CodecBuffer* GetOutputInfo(struct CodecInstance *instance, uint32_t id)
633 {
634 if (instance == NULL) {
635 HDF_LOGE("%{public}s: Invalid param!", __func__);
636 return NULL;
637 }
638 for (int32_t i = 0; i < instance->outputInfoCount; i++) {
639 if (instance->outputInfos[i]->bufferId == id) {
640 return instance->outputInfos[i];
641 }
642 }
643 HDF_LOGE("%{public}s: not found bufferId:%{public}d!", __func__, id);
644 return NULL;
645 }
646
ReleaseCodecBuffer(CodecBuffer * info)647 void ReleaseCodecBuffer(CodecBuffer *info)
648 {
649 if (info == NULL) {
650 HDF_LOGI("%{public}s: Invalid param!", __func__);
651 return;
652 }
653 for (uint32_t i = 0; i < info->bufferCnt; i++) {
654 if (info->buffer[i].type == BUFFER_TYPE_HANDLE) {
655 FreeBufferHandle((BufferHandle *)info->buffer[i].buf);
656 }
657 }
658 OsalMemFree(info);
659 }
660
ReleaseInputInfo(struct CodecInstance * instance)661 void ReleaseInputInfo(struct CodecInstance *instance)
662 {
663 if (instance == NULL) {
664 HDF_LOGE("%{public}s: Invalid param!", __func__);
665 return;
666 }
667 for (int32_t i = 0; i < instance->inputInfoCount; i++) {
668 ReleaseCodecBuffer(instance->inputInfos[i]);
669 instance->inputInfos[i] = NULL;
670 }
671 }
672
ReleaseOutputInfo(struct CodecInstance * instance)673 void ReleaseOutputInfo(struct CodecInstance *instance)
674 {
675 if (instance == NULL) {
676 HDF_LOGE("%{public}s: Invalid param!", __func__);
677 return;
678 }
679 for (int32_t i = 0; i < instance->outputInfoCount; i++) {
680 ReleaseCodecBuffer(instance->outputInfos[i]);
681 instance->outputInfos[i] = NULL;
682 }
683 }
684
ResetBuffers(struct CodecInstance * instance)685 void ResetBuffers(struct CodecInstance *instance)
686 {
687 if (instance == NULL) {
688 HDF_LOGE("%{public}s: Invalid param!", __func__);
689 return;
690 }
691 int32_t i;
692 ReleaseInputShm(instance);
693 ReleaseOutputShm(instance);
694 for (i = 0; i< instance->inputInfoCount; i++) {
695 ReleaseCodecBuffer(instance->inputInfos[i]);
696 }
697 for (i = 0; i< instance->outputInfoCount; i++) {
698 ReleaseCodecBuffer(instance->outputInfos[i]);
699 }
700
701 instance->inputBuffersCount = 0;
702 instance->outputBuffersCount = 0;
703 instance->inputInfoCount = 0;
704 instance->outputInfoCount = 0;
705 }
706
EmptyCodecBuffer(CodecBuffer * buf)707 void EmptyCodecBuffer(CodecBuffer *buf)
708 {
709 if (buf == NULL) {
710 return;
711 }
712 for (uint32_t i = 0; i < buf->bufferCnt; i++) {
713 buf->buffer[i].length = 0;
714 buf->buffer[i].offset = 0;
715 }
716 }
717
CopyCodecBufferWithTypeSwitch(struct CodecInstance * instance,CodecBuffer * dst,const CodecBuffer * src,bool ignoreBuf)718 bool CopyCodecBufferWithTypeSwitch(struct CodecInstance *instance, CodecBuffer *dst,
719 const CodecBuffer *src, bool ignoreBuf)
720 {
721 if (dst == NULL || src == NULL) {
722 HDF_LOGE("%{public}s: dst or src is Nullpoint", __func__);
723 return false;
724 }
725 if (dst->bufferCnt != src->bufferCnt) {
726 HDF_LOGE("%{public}s: size not match", __func__);
727 return false;
728 }
729 dst->bufferId = src->bufferId;
730 dst->timeStamp = src->timeStamp;
731 dst->flag = src->flag;
732 for (uint32_t i = 0; i < src->bufferCnt; i++) {
733 dst->buffer[i].offset = src->buffer[i].offset;
734 dst->buffer[i].length = src->buffer[i].length;
735 dst->buffer[i].capacity = src->buffer[i].capacity;
736 if (ignoreBuf) {
737 continue;
738 } else if (dst->buffer[i].type == src->buffer[i].type) {
739 dst->buffer[i].buf = src->buffer[i].buf;
740 } else if (dst->buffer[i].type == BUFFER_TYPE_VIRTUAL && src->buffer[i].type == BUFFER_TYPE_FD) {
741 dst->buffer[i].buf = (intptr_t)GetShmById(instance, src->bufferId)->virAddr;
742 } else if (dst->buffer[i].type == BUFFER_TYPE_VIRTUAL && src->buffer[i].type == BUFFER_TYPE_HANDLE) {
743 dst->buffer[i].buf = (intptr_t)GetShmById(instance, src->bufferId)->virAddr;
744 }
745 if (dst->buffer[i].buf == 0) {
746 HDF_LOGE("%{public}s: buf value invalid! bufferId:%{public}d", __func__, src->bufferId);
747 return false;
748 }
749 }
750 return true;
751 }
752
DupBufferHandle(const BufferHandle * handle)753 static BufferHandle *DupBufferHandle(const BufferHandle *handle)
754 {
755 if (handle == NULL) {
756 HDF_LOGE("%{public}s buffer handle is NULL", __func__);
757 return NULL;
758 }
759
760 BufferHandle *newHandle = AllocateBufferHandle(handle->reserveFds, handle->reserveInts);
761 if (newHandle == NULL) {
762 HDF_LOGE("%{public}s AllocateBufferHandle failed, newHandle is NULL", __func__);
763 return NULL;
764 }
765
766 newHandle->fd = handle->fd;
767 newHandle->width = handle->width;
768 newHandle->stride = handle->stride;
769 newHandle->height = handle->height;
770 newHandle->size = handle->size;
771 newHandle->format = handle->format;
772 newHandle->usage = handle->usage;
773 newHandle->virAddr = handle->virAddr;
774 newHandle->phyAddr = handle->phyAddr;
775
776 return newHandle;
777 }
778
DupCodecBuffer(const CodecBuffer * src)779 CodecBuffer* DupCodecBuffer(const CodecBuffer *src)
780 {
781 if (src == NULL) {
782 HDF_LOGE("%{public}s: CodecBuffer src Nullpoint", __func__);
783 return NULL;
784 }
785 int32_t size = sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * src->bufferCnt;
786 CodecBuffer *dst = (CodecBuffer *)OsalMemAlloc(size);
787 if (dst == NULL) {
788 HDF_LOGE("%{public}s: malloc dst failed", __func__);
789 return NULL;
790 }
791 int32_t ret = memcpy_s(dst, size, src, size);
792 if (ret != EOK) {
793 HDF_LOGE("%{public}s: memcpy_s failed, error code: %{public}d", __func__, ret);
794 OsalMemFree(dst);
795 return NULL;
796 }
797 for (uint32_t i = 0; i < src->bufferCnt; i++) {
798 if (dst->buffer[i].type == BUFFER_TYPE_HANDLE) {
799 dst->buffer[i].buf = (intptr_t)DupBufferHandle((BufferHandle *)src->buffer[i].buf);
800 }
801 }
802 return dst;
803 }
804
805