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