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_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 CODEC_BUFFER_MANAGER_LIB_NAME "libcodec_buffer_manager.z.so"
27 #define BUFFER_COUNT 1
28
InitCodecOemIf(struct CodecInstance * instance)29 static int32_t InitCodecOemIf(struct CodecInstance *instance)
30 {
31 if (instance == NULL || instance->codecOemIface == NULL) {
32 HDF_LOGE("%{public}s: Invalid param!", __func__);
33 return HDF_FAILURE;
34 }
35
36 void *libHandle = dlopen(CODEC_OEM_INTERFACE_LIB_NAME, RTLD_NOW);
37 if (libHandle == NULL) {
38 HDF_LOGE("%{public}s: lib %{public}s dlopen failed, error code[%{public}s]",
39 __func__, CODEC_OEM_INTERFACE_LIB_NAME, dlerror());
40 return HDF_FAILURE;
41 }
42
43 struct CodecOemIf *iface = instance->codecOemIface;
44 iface->codecInit = (CodecInitType)dlsym(libHandle, "CodecInit");
45 iface->codecDeinit = (CodecDeinitType)dlsym(libHandle, "CodecDeinit");
46 iface->codecCreate = (CodecCreateType)dlsym(libHandle, "CodecCreate");
47 iface->codecDestroy = (CodecDestroyType)dlsym(libHandle, "CodecDestroy");
48 iface->codecSetParameter = (CodecSetParameterType)dlsym(libHandle, "CodecSetParameter");
49 iface->codecGetParameter = (CodecGetParameterType)dlsym(libHandle, "CodecGetParameter");
50 iface->codecStart = (CodecStartType)dlsym(libHandle, "CodecStart");
51 iface->codecStop = (CodecStopType)dlsym(libHandle, "CodecStop");
52 iface->codecFlush = (CodecFlushType)dlsym(libHandle, "CodecFlush");
53 iface->codecSetCallback = (CodecSetCallbackType)dlsym(libHandle, "CodecSetCallback");
54 iface->codecDecode = (CodecDecodeType)dlsym(libHandle, "CodecDecode");
55 iface->codecEncode = (CodecEncodeType)dlsym(libHandle, "CodecEncode");
56 iface->codecEncodeHeader = (CodecEncodeHeaderType)dlsym(libHandle, "CodecEncodeHeader");
57
58 instance->oemLibHandle = libHandle;
59 return HDF_SUCCESS;
60 }
61
InitBufferManagerIf(struct CodecInstance * instance)62 static int32_t InitBufferManagerIf(struct CodecInstance *instance)
63 {
64 if (instance == NULL || instance->bufferManagerIface == NULL) {
65 HDF_LOGE("%{public}s: Invalid param!", __func__);
66 return HDF_FAILURE;
67 }
68
69 void *libHandle = dlopen(CODEC_BUFFER_MANAGER_LIB_NAME, RTLD_NOW);
70 if (libHandle == NULL) {
71 HDF_LOGE("%{public}s: lib %{public}s dlopen failed, error code[%{public}s]",
72 __func__, CODEC_BUFFER_MANAGER_LIB_NAME, dlerror());
73 return HDF_FAILURE;
74 }
75
76 struct BufferManagerIf *iface = instance->bufferManagerIface;
77 iface->getBufferManager = (GetBufferManagerType)dlsym(libHandle, "GetBufferManager");
78 iface->deleteBufferManager = (DeleteBufferManagerType)dlsym(libHandle, "DeleteBufferManager");
79 if (iface->getBufferManager != NULL) {
80 HDF_LOGI("%{public}s: dlsym ok", __func__);
81 instance->bufferManagerWrapper = iface->getBufferManager();
82 } else {
83 HDF_LOGE("%{public}s: lib %{public}s dlsym failed, error code[%{public}s]",
84 __func__, CODEC_BUFFER_MANAGER_LIB_NAME, dlerror());
85 return HDF_FAILURE;
86 }
87
88 instance->bufferManagerLibHandle = libHandle;
89 return HDF_SUCCESS;
90 }
91
WaitForOutputDataBuffer(struct CodecInstance * instance,CodecBuffer * outputData)92 static int32_t WaitForOutputDataBuffer(struct CodecInstance *instance, CodecBuffer *outputData)
93 {
94 struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper;
95 CodecBuffer *output = NULL;
96 while (instance->codecStatus == CODEC_STATUS_STARTED) {
97 if (bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)
98 && bmWrapper->IsUsedOutputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) {
99 output = bmWrapper->GetUsedOutputDataBuffer(bmWrapper, QUEUE_TIME_OUT);
100 if (output == NULL) {
101 continue;
102 }
103 if (!SetOemCodecBufferType(outputData, output)) {
104 HDF_LOGE("%{public}s: SetOemCodecBufferType failed!", __func__);
105 return HDF_FAILURE;
106 }
107 if (!CopyCodecBufferWithTypeSwitch(instance, outputData, output, false)) {
108 HDF_LOGE("%{public}s: CopyCodecBuffer failed!", __func__);
109 return HDF_FAILURE;
110 }
111 break;
112 }
113 }
114 return HDF_SUCCESS;
115 }
116
PrepareInputDataBuffer(struct BufferManagerWrapper * bmWrapper,struct CodecInstance * instance,CodecBuffer * bufferToOemCodec)117 static int32_t PrepareInputDataBuffer(struct BufferManagerWrapper *bmWrapper,
118 struct CodecInstance *instance, CodecBuffer *bufferToOemCodec)
119 {
120 if (!bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) {
121 return HDF_ERR_TIMEOUT;
122 }
123 CodecBuffer *bufferInQueue = bmWrapper->GetInputDataBuffer(bmWrapper, QUEUE_TIME_OUT);
124 if (bufferInQueue == NULL) {
125 return HDF_ERR_TIMEOUT;
126 }
127
128 if (!SetOemCodecBufferType(bufferToOemCodec, bufferInQueue)) {
129 HDF_LOGE("%{public}s: SetOemCodecBufferType failed!", __func__);
130 return HDF_FAILURE;
131 }
132 if (!CopyCodecBufferWithTypeSwitch(instance, bufferToOemCodec, bufferInQueue, false)) {
133 HDF_LOGE("%{public}s: CopyCodecBuffer failed!", __func__);
134 return HDF_FAILURE;
135 }
136 return HDF_SUCCESS;
137 }
138
CodecTaskThread(void * arg)139 static void *CodecTaskThread(void *arg)
140 {
141 if (arg == NULL) {
142 HDF_LOGE("%{public}s: Invalid arg, exit CodecTaskThread!", __func__);
143 return NULL;
144 }
145 struct CodecInstance *instance = (struct CodecInstance *)arg;
146 struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper;
147 if (bmWrapper == NULL) {
148 HDF_LOGE("%{public}s: BufferManager not ready!", __func__);
149 return NULL;
150 }
151 HDF_LOGI("%{public}s: CodecTaskThread start!", __func__);
152
153 int32_t codecBufferSize = sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * BUFFER_COUNT;
154 CodecBuffer *inputData = (CodecBuffer *)OsalMemCalloc(codecBufferSize);
155 CodecBuffer *outputData = (CodecBuffer *)OsalMemCalloc(codecBufferSize);
156 int32_t ret = HDF_FAILURE;
157
158 inputData->bufferCnt = BUFFER_COUNT;
159 outputData->bufferCnt = BUFFER_COUNT;
160 if (WaitForOutputDataBuffer(instance, outputData) != HDF_SUCCESS) {
161 return NULL;
162 }
163 while (instance->codecStatus == CODEC_STATUS_STARTED) {
164 if (PrepareInputDataBuffer(bmWrapper, instance, inputData) != HDF_SUCCESS) {
165 continue;
166 }
167
168 if (instance->codecType == VIDEO_DECODER) {
169 ret = instance->codecOemIface->codecDecode(instance->handle, inputData, outputData, QUEUE_TIME_OUT);
170 } else if (instance->codecType == VIDEO_ENCODER) {
171 ret = instance->codecOemIface->codecEncode(instance->handle, inputData, outputData, QUEUE_TIME_OUT);
172 }
173 if (ret == HDF_SUCCESS || (outputData->flag & STREAM_FLAG_EOS)) {
174 HDF_LOGI("%{public}s: output reach STREAM_FLAG_EOS!", __func__);
175 instance->codecStatus = CODEC_STATUS_STOPED;
176 }
177 }
178
179 OsalMemFree(inputData);
180 OsalMemFree(outputData);
181 HDF_LOGI("%{public}s: codec task thread finished!", __func__);
182 return NULL;
183 }
184
GetCodecInstance(void)185 struct CodecInstance* GetCodecInstance(void)
186 {
187 struct CodecInstance *instance = (struct CodecInstance *)OsalMemCalloc(sizeof(struct CodecInstance));
188 if (instance == NULL) {
189 HDF_LOGE("%{public}s: instance mem alloc failed", __func__);
190 return NULL;
191 }
192
193 instance->codecStatus = CODEC_STATUS_IDLE;
194 instance->hasCallback = false;
195 return instance;
196 }
197
InitCodecInstance(struct CodecInstance * instance)198 int32_t InitCodecInstance(struct CodecInstance *instance)
199 {
200 if (instance == NULL) {
201 HDF_LOGE("%{public}s: Invalid param!", __func__);
202 return HDF_FAILURE;
203 }
204
205 instance->codecOemIface = (struct CodecOemIf *)OsalMemCalloc(sizeof(struct CodecOemIf));
206 if (instance->codecOemIface == NULL) {
207 HDF_LOGE("%{public}s: codecOemIface mem alloc failed", __func__);
208 return HDF_FAILURE;
209 }
210 int32_t ret = InitCodecOemIf(instance);
211 if (ret != HDF_SUCCESS) {
212 HDF_LOGE("%{public}s: InitCodecOemIf failed", __func__);
213 return HDF_FAILURE;
214 }
215 instance->bufferManagerIface = (struct BufferManagerIf *)OsalMemAlloc(sizeof(struct BufferManagerIf));
216 if (instance->bufferManagerIface == NULL) {
217 HDF_LOGE("%{public}s: bufferManagerIface mem alloc failed", __func__);
218 return HDF_FAILURE;
219 }
220 return InitBufferManagerIf(instance);
221 }
222
RunCodecInstance(struct CodecInstance * instance)223 int32_t RunCodecInstance(struct CodecInstance *instance)
224 {
225 if (instance == NULL) {
226 HDF_LOGE("%{public}s: Invalid param!", __func__);
227 return HDF_FAILURE;
228 }
229
230 pthread_attr_t attr;
231 pthread_attr_init(&attr);
232 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
233
234 instance->codecStatus = CODEC_STATUS_STARTED;
235 int32_t ret = pthread_create(&instance->task, NULL, CodecTaskThread, instance);
236 if (ret != 0) {
237 HDF_LOGE("%{public}s: run codec task thread failed!", __func__);
238 return HDF_FAILURE;
239 }
240 return HDF_SUCCESS;
241 }
242
StopCodecInstance(struct CodecInstance * instance)243 int32_t StopCodecInstance(struct CodecInstance *instance)
244 {
245 if (instance == NULL) {
246 HDF_LOGE("%{public}s: Invalid param!", __func__);
247 return HDF_FAILURE;
248 }
249 instance->codecStatus = CODEC_STATUS_STOPED;
250 return HDF_SUCCESS;
251 }
252
DestroyCodecInstance(struct CodecInstance * instance)253 int32_t DestroyCodecInstance(struct CodecInstance *instance)
254 {
255 if (instance == NULL) {
256 HDF_LOGE("%{public}s: Invalid param!", __func__);
257 return HDF_FAILURE;
258 }
259
260 if (instance->codecStatus == CODEC_STATUS_STARTED) {
261 HDF_LOGE("%{public}s: wait codec task stop!", __func__);
262 instance->codecStatus = CODEC_STATUS_STOPED;
263 pthread_join(instance->task, NULL);
264 }
265
266 ReleaseInputShm(instance);
267 ReleaseOutputShm(instance);
268 ReleaseInputInfo(instance);
269 ReleaseOutputInfo(instance);
270
271 if (instance->codecOemIface != NULL) {
272 OsalMemFree(instance->codecOemIface);
273 }
274 dlclose(instance->oemLibHandle);
275 if (instance->bufferManagerIface != NULL) {
276 instance->bufferManagerIface->deleteBufferManager(&(instance->bufferManagerWrapper));
277 OsalMemFree(instance->bufferManagerIface);
278 }
279 dlclose(instance->bufferManagerLibHandle);
280 OsalMemFree(instance);
281 return HDF_SUCCESS;
282 }
283
SetOemCodecBufferType(CodecBuffer * bufferToOemCodec,CodecBuffer * bufferInQueue)284 bool SetOemCodecBufferType(CodecBuffer *bufferToOemCodec, CodecBuffer *bufferInQueue)
285 {
286 if (bufferToOemCodec == NULL || bufferInQueue == NULL) {
287 HDF_LOGE("%{public}s: Invalid params!", __func__);
288 return false;
289 }
290 if (bufferInQueue->buffer[0].type == BUFFER_TYPE_HANDLE) {
291 bufferToOemCodec->buffer[0].type = BUFFER_TYPE_HANDLE;
292 } else {
293 bufferToOemCodec->buffer[0].type = BUFFER_TYPE_VIRTUAL;
294 }
295 return true;
296 }
297
AddInputShm(struct CodecInstance * instance,const CodecBufferInfo * bufferInfo,int32_t bufferId)298 int32_t AddInputShm(struct CodecInstance *instance, const CodecBufferInfo *bufferInfo, int32_t bufferId)
299 {
300 if (instance == NULL || bufferInfo == NULL) {
301 HDF_LOGE("%{public}s: Invalid param!", __func__);
302 return HDF_FAILURE;
303 }
304 int32_t count = instance->inputBuffersCount;
305 if (count >= MAX_BUFFER_NUM) {
306 HDF_LOGE("%{public}s: ShareMemory buffer array full!", __func__);
307 return HDF_FAILURE;
308 }
309 instance->inputBuffers[count].id = bufferId;
310 instance->inputBuffers[count].size = bufferInfo->capacity;
311 instance->inputBuffers[count].type = bufferInfo->type;
312 if (bufferInfo->type == BUFFER_TYPE_HANDLE) {
313 BufferHandle *bufferHandle = (BufferHandle *)bufferInfo->buf;
314 if (bufferHandle == NULL) {
315 HDF_LOGE("%{public}s: null bufferHandle!", __func__);
316 return HDF_FAILURE;
317 }
318 instance->inputBuffers[count].fd = bufferHandle->fd;
319 } else if (bufferInfo->type == BUFFER_TYPE_FD) {
320 instance->inputBuffers[count].fd = (int32_t)bufferInfo->buf;
321 if (OpenFdShareMemory(&instance->inputBuffers[count]) != HDF_SUCCESS) {
322 return HDF_FAILURE;
323 }
324 }
325 instance->inputBuffersCount++;
326 return HDF_SUCCESS;
327 }
328
AddOutputShm(struct CodecInstance * instance,const CodecBufferInfo * bufferInfo,int32_t bufferId)329 int32_t AddOutputShm(struct CodecInstance *instance, const CodecBufferInfo *bufferInfo, int32_t bufferId)
330 {
331 if (instance == NULL || bufferInfo == NULL) {
332 HDF_LOGE("%{public}s: Invalid param!", __func__);
333 return HDF_FAILURE;
334 }
335 int32_t count = instance->outputBuffersCount;
336 if (count >= MAX_BUFFER_NUM) {
337 HDF_LOGE("%{public}s: ShareMemory buffer array full!", __func__);
338 return HDF_FAILURE;
339 }
340 instance->outputBuffers[count].id = bufferId;
341 instance->outputBuffers[count].size = bufferInfo->capacity;
342 instance->outputBuffers[count].type = bufferInfo->type;
343 if (bufferInfo->type == BUFFER_TYPE_HANDLE) {
344 BufferHandle *bufferHandle = (BufferHandle *)bufferInfo->buf;
345 if (bufferHandle == NULL) {
346 HDF_LOGE("%{public}s: null bufferHandle!", __func__);
347 return HDF_FAILURE;
348 }
349 instance->outputBuffers[count].fd = bufferHandle->fd;
350 } else if (bufferInfo->type == BUFFER_TYPE_FD) {
351 instance->outputBuffers[count].fd = (int32_t)bufferInfo->buf;
352 if (OpenFdShareMemory(&instance->outputBuffers[count]) != HDF_SUCCESS) {
353 return HDF_FAILURE;
354 }
355 }
356 instance->outputBuffersCount++;
357 return HDF_SUCCESS;
358 }
359
GetShmById(struct CodecInstance * instance,int32_t id)360 static ShareMemory* GetShmById(struct CodecInstance *instance, int32_t id)
361 {
362 int32_t i;
363 if (instance == NULL) {
364 HDF_LOGE("%{public}s: Invalid param!", __func__);
365 return NULL;
366 }
367 for (i = 0; i < instance->inputBuffersCount; i++) {
368 if (instance->inputBuffers[i].id == id) {
369 return &(instance->inputBuffers[i]);
370 }
371 }
372 for (i = 0; i < instance->outputBuffersCount; i++) {
373 if (instance->outputBuffers[i].id == id) {
374 return &(instance->outputBuffers[i]);
375 }
376 }
377 HDF_LOGE("%{public}s: not found for bufferId:%{public}d!", __func__, id);
378 return NULL;
379 }
380
GetFdById(struct CodecInstance * instance,int32_t id)381 int32_t GetFdById(struct CodecInstance *instance, int32_t id)
382 {
383 if (instance == NULL) {
384 HDF_LOGE("%{public}s: Invalid param!", __func__);
385 return HDF_FAILURE;
386 }
387 int32_t i;
388 for (i = 0; i < instance->inputBuffersCount; i++) {
389 if (instance->inputBuffers[i].id == id) {
390 return instance->inputBuffers[i].fd;
391 }
392 }
393 for (i = 0; i < instance->outputBuffersCount; i++) {
394 if (instance->outputBuffers[i].id == id) {
395 return instance->outputBuffers[i].fd;
396 }
397 }
398 HDF_LOGE("%{public}s: failed to find! bufferId:%{public}d!", __func__, id);
399 return HDF_FAILURE;
400 }
401
ReleaseInputShm(struct CodecInstance * instance)402 void ReleaseInputShm(struct CodecInstance *instance)
403 {
404 if (instance == NULL) {
405 HDF_LOGE("%{public}s: Invalid param!", __func__);
406 return;
407 }
408 for (int32_t i = 0; i < instance->inputBuffersCount; i++) {
409 if (instance->inputBuffers[i].type == BUFFER_TYPE_FD) {
410 ReleaseFdShareMemory(&instance->inputBuffers[i]);
411 }
412 }
413 }
ReleaseOutputShm(struct CodecInstance * instance)414 void ReleaseOutputShm(struct CodecInstance *instance)
415 {
416 if (instance == NULL) {
417 HDF_LOGE("%{public}s: Invalid param!", __func__);
418 return;
419 }
420 for (int32_t i = 0; i < instance->outputBuffersCount; i++) {
421 if (instance->outputBuffers[i].type == BUFFER_TYPE_FD) {
422 ReleaseFdShareMemory(&instance->outputBuffers[i]);
423 }
424 }
425 }
426
AddInputInfo(struct CodecInstance * instance,CodecBuffer * info)427 int32_t AddInputInfo(struct CodecInstance *instance, CodecBuffer *info)
428 {
429 if (instance == NULL || info == NULL) {
430 HDF_LOGE("%{public}s: Invalid param!", __func__);
431 return HDF_FAILURE;
432 }
433 if (instance->inputInfoCount >= MAX_BUFFER_NUM) {
434 HDF_LOGE("%{public}s: CodecBuffer array full!", __func__);
435 return HDF_FAILURE;
436 }
437 instance->inputInfos[instance->inputInfoCount] = info;
438 instance->inputInfoCount++;
439 return HDF_SUCCESS;
440 }
441
AddOutputInfo(struct CodecInstance * instance,CodecBuffer * info)442 int32_t AddOutputInfo(struct CodecInstance *instance, CodecBuffer *info)
443 {
444 if (instance == NULL || info == NULL) {
445 HDF_LOGE("%{public}s: Invalid param!", __func__);
446 return HDF_FAILURE;
447 }
448 if (instance->outputInfoCount >= MAX_BUFFER_NUM) {
449 HDF_LOGE("%{public}s: CodecBuffer array full!", __func__);
450 return HDF_FAILURE;
451 }
452 instance->outputInfos[instance->outputInfoCount] = info;
453 instance->outputInfoCount++;
454 return HDF_SUCCESS;
455 }
456
GetInputInfo(struct CodecInstance * instance,uint32_t id)457 CodecBuffer* GetInputInfo(struct CodecInstance *instance, uint32_t id)
458 {
459 if (instance == NULL) {
460 HDF_LOGE("%{public}s: Invalid param!", __func__);
461 return NULL;
462 }
463 for (int32_t i = 0; i < instance->inputInfoCount; i++) {
464 if (instance->inputInfos[i]->bufferId == id) {
465 return instance->inputInfos[i];
466 }
467 }
468 return NULL;
469 }
470
GetOutputInfo(struct CodecInstance * instance,uint32_t id)471 CodecBuffer* GetOutputInfo(struct CodecInstance *instance, uint32_t id)
472 {
473 if (instance == NULL) {
474 HDF_LOGE("%{public}s: Invalid param!", __func__);
475 return NULL;
476 }
477 for (int32_t i = 0; i < instance->outputInfoCount; i++) {
478 if (instance->outputInfos[i]->bufferId == id) {
479 return instance->outputInfos[i];
480 }
481 }
482 return NULL;
483 }
484
ReleaseCodecBuffer(CodecBuffer * info)485 void ReleaseCodecBuffer(CodecBuffer *info)
486 {
487 if (info == NULL) {
488 HDF_LOGI("%{public}s: Invalid param!", __func__);
489 return;
490 }
491 for (uint32_t i = 0; i < info->bufferCnt; i++) {
492 if (info->buffer[i].type == BUFFER_TYPE_HANDLE) {
493 FreeBufferHandle((BufferHandle *)info->buffer[i].buf);
494 }
495 }
496 OsalMemFree(info);
497 }
498
ReleaseInputInfo(struct CodecInstance * instance)499 void ReleaseInputInfo(struct CodecInstance *instance)
500 {
501 if (instance == NULL) {
502 HDF_LOGE("%{public}s: Invalid param!", __func__);
503 return;
504 }
505 for (int32_t i = 0; i < instance->inputInfoCount; i++) {
506 ReleaseCodecBuffer(instance->inputInfos[i]);
507 instance->inputInfos[i] = NULL;
508 }
509 }
510
ReleaseOutputInfo(struct CodecInstance * instance)511 void ReleaseOutputInfo(struct CodecInstance *instance)
512 {
513 if (instance == NULL) {
514 HDF_LOGE("%{public}s: Invalid param!", __func__);
515 return;
516 }
517 for (int32_t i = 0; i < instance->outputInfoCount; i++) {
518 ReleaseCodecBuffer(instance->outputInfos[i]);
519 instance->outputInfos[i] = NULL;
520 }
521 }
522
ResetBuffers(struct CodecInstance * instance)523 void ResetBuffers(struct CodecInstance *instance)
524 {
525 if (instance == NULL) {
526 HDF_LOGE("%{public}s: Invalid param!", __func__);
527 return;
528 }
529 int32_t i;
530 ReleaseInputShm(instance);
531 ReleaseOutputShm(instance);
532 for (i = 0; i< instance->inputInfoCount; i++) {
533 ReleaseCodecBuffer(instance->inputInfos[i]);
534 }
535 for (i = 0; i< instance->outputInfoCount; i++) {
536 ReleaseCodecBuffer(instance->outputInfos[i]);
537 }
538
539 instance->inputBuffersCount = 0;
540 instance->outputBuffersCount = 0;
541 instance->inputInfoCount = 0;
542 instance->outputInfoCount = 0;
543 }
544
EmptyCodecBuffer(CodecBuffer * buf)545 void EmptyCodecBuffer(CodecBuffer *buf)
546 {
547 if (buf == NULL) {
548 return;
549 }
550 for (uint32_t i = 0; i < buf->bufferCnt; i++) {
551 buf->buffer[i].length = 0;
552 buf->buffer[i].offset = 0;
553 }
554 }
555
CopyCodecBufferWithTypeSwitch(struct CodecInstance * instance,CodecBuffer * dst,const CodecBuffer * src,bool ignoreBuf)556 bool CopyCodecBufferWithTypeSwitch(struct CodecInstance *instance, CodecBuffer *dst,
557 const CodecBuffer *src, bool ignoreBuf)
558 {
559 if (dst == NULL || src == NULL) {
560 HDF_LOGE("%{public}s: Nullpoint, dst: %{public}p, src: %{public}p", __func__, dst, src);
561 return false;
562 }
563 if (dst->bufferCnt != src->bufferCnt) {
564 HDF_LOGE("%{public}s: size not match", __func__);
565 return false;
566 }
567 dst->bufferId = src->bufferId;
568 dst->timeStamp = src->timeStamp;
569 dst->flag = src->flag;
570 for (uint32_t i = 0; i < src->bufferCnt; i++) {
571 dst->buffer[i].offset = src->buffer[i].offset;
572 dst->buffer[i].length = src->buffer[i].length;
573 dst->buffer[i].capacity = src->buffer[i].capacity;
574 if (ignoreBuf) {
575 continue;
576 } else if (dst->buffer[i].type == src->buffer[i].type) {
577 dst->buffer[i].buf = src->buffer[i].buf;
578 } else if (dst->buffer[i].type == BUFFER_TYPE_VIRTUAL && src->buffer[i].type == BUFFER_TYPE_FD) {
579 dst->buffer[i].buf = (intptr_t)GetShmById(instance, src->bufferId)->virAddr;
580 } else if (dst->buffer[i].type == BUFFER_TYPE_VIRTUAL && src->buffer[i].type == BUFFER_TYPE_HANDLE) {
581 dst->buffer[i].buf = (intptr_t)GetShmById(instance, src->bufferId)->virAddr;
582 }
583 if (dst->buffer[i].buf == 0) {
584 HDF_LOGE("%{public}s: buf value invalid! bufferId:%{public}d", __func__, src->bufferId);
585 return false;
586 }
587 }
588 return true;
589 }
590
DupBufferHandle(const BufferHandle * handle)591 static BufferHandle *DupBufferHandle(const BufferHandle *handle)
592 {
593 if (handle == NULL) {
594 HDF_LOGE("%{public}s handle is NULL", __func__);
595 return NULL;
596 }
597
598 BufferHandle *newHandle = AllocateBufferHandle(handle->reserveFds, handle->reserveInts);
599 if (newHandle == NULL) {
600 HDF_LOGE("%{public}s AllocateBufferHandle failed, newHandle is NULL", __func__);
601 return NULL;
602 }
603
604 newHandle->fd = handle->fd;
605 newHandle->width = handle->width;
606 newHandle->stride = handle->stride;
607 newHandle->height = handle->height;
608 newHandle->size = handle->size;
609 newHandle->format = handle->format;
610 newHandle->usage = handle->usage;
611 newHandle->virAddr = handle->virAddr;
612 newHandle->phyAddr = handle->phyAddr;
613 newHandle->key = handle->key;
614
615 return newHandle;
616 }
617
DupCodecBuffer(const CodecBuffer * src)618 CodecBuffer* DupCodecBuffer(const CodecBuffer *src)
619 {
620 if (src == NULL) {
621 HDF_LOGE("%{public}s: CodecBuffer src Nullpoint", __func__);
622 return NULL;
623 }
624 int32_t size = sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * src->bufferCnt;
625 CodecBuffer *dst = (CodecBuffer *)OsalMemAlloc(size);
626 if (dst == NULL) {
627 HDF_LOGE("%{public}s: malloc dst failed", __func__);
628 return NULL;
629 }
630 int32_t ret = memcpy_s(dst, size, src, size);
631 if (ret != EOK) {
632 HDF_LOGE("%{public}s: memcpy_s failed, error code: %{public}d", __func__, ret);
633 OsalMemFree(dst);
634 return NULL;
635 }
636 for (uint32_t i = 0; i < src->bufferCnt; i++) {
637 if (dst->buffer[i].type == BUFFER_TYPE_HANDLE) {
638 dst->buffer[i].buf = (intptr_t)DupBufferHandle((BufferHandle *)src->buffer[i].buf);
639 }
640 }
641 return dst;
642 }
643
644