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