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