• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <securec.h>
17 #include <string.h>
18 #include <sys/stat.h>
19 #include "codec_callback_stub.h"
20 #include "codec_type.h"
21 #include "codec_utils.h"
22 #include "codec_gralloc_wrapper.h"
23 #include "hdf_log.h"
24 #include "icodec.h"
25 #include "share_mem.h"
26 
27 #define HDF_LOG_TAG codec_hdi_demo_encode
28 #define TEST_SERVICE_NAME   "codec_hdi_service"
29 #define QUEUE_TIME_OUT                      10
30 #define USLEEP_TIME_OUT                     10000
31 #define FRAME_SIZE_MULTI                    3
32 #define FRAME_SIZE_OPERATOR                 2
33 #define ENC_DEFAULT_FRAME_RATE              24
34 #define PARAM_ARRAY_LEN                     20
35 #define YUV_ALIGNMENT                       16
36 #define BUF_COUNT                           1
37 #define TIME_OUTMS                          0
38 #define RELEASE_FENCEFD                     (-1)
39 #define FOUR_BYTE_PIX_BUF_SIZE_OPERATOR     4
40 #define ENC_GET_PARAM_COUNT                 3
41 
42 static struct ICodec *g_codecProxy = NULL;
43 static CODEC_HANDLETYPE g_handle = NULL;
44 ShareMemory *g_inputBuffers = NULL;
45 ShareMemory *g_outputBuffers = NULL;
46 CodecBuffer **g_inputInfosData = NULL;
47 CodecBuffer **g_outputInfosData = NULL;
48 
49 CodecCmd g_cmd = {0};
50 CodecEnvData g_data = {0};
51 
52 bool g_pktEos = false;
53 int32_t g_srcFileSize = 0;
54 int32_t g_totalSrcSize = 0;
55 int32_t g_totalDstSize = 0;
56 int32_t g_frameCount = 0;
57 int32_t g_frameStride = 0;
58 int32_t g_frameSize = 0;
59 CodecCallback g_callback;
60 
AlignUp(uint32_t width,uint32_t alignment)61 static uint32_t inline AlignUp(uint32_t width, uint32_t alignment)
62 {
63     if (alignment < 1) {
64         return width;
65     }
66     return (((width) + alignment - 1) & (~(alignment - 1)));
67 }
68 
GetFrameSize(void)69 static int32_t GetFrameSize(void)
70 {
71     int32_t frameSize = 0;
72     int32_t wStride = AlignUp(g_cmd.width, YUV_ALIGNMENT);
73     switch (g_cmd.pixFmt) {
74         case PIXEL_FMT_YCBCR_420_SP:
75         case PIXEL_FMT_YCBCR_420_P:
76             frameSize = (wStride * g_cmd.height * FRAME_SIZE_MULTI) / FRAME_SIZE_OPERATOR;
77             break;
78         case PIXEL_FMT_BGRA_8888:
79         case PIXEL_FMT_RGBA_8888:
80             frameSize = wStride * g_cmd.height * FOUR_BYTE_PIX_BUF_SIZE_OPERATOR;
81             break;
82         default:
83             break;
84     }
85     return frameSize;
86 }
87 
DumpOutputToFile(FILE * fp,uint8_t * addr,uint32_t len)88 static void DumpOutputToFile(FILE *fp, uint8_t *addr, uint32_t len)
89 {
90     if (fp == NULL || addr == NULL) {
91         HDF_LOGE("%{public}s: invalid param!", __func__);
92         return;
93     }
94     size_t ret = fwrite(addr, 1, len, fp);
95     if (ret != len) {
96         HDF_LOGE("%{public}s: Dump packet failed, ret: %{public}zu", __func__, ret);
97     }
98 }
99 
ReadInputFromFile(FILE * fp,uint8_t * addr)100 static int32_t ReadInputFromFile(FILE *fp, uint8_t *addr)
101 {
102     if (fp == NULL || addr == NULL) {
103         HDF_LOGE("%{public}s: invalid param!", __func__);
104         return 0;
105     }
106     return fread(addr, 1, g_frameSize, fp);
107 }
108 
GetShareMemoryById(int32_t id)109 static ShareMemory* GetShareMemoryById(int32_t id)
110 {
111     uint32_t i;
112     for (i = 0; i < g_data.inputBufferCount; i++) {
113         if (g_inputBuffers[i].id == id) {
114             return &g_inputBuffers[i];
115         }
116     }
117     for (i = 0; i < g_data.outputBufferCount; i++) {
118         if (g_outputBuffers[i].id == id) {
119             return &g_outputBuffers[i];
120         }
121     }
122     return NULL;
123 }
124 
ReleaseShm(void)125 static void ReleaseShm(void)
126 {
127     uint32_t i;
128     if (g_inputBuffers != NULL) {
129         for (i = 0; i < g_data.inputBufferCount; i++) {
130             CodecBuffer *info = g_inputInfosData[i];
131             ReleaseGrShareMemory((BufferHandle *)info->buffer[0].buf, &g_inputBuffers[i]);
132         }
133     }
134     if (g_outputBuffers != NULL) {
135         for (i = 0; i < g_data.outputBufferCount; i++) {
136             ReleaseFdShareMemory(&g_outputBuffers[i]);
137         }
138     }
139 }
140 
ReleaseCodecBuffer(CodecBuffer * info)141 void ReleaseCodecBuffer(CodecBuffer *info)
142 {
143     if (info == NULL) {
144         HDF_LOGE("%{public}s: Invalid param!", __func__);
145         return;
146     }
147     for (uint32_t i = 0; i < info->bufferCnt; i++) {
148         if (info->buffer[i].type == BUFFER_TYPE_HANDLE) {
149             DestroyGrShareMemory((BufferHandle *)info->buffer[i].buf);
150         }
151     }
152     OsalMemFree(info);
153 }
154 
ReleaseCodecBuffers(void)155 static void ReleaseCodecBuffers(void)
156 {
157     uint32_t i;
158     if (g_inputInfosData != NULL) {
159         for (i = 0; i < g_data.inputBufferCount; i++) {
160             ReleaseCodecBuffer(g_inputInfosData[i]);
161             g_inputInfosData[i] = NULL;
162         }
163     }
164     if (g_outputInfosData != NULL) {
165         for (i = 0; i < g_data.outputBufferCount; i++) {
166             ReleaseCodecBuffer(g_outputInfosData[i]);
167             g_outputInfosData[i] = NULL;
168         }
169     }
170 }
171 
CalcFrameParams(void)172 static int32_t CalcFrameParams(void)
173 {
174     g_frameSize = GetFrameSize();
175     g_frameStride = AlignUp(g_cmd.width, YUV_ALIGNMENT);
176     if (g_frameSize <= 0 || g_frameStride <= 0) {
177         HDF_LOGI("%{public}s: g_frameSize or g_frameStride invalid!", __func__);
178         return HDF_FAILURE;
179     }
180     return HDF_SUCCESS;
181 }
182 
AllocateBuffer(int32_t inputBufferNum,int32_t outputBufferNum)183 static bool AllocateBuffer(int32_t inputBufferNum, int32_t outputBufferNum)
184 {
185     g_inputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * inputBufferNum);
186     g_outputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * outputBufferNum);
187     g_inputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * inputBufferNum);
188     g_outputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * outputBufferNum);
189     if (g_inputBuffers != NULL && g_outputBuffers != NULL && g_inputInfosData != NULL && g_outputInfosData != NULL) {
190         return true;
191     }
192 
193     HDF_LOGE("%{public}s: alloc buffers failed!", __func__);
194     OsalMemFree(g_inputBuffers);
195     OsalMemFree(g_outputBuffers);
196     OsalMemFree(g_inputInfosData);
197     OsalMemFree(g_outputInfosData);
198     g_inputBuffers = NULL;
199     g_outputBuffers = NULL;
200     g_inputInfosData = NULL;
201     g_outputInfosData = NULL;
202 
203     return false;
204 }
205 
FreeInfosData(CodecBuffer ** g_InfosData,int32_t num)206 static void FreeInfosData(CodecBuffer **g_InfosData, int32_t num)
207 {
208     if (g_InfosData == NULL) {
209         HDF_LOGE("%{public}s: invalid param!", __func__);
210         return;
211     }
212     for (int32_t n = 0; n < num; n++) {
213         OsalMemFree(g_InfosData[n]);
214     }
215 }
216 
InitInputInfosData(int32_t num)217 static bool InitInputInfosData(int32_t num)
218 {
219     BufferHandle *bufferHandle = NULL;
220     if (CreateGrShareMemory(&bufferHandle, g_cmd, &g_inputBuffers[num]) != HDF_SUCCESS) {
221         return false;
222     }
223     g_inputInfosData[num] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * BUF_COUNT);
224     if (g_inputInfosData[num] == NULL) {
225         FreeInfosData(g_inputInfosData, num);
226         HDF_LOGE("%{public}s: g_inputInfosData[%{public}d] is NULL!", __func__, num);
227         return false;
228     }
229     g_inputInfosData[num]->bufferCnt = BUF_COUNT;
230     g_inputInfosData[num]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
231     g_inputInfosData[num]->bufferId = g_inputBuffers[num].id;
232     g_inputInfosData[num]->buffer[0].type = BUFFER_TYPE_HANDLE;
233     g_inputInfosData[num]->buffer[0].buf = (intptr_t)bufferHandle;
234     g_inputInfosData[num]->buffer[0].capacity = bufferHandle->size;
235     return true;
236 }
237 
InitOutputInfosData(int32_t outputBufferSize,int32_t num)238 static bool InitOutputInfosData(int32_t outputBufferSize, int32_t num)
239 {
240     g_outputInfosData[num] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * BUF_COUNT);
241     if (g_outputInfosData[num] == NULL) {
242         FreeInfosData(g_outputInfosData, num);
243         HDF_LOGE("%{public}s: g_outputInfosData[%{public}d] is NULL!", __func__, num);
244         return false;
245     }
246     g_outputInfosData[num]->bufferCnt = BUF_COUNT;
247     g_outputInfosData[num]->bufferId = g_outputBuffers[num].id;
248     g_outputInfosData[num]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
249     g_outputInfosData[num]->buffer[0].type = BUFFER_TYPE_FD;
250     g_outputInfosData[num]->buffer[0].buf = (intptr_t)g_outputBuffers[num].fd;
251     g_outputInfosData[num]->buffer[0].capacity = outputBufferSize;
252     return true;
253 }
254 
InitBuffer(int32_t inputBufferNum,int32_t inputBufferSize,int32_t outputBufferNum,int32_t outputBufferSize)255 static bool InitBuffer(int32_t inputBufferNum, int32_t inputBufferSize,
256     int32_t outputBufferNum, int32_t outputBufferSize)
257 {
258     int32_t queueRet;
259     if (!AllocateBuffer(inputBufferNum, outputBufferNum)) {
260         return false;
261     }
262 
263     for (int32_t i = 0; i < inputBufferNum; i++) {
264         g_inputBuffers[i].id = i;
265         g_inputBuffers[i].type = BUFFER_TYPE_HANDLE;
266         bool ret = InitInputInfosData(i);
267         if (!ret) {
268             HDF_LOGE("%{public}s: InitInputInfosData[%{public}d] failed!", __func__, i);
269             return false;
270         }
271         queueRet = g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
272         g_inputInfosData[i], TIME_OUTMS, RELEASE_FENCEFD);
273         if (queueRet != HDF_SUCCESS) {
274             FreeInfosData(g_inputInfosData, i);
275             HDF_LOGE("%{public}s: CodecQueueInput g_inputInfosData[%{public}d] initial failed!", __func__, i);
276             return false;
277         }
278     }
279 
280     for (int32_t j = 0; j < outputBufferNum; j++) {
281         g_outputBuffers[j].id = inputBufferNum + j;
282         g_outputBuffers[j].size = outputBufferSize;
283         if (CreateFdShareMemory(&g_outputBuffers[j]) != HDF_SUCCESS) {
284             return false;
285         }
286         bool ret = InitOutputInfosData(outputBufferSize, j);
287         if (!ret) {
288             FreeInfosData(g_inputInfosData, inputBufferNum);
289             HDF_LOGE("%{public}s: InitOutputInfosData[%{public}d] failed!", __func__, j);
290             return false;
291         }
292         queueRet = g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
293         g_outputInfosData[j], TIME_OUTMS, RELEASE_FENCEFD);
294         if (queueRet != HDF_SUCCESS) {
295             FreeInfosData(g_inputInfosData, inputBufferNum);
296             FreeInfosData(g_outputInfosData, j);
297             HDF_LOGE("%{public}s: CodecQueueInput g_outputInfosData[%{public}d] initial failed!", __func__, j);
298             return false;
299         }
300     }
301     return true;
302 }
303 
CheckEncSetup(Param * setParams,Param * getParams,int32_t paramCnt)304 static void CheckEncSetup(Param *setParams, Param *getParams, int32_t paramCnt)
305 {
306     if (setParams == NULL || getParams == NULL || paramCnt <= 0) {
307         HDF_LOGE("%{public}s: params is null or invalid count!", __func__);
308         return;
309     }
310     for (int32_t i = 0; i < paramCnt; i++) {
311         if (setParams[i].size != getParams[i].size) {
312             HDF_LOGE("%{public}s: params size incorrect!", __func__);
313             return;
314         }
315         if (memcmp(setParams[i].val, getParams[i].val, setParams[i].size) != 0) {
316             HDF_LOGE("%{public}s: params val incorrect! index:%{public}d", __func__, i);
317             return;
318         }
319     }
320 
321     HDF_LOGI("%{public}s: get all params correctly!", __func__);
322 }
323 
GetSetupParams(Param * setParams,int32_t paramCnt)324 static int32_t GetSetupParams(Param *setParams, int32_t paramCnt)
325 {
326     Param *getParams = (Param *)OsalMemCalloc(sizeof(Param) * paramCnt);
327     if (getParams == NULL) {
328         HDF_LOGE("%{public}s: getParams is NULL!", __func__);
329         return HDF_ERR_MALLOC_FAIL;
330     }
331 
332     for (int32_t i = 0; i < paramCnt; i++) {
333         getParams[i].key = setParams[i].key;
334     }
335     int32_t ret = g_codecProxy->CodecGetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, getParams, paramCnt);
336     if (ret != HDF_SUCCESS) {
337         HDF_LOGE("%{public}s: CodecGetParameter failed, ret:%{public}d", __func__, ret);
338         FreeParams(getParams, paramCnt);
339         return HDF_FAILURE;
340     }
341     CheckEncSetup(setParams, getParams, paramCnt);
342     FreeParams(getParams, paramCnt);
343     return HDF_SUCCESS;
344 }
345 
SetupBasicEncParams(Param * params)346 static int32_t SetupBasicEncParams(Param *params)
347 {
348     if (params == NULL) {
349         HDF_LOGE("%{public}s: invalid params!", __func__);
350         return 0;
351     }
352     Param *param = NULL;
353     int32_t paramCount = 0;
354 
355     param = &params[paramCount++];
356     param->key = KEY_VIDEO_WIDTH;
357     param->val = &g_cmd.width;
358     param->size = sizeof(g_cmd.width);
359 
360     param = &params[paramCount++];
361     param->key = KEY_VIDEO_HEIGHT;
362     param->val = &g_cmd.height;
363     param->size = sizeof(g_cmd.height);
364 
365     param = &params[paramCount++];
366     param->key = KEY_CODEC_TYPE;
367     param->val = &g_cmd.type;
368     param->size = sizeof(g_cmd.type);
369 
370     param = &params[paramCount++];
371     param->key = KEY_PIXEL_FORMAT;
372     param->val = &g_cmd.pixFmt;
373     param->size = sizeof(g_cmd.pixFmt);
374 
375     param = &params[paramCount++];
376     param->key = KEY_VIDEO_STRIDE;
377     param->val = &g_frameStride;
378     param->size = sizeof(g_frameStride);
379 
380     param = &params[paramCount++];
381     param->key = KEY_VIDEO_FRAME_RATE;
382     param->val = &g_cmd.fps;
383     param->size = sizeof(g_cmd.fps);
384 
385     return paramCount;
386 }
387 
SetupEncParams(void)388 static int32_t SetupEncParams(void)
389 {
390     Param params[PARAM_ARRAY_LEN] = {0};
391     Param *param = NULL;
392     int32_t paramCount = 0;
393 
394     paramCount = SetupBasicEncParams(params);
395 
396     param = &params[paramCount++];
397     param->key = KEY_VIDEO_RC_MODE;
398     int32_t rcMode = VID_CODEC_RC_VBR;
399     param->val = &rcMode;
400     param->size = sizeof(rcMode);
401 
402     param = &params[paramCount++];
403     param->key = KEY_VIDEO_GOP_MODE;
404     int32_t gopMode = VID_CODEC_GOPMODE_NORMALP;
405     param->val = &gopMode;
406     param->size = sizeof(gopMode);
407 
408     int32_t ret = g_codecProxy->CodecSetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, params, paramCount);
409     if (ret != HDF_SUCCESS) {
410         HDF_LOGE("%{public}s: CodecSetParameter failed, ret:%{public}d", __func__, ret);
411         return ret;
412     }
413 
414     ret = GetSetupParams(params, paramCount);
415     if (ret != HDF_SUCCESS) {
416         HDF_LOGE("%{public}s: GetSetupParams failed", __func__);
417         return ret;
418     }
419 
420     return HDF_SUCCESS;
421 }
422 
GetEncParameter(void)423 static int32_t GetEncParameter(void)
424 {
425     int32_t paramIndex = 0;
426     int32_t ret;
427 
428     // get buffer size and count
429     Param *param = (Param *)OsalMemCalloc(sizeof(Param) * ENC_GET_PARAM_COUNT);
430     if (param == NULL) {
431         HDF_LOGE("%{public}s: param malloc failed!", __func__);
432         return HDF_FAILURE;
433     }
434     param[paramIndex++].key = KEY_BUFFERSIZE;
435     param[paramIndex++].key = KEY_INPUT_BUFFER_COUNT;
436     param[paramIndex++].key = KEY_OUTPUT_BUFFER_COUNT;
437     ret = g_codecProxy->CodecGetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, param, ENC_GET_PARAM_COUNT);
438     if (ret != HDF_SUCCESS) {
439         HDF_LOGE("%{public}s: CodecGetParameter failed", __func__);
440         FreeParams(param, ENC_GET_PARAM_COUNT);
441         return HDF_FAILURE;
442     }
443     paramIndex = 0;
444     g_data.bufferSize = *(uint32_t *)param[paramIndex++].val;
445     g_data.inputBufferCount = *(uint32_t *)param[paramIndex++].val;
446     g_data.outputBufferCount = *(uint32_t *)param[paramIndex++].val;
447 
448     FreeParams(param, ENC_GET_PARAM_COUNT);
449     return HDF_SUCCESS;
450 }
451 
CodecCallbackOnEvent(UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])452 static int32_t CodecCallbackOnEvent(UINTPTR userData, EventType event, uint32_t length, int32_t eventData[])
453 {
454     HDF_LOGI("%{public}s: userData: %{public}d, event: %{public}d!", __func__, userData, event);
455     return HDF_SUCCESS;
456 }
457 
CodecCallbackInputBufferAvailable(UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)458 static int32_t CodecCallbackInputBufferAvailable(UINTPTR userData, CodecBuffer *inBuf, int32_t *acquireFd)
459 {
460     if (inBuf == NULL) {
461         HDF_LOGE("%{public}s: invalid input buffer!", __func__);
462         return HDF_FAILURE;
463     }
464     ShareMemory *sm = GetShareMemoryById(inBuf->bufferId);
465     g_frameCount++;
466     int32_t readSize = ReadInputFromFile(g_data.fpInput, sm->virAddr);
467     g_totalSrcSize += readSize;
468     g_pktEos = (g_totalSrcSize >= g_srcFileSize);
469     if (g_pktEos) {
470         HDF_LOGI("%{public}s: client inputData reach STREAM_FLAG_EOS, g_frameCount:%{public}d",
471             __func__, g_frameCount);
472         inBuf->flag = STREAM_FLAG_EOS;
473     }
474 
475     inBuf->buffer[0].length = readSize;
476     g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, inBuf, QUEUE_TIME_OUT, -1);
477     return HDF_SUCCESS;
478 }
479 
CodecCallbackOutputBufferAvailable(UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)480 static int32_t CodecCallbackOutputBufferAvailable(UINTPTR userData, CodecBuffer *outBuf, int32_t *acquireFd)
481 {
482     if (outBuf == NULL) {
483         HDF_LOGE("%{public}s: invalid output buffer!", __func__);
484         return HDF_FAILURE;
485     }
486     g_totalDstSize += outBuf->buffer[0].length;
487     ShareMemory *sm = GetShareMemoryById(outBuf->bufferId);
488     DumpOutputToFile(g_data.fpOutput, sm->virAddr, outBuf->buffer[0].length);
489 
490     outBuf->buffer[0].length = 0;
491     g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, outBuf, QUEUE_TIME_OUT, -1);
492     if (outBuf->flag & STREAM_FLAG_EOS) {
493         HDF_LOGI("%{public}s: client reach STREAM_FLAG_EOS, CodecEncode loopEnd", __func__);
494         g_data.loopEnd = 1;
495     }
496     return HDF_SUCCESS;
497 }
498 
CodecCallbackServiceConstruct(CodecCallback * service)499 static int32_t CodecCallbackServiceConstruct(CodecCallback *service)
500 {
501     if (service == NULL) {
502         HDF_LOGE("%{public}s: invalid output buffer!", __func__);
503         return HDF_FAILURE;
504     }
505     service->OnEvent = CodecCallbackOnEvent;
506     service->InputBufferAvailable = CodecCallbackInputBufferAvailable;
507     service->OutputBufferAvailable = CodecCallbackOutputBufferAvailable;
508     return HDF_SUCCESS;
509 }
510 
RevertEncodeStep1(void)511 static void RevertEncodeStep1(void)
512 {
513     if (g_data.fpInput) {
514         fclose(g_data.fpInput);
515         g_data.fpInput = NULL;
516     }
517     if (g_data.fpOutput) {
518         fclose(g_data.fpOutput);
519         g_data.fpOutput = NULL;
520     }
521 }
522 
RevertEncodeStep2(void)523 static void RevertEncodeStep2(void)
524 {
525     int32_t ret = g_codecProxy->CodecDeinit(g_codecProxy);
526     if (ret != HDF_SUCCESS) {
527         HDF_LOGE("%{public}s: failed to CodecDeinit %{public}d", __func__, ret);
528     }
529     RevertEncodeStep1();
530 }
531 
RevertEncodeStep3(void)532 static void RevertEncodeStep3(void)
533 {
534     ReleaseShm();
535     ReleaseCodecBuffers();
536 
537     if (g_inputBuffers != NULL) {
538         OsalMemFree(g_inputBuffers);
539     }
540     if (g_outputBuffers != NULL) {
541         OsalMemFree(g_outputBuffers);
542     }
543     if (g_inputInfosData != NULL) {
544         OsalMemFree(g_inputInfosData);
545     }
546     if (g_outputInfosData != NULL) {
547         OsalMemFree(g_outputInfosData);
548     }
549     int32_t ret = g_codecProxy->CodecDestroy(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
550     if (ret != HDF_SUCCESS) {
551         HDF_LOGE("%{public}s: failed to CodecDestroy %{public}d", __func__, ret);
552     }
553     RevertEncodeStep2();
554 }
555 
OpenFile(void)556 static int32_t OpenFile(void)
557 {
558     struct stat fileStat = {0};
559     stat(g_cmd.fileInput, &fileStat);
560     g_srcFileSize = fileStat.st_size;
561     HDF_LOGI("%{public}s: input file size %{public}d", __func__, g_srcFileSize);
562 
563     g_data.fpInput = fopen(g_cmd.fileInput, "rb");
564     if (g_data.fpInput == NULL) {
565         HDF_LOGE("%{public}s: failed to open input file %{public}s", __func__, g_cmd.fileInput);
566         RevertEncodeStep1();
567         return HDF_FAILURE;
568     }
569 
570     g_data.fpOutput = fopen(g_cmd.fileOutput, "w+b");
571     if (g_data.fpOutput == NULL) {
572         HDF_LOGE("%{public}s: failed to open output file %{public}s", __func__, g_cmd.fileOutput);
573         RevertEncodeStep1();
574         return HDF_FAILURE;
575     }
576 
577     return HDF_SUCCESS;
578 }
579 
EncodeEnd(void)580 static void EncodeEnd(void)
581 {
582     DirectionType directType = ALL_TYPE;
583     int32_t ret = g_codecProxy->CodecFlush(g_codecProxy, (CODEC_HANDLETYPE)g_handle, directType);
584     if (ret != HDF_SUCCESS) {
585         HDF_LOGE("%{public}s: CodecFlush failed", __func__);
586     }
587 
588     ret = g_codecProxy->CodecStop(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
589     if (ret != HDF_SUCCESS) {
590         HDF_LOGE("%{public}s: failed to CodecStop %{public}d", __func__, ret);
591     }
592 
593     RevertEncodeStep3();
594 }
595 
Encode(void)596 static int32_t Encode(void)
597 {
598     int32_t ret = 0;
599 
600     if (OpenFile() != HDF_SUCCESS) {
601         return HDF_FAILURE;
602     }
603 
604     ret = g_codecProxy->CodecInit(g_codecProxy);
605     if (ret != HDF_SUCCESS) {
606         HDF_LOGE("%{public}s: CodecInit failed", __func__);
607         RevertEncodeStep1();
608         return HDF_FAILURE;
609     }
610 
611     ret = g_codecProxy->CodecCreate(g_codecProxy, g_data.codecName, &g_handle);
612     if (ret != HDF_SUCCESS) {
613         HDF_LOGE("%{public}s: CodecCreate failed, ret:%{public}d", __func__, ret);
614         RevertEncodeStep2();
615         return HDF_FAILURE;
616     }
617 
618     if (CalcFrameParams() != HDF_SUCCESS || SetupEncParams() != HDF_SUCCESS || GetEncParameter() != HDF_SUCCESS) {
619         HDF_LOGE("%{public}s: params handling failed", __func__);
620         RevertEncodeStep3();
621         return HDF_FAILURE;
622     }
623 
624     if (!InitBuffer(g_data.inputBufferCount, g_frameSize, g_data.outputBufferCount, g_data.bufferSize)) {
625         HDF_LOGE("%{public}s: InitBuffer failed", __func__);
626         RevertEncodeStep3();
627         return HDF_FAILURE;
628     }
629 
630     if (CodecCallbackServiceConstruct(&g_callback) != HDF_SUCCESS) {
631         HDF_LOGE("%{public}s: CodecCallbackStubObtain failed", __func__);
632         RevertEncodeStep3();
633         return HDF_FAILURE;
634     }
635     struct CodecCallbackStub *cb = CodecCallbackStubObtain(&g_callback);
636     if (cb == NULL) {
637         HDF_LOGE("%{public}s: CodecCallbackStubObtain failed", __func__);
638         RevertEncodeStep3();
639         return HDF_FAILURE;
640     }
641     if (g_codecProxy->CodecSetCallback(g_codecProxy, g_handle, &cb->service, 0) != HDF_SUCCESS) {
642         HDF_LOGE("%{public}s: CodecSetCallback failed", __func__);
643         RevertEncodeStep3();
644         return HDF_FAILURE;
645     }
646 
647     g_codecProxy->CodecStart(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
648 
649     while (g_data.loopEnd != 1) {
650         usleep(USLEEP_TIME_OUT);
651     }
652     EncodeEnd();
653     CodecCallbackStubRelease(cb);
654 
655     return HDF_SUCCESS;
656 }
657 
main(int32_t argc,char ** argv)658 int32_t main(int32_t argc, char **argv)
659 {
660     if (GrAllocatorInit() != HDF_SUCCESS) {
661         HDF_LOGE("GrAllocatorInit failed!");
662         return HDF_FAILURE;
663     }
664 
665     g_cmd.fps = ENC_DEFAULT_FRAME_RATE;
666     g_cmd.pixFmt = PIXEL_FMT_YCBCR_420_SP;
667     g_cmd.type = VIDEO_ENCODER;
668     int32_t ret = ParseArguments(&g_cmd, argc, argv);
669     HDF_LOGI("%{public}s: ParseArguments width:%{public}d", __func__, g_cmd.width);
670     HDF_LOGI("%{public}s: ParseArguments height:%{public}d", __func__, g_cmd.height);
671     HDF_LOGI("%{public}s: ParseArguments codecName:%{public}s", __func__, g_cmd.codecName);
672     HDF_LOGI("%{public}s: ParseArguments input:%{public}s", __func__, g_cmd.fileInput);
673     HDF_LOGI("%{public}s: ParseArguments output:%{public}s", __func__, g_cmd.fileOutput);
674     HDF_LOGI("%{public}s: ParseArguments fps:%{public}d", __func__, g_cmd.fps);
675     HDF_LOGI("%{public}s: ParseArguments pixFmt:%{public}d", __func__, g_cmd.pixFmt);
676     if (ret != HDF_SUCCESS) {
677         HDF_LOGE("%{public}s: ParseArguments failed", __func__);
678         return ret;
679     }
680 
681     ret = memset_s(&g_data, sizeof(g_data), 0, sizeof(g_data));
682     if (ret != EOK) {
683         HDF_LOGE("%{public}s, memset_s g_data failed!", __func__);
684         return HDF_FAILURE;
685     }
686     g_codecProxy = HdiCodecGet(TEST_SERVICE_NAME);
687 
688     g_data.codecName = g_cmd.codecName;
689 
690     ret = Encode();
691     if (ret == HDF_SUCCESS) {
692         HDF_LOGI("%{public}s: test success", __func__);
693     } else {
694         HDF_LOGE("%{public}s: test failed ret %{public}d", __func__, ret);
695     }
696 
697     HdiCodecRelease(g_codecProxy);
698     HDF_LOGI("%{public}s: test exit", __func__);
699     return ret;
700 }
701 
702