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