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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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 = ¶ms[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