• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&param, 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, &param, 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(&param, 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, &param, 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(&param, 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, &param, 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(&param, 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, &param, 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(&param, 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, &param, 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