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