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 = ¶ms[paramCount++];
354 param->key = KEY_VIDEO_WIDTH;
355 param->val = &g_cmd.width;
356 param->size = sizeof(g_cmd.width);
357
358 param = ¶ms[paramCount++];
359 param->key = KEY_VIDEO_HEIGHT;
360 param->val = &g_cmd.height;
361 param->size = sizeof(g_cmd.height);
362
363 param = ¶ms[paramCount++];
364 param->key = KEY_CODEC_TYPE;
365 param->val = &g_cmd.type;
366 param->size = sizeof(g_cmd.type);
367
368 param = ¶ms[paramCount++];
369 param->key = KEY_PIXEL_FORMAT;
370 param->val = &g_cmd.pixFmt;
371 param->size = sizeof(g_cmd.pixFmt);
372
373 param = ¶ms[paramCount++];
374 param->key = KEY_VIDEO_STRIDE;
375 param->val = &g_frameStride;
376 param->size = sizeof(g_frameStride);
377
378 param = ¶ms[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 = ¶ms[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 = ¶ms[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 }