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