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 <pthread.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <securec.h>
20 #include <sys/stat.h>
21 #include "codec_callback_stub.h"
22 #include "codec_utils.h"
23 #include "codec_gralloc_wrapper.h"
24 #include "hdf_log.h"
25 #include "hdi_mpp.h"
26 #include "icodec.h"
27 #include "osal_mem.h"
28 #include "share_mem.h"
29
30 #define HDF_LOG_TAG codec_hdi_demo_decode
31 #define TEST_SERVICE_NAME "codec_hdi_service"
32 #define INPUT_BUFFER_NUM 4
33 #define OUTPUT_BUFFER_NUM 10
34 #define STREAM_PACKET_BUFFER_SIZE (4 * 1024)
35 #define QUEUE_TIME_OUT 10
36 #define HEIGHT_OPERATOR 2
37 #define FRAME_SIZE_OPERATOR 2
38 #define START_CODE_OFFSET_ONE (-1)
39 #define START_CODE_OFFSET_SEC (-2)
40 #define START_CODE_OFFSET_THIRD (-3)
41 #define START_CODE_SIZE_FRAME 4
42 #define START_CODE_SIZE_SLICE 3
43 #define START_CODE 0x1
44
45 typedef struct {
46 char *codecName;
47 /* end of stream flag when set quit the loop */
48 unsigned int loopEnd;
49 /* input and output */
50 FILE *fpInput;
51 FILE *fpOutput;
52 int32_t frameNum;
53 CodecCallback cb;
54 } MpiDecLoopData;
55
56 static struct ICodec *g_codecProxy = NULL;
57 static CODEC_HANDLETYPE g_handle = NULL;
58 ShareMemory *g_inputBuffers = NULL;
59 ShareMemory *g_outputBuffers = NULL;
60 CodecBuffer **g_inputInfosData = NULL;
61 CodecBuffer **g_outputInfosData = NULL;
62
63 CodecCmd g_cmd = {0};
64 MpiDecLoopData g_data = {0};
65 uint32_t g_autoSplit = 0;
66 bool g_pktEos = false;
67 uint8_t *g_readFileBuf;
68 int32_t g_srcFileSize = 0;
69 int32_t g_totalSrcSize = 0;
70 int32_t g_totalFrames = 0;
71
DumpOutputToFile(FILE * fp,uint8_t * addr)72 static void DumpOutputToFile(FILE *fp, uint8_t *addr)
73 {
74 uint32_t width = g_cmd.width;
75 uint32_t height = g_cmd.height;
76 uint32_t horStride = g_cmd.width;
77 uint32_t verStride = g_cmd.height;
78 uint8_t *base = addr;
79 size_t ret = 0;
80
81 // MPP_FMT_YUV420SP
82 uint32_t i;
83 uint8_t *baseY = base;
84 uint8_t *baseC = base + horStride * verStride;
85
86 for (i = 0; i < height; i++, baseY += horStride) {
87 ret = fwrite(baseY, 1, width, fp);
88 if (ret != width) {
89 HDF_LOGE("%{public}s: DumpOutputToFile failed", __func__);
90 continue;
91 }
92 }
93 for (i = 0; i < height / HEIGHT_OPERATOR; i++, baseC += horStride) {
94 ret = fwrite(baseC, 1, width, fp);
95 if (ret != width) {
96 HDF_LOGE("%{public}s: DumpOutputToFile failed", __func__);
97 continue;
98 }
99 }
100 }
101
ReadInputFromFile(FILE * fp,uint8_t * buf)102 static int32_t ReadInputFromFile(FILE *fp, uint8_t *buf)
103 {
104 return fread(buf, 1, STREAM_PACKET_BUFFER_SIZE, fp);
105 }
106
ReadOneFrameFromFile(FILE * fp,uint8_t * buf)107 static int32_t ReadOneFrameFromFile(FILE *fp, uint8_t *buf)
108 {
109 int32_t readSize = 0;
110 // read start code first
111 size_t t = fread(buf, 1, START_CODE_SIZE_FRAME, fp);
112 if (t < START_CODE_SIZE_FRAME) {
113 return readSize;
114 }
115 uint8_t *temp = buf;
116 temp += START_CODE_SIZE_FRAME;
117 while (!feof(fp)) {
118 t = fread(temp, 1, 1, fp);
119 if (t != 1) {
120 continue;
121 }
122
123 if (*temp == START_CODE) {
124 // check start code
125 if ((temp[START_CODE_OFFSET_ONE] == 0) && (temp[START_CODE_OFFSET_SEC] == 0) &&
126 (temp[START_CODE_OFFSET_THIRD] == 0)) {
127 fseek(fp, -START_CODE_SIZE_FRAME, SEEK_CUR);
128 temp -= (START_CODE_SIZE_FRAME - 1);
129 break;
130 } else if ((temp[START_CODE_OFFSET_ONE] == 0) && (temp[START_CODE_OFFSET_SEC] == 0)) {
131 fseek(fp, -START_CODE_SIZE_SLICE, SEEK_CUR);
132 temp -= (START_CODE_SIZE_SLICE - 1);
133 break;
134 }
135 }
136 temp++;
137 }
138 readSize = (temp - buf);
139 return readSize;
140 }
141
GetShareMemoryById(int32_t id)142 static ShareMemory* GetShareMemoryById(int32_t id)
143 {
144 int32_t i;
145 for (i = 0; i < INPUT_BUFFER_NUM; i++) {
146 if (g_inputBuffers[i].id == id) {
147 return &g_inputBuffers[i];
148 }
149 }
150 for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
151 if (g_outputBuffers[i].id == id) {
152 return &g_outputBuffers[i];
153 }
154 }
155 return NULL;
156 }
157
ReleaseShm(void)158 static void ReleaseShm(void)
159 {
160 int32_t i;
161 if (g_inputBuffers != NULL) {
162 for (i = 0; i < INPUT_BUFFER_NUM; i++) {
163 ReleaseFdShareMemory(&g_inputBuffers[i]);
164 }
165 }
166 if (g_outputBuffers != NULL) {
167 for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
168 CodecBuffer *info = g_outputInfosData[i];
169 ReleaseGrShareMemory((BufferHandle *)info->buffer[0].buf, &g_outputBuffers[i]);
170 }
171 }
172 }
173
ReleaseCodecBuffer(CodecBuffer * info)174 void ReleaseCodecBuffer(CodecBuffer *info)
175 {
176 if (info == NULL) {
177 HDF_LOGE("%{public}s: Invalid param!", __func__);
178 return;
179 }
180 for (uint32_t i = 0; i < info->bufferCnt; i++) {
181 if (info->buffer[i].type == BUFFER_TYPE_HANDLE) {
182 DestroyGrShareMemory((BufferHandle *)info->buffer[i].buf);
183 }
184 }
185 OsalMemFree(info);
186 }
187
ReleaseCodecBuffers(void)188 static void ReleaseCodecBuffers(void)
189 {
190 int32_t i;
191 if (g_inputInfosData != NULL) {
192 for (i = 0; i < INPUT_BUFFER_NUM; i++) {
193 ReleaseCodecBuffer(g_inputInfosData[i]);
194 g_inputInfosData[i] = NULL;
195 }
196 }
197 if (g_outputInfosData != NULL) {
198 for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
199 ReleaseCodecBuffer(g_outputInfosData[i]);
200 g_outputInfosData[i] = NULL;
201 }
202 }
203 }
204
AllocateBuffer(int32_t inputBufferNum,int32_t inputBufferSize,int32_t outputBufferNum,int32_t outputBufferSize)205 static bool AllocateBuffer(int32_t inputBufferNum, int32_t inputBufferSize,
206 int32_t outputBufferNum, int32_t outputBufferSize)
207 {
208 g_inputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * inputBufferNum);
209 g_outputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * outputBufferNum);
210 g_inputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * inputBufferNum);
211 g_outputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * outputBufferNum);
212 if (g_inputBuffers != NULL && g_outputBuffers != NULL && g_inputInfosData != NULL && g_outputInfosData != NULL) {
213 return true;
214 }
215
216 HDF_LOGE("%{public}s: alloc buffers failed!", __func__);
217 OsalMemFree(g_inputBuffers);
218 OsalMemFree(g_outputBuffers);
219 OsalMemFree(g_inputInfosData);
220 OsalMemFree(g_outputInfosData);
221 g_inputBuffers = NULL;
222 g_outputBuffers = NULL;
223 g_inputInfosData = NULL;
224 g_outputInfosData = NULL;
225
226 return false;
227 }
228
InitAllocInfo(AllocInfo * alloc)229 static void InitAllocInfo(AllocInfo *alloc)
230 {
231 if (alloc == NULL) {
232 HDF_LOGI("%{public}s: ignore null alloc!", __func__);
233 return;
234 }
235 alloc->width = g_cmd.width;
236 alloc->height = g_cmd.height;
237 alloc->usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA;
238 alloc->format = PIXEL_FMT_YCBCR_420_SP;
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 = 0;
245 int32_t bufCount = 1;
246 if (!AllocateBuffer(inputBufferNum, inputBufferSize, outputBufferNum, outputBufferSize)) {
247 return false;
248 }
249 for (int32_t i = 0; i < inputBufferNum; i++) {
250 g_inputBuffers[i].id = i;
251 g_inputBuffers[i].size = inputBufferSize;
252 CreateFdShareMemory(&g_inputBuffers[i]);
253 g_inputInfosData[i] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCount);
254 g_inputInfosData[i]->bufferCnt = 1;
255 g_inputInfosData[i]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
256 g_inputInfosData[i]->bufferId = g_inputBuffers[i].id;
257 g_inputInfosData[i]->buffer[0].type = BUFFER_TYPE_FD;
258 g_inputInfosData[i]->buffer[0].buf = (intptr_t)g_inputBuffers[i].fd;
259 g_inputInfosData[i]->buffer[0].capacity = inputBufferSize;
260 queueRet = g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
261 g_inputInfosData[i], (uint32_t)0, -1);
262 if (queueRet != HDF_SUCCESS) {
263 HDF_LOGE("%{public}s: input buffer initial failed!", __func__);
264 return false;
265 }
266 }
267
268 AllocInfo alloc;
269 InitAllocInfo(&alloc);
270 for (int32_t j = 0; j < outputBufferNum; j++) {
271 g_outputBuffers[j].id = inputBufferNum + j;
272 g_outputBuffers[j].type = BUFFER_TYPE_HANDLE;
273 BufferHandle *bufferHandle;
274 CreateGrShareMemory(&bufferHandle, &alloc, &g_outputBuffers[j]);
275 g_outputInfosData[j] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCount);
276 g_outputInfosData[j]->bufferCnt = 1;
277 g_outputInfosData[j]->bufferId = g_outputBuffers[j].id;
278 g_outputInfosData[j]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
279 g_outputInfosData[j]->buffer[0].type = BUFFER_TYPE_HANDLE;
280 g_outputInfosData[j]->buffer[0].buf = (intptr_t)bufferHandle;
281 g_outputInfosData[j]->buffer[0].capacity = bufferHandle->size;
282 queueRet = g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
283 g_outputInfosData[j], (uint32_t)0, -1);
284 if (queueRet != HDF_SUCCESS) {
285 HDF_LOGE("%{public}s: output buffer initial failed!", __func__);
286 return false;
287 }
288 }
289 return true;
290 }
291
TestOnEvent(UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])292 int32_t TestOnEvent(UINTPTR userData, EventType event, uint32_t length, int32_t eventData[])
293 {
294 HDF_LOGI("%{public}s: TestOnEvent : event = %{public}d", __func__, event);
295 return HDF_SUCCESS;
296 }
297
TestInputBufferAvailable(UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)298 int32_t TestInputBufferAvailable(UINTPTR userData, CodecBuffer *inBuf, int32_t *acquireFd)
299 {
300 HDF_LOGI("%{public}s: TestInputBufferAvailable enter", __func__);
301 return HDF_SUCCESS;
302 }
303
TestOutputBufferAvailable(UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)304 int32_t TestOutputBufferAvailable(UINTPTR userData, CodecBuffer *outBuf, int32_t *acquireFd)
305 {
306 HDF_LOGI("%{public}s: TestOutputBufferAvailable write %{public}d", __func__, outBuf->buffer[0].length);
307 return HDF_SUCCESS;
308 }
309
SetExtDecParameter(void)310 static int32_t SetExtDecParameter(void)
311 {
312 Param param;
313 int32_t paramCnt;
314 int32_t ret;
315
316 // set split_parse enable mpp internal frame spliter when the input
317 paramCnt = 1;
318 memset_s(¶m, sizeof(Param), 0, sizeof(Param));
319 param.key = (ParamKey)KEY_EXT_SPLIT_PARSE_RK;
320 param.val = &g_autoSplit;
321 param.size = sizeof(uint32_t);
322 ret = g_codecProxy->CodecSetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, ¶m, paramCnt);
323 if (ret != HDF_SUCCESS) {
324 HDF_LOGE("%{public}s: CodecSetParameter failed", __func__);
325 return HDF_FAILURE;
326 }
327
328 // set decode frame number
329 memset_s(¶m, sizeof(Param), 0, sizeof(Param));
330 paramCnt = 1;
331 int32_t num = g_data.frameNum;
332 param.key = (ParamKey)KEY_EXT_DEC_FRAME_NUM_RK;
333 param.val = #
334 param.size = sizeof(int32_t);
335 ret = g_codecProxy->CodecSetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, ¶m, paramCnt);
336 if (ret != HDF_SUCCESS) {
337 HDF_LOGE("%{public}s: CodecSetParameter failed", __func__);
338 return HDF_FAILURE;
339 }
340
341 return HDF_SUCCESS;
342 }
343
SetDecParameter(void)344 static int32_t SetDecParameter(void)
345 {
346 Param param;
347 int32_t paramCnt = 1;
348 int32_t ret;
349
350 // set CodecType
351 memset_s(¶m, sizeof(Param), 0, sizeof(Param));
352 CodecType ct = VIDEO_DECODER;
353 param.key = KEY_CODEC_TYPE;
354 param.val = &ct;
355 param.size = sizeof(ct);
356 ret = g_codecProxy->CodecSetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, ¶m, paramCnt);
357 if (ret != HDF_SUCCESS) {
358 HDF_LOGE("%{public}s: CodecSetParameter KEY_CODEC_TYPE failed", __func__);
359 return HDF_FAILURE;
360 }
361
362 // get default config
363 memset_s(¶m, sizeof(Param), 0, sizeof(Param));
364 paramCnt = 1;
365 param.key = (ParamKey)KEY_EXT_DEFAULT_CFG_RK;
366 int32_t needDefault = 1;
367 param.val = &needDefault;
368 param.size = sizeof(int32_t);
369 ret = g_codecProxy->CodecGetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, ¶m, paramCnt);
370 if (ret != HDF_SUCCESS) {
371 HDF_LOGE("%{public}s: CodecSetParameter failed", __func__);
372 return HDF_FAILURE;
373 }
374
375 // get format
376 memset_s(¶m, sizeof(Param), 0, sizeof(Param));
377 paramCnt = 1;
378 param.key = KEY_PIXEL_FORMAT;
379 CodecPixelFormat fmt = PIXEL_FORMAT_NONE;
380 param.val = &fmt;
381 param.size = sizeof(CodecPixelFormat);
382 ret = g_codecProxy->CodecGetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, ¶m, paramCnt);
383 if (ret != HDF_SUCCESS) {
384 HDF_LOGE("%{public}s: CodecSetParameter failed", __func__);
385 return HDF_FAILURE;
386 }
387
388 if (SetExtDecParameter() != HDF_SUCCESS) {
389 return HDF_FAILURE;
390 }
391
392 return HDF_SUCCESS;
393 }
394
DecodeLoopHandleInput(const MpiDecLoopData * decData)395 static void DecodeLoopHandleInput(const MpiDecLoopData *decData)
396 {
397 int32_t ret = 0;
398 int32_t readSize = 0;
399 int32_t acquireFd = 0;
400
401 CodecBuffer *inputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
402 inputData->buffer[0].type = BUFFER_TYPE_FD;
403 inputData->bufferCnt = 1;
404 inputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
405 ret = g_codecProxy->CodecDequeueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, QUEUE_TIME_OUT,
406 &acquireFd, inputData);
407 if (ret == HDF_SUCCESS) {
408 if (g_autoSplit == 1) {
409 readSize = ReadInputFromFile(decData->fpInput, g_readFileBuf);
410 g_totalSrcSize += readSize;
411 g_pktEos = (readSize <= 0);
412 } else {
413 readSize = ReadOneFrameFromFile(decData->fpInput, g_readFileBuf);
414 g_totalSrcSize += readSize;
415 g_pktEos = ((g_totalSrcSize >= g_srcFileSize) || (readSize <= 0));
416 }
417 if (g_pktEos) {
418 HDF_LOGI("%{public}s: client inputData reach STREAM_FLAG_EOS", __func__);
419 inputData->flag = STREAM_FLAG_EOS;
420 }
421
422 ShareMemory *sm = GetShareMemoryById(inputData->bufferId);
423 memcpy_s(sm->virAddr, readSize, (uint8_t*)g_readFileBuf, readSize);
424 inputData->buffer[0].length = readSize;
425 g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, inputData, QUEUE_TIME_OUT, -1);
426 }
427 OsalMemFree(inputData);
428 }
429
DecodeLoop(MpiDecLoopData * decData)430 static int32_t DecodeLoop(MpiDecLoopData *decData)
431 {
432 int32_t ret = 0;
433
434 if (!g_pktEos) {
435 DecodeLoopHandleInput(decData);
436 }
437
438 CodecBuffer *outputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
439 outputData->buffer[0].type = BUFFER_TYPE_HANDLE;
440 outputData->bufferCnt = 1;
441 outputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
442
443 int32_t acquireFd = 0;
444 ret = g_codecProxy->CodecDequeueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, QUEUE_TIME_OUT,
445 &acquireFd, outputData);
446 if (ret == HDF_SUCCESS) {
447 g_totalFrames++;
448 ShareMemory *sm = GetShareMemoryById(outputData->bufferId);
449 DumpOutputToFile(decData->fpOutput, sm->virAddr);
450
451 CodecBuffer *queOutputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
452 queOutputData->buffer[0].type = BUFFER_TYPE_HANDLE;
453 queOutputData->buffer[0].buf = outputData->buffer[0].buf;
454 queOutputData->buffer[0].capacity = outputData->buffer[0].capacity;
455 queOutputData->bufferId = outputData->bufferId;
456 queOutputData->bufferCnt = 1;
457 queOutputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
458 g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, queOutputData, QUEUE_TIME_OUT, -1);
459 if (outputData->flag & STREAM_FLAG_EOS) {
460 HDF_LOGI("%{public}s: reach STREAM_FLAG_EOS, loopEnd, g_totalFrames:%{public}d", __func__, g_totalFrames);
461 decData->loopEnd = 1;
462 }
463 OsalMemFree(queOutputData);
464 }
465 OsalMemFree(outputData);
466
467 return ret;
468 }
469
DecodeThread(void * arg)470 static void *DecodeThread(void *arg)
471 {
472 MpiDecLoopData *decData = (MpiDecLoopData *)arg;
473
474 while (!decData->loopEnd) {
475 DecodeLoop(decData);
476 }
477
478 HDF_LOGD("%{public}s: client loopEnd", __func__);
479 return NULL;
480 }
481
RevertDecodeStep1(void)482 static void RevertDecodeStep1(void)
483 {
484 if (g_data.fpInput) {
485 fclose(g_data.fpInput);
486 g_data.fpInput = NULL;
487 }
488 if (g_data.fpOutput) {
489 fclose(g_data.fpOutput);
490 g_data.fpOutput = NULL;
491 }
492 }
493
RevertDecodeStep2(void)494 static void RevertDecodeStep2(void)
495 {
496 int32_t ret = g_codecProxy->CodecDeinit(g_codecProxy);
497 if (ret != HDF_SUCCESS) {
498 HDF_LOGE("%{public}s: CodecDeinit failed, ret:%{public}d", __func__, ret);
499 }
500 RevertDecodeStep1();
501 }
502
RevertDecodeStep3(void)503 static void RevertDecodeStep3(void)
504 {
505 ReleaseShm();
506 ReleaseCodecBuffers();
507
508 if (g_inputBuffers != NULL) {
509 OsalMemFree(g_inputBuffers);
510 }
511 if (g_outputBuffers != NULL) {
512 OsalMemFree(g_outputBuffers);
513 }
514 if (g_inputInfosData != NULL) {
515 OsalMemFree(g_inputInfosData);
516 }
517 if (g_outputInfosData != NULL) {
518 OsalMemFree(g_outputInfosData);
519 }
520 int32_t ret = g_codecProxy->CodecDestroy(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
521 if (ret != HDF_SUCCESS) {
522 HDF_LOGE("%{public}s: CodecDestroy failed, ret:%{public}d", __func__, ret);
523 }
524 RevertDecodeStep2();
525 }
526
OpenFile(void)527 static int32_t OpenFile(void)
528 {
529 struct stat fileStat = {0};
530 stat(g_cmd.fileInput, &fileStat);
531 g_srcFileSize = fileStat.st_size;
532 HDF_LOGI("%{public}s: input file size %{public}d", __func__, g_srcFileSize);
533
534 g_data.fpInput = fopen(g_cmd.fileInput, "rb");
535 if (g_data.fpInput == NULL) {
536 HDF_LOGE("%{public}s: failed to open input file %{public}s", __func__, g_cmd.fileInput);
537 RevertDecodeStep1();
538 return HDF_FAILURE;
539 }
540 g_data.fpOutput = fopen(g_cmd.fileOutput, "w+b");
541 if (g_data.fpOutput == NULL) {
542 HDF_LOGE("%{public}s: failed to open output file %{public}s", __func__, g_cmd.fileOutput);
543 RevertDecodeStep1();
544 return HDF_FAILURE;
545 }
546
547 g_readFileBuf = (uint8_t *)OsalMemAlloc(g_cmd.width * g_cmd.height * FRAME_SIZE_OPERATOR);
548 if (g_readFileBuf == NULL) {
549 HDF_LOGE("%{public}s: g_readFileBuf malloc failed", __func__);
550 RevertDecodeStep3();
551 return HDF_FAILURE;
552 }
553
554 return HDF_SUCCESS;
555 }
556
DecodeEnd(void)557 static void DecodeEnd(void)
558 {
559 DirectionType directType = ALL_TYPE;
560 int32_t ret = g_codecProxy->CodecFlush(g_codecProxy, (CODEC_HANDLETYPE)g_handle, directType);
561 if (ret != HDF_SUCCESS) {
562 HDF_LOGE("%{public}s: CodecFlush failed, ret:%{public}d", __func__, ret);
563 }
564
565 ret = g_codecProxy->CodecStop(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
566 if (ret != HDF_SUCCESS) {
567 HDF_LOGE("%{public}s: CodecStop failed, ret:%{public}d", __func__, ret);
568 }
569
570 RevertDecodeStep3();
571 if (g_readFileBuf != NULL) {
572 OsalMemFree(g_readFileBuf);
573 }
574 }
575
Decode(void)576 static int32_t Decode(void)
577 {
578 pthread_t thd;
579 pthread_attr_t attr;
580 int32_t ret = 0;
581
582 if (OpenFile() != HDF_SUCCESS) {
583 HDF_LOGE("%{public}s: Failed to open file!", __func__);
584 return HDF_FAILURE;
585 }
586
587 ret = g_codecProxy->CodecInit(g_codecProxy);
588 if (ret != HDF_SUCCESS) {
589 HDF_LOGE("%{public}s: CodecInit failed, ret:%{public}d", __func__, ret);
590 RevertDecodeStep1();
591 return HDF_FAILURE;
592 }
593
594 ret = g_codecProxy->CodecCreate(g_codecProxy, g_data.codecName, &g_handle);
595 if (ret != HDF_SUCCESS) {
596 HDF_LOGE("%{public}s: CodecCreate failed, ret:%{public}d", __func__, ret);
597 RevertDecodeStep2();
598 return HDF_FAILURE;
599 }
600 if (SetDecParameter() != HDF_SUCCESS) {
601 HDF_LOGE("%{public}s: SetDecParameter failed", __func__);
602 RevertDecodeStep3();
603 return HDF_FAILURE;
604 }
605
606 if (!InitBuffer(INPUT_BUFFER_NUM, g_cmd.width * g_cmd.height * FRAME_SIZE_OPERATOR, OUTPUT_BUFFER_NUM,
607 g_cmd.width * g_cmd.height * FRAME_SIZE_OPERATOR)) {
608 HDF_LOGE("%{public}s: InitBuffer failed", __func__);
609 RevertDecodeStep3();
610 return HDF_FAILURE;
611 }
612
613 g_codecProxy->CodecStart(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
614
615 pthread_attr_init(&attr);
616 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
617 ret = pthread_create(&thd, &attr, DecodeThread, &g_data);
618 if (ret != 0) {
619 HDF_LOGE("%{public}s: failed to create thread for input ret %{public}d", __func__, ret);
620 DecodeEnd();
621 pthread_attr_destroy(&attr);
622 return HDF_SUCCESS;
623 }
624
625 pthread_join(thd, NULL);
626 DecodeEnd();
627 pthread_attr_destroy(&attr);
628
629 return HDF_SUCCESS;
630 }
631
main(int32_t argc,char ** argv)632 int32_t main(int32_t argc, char **argv)
633 {
634 if (GrAllocatorInit() != HDF_SUCCESS) {
635 HDF_LOGE("GrAllocatorInit failed!");
636 return HDF_FAILURE;
637 }
638
639 g_cmd.type = VIDEO_DECODER;
640 int32_t ret = ParseArguments(&g_cmd, argc, argv);
641 HDF_LOGI("%{public}s: ParseArguments width:%{public}d", __func__, g_cmd.width);
642 HDF_LOGI("%{public}s: ParseArguments height:%{public}d", __func__, g_cmd.height);
643 HDF_LOGI("%{public}s: ParseArguments codecName:%{public}s", __func__, g_cmd.codecName);
644 HDF_LOGI("%{public}s: ParseArguments input:%{public}s", __func__, g_cmd.fileInput);
645 HDF_LOGI("%{public}s: ParseArguments output:%{public}s", __func__, g_cmd.fileOutput);
646 if (ret != HDF_SUCCESS) {
647 HDF_LOGE("ParseArguments failed!");
648 return ret;
649 }
650
651 memset_s(&g_data, sizeof(g_data), 0, sizeof(g_data));
652 g_codecProxy = HdiCodecGet(TEST_SERVICE_NAME);
653 g_data.codecName = g_cmd.codecName;
654
655 ret = Decode();
656 if (ret == HDF_SUCCESS) {
657 HDF_LOGI("%{public}s: test success", __func__);
658 } else {
659 HDF_LOGE("%{public}s: test failed ret %{public}d", __func__, ret);
660 }
661
662 // Release
663 HdiCodecRelease(g_codecProxy);
664 HDF_LOGI("%{public}s: test exit", __func__);
665 return ret;
666 }
667
668