• 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 <securec.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <sys/stat.h>
21 #include "codec_callback_stub.h"
22 #include "codec_type.h"
23 #include "codec_utils.h"
24 #include "codec_gralloc_wrapper.h"
25 #include "hdf_log.h"
26 #include "hdi_mpp.h"
27 #include "hdi_mpp_config.h"
28 #include "icodec.h"
29 #include "osal_mem.h"
30 #include "share_mem.h"
31 
32 #define HDF_LOG_TAG codec_hdi_demo_encode
33 #define TEST_SERVICE_NAME   "codec_hdi_service"
34 #define QUEUE_TIME_OUT              10
35 #define READ_SEGMENT_SIZE           8192
36 #define FRAME_SIZE_MULTI         	3
37 #define FRAME_SIZE_OPERATOR         2
38 #define BPS_BASE		            16
39 #define BPS_MAX			            17
40 #define BPS_MEDIUM			        15
41 #define BPS_MIN            			1
42 #define BPS_TARGET         			2
43 #define FIXQP_INIT_VALUE            20
44 #define FIXQP_MAX_VALUE             20
45 #define FIXQP_MIN_VALUE             20
46 #define FIXQP_MAX_I_VALUE           20
47 #define FIXQP_MIN_I_VALUE           20
48 #define FIXQP_IP_VALUE              2
49 #define OTHER_QP_INIT_VALUE         26
50 #define OTHER_QP_MAX_VALUE          51
51 #define OTHER_QP_MIN_VALUE          10
52 #define OTHER_QP_MAX_I_VALUE        51
53 #define OTHER_QP_MIN_I_VALUE        10
54 #define OTHER_QP_IP_VALUE           2
55 #define AVC_SETUP_LEVEL_DEFAULT     40
56 #define AVC_SETUP_CABAC_EN_DEFAULT  1
57 #define AVC_SETUP_CABAC_IDC_DEFAULT 0
58 #define AVC_SETUP_TRANS_DEFAULT     1
59 #define AVC_SETUP_PROFILE_DEFAULT   100
60 #define FPS_OUT_NUM_OPERATOR        2
61 #define INPUT_BUFFER_NUM            4
62 #define INPUT_BUFFER_SIZE_OPERATOR  2
63 #define OUTPUT_BUFFER_NUM           4
64 #define ENC_SETUP_DROP_THD          20
65 #define ENC_SETUP_FPS_IN_NUM        24
66 #define ENC_SETUP_FPS_OUT_NUM       24
67 #define PARAM_ARRAY_LEN             20
68 
69 typedef struct {
70     char            *codecName;
71     /* end of stream flag when set quit the loop */
72     unsigned int    loopEnd;
73     /* input and output */
74     FILE            *fpInput;
75     FILE            *fpOutput;
76     int32_t         frameNum;
77     CodecCallback   cb;
78 } CodecEnvData;
79 
80 static struct ICodec *g_codecProxy = NULL;
81 static CODEC_HANDLETYPE g_handle = NULL;
82 ShareMemory *g_inputBuffers = NULL;
83 ShareMemory *g_outputBuffers = NULL;
84 CodecBuffer **g_inputInfosData = NULL;
85 CodecBuffer **g_outputInfosData = NULL;
86 
87 CodecCmd g_cmd = {0};
88 CodecEnvData g_data = {0};
89 RKHdiEncodeSetup g_encodeSetup = {0};
90 
91 bool g_pktEos = false;
92 int32_t g_srcFileSize = 0;
93 int32_t g_totalSrcSize = 0;
94 int32_t g_totalDstSize = 0;
95 int32_t g_frameCount = 0;
96 
DumpOutputToFile(FILE * fp,uint8_t * addr,uint32_t len)97 void DumpOutputToFile(FILE *fp, uint8_t *addr, uint32_t len)
98 {
99     size_t ret = fwrite(addr, 1, len, fp);
100     if (ret != len) {
101         HDF_LOGE("%{public}s: DumpOutputToFile failed", __func__);
102     }
103 }
104 
ReadInputFromFile(FILE * fp,uint8_t * addr)105 static int32_t ReadInputFromFile(FILE *fp, uint8_t *addr)
106 {
107     int32_t readSize = 0;
108     int32_t frameSize = g_cmd.width * g_cmd.height * FRAME_SIZE_MULTI / FRAME_SIZE_OPERATOR;
109     int32_t loop = frameSize / READ_SEGMENT_SIZE;
110     for (int32_t i = 0; i < loop; i++) {
111         readSize += fread(addr + readSize, 1, READ_SEGMENT_SIZE, fp);
112     }
113     if (frameSize % READ_SEGMENT_SIZE > 0) {
114         readSize += fread(addr + readSize, 1, frameSize % READ_SEGMENT_SIZE, fp);
115     }
116     return readSize;
117 }
118 
GetShareMemoryById(int32_t id)119 static ShareMemory* GetShareMemoryById(int32_t id)
120 {
121     int32_t i;
122     for (i = 0; i < INPUT_BUFFER_NUM; i++) {
123         if (g_inputBuffers[i].id == id) {
124             return &g_inputBuffers[i];
125         }
126     }
127     for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
128         if (g_outputBuffers[i].id == id) {
129             return &g_outputBuffers[i];
130         }
131     }
132     return NULL;
133 }
134 
ReleaseShm(void)135 static void ReleaseShm(void)
136 {
137     int32_t i;
138     if (g_inputBuffers != NULL) {
139         for (i = 0; i < INPUT_BUFFER_NUM; i++) {
140             CodecBuffer *info = g_inputInfosData[i];
141             ReleaseGrShareMemory((BufferHandle *)info->buffer[0].buf, &g_inputBuffers[i]);
142         }
143     }
144     if (g_outputBuffers != NULL) {
145         for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
146             ReleaseFdShareMemory(&g_outputBuffers[i]);
147         }
148     }
149 }
150 
ReleaseCodecBuffer(CodecBuffer * info)151 void ReleaseCodecBuffer(CodecBuffer *info)
152 {
153     if (info == NULL) {
154         HDF_LOGE("%{public}s: Invalid param!", __func__);
155         return;
156     }
157     for (uint32_t i = 0; i < info->bufferCnt; i++) {
158         if (info->buffer[i].type == BUFFER_TYPE_HANDLE) {
159             DestroyGrShareMemory((BufferHandle *)info->buffer[i].buf);
160         }
161     }
162     OsalMemFree(info);
163 }
164 
ReleaseCodecBuffers(void)165 static void ReleaseCodecBuffers(void)
166 {
167     int32_t i;
168     if (g_inputInfosData != NULL) {
169         for (i = 0; i < INPUT_BUFFER_NUM; i++) {
170             ReleaseCodecBuffer(g_inputInfosData[i]);
171             g_inputInfosData[i] = NULL;
172         }
173     }
174     if (g_outputInfosData != NULL) {
175         for (i = 0; i < OUTPUT_BUFFER_NUM; i++) {
176             ReleaseCodecBuffer(g_outputInfosData[i]);
177             g_outputInfosData[i] = NULL;
178         }
179     }
180 }
181 
AllocateBuffer(int32_t inputBufferNum,int32_t inputBufferSize,int32_t outputBufferNum,int32_t outputBufferSize)182 static bool AllocateBuffer(int32_t inputBufferNum, int32_t inputBufferSize,
183     int32_t outputBufferNum, int32_t outputBufferSize)
184 {
185     g_inputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * inputBufferNum);
186     g_outputBuffers = (ShareMemory *)OsalMemCalloc(sizeof(ShareMemory) * outputBufferNum);
187     g_inputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * inputBufferNum);
188     g_outputInfosData = (CodecBuffer **)OsalMemCalloc(sizeof(CodecBuffer*) * outputBufferNum);
189     if (g_inputBuffers != NULL && g_outputBuffers != NULL && g_inputInfosData != NULL && g_outputInfosData != NULL) {
190         return true;
191     }
192 
193     HDF_LOGE("%{public}s: alloc buffers failed!", __func__);
194     OsalMemFree(g_inputBuffers);
195     OsalMemFree(g_outputBuffers);
196     OsalMemFree(g_inputInfosData);
197     OsalMemFree(g_outputInfosData);
198     g_inputBuffers = NULL;
199     g_outputBuffers = NULL;
200     g_inputInfosData = NULL;
201     g_outputInfosData = NULL;
202 
203     return false;
204 }
205 
InitAllocInfo(AllocInfo * alloc)206 static void InitAllocInfo(AllocInfo *alloc)
207 {
208     if (alloc == NULL) {
209         HDF_LOGI("%{public}s: ignore null alloc!", __func__);
210         return;
211     }
212     alloc->width = g_cmd.width;
213     alloc->height = g_cmd.height;
214     alloc->usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA;
215     alloc->format = PIXEL_FMT_YCBCR_420_SP;
216 }
217 
InitBuffer(int32_t inputBufferNum,int32_t inputBufferSize,int32_t outputBufferNum,int32_t outputBufferSize)218 static bool InitBuffer(int32_t inputBufferNum, int32_t inputBufferSize,
219     int32_t outputBufferNum, int32_t outputBufferSize)
220 {
221     int32_t queueRet = 0;
222     int32_t bufCount = 1;
223     if (!AllocateBuffer(inputBufferNum, inputBufferSize, outputBufferNum, outputBufferSize)) {
224         return false;
225     }
226 
227     AllocInfo alloc;
228     InitAllocInfo(&alloc);
229     for (int32_t i = 0; i < inputBufferNum; i++) {
230         g_inputBuffers[i].id = i;
231         g_inputBuffers[i].type = BUFFER_TYPE_HANDLE;
232         BufferHandle *bufferHandle;
233         CreateGrShareMemory(&bufferHandle, &alloc, &g_inputBuffers[i]);
234         g_inputInfosData[i] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCount);
235         g_inputInfosData[i]->bufferCnt = 1;
236         g_inputInfosData[i]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
237         g_inputInfosData[i]->bufferId = g_inputBuffers[i].id;
238         g_inputInfosData[i]->buffer[0].type = BUFFER_TYPE_HANDLE;
239         g_inputInfosData[i]->buffer[0].buf = (intptr_t)bufferHandle;
240         g_inputInfosData[i]->buffer[0].capacity = bufferHandle->size;
241         queueRet = g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
242             g_inputInfosData[i], (uint32_t)0, -1);
243         if (queueRet != HDF_SUCCESS) {
244             HDF_LOGE("%{public}s: input buffer initial failed!", __func__);
245             return false;
246         }
247     }
248 
249     for (int32_t j = 0; j < outputBufferNum; j++) {
250         g_outputBuffers[j].id = inputBufferNum + j;
251         g_outputBuffers[j].size = outputBufferSize;
252         CreateFdShareMemory(&g_outputBuffers[j]);
253         g_outputInfosData[j] = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCount);
254         g_outputInfosData[j]->bufferCnt = 1;
255         g_outputInfosData[j]->bufferId = g_outputBuffers[j].id;
256         g_outputInfosData[j]->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
257         g_outputInfosData[j]->buffer[0].type = BUFFER_TYPE_FD;
258         g_outputInfosData[j]->buffer[0].buf = (intptr_t)g_outputBuffers[j].fd;
259         g_outputInfosData[j]->buffer[0].capacity = outputBufferSize;
260         queueRet = g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle,
261             g_outputInfosData[j], (uint32_t)0, -1);
262         if (queueRet != HDF_SUCCESS) {
263             HDF_LOGE("%{public}s: output buffer initial failed!", __func__);
264             return false;
265         }
266     }
267     return true;
268 }
269 
TestOnEvent(UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])270 int32_t TestOnEvent(UINTPTR userData, EventType event, uint32_t length, int32_t eventData[])
271 {
272     HDF_LOGI("%{public}s: TestOnEvent: event = %{public}d", __func__, event);
273     return HDF_SUCCESS;
274 }
275 
TestInputBufferAvailable(UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)276 int32_t TestInputBufferAvailable(UINTPTR userData, CodecBuffer *inBuf, int32_t *acquireFd)
277 {
278     HDF_LOGI("%{public}s: TestInputBufferAvailable enter", __func__);
279     return HDF_SUCCESS;
280 }
281 
TestOutputBufferAvailable(UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)282 int32_t TestOutputBufferAvailable(UINTPTR userData, CodecBuffer *outBuf, int32_t *acquireFd)
283 {
284     HDF_LOGI("%{public}s: TestOutputBufferAvailable write %{public}d", __func__, outBuf->buffer[0].length);
285     return HDF_SUCCESS;
286 }
287 
SetQpValue(RKHdiEncodeSetup * encSetup)288 static void SetQpValue(RKHdiEncodeSetup *encSetup)
289 {
290     switch (encSetup->rc.rcMode) {
291         case MPP_ENC_RC_MODE_FIXQP: {
292             encSetup->rc.qpInit = FIXQP_INIT_VALUE;
293             encSetup->rc.qpMax = FIXQP_MAX_VALUE;
294             encSetup->rc.qpMin = FIXQP_MIN_VALUE;
295             encSetup->rc.qpMaxI = FIXQP_MAX_I_VALUE;
296             encSetup->rc.qpMinI = FIXQP_MIN_I_VALUE;
297             encSetup->rc.qpIp = FIXQP_IP_VALUE;
298             break;
299         }
300         case MPP_ENC_RC_MODE_CBR:
301         case MPP_ENC_RC_MODE_VBR:
302         case MPP_ENC_RC_MODE_AVBR: {
303             encSetup->rc.qpInit = OTHER_QP_INIT_VALUE;
304             encSetup->rc.qpMax = OTHER_QP_MAX_VALUE;
305             encSetup->rc.qpMin = OTHER_QP_MIN_VALUE;
306             encSetup->rc.qpMaxI = OTHER_QP_MAX_I_VALUE;
307             encSetup->rc.qpMinI = OTHER_QP_MIN_I_VALUE;
308             encSetup->rc.qpIp = OTHER_QP_IP_VALUE;
309             break;
310         }
311         default: {
312             HDF_LOGE("%{public}s: unsupported encoder rc mode %{public}d", __func__, encSetup->rc.rcMode);
313             break;
314         }
315     }
316 }
317 
CalcBpsRange(RKHdiEncodeSetup * encSetup)318 static void CalcBpsRange(RKHdiEncodeSetup *encSetup)
319 {
320     switch (encSetup->rc.rcMode) {
321         case MPP_ENC_RC_MODE_FIXQP: {
322             /* do not setup bitrate on FIXQP mode */
323             break;
324         }
325         case MPP_ENC_RC_MODE_CBR: {
326             /* CBR mode has narrow bound */
327             encSetup->rc.bpsMax = encSetup->rc.bpsTarget * BPS_MAX / BPS_BASE;
328             encSetup->rc.bpsMin = encSetup->rc.bpsTarget * BPS_MEDIUM / BPS_BASE;
329             break;
330         }
331         case MPP_ENC_RC_MODE_VBR:
332         case MPP_ENC_RC_MODE_AVBR: {
333             /* VBR mode has wide bound */
334             encSetup->rc.bpsMax = encSetup->rc.bpsTarget * BPS_MAX / BPS_BASE;
335             encSetup->rc.bpsMin = encSetup->rc.bpsTarget * BPS_MIN / BPS_BASE;
336             break;
337         }
338         default: {
339             /* default use CBR mode */
340             encSetup->rc.bpsMax = encSetup->rc.bpsTarget * BPS_MAX / BPS_BASE;
341             encSetup->rc.bpsMin = encSetup->rc.bpsTarget * BPS_MEDIUM / BPS_BASE;
342             break;
343         }
344     }
345     /* setup qp for different codec and rc_mode */
346     switch (encSetup->codecMime.mimeCodecType) {
347         case MPP_VIDEO_CodingAVC:
348         case MPP_VIDEO_CodingHEVC: {
349             SetQpValue(encSetup);
350             break;
351         }
352         default: {
353             break;
354         }
355     }
356 }
357 
SetCodecTypeData(RKHdiCodecMimeSetup * codecMimeSet)358 static void SetCodecTypeData(RKHdiCodecMimeSetup *codecMimeSet)
359 {
360     switch (codecMimeSet->mimeCodecType) {
361         case MEDIA_MIMETYPE_VIDEO_AVC: {
362             /*
363             * H.264 profile_idc parameter
364             * 66  - Baseline profile
365             * 77  - Main profile
366             * 100 - High profile
367             */
368             codecMimeSet->avcSetup.profile = AVC_SETUP_PROFILE_DEFAULT;
369             /*
370             * H.264 level_idc parameter
371             * 10 / 11 / 12 / 13    - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
372             * 20 / 21 / 22         - cif@30fps / half-D1@@25fps / D1@12.5fps
373             * 30 / 31 / 32         - D1@25fps / 720p@30fps / 720p@60fps
374             * 40 / 41 / 42         - 1080p@30fps / 1080p@30fps / 1080p@60fps
375             * 50 / 51 / 52         - 4K@30fps
376             */
377             codecMimeSet->avcSetup.level = AVC_SETUP_LEVEL_DEFAULT;
378             codecMimeSet->avcSetup.cabacEn = AVC_SETUP_CABAC_EN_DEFAULT;
379             codecMimeSet->avcSetup.cabacIdc = AVC_SETUP_CABAC_IDC_DEFAULT;
380             codecMimeSet->avcSetup.trans8x8 = AVC_SETUP_TRANS_DEFAULT;
381             break;
382         }
383         case MEDIA_MIMETYPE_VIDEO_HEVC: {
384             break;
385         }
386         default: {
387             HDF_LOGE("%{public}s: unsupport encoder coding type %{public}d", __func__, codecMimeSet->mimeCodecType);
388             break;
389         }
390     }
391 }
392 
FreeParams(Param * params,int32_t paramCnt)393 static void FreeParams(Param *params, int32_t paramCnt)
394 {
395     if (params == NULL || paramCnt <= 0) {
396         HDF_LOGE("%{public}s: params is null or invalid count!", __func__);
397         return;
398     }
399     for (int32_t j = 0; j < paramCnt; j++) {
400         if (params[j].val != NULL && params[j].size > 0) {
401             OsalMemFree(params[j].val);
402             params[j].val = NULL;
403         }
404     }
405     OsalMemFree(params);
406 }
407 
CheckEncSetup(Param * setParams,Param * getParams,int32_t paramCnt)408 static void CheckEncSetup(Param *setParams, Param *getParams, int32_t paramCnt)
409 {
410     if (setParams == NULL || getParams == NULL || paramCnt <= 0) {
411         HDF_LOGE("%{public}s: params is null or invalid count!", __func__);
412         return;
413     }
414     for (int32_t i = 0; i < paramCnt; i++) {
415         if (setParams[i].size != getParams[i].size) {
416             HDF_LOGE("%{public}s: params size incorrect!", __func__);
417             return;
418         }
419         if (memcmp(setParams[i].val, getParams[i].val, setParams[i].size) != 0) {
420             HDF_LOGE("%{public}s: params val incorrect! index:%{public}d", __func__, i);
421             return;
422         }
423     }
424 
425     HDF_LOGI("%{public}s: get all params correctly!", __func__);
426 }
427 
GetSetupParams(Param * setParams,int32_t paramCnt)428 static int32_t GetSetupParams(Param *setParams, int32_t paramCnt)
429 {
430     Param *getParams = (Param *)OsalMemCalloc(sizeof(Param) * paramCnt);
431 
432     for (int32_t i = 0; i < paramCnt; i++) {
433         getParams[i].key = setParams[i].key;
434     }
435     int32_t ret = g_codecProxy->CodecGetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, getParams, paramCnt);
436     if (ret != HDF_SUCCESS) {
437         HDF_LOGE("%{public}s: CodecGetParameter failed, ret:%{public}d", __func__, ret);
438         FreeParams(getParams, paramCnt);
439         return HDF_FAILURE;
440     }
441     CheckEncSetup(setParams, getParams, paramCnt);
442     FreeParams(getParams, paramCnt);
443     return HDF_SUCCESS;
444 }
445 
SetupExtEncParams(Param * params,RKHdiEncodeSetup * encSetup,int32_t count)446 static int32_t SetupExtEncParams(Param *params, RKHdiEncodeSetup *encSetup, int32_t count)
447 {
448     Param *param = NULL;
449     int32_t paramCount = count;
450 
451     param = &params[paramCount++];
452     param->key = (ParamKey)KEY_EXT_SETUP_DROP_MODE_RK;
453     encSetup->drop.dropMode = MPP_ENC_RC_DROP_FRM_DISABLED;
454     encSetup->drop.dropThd = ENC_SETUP_DROP_THD;
455     encSetup->drop.dropGap = 1;
456     param->val = &(encSetup->drop);
457     param->size = sizeof(encSetup->drop);
458 
459     param = &params[paramCount++];
460     param->key = KEY_MIMETYPE;
461     encSetup->codecMime.mimeCodecType = MEDIA_MIMETYPE_VIDEO_AVC;
462     SetCodecTypeData(&encSetup->codecMime);
463     param->val = &(encSetup->codecMime);
464     param->size = sizeof(encSetup->codecMime);
465 
466     param = &params[paramCount++];
467     param->key = KEY_CODEC_TYPE;
468     encSetup->codecType = VIDEO_ENCODER;
469     param->val = &encSetup->codecType;
470     param->size = sizeof(encSetup->codecType);
471 
472     param = &params[paramCount++];
473     param->key = KEY_VIDEO_RC_MODE;
474     encSetup->rc.rcMode = VID_CODEC_RC_VBR;
475     encSetup->rc.bpsTarget = g_cmd.width * g_cmd.height * BPS_TARGET / BPS_BASE *
476         (encSetup->fps.fpsOutNum / encSetup->fps.fpsOutDen);
477     CalcBpsRange(encSetup);
478     param->val = &(encSetup->rc);
479     param->size = sizeof(encSetup->rc);
480 
481     param = &params[paramCount++];
482     param->key = KEY_VIDEO_GOP_MODE;
483     encSetup->gop.gopMode = VID_CODEC_GOPMODE_NORMALP;
484     encSetup->gop.gopLen = 0;
485     encSetup->gop.viLen = 0;
486     encSetup->gop.gop = encSetup->fps.fpsOutNum * FPS_OUT_NUM_OPERATOR;
487     param->val = &(encSetup->gop);
488     param->size = sizeof(encSetup->gop);
489 
490     param = &params[paramCount++];
491     param->key = (ParamKey)KEY_EXT_ENC_VALIDATE_SETUP_RK;
492 
493     return paramCount;
494 }
495 
SetupEncParams(RKHdiEncodeSetup * encSetup)496 static int32_t SetupEncParams(RKHdiEncodeSetup *encSetup)
497 {
498     Param params[PARAM_ARRAY_LEN] = {0};
499     Param *param = NULL;
500     int32_t paramCount = 0;
501 
502     param = &params[paramCount++];
503     param->key = KEY_VIDEO_WIDTH;
504     encSetup->width = g_cmd.width;
505     param->val = &(encSetup->width);
506     param->size = sizeof(encSetup->width);
507 
508     param = &params[paramCount++];
509     param->key = KEY_VIDEO_HEIGHT;
510     encSetup->height = g_cmd.height;
511     param->val = &(encSetup->height);
512     param->size = sizeof(encSetup->height);
513 
514     param = &params[paramCount++];
515     param->key = KEY_PIXEL_FORMAT;
516     encSetup->fmt = PIXEL_FORMAT_YCBCR_420_SP;
517     param->val = &(encSetup->fmt);
518     param->size = sizeof(encSetup->fmt);
519 
520     param = &params[paramCount++];
521     param->key = KEY_VIDEO_STRIDE;
522     encSetup->stride.horStride = GetDefaultHorStride(g_cmd.width, encSetup->fmt);
523     encSetup->stride.verStride = g_cmd.height;
524     param->val = &(encSetup->stride);
525     param->size = sizeof(encSetup->stride);
526 
527     param = &params[paramCount++];
528     param->key = KEY_VIDEO_FRAME_RATE;
529     encSetup->fps.fpsInFlex = 0;
530     encSetup->fps.fpsInNum = ENC_SETUP_FPS_IN_NUM;
531     encSetup->fps.fpsOutNum = ENC_SETUP_FPS_OUT_NUM;
532     encSetup->fps.fpsInDen = 1;
533     encSetup->fps.fpsOutDen = 1;
534     encSetup->fps.fpsOutFlex = 0;
535     param->val = &(encSetup->fps);
536     param->size = sizeof(encSetup->fps);
537 
538     paramCount = SetupExtEncParams(params, encSetup, paramCount);
539     int32_t ret = g_codecProxy->CodecSetParameter(g_codecProxy, (CODEC_HANDLETYPE)g_handle, params, paramCount);
540     if (ret != HDF_SUCCESS) {
541         HDF_LOGE("%{public}s: CodecSetParameter failed, ret:%{public}d", __func__, ret);
542         return ret;
543     }
544 
545     ret = GetSetupParams(params, paramCount - 1);
546     if (ret != HDF_SUCCESS) {
547         HDF_LOGE("%{public}s: GetSetupParams failed", __func__);
548         return ret;
549     }
550 
551     return HDF_SUCCESS;
552 }
553 
EncodeLoopHandleInput(const CodecEnvData * envData,uint8_t * readData)554 static void EncodeLoopHandleInput(const CodecEnvData *envData, uint8_t *readData)
555 {
556     int32_t ret = 0;
557     int32_t acquireFd = 0;
558 
559     CodecBuffer *inputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
560     inputData->buffer[0].type = BUFFER_TYPE_HANDLE;
561     inputData->bufferCnt = 1;
562     inputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
563     ret = g_codecProxy->CodecDequeueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, QUEUE_TIME_OUT,
564         &acquireFd, inputData);
565     if (ret == HDF_SUCCESS) {
566         // when packet size is valid read the input binary file
567         g_frameCount++;
568         int32_t readSize = ReadInputFromFile(envData->fpInput, readData);
569         g_totalSrcSize += readSize;
570         g_pktEos = (g_totalSrcSize >= g_srcFileSize);
571         if (g_pktEos) {
572             HDF_LOGI("%{public}s: client inputData reach STREAM_FLAG_EOS, g_frameCount:%{public}d",
573                 __func__, g_frameCount);
574             inputData->flag = STREAM_FLAG_EOS;
575         }
576 
577         ShareMemory *sm = GetShareMemoryById(inputData->bufferId);
578         memcpy_s(sm->virAddr, readSize, (uint8_t*)readData, readSize);
579         inputData->buffer[0].length = readSize;
580         g_codecProxy->CodecQueueInput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, inputData, QUEUE_TIME_OUT, -1);
581     }
582     OsalMemFree(inputData);
583 }
584 
EncodeLoop(CodecEnvData * envData,uint8_t * readData)585 static int32_t EncodeLoop(CodecEnvData *envData, uint8_t *readData)
586 {
587     int32_t ret = 0;
588 
589     if (!g_pktEos) {
590         EncodeLoopHandleInput(envData, readData);
591     }
592 
593     CodecBuffer *outputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
594     outputData->buffer[0].type = BUFFER_TYPE_FD;
595     outputData->bufferCnt = 1;
596     outputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
597 
598     int32_t acquireFd = 0;
599     ret = g_codecProxy->CodecDequeueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, QUEUE_TIME_OUT,
600         &acquireFd, outputData);
601     if (ret == HDF_SUCCESS) {
602         g_totalDstSize += outputData->buffer[0].length;
603         ShareMemory *sm = GetShareMemoryById(outputData->bufferId);
604         DumpOutputToFile(envData->fpOutput, sm->virAddr, outputData->buffer[0].length);
605 
606         CodecBuffer *queOutputData = (CodecBuffer *)OsalMemCalloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo));
607         queOutputData->buffer[0].type = BUFFER_TYPE_FD;
608         queOutputData->buffer[0].buf = outputData->buffer[0].buf;
609         queOutputData->buffer[0].capacity = outputData->buffer[0].capacity;
610         queOutputData->bufferId = outputData->bufferId;
611         queOutputData->bufferCnt = 1;
612         queOutputData->flag = STREAM_FLAG_CODEC_SPECIFIC_INF;
613         g_codecProxy->CodecQueueOutput(g_codecProxy, (CODEC_HANDLETYPE)g_handle, queOutputData, QUEUE_TIME_OUT, -1);
614         if (outputData->flag & STREAM_FLAG_EOS) {
615             HDF_LOGI("%{public}s: client reach STREAM_FLAG_EOS, CodecEncode loopEnd", __func__);
616             envData->loopEnd = 1;
617         }
618         OsalMemFree(queOutputData);
619     }
620     OsalMemFree(outputData);
621 
622     return ret;
623 }
624 
EncodeThread(void * arg)625 static void *EncodeThread(void *arg)
626 {
627     CodecEnvData *envData = (CodecEnvData *)arg;
628     uint8_t *readData = (uint8_t*)OsalMemCalloc(g_cmd.width * g_cmd.height * 2);
629     if (readData == NULL) {
630         HDF_LOGE("%{public}s: input readData buffer mem alloc failed", __func__);
631         return NULL;
632     }
633 
634     HDF_LOGI("%{public}s: client EncodeThread start", __func__);
635     while (envData->loopEnd != 1) {
636         EncodeLoop(envData, readData);
637     }
638     OsalMemFree(readData);
639     HDF_LOGI("%{public}s: client loopEnd, g_totalSrcSize:%{public}d, g_totalDstSize: %{public}d",
640         __func__, g_totalSrcSize, g_totalDstSize);
641     return NULL;
642 }
643 
RevertEncodeStep1(void)644 static void RevertEncodeStep1(void)
645 {
646     if (g_data.fpInput) {
647         fclose(g_data.fpInput);
648         g_data.fpInput = NULL;
649     }
650     if (g_data.fpOutput) {
651         fclose(g_data.fpOutput);
652         g_data.fpOutput = NULL;
653     }
654 }
655 
RevertEncodeStep2(void)656 static void RevertEncodeStep2(void)
657 {
658     int32_t ret = g_codecProxy->CodecDeinit(g_codecProxy);
659     if (ret != HDF_SUCCESS) {
660         HDF_LOGE("%{public}s: failed to CodecDeinit %{public}d", __func__, ret);
661     }
662     RevertEncodeStep1();
663 }
664 
RevertEncodeStep3(void)665 static void RevertEncodeStep3(void)
666 {
667     ReleaseShm();
668     ReleaseCodecBuffers();
669 
670     if (g_inputBuffers != NULL) {
671         OsalMemFree(g_inputBuffers);
672     }
673     if (g_outputBuffers != NULL) {
674         OsalMemFree(g_outputBuffers);
675     }
676     if (g_inputInfosData != NULL) {
677         OsalMemFree(g_inputInfosData);
678     }
679     if (g_outputInfosData != NULL) {
680         OsalMemFree(g_outputInfosData);
681     }
682     int32_t ret = g_codecProxy->CodecDestroy(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
683     if (ret != HDF_SUCCESS) {
684         HDF_LOGE("%{public}s: failed to CodecDestroy %{public}d", __func__, ret);
685     }
686     RevertEncodeStep2();
687 }
688 
OpenFile(void)689 static int32_t OpenFile(void)
690 {
691     struct stat fileStat = {0};
692     stat(g_cmd.fileInput, &fileStat);
693     g_srcFileSize = fileStat.st_size;
694     HDF_LOGI("%{public}s: input file size %{public}d", __func__, g_srcFileSize);
695 
696     g_data.fpInput = fopen(g_cmd.fileInput, "rb");
697     if (g_data.fpInput == NULL) {
698         HDF_LOGE("%{public}s: failed to open input file %{public}s", __func__, g_cmd.fileInput);
699         RevertEncodeStep1();
700         return HDF_FAILURE;
701     }
702 
703     g_data.fpOutput = fopen(g_cmd.fileOutput, "w+b");
704     if (g_data.fpOutput == NULL) {
705         HDF_LOGE("%{public}s: failed to open output file %{public}s", __func__, g_cmd.fileOutput);
706         RevertEncodeStep1();
707         return HDF_FAILURE;
708     }
709 
710     return HDF_SUCCESS;
711 }
712 
EncodeEnd(void)713 static void EncodeEnd(void)
714 {
715     DirectionType directType = ALL_TYPE;
716     int32_t ret = g_codecProxy->CodecFlush(g_codecProxy, (CODEC_HANDLETYPE)g_handle, directType);
717     if (ret != HDF_SUCCESS) {
718         HDF_LOGE("%{public}s: CodecFlush failed", __func__);
719     }
720 
721     ret = g_codecProxy->CodecStop(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
722     if (ret != HDF_SUCCESS) {
723         HDF_LOGE("%{public}s: failed to CodecStop %{public}d", __func__, ret);
724     }
725 
726     RevertEncodeStep3();
727 }
728 
Encode(void)729 static int32_t Encode(void)
730 {
731     pthread_t thd;
732     pthread_attr_t attr;
733     int32_t bufferSize = g_cmd.width * g_cmd.height * INPUT_BUFFER_SIZE_OPERATOR;
734     int32_t ret = 0;
735 
736     if (OpenFile() != HDF_SUCCESS) {
737         return HDF_FAILURE;
738     }
739 
740     ret = g_codecProxy->CodecInit(g_codecProxy);
741     if (ret != HDF_SUCCESS) {
742         HDF_LOGE("%{public}s: CodecInit failed", __func__);
743         RevertEncodeStep1();
744         return HDF_FAILURE;
745     }
746 
747     ret = g_codecProxy->CodecCreate(g_codecProxy, g_data.codecName, &g_handle);
748     if (ret != HDF_SUCCESS) {
749         HDF_LOGE("%{public}s: CodecCreate failed, ret:%{public}d", __func__, ret);
750         RevertEncodeStep2();
751         return HDF_FAILURE;
752     }
753 
754     if (SetupEncParams(&g_encodeSetup) != HDF_SUCCESS) {
755         RevertEncodeStep3();
756         return HDF_FAILURE;
757     }
758     if (!InitBuffer(INPUT_BUFFER_NUM, bufferSize, OUTPUT_BUFFER_NUM, bufferSize)) {
759         HDF_LOGE("%{public}s: InitBuffer failed", __func__);
760         RevertEncodeStep3();
761         return HDF_FAILURE;
762     }
763 
764     g_codecProxy->CodecStart(g_codecProxy, (CODEC_HANDLETYPE)g_handle);
765 
766     pthread_attr_init(&attr);
767     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
768     ret = pthread_create(&thd, &attr, EncodeThread, &g_data);
769     if (ret != 0) {
770         HDF_LOGE("%{public}s: failed to create thread for input ret %{public}d", __func__, ret);
771         EncodeEnd();
772         pthread_attr_destroy(&attr);
773         return HDF_FAILURE;
774     }
775 
776     pthread_join(thd, NULL);
777     EncodeEnd();
778     pthread_attr_destroy(&attr);
779 
780     return HDF_SUCCESS;
781 }
782 
main(int32_t argc,char ** argv)783 int32_t main(int32_t argc, char **argv)
784 {
785     if (GrAllocatorInit() != HDF_SUCCESS) {
786         HDF_LOGE("GrAllocatorInit failed!");
787         return HDF_FAILURE;
788     }
789 
790     g_cmd.type = VIDEO_ENCODER;
791     int32_t ret = ParseArguments(&g_cmd, argc, argv);
792     HDF_LOGI("%{public}s: ParseArguments width:%{public}d", __func__, g_cmd.width);
793     HDF_LOGI("%{public}s: ParseArguments height:%{public}d", __func__, g_cmd.height);
794     HDF_LOGI("%{public}s: ParseArguments codecName:%{public}s", __func__, g_cmd.codecName);
795     HDF_LOGI("%{public}s: ParseArguments input:%{public}s", __func__, g_cmd.fileInput);
796     HDF_LOGI("%{public}s: ParseArguments output:%{public}s", __func__, g_cmd.fileOutput);
797     if (ret != HDF_SUCCESS) {
798         HDF_LOGE("%{public}s: ParseArguments failed", __func__);
799         return ret;
800     }
801 
802     memset_s(&g_data, sizeof(g_data), 0, sizeof(g_data));
803     g_codecProxy = HdiCodecGet(TEST_SERVICE_NAME);
804 
805     g_data.codecName = g_cmd.codecName;
806 
807     ret = Encode();
808     if (ret == HDF_SUCCESS) {
809         HDF_LOGI("%{public}s: test success", __func__);
810     } else {
811         HDF_LOGE("%{public}s: test failed ret %{public}d", __func__, ret);
812     }
813 
814     HdiCodecRelease(g_codecProxy);
815     HDF_LOGI("%{public}s: test exit", __func__);
816     return ret;
817 }
818 
819