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 "hdi_mpp.h"
17 #include <dlfcn.h>
18 #include <hdf_base.h>
19 #include <hdf_log.h>
20 #include <securec.h>
21 #include "hdi_mpp_component_manager.h"
22 #include "hdi_mpp_config.h"
23 #include "im2d.h"
24 #include "mpp_common.h"
25 #include "rga.h"
26 #include "rk_vdec_cfg.h"
27
28 #define HDF_LOG_TAG codec_hdi_mpp
29 #define BITWISE_LEFT_SHIFT_WITH_ONE (1 << 20)
30 #define SLEEP_INTERVAL_MICROSECONDS 1000
31 #define BUFFER_GROUP_LIMIT_NUM 24
32 #define FRAME_STRIDE_ALIGNMENT 16
33
InitComponentSetup(RKHdiBaseComponent * component)34 static void InitComponentSetup(RKHdiBaseComponent *component)
35 {
36 component->setup.fmt = PIXEL_FMT_BUTT;
37 component->fmt = MPP_FMT_BUTT;
38 SetDefaultFps(&component->setup);
39 SetDefaultDropMode(&component->setup);
40 component->setup.rc.rcMode = MPP_ENC_RC_MODE_VBR;
41 SetDefaultGopMode(&component->setup);
42 }
43
CreateMppComponent(MppCtxType ctxType,MppCodingType codingType)44 static RKHdiBaseComponent* CreateMppComponent(MppCtxType ctxType, MppCodingType codingType)
45 {
46 RKHdiBaseComponent* component = (RKHdiBaseComponent *)malloc(sizeof(RKHdiBaseComponent));
47 if (component == NULL) {
48 HDF_LOGE("%{public}s: malloc failed!", __func__);
49 return NULL;
50 }
51 int32_t ret = memset_s(component, sizeof(RKHdiBaseComponent), 0, sizeof(RKHdiBaseComponent));
52 if (ret != EOK) {
53 HDF_LOGE("%{public}s: memset failed, error code: %{public}d", __func__, ret);
54 }
55 InitComponentSetup(component);
56
57 ret = GetMppApi(&component->mppApi);
58 if ((ret != HDF_SUCCESS) || (component->mppApi == NULL)) {
59 HDF_LOGE("%{public}s: GetMppAPI failed!", __func__);
60 component->mppApi = NULL;
61 free(component);
62 return NULL;
63 }
64
65 component->ctxType = ctxType;
66 component->codingType = codingType;
67 component->frameNum = 0;
68 ret = InitMppConfig(component);
69 if (ret != 0) {
70 HDF_LOGE("%{public}s: config mpp cfg init failed!", __func__);
71 ReleaseMppApi(component->mppApi);
72 component->mppApi = NULL;
73 free(component);
74 return NULL;
75 }
76
77 return component;
78 }
79
DestroyMppComponent(RKHdiBaseComponent * component)80 static void DestroyMppComponent(RKHdiBaseComponent *component)
81 {
82 if (component == NULL) {
83 HDF_LOGE("%{public}s: component is NULL", __func__);
84 }
85 DeinitMppConfig(component);
86 ReleaseMppApi(component->mppApi);
87 component->mppApi = NULL;
88 free(component);
89 component = NULL;
90 }
91
CodecInit(void)92 int32_t CodecInit(void)
93 {
94 return HDF_SUCCESS;
95 }
96
CodecDeinit(void)97 int32_t CodecDeinit(void)
98 {
99 return HDF_SUCCESS;
100 }
101
CodecSetCallback(CODEC_HANDLETYPE handle,CodecCallback * cb,UINTPTR instance)102 int32_t CodecSetCallback(CODEC_HANDLETYPE handle, CodecCallback *cb, UINTPTR instance)
103 {
104 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
105 if (component == NULL) {
106 HDF_LOGE("%{public}s: component is NULL", __func__);
107 return HDF_FAILURE;
108 }
109 if (cb == NULL) {
110 HDF_LOGE("%{public}s: call back is NULL", __func__);
111 return HDF_FAILURE;
112 }
113
114 component->pCallbacks = cb;
115
116 return HDF_SUCCESS;
117 }
118
GetMppCtxType(const char * name)119 static MppCtxType GetMppCtxType(const char* name)
120 {
121 char *pos = strstr(name, "decoder");
122 if (pos != NULL) {
123 return MPP_CTX_DEC;
124 }
125
126 pos = strstr(name, "encoder");
127 if (pos != NULL) {
128 return MPP_CTX_ENC;
129 }
130
131 HDF_LOGE("%{public}s: CtxType undefined!", __func__);
132 return MPP_CTX_BUTT;
133 }
134
GetMppCodingType(const char * name)135 static MppCodingType GetMppCodingType(const char* name)
136 {
137 char *pos = strstr(name, "avc");
138 if (pos != NULL) {
139 return MPP_VIDEO_CodingAVC;
140 }
141
142 pos = strstr(name, "hevc");
143 if (pos != NULL) {
144 return MPP_VIDEO_CodingHEVC;
145 }
146
147 pos = strstr(name, "mpeg4");
148 if (pos != NULL) {
149 return MPP_VIDEO_CodingMPEG4;
150 }
151
152 pos = strstr(name, "mpeg2");
153 if (pos != NULL) {
154 return MPP_VIDEO_CodingMPEG2;
155 }
156
157 pos = strstr(name, "vp8");
158 if (pos != NULL) {
159 return MPP_VIDEO_CodingVP8;
160 }
161
162 pos = strstr(name, "vp9");
163 if (pos != NULL) {
164 return MPP_VIDEO_CodingVP9;
165 }
166
167 pos = strstr(name, "flv1");
168 if (pos != NULL) {
169 return MPP_VIDEO_CodingFLV1;
170 }
171
172 pos = strstr(name, "mjpeg");
173 if (pos != NULL) {
174 return MPP_VIDEO_CodingMJPEG;
175 }
176
177 HDF_LOGE("%{public}s: CodingType unsupported! name:%{public}s", __func__, name);
178 return MPP_VIDEO_CodingMax;
179 }
180
CodecCreate(const char * name,CODEC_HANDLETYPE * handle)181 int32_t CodecCreate(const char* name, CODEC_HANDLETYPE *handle)
182 {
183 if (name == NULL || handle == NULL) {
184 HDF_LOGE("%{public}s: invalid params!", __func__);
185 return HDF_FAILURE;
186 }
187 MppCtxType ctxType = GetMppCtxType(name);
188 if (ctxType == MPP_CTX_BUTT) {
189 HDF_LOGE("%{public}s: MppCtxType:%{public}d not support!", __func__, ctxType);
190 return HDF_ERR_NOT_SUPPORT;
191 }
192 MppCodingType codingType = GetMppCodingType(name);
193 if (codingType == MPP_VIDEO_CodingMax) {
194 HDF_LOGE("%{public}s: MppCodingType:%{public}d not support!", __func__, codingType);
195 return HDF_ERR_NOT_SUPPORT;
196 }
197
198 MPP_RET ret = MPP_OK;
199 MppCtx ctx = NULL;
200 RKHdiBaseComponent* component = CreateMppComponent(ctxType, codingType);
201 if (component == NULL) {
202 return HDF_FAILURE;
203 }
204
205 ret = component->mppApi->HdiMppCreate(&ctx, &(component->mpi));
206 if (ret != MPP_OK) {
207 HDF_LOGE("%{public}s: mpp create failed", __func__);
208 return HDF_FAILURE;
209 }
210 *handle = ctx;
211 component->ctx = ctx;
212 component->componentName = name;
213 if (!AddToMppComponentManager(*handle, component)) {
214 HDF_LOGE("%{public}s: AddToMppComponentManager failed!", __func__);
215 return HDF_FAILURE;
216 }
217 if (component->ctxType == MPP_CTX_ENC) {
218 MppPollType timeout = MPP_POLL_BLOCK;
219 ret = component->mpi->control(ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
220 if (ret != MPP_OK) {
221 HDF_LOGE("%{public}s: mpi control set output timeout failed ret %{public}d", __func__, ret);
222 return HDF_FAILURE;
223 }
224 }
225
226 ret = component->mppApi->HdiMppInit(ctx, ctxType, codingType);
227 if (ret != MPP_OK) {
228 HDF_LOGE("%{public}s: mpp init failed", __func__);
229 return HDF_FAILURE;
230 }
231
232 return HDF_SUCCESS;
233 }
234
CodecDestroy(CODEC_HANDLETYPE handle)235 int32_t CodecDestroy(CODEC_HANDLETYPE handle)
236 {
237 MPP_RET ret = MPP_OK;
238 MppCtx ctx = handle;
239
240 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
241 if (component == NULL) {
242 HDF_LOGE("%{public}s: component is NULL", __func__);
243 return HDF_FAILURE;
244 }
245
246 RKMppApi *mppApi = component->mppApi;
247 if (component->packet != NULL) {
248 mppApi->HdiMppPacketDeinit(&component->packet);
249 component->packet = NULL;
250 }
251
252 if (component->frame != NULL) {
253 mppApi->HdiMppFrameDeinit(&component->frame);
254 component->frame = NULL;
255 }
256
257 if (component->frmBuf != NULL) {
258 mppApi->HdiMppBufferPutWithCaller(component->frmBuf, __func__);
259 component->frmBuf = NULL;
260 }
261
262 if (component->pktBuf != NULL) {
263 mppApi->HdiMppBufferPutWithCaller(component->pktBuf, __func__);
264 component->pktBuf = NULL;
265 }
266
267 if (component->frmGrp != NULL) {
268 mppApi->HdiMppBufferGroupPut(component->frmGrp);
269 component->frmGrp = NULL;
270 }
271
272 if (component->ctxType == MPP_CTX_DEC) {
273 HDF_LOGI("%{public}s: dec frame count : %{public}d, error count : %{public}d", __func__,
274 component->frameCount, component->frameErr);
275 HDF_LOGI("%{public}s: dec max memory %{public}.2f MB", __func__,
276 component->maxUsage / (float)BITWISE_LEFT_SHIFT_WITH_ONE);
277 } else if (component->ctxType == MPP_CTX_ENC) {
278 HDF_LOGI("%{public}s: enc frame count : %{public}d", __func__, component->frameCount);
279 } else {
280 HDF_LOGE("%{public}s: CtxType undefined!", __func__);
281 }
282
283 ret = mppApi->HdiMppDestroy(ctx);
284 RemoveFromMppComponentManager(handle);
285 DestroyMppComponent(component);
286 if (ret != MPP_OK) {
287 HDF_LOGE("%{public}s: mpp destroy failed", __func__);
288 return HDF_FAILURE;
289 }
290
291 return HDF_SUCCESS;
292 }
293
SetExtMppParam(RKHdiBaseComponent * component,Param * param)294 int32_t SetExtMppParam(RKHdiBaseComponent* component, Param *param)
295 {
296 int32_t ret = HDF_SUCCESS;
297 int32_t paramKey = param->key;
298
299 switch (paramKey) {
300 case KEY_EXT_SPLIT_PARSE_RK:
301 ret = SetParamSplitParse(component, param);
302 if (ret != HDF_SUCCESS) {
303 HDF_LOGE("%{public}s: config set split parse failed", __func__);
304 }
305 break;
306 case KEY_EXT_DEC_FRAME_NUM_RK:
307 case KEY_EXT_ENC_FRAME_NUM_RK:
308 ret = SetParamCodecFrameNum(component, param);
309 if (ret != HDF_SUCCESS) {
310 HDF_LOGE("%{public}s: config set frame number failed", __func__);
311 }
312 break;
313 case KEY_EXT_SETUP_DROP_MODE_RK:
314 ret = SetParamDrop(component, param);
315 break;
316 default:
317 HDF_LOGE("%{public}s: param key unsupport, key:%{public}d", __func__, paramKey);
318 return HDF_FAILURE;
319 }
320 return ret;
321 }
322
SetMppParam(RKHdiBaseComponent * component,Param * param)323 int32_t SetMppParam(RKHdiBaseComponent* component, Param *param)
324 {
325 int32_t ret = HDF_SUCCESS;
326 int32_t paramKey = param->key;
327
328 switch (paramKey) {
329 case KEY_VIDEO_WIDTH:
330 ret = SetParamWidth(component, param);
331 break;
332 case KEY_VIDEO_HEIGHT:
333 ret = SetParamHeight(component, param);
334 break;
335 case KEY_PIXEL_FORMAT:
336 ret = SetParamPixelFmt(component, param);
337 break;
338 case KEY_VIDEO_STRIDE:
339 ret = SetParamStride(component, param);
340 break;
341 case KEY_VIDEO_FRAME_RATE:
342 ret = SetParamFps(component, param);
343 break;
344 case KEY_VIDEO_RC_MODE:
345 ret = SetParamRateControl(component, param);
346 break;
347 case KEY_VIDEO_GOP_MODE:
348 ret = SetParamGop(component, param);
349 break;
350 case KEY_MIMETYPE:
351 ret = SetParamMimeCodecType(component, param);
352 break;
353 case KEY_CODEC_TYPE:
354 ret = SetParamCodecType(component, param);
355 break;
356 default:
357 ret = SetExtMppParam(component, param);
358 }
359 return ret;
360 }
361
CodecSetParameter(CODEC_HANDLETYPE handle,Param * params,int32_t paramCnt)362 int32_t CodecSetParameter(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt)
363 {
364 MppCtx ctx = handle;
365 int32_t ret = HDF_SUCCESS;
366 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
367
368 if (component == NULL) {
369 HDF_LOGE("%{public}s: component is NULL", __func__);
370 return HDF_FAILURE;
371 }
372 if (ctx != component->ctx) {
373 HDF_LOGE("%{public}s: ctx not match %{public}d", __func__, ctx);
374 return HDF_FAILURE;
375 }
376
377 for (int32_t i = 0; i < paramCnt; i++) {
378 ret = SetMppParam(component, params + i);
379 if (ret != HDF_SUCCESS) {
380 HDF_LOGE("%{public}s: SetMppParam faild, param key:%{public}d", __func__, params[i].key);
381 return ret;
382 }
383 }
384
385 return HDF_SUCCESS;
386 }
387
GetExtMppParam(RKHdiBaseComponent * component,Param * param)388 int32_t GetExtMppParam(RKHdiBaseComponent* component, Param *param)
389 {
390 int32_t ret = HDF_SUCCESS;
391 int32_t paramKey = param->key;
392
393 switch (paramKey) {
394 case KEY_EXT_SPLIT_PARSE_RK:
395 ret = GetParamSplitParse(component, param);
396 if (ret != HDF_SUCCESS) {
397 HDF_LOGE("%{public}s: config set split parse failed", __func__);
398 }
399 break;
400 case KEY_EXT_DEC_FRAME_NUM_RK:
401 case KEY_EXT_ENC_FRAME_NUM_RK:
402 ret = GetParamCodecFrameNum(component, param);
403 if (ret != HDF_SUCCESS) {
404 HDF_LOGE("%{public}s: config set frame number failed", __func__);
405 }
406 break;
407 case KEY_EXT_SETUP_DROP_MODE_RK:
408 ret = GetParamDrop(component, param);
409 break;
410 default:
411 HDF_LOGE("%{public}s: param key unsupport, key:%{public}d", __func__, paramKey);
412 return HDF_FAILURE;
413 }
414 return ret;
415 }
416
GetMppParam(RKHdiBaseComponent * component,Param * param)417 int32_t GetMppParam(RKHdiBaseComponent* component, Param *param)
418 {
419 int32_t ret = HDF_SUCCESS;
420 int32_t paramKey = param->key;
421
422 switch (paramKey) {
423 case KEY_INPUT_BUFFER_COUNT:
424 ret = GetParamInputBufferCount(component, param);
425 break;
426 case KEY_OUTPUT_BUFFER_COUNT:
427 ret = GetParamOutputBufferCount(component, param);
428 break;
429 case KEY_BUFFERSIZE:
430 ret = GetParamBufferSize(component, param);
431 break;
432 case KEY_VIDEO_WIDTH:
433 ret = GetParamWidth(component, param);
434 break;
435 case KEY_VIDEO_HEIGHT:
436 ret = GetParamHeight(component, param);
437 break;
438 case KEY_PIXEL_FORMAT:
439 ret = GetParamPixleFmt(component, param);
440 break;
441 case KEY_VIDEO_STRIDE:
442 ret = GetParamStride(component, param);
443 break;
444 case KEY_VIDEO_FRAME_RATE:
445 ret = GetParamFps(component, param);
446 break;
447 case KEY_VIDEO_RC_MODE:
448 ret = GetParamRateControl(component, param);
449 break;
450 case KEY_VIDEO_GOP_MODE:
451 ret = GetParamGop(component, param);
452 break;
453 case KEY_MIMETYPE:
454 ret = GetParamMimeCodecType(component, param);
455 break;
456 case KEY_CODEC_TYPE:
457 ret = GetParamCodecType(component, param);
458 break;
459 default:
460 ret = GetExtMppParam(component, param);
461 }
462 return ret;
463 }
464
CodecGetParameter(CODEC_HANDLETYPE handle,Param * params,int32_t paramCnt)465 int32_t CodecGetParameter(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt)
466 {
467 int32_t ret = HDF_SUCCESS;
468 MppCtx ctx = handle;
469 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
470
471 if (component == NULL) {
472 HDF_LOGE("%{public}s: component is NULL", __func__);
473 return HDF_FAILURE;
474 }
475 if (ctx != component->ctx) {
476 HDF_LOGE("%{public}s: ctx not match %{public}d", __func__, ctx);
477 return HDF_FAILURE;
478 }
479
480 for (int32_t i = 0; i < paramCnt; i++) {
481 ret = GetMppParam(component, params + i);
482 if (ret != HDF_SUCCESS) {
483 HDF_LOGE("%{public}s: GetMppParam faild, param key:%{public}d", __func__, params[i].key);
484 return ret;
485 }
486 }
487
488 return HDF_SUCCESS;
489 }
490
CodecStart(CODEC_HANDLETYPE handle)491 int32_t CodecStart(CODEC_HANDLETYPE handle)
492 {
493 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
494
495 if (component == NULL) {
496 HDF_LOGE("%{public}s: component is NULL", __func__);
497 return HDF_FAILURE;
498 }
499 int32_t ret = HDF_FAILURE;
500 if (component->ctxType == MPP_CTX_ENC) {
501 ret = SetEncCfg(component);
502 } else if (component->ctxType == MPP_CTX_DEC) {
503 ret = SetDecCfg(component);
504 }
505 return ret;
506 }
507
CodecStop(CODEC_HANDLETYPE handle)508 int32_t CodecStop(CODEC_HANDLETYPE handle)
509 {
510 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
511
512 if (component == NULL) {
513 HDF_LOGE("%{public}s: component is NULL", __func__);
514 return HDF_FAILURE;
515 }
516 return HDF_SUCCESS;
517 }
518
CodecFlush(CODEC_HANDLETYPE handle,DirectionType directType)519 int32_t CodecFlush(CODEC_HANDLETYPE handle, DirectionType directType)
520 {
521 MPP_RET ret = MPP_OK;
522 MppCtx ctx = handle;
523 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
524 if (component == NULL) {
525 HDF_LOGE("%{public}s: component is NULL", __func__);
526 return HDF_FAILURE;
527 }
528 switch (directType) {
529 case INPUT_TYPE:
530 case OUTPUT_TYPE:
531 case ALL_TYPE:
532 ret = component->mpi->reset(ctx);
533 if (ret != 0) {
534 HDF_LOGE("%{public}s: reset failed", __func__);
535 return HDF_FAILURE;
536 }
537 break;
538 default:
539 HDF_LOGE("%{public}s: directType failed", __func__);
540 return HDF_FAILURE;
541 }
542
543 if (component->pCallbacks != NULL) {
544 UINTPTR userData = (UINTPTR)component->ctx;
545 EventType event = EVENT_FLUSH_COMPLETE;
546 uint32_t length = 0;
547 int32_t *eventData = NULL;
548 component->pCallbacks->OnEvent(userData, event, length, eventData);
549 }
550
551 return HDF_SUCCESS;
552 }
553
DecodeInitPacket(RKHdiBaseComponent * component,MppPacket * pPacket,CodecBuffer * inputData,RK_U32 pkt_eos)554 int32_t DecodeInitPacket(RKHdiBaseComponent* component, MppPacket *pPacket, CodecBuffer *inputData, RK_U32 pkt_eos)
555 {
556 MPP_RET ret = MPP_OK;
557 RKMppApi *mppApi = component->mppApi;
558 uint8_t *inBuffer = (uint8_t *)inputData->buffer[0].buf;
559 uint32_t inBufferSize = inputData->buffer[0].length;
560
561 ret = mppApi->HdiMppPacketInit(pPacket, inBuffer, inBufferSize);
562 if (ret != MPP_OK) {
563 HDF_LOGE("%{public}s: mpp packet_init failed", __func__);
564 return HDF_FAILURE;
565 }
566
567 mppApi->HdiMppPacketSetData(*pPacket, inBuffer);
568 mppApi->HdiMppPacketSetSize(*pPacket, inBufferSize);
569 mppApi->HdiMppPacketSetPos(*pPacket, inBuffer);
570 mppApi->HdiMppPacketSetLength(*pPacket, inBufferSize);
571 // setup eos flag
572 if (pkt_eos != 0) {
573 mppApi->HdiMppPacketSetEos(*pPacket);
574 }
575 return HDF_SUCCESS;
576 }
577
DecodeGetFrame(RKHdiBaseComponent * component,MppCtx ctx,MppFrame * frame)578 MPP_RET DecodeGetFrame(RKHdiBaseComponent* component, MppCtx ctx, MppFrame *frame)
579 {
580 MppApi *mpi = component->mpi;
581 MPP_RET ret = MPP_OK;
582 RK_S32 retryTimes = 10;
583 while (true) {
584 ret = mpi->decode_get_frame(ctx, frame);
585 if (ret != MPP_ERR_TIMEOUT) {
586 break;
587 }
588 if (retryTimes > 0) {
589 retryTimes--;
590 usleep(SLEEP_INTERVAL_MICROSECONDS);
591 } else {
592 HDF_LOGE("%{public}s: decode_get_frame failed too much time", __func__);
593 break;
594 }
595 }
596 return ret;
597 }
598
HandleDecodeFrameInfoChange(RKHdiBaseComponent * component,MppFrame frame,MppCtx ctx)599 int32_t HandleDecodeFrameInfoChange(RKHdiBaseComponent* component, MppFrame frame, MppCtx ctx)
600 {
601 MPP_RET ret = MPP_OK;
602 RKMppApi *mppApi = component->mppApi;
603 MppApi *mpi = component->mpi;
604 RK_U32 width = mppApi->HdiMppFrameGetWidth(frame);
605 RK_U32 height = mppApi->HdiMppFrameGetHeight(frame);
606 RK_U32 hor_stride = mppApi->HdiMppFrameGetHorStride(frame);
607 RK_U32 ver_stride = mppApi->HdiMppFrameGetVerStride(frame);
608 RK_U32 buf_size = mppApi->HdiMppFrameGetBufferSize(frame);
609
610 component->setup.width = width;
611 component->setup.height = height;
612 CheckSetupStride(component);
613
614 HDF_LOGI("%{public}s: decode_get_frame get info changed found", __func__);
615 HDF_LOGI("%{public}s: decoder require buffer w:h [%{public}d:%{public}d]", __func__, width, height);
616 HDF_LOGI("%{public}s: decoder require stride [%{public}d:%{public}d]", __func__, hor_stride, ver_stride);
617 HDF_LOGI("%{public}s: decoder require buf_size %{public}d", __func__, buf_size);
618
619 if (component->frmGrp == NULL) {
620 ret = mppApi->HdiMppBufferGroupGet(&component->frmGrp,
621 MPP_BUFFER_TYPE_DRM, MPP_BUFFER_INTERNAL, NULL, __func__);
622 if (ret != MPP_OK) {
623 HDF_LOGE("%{public}s: get mpp buffer group failed ret %{public}d", __func__, ret);
624 return HDF_FAILURE;
625 }
626 ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, component->frmGrp);
627 if (ret != MPP_OK) {
628 HDF_LOGE("%{public}s: set buffer group failed ret %{public}d", __func__, ret);
629 return HDF_FAILURE;
630 }
631 } else {
632 ret = mppApi->HdiMppBufferGroupClear(component->frmGrp);
633 if (ret != MPP_OK) {
634 HDF_LOGE("%{public}s: clear buffer group failed ret %{public}d", __func__, ret);
635 return HDF_FAILURE;
636 }
637 }
638
639 ret = mppApi->HdiMppBufferGroupLimitConfig(component->frmGrp, buf_size, BUFFER_GROUP_LIMIT_NUM);
640 if (ret != MPP_OK) {
641 HDF_LOGE("%{public}s: limit buffer group failed ret %{public}d", __func__, ret);
642 return HDF_FAILURE;
643 }
644 ret = mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
645 if (ret != MPP_OK) {
646 HDF_LOGE("%{public}s: info change ready failed ret %{public}d", __func__, ret);
647 return HDF_FAILURE;
648 }
649 return HDF_SUCCESS;
650 }
651
PutDecodeFrameToOutput(RKHdiBaseComponent * component,MppFrame frame,CodecBuffer * outInfo)652 static IM_STATUS PutDecodeFrameToOutput(RKHdiBaseComponent* component, MppFrame frame, CodecBuffer *outInfo)
653 {
654 RKMppApi *mppApi = component->mppApi;
655 MppBuffer mppBuffer = mppApi->HdiMppFrameGetBuffer(frame);
656 rga_buffer_t src;
657 rga_buffer_t dst;
658 im_rect rect;
659
660 int32_t err = memset_s(&src, sizeof(src), 0, sizeof(src));
661 if (err != EOK) {
662 HDF_LOGE("%{public}s: memset_s src failed, error code: %{public}d", __func__, err);
663 return IM_STATUS_FAILED;
664 }
665 memset_s(&dst, sizeof(dst), 0, sizeof(dst));
666 if (err != EOK) {
667 HDF_LOGE("%{public}s: memset_s dst failed, error code: %{public}d", __func__, err);
668 return IM_STATUS_FAILED;
669 }
670 if (outInfo->buffer[0].buf == 0) {
671 HDF_LOGE("%{public}s: output buf invalid", __func__);
672 return IM_STATUS_INVALID_PARAM;
673 }
674
675 src.fd = mppApi->HdiMppBufferGetFdWithCaller(mppBuffer, __func__);
676 src.width = mppApi->HdiMppFrameGetWidth(frame);
677 src.height = mppApi->HdiMppFrameGetHeight(frame);
678 src.wstride = mppApi->HdiMppFrameGetHorStride(frame);
679 src.hstride = mppApi->HdiMppFrameGetVerStride(frame);
680 src.format = RK_FORMAT_YCbCr_420_SP;
681
682 if (outInfo->buffer[0].type == BUFFER_TYPE_HANDLE) {
683 BufferHandle *bufferHandle = (BufferHandle *)outInfo->buffer[0].buf;
684 dst.fd = bufferHandle->fd;
685 } else {
686 dst.vir_addr = (void *)outInfo->buffer[0].buf;
687 }
688 dst.width = src.width;
689 dst.height = src.height;
690 dst.wstride = component->setup.stride.horStride;
691 dst.hstride = component->setup.stride.verStride;
692 dst.format = ConvertHdiFormat2RgaFormat(component->setup.fmt);
693
694 rect.x = 0;
695 rect.y = 0;
696 rect.width = dst.width;
697 rect.height = dst.height;
698 return imcrop(src, dst, rect);
699 }
700
HandleDecodeFrameOutput(RKHdiBaseComponent * component,MppFrame frame,int32_t frm_eos,CodecBuffer * outInfo)701 void HandleDecodeFrameOutput(RKHdiBaseComponent* component, MppFrame frame, int32_t frm_eos, CodecBuffer *outInfo)
702 {
703 RKMppApi *mppApi = component->mppApi;
704 RK_U32 err_info = mppApi->HdiMppFrameGetErrinfo(frame);
705 RK_U32 discard = mppApi->HdiMppFrameGetDiscard(frame);
706 component->frameCount++;
707
708 if ((err_info | discard) != 0) {
709 component->frameErr++;
710 HDF_LOGE("%{public}s: bad output data, err_info: %{public}d", __func__, err_info);
711 return;
712 }
713 if (outInfo == NULL || outInfo->bufferCnt == 0) {
714 HDF_LOGE("%{public}s: outInfo param invalid!", __func__);
715 return;
716 }
717 // have output data
718 IM_STATUS ret = PutDecodeFrameToOutput(component, frame, outInfo);
719 if (ret != IM_STATUS_SUCCESS) {
720 HDF_LOGE("%{public}s: copy decode output data failed, error code: %{public}d", __func__, ret);
721 }
722
723 if (frm_eos != 0) {
724 outInfo->flag |= STREAM_FLAG_EOS;
725 HDF_LOGI("%{public}s: dec reach STREAM_FLAG_EOS, frame count : %{public}d, error count : %{public}d",
726 __func__, component->frameCount, component->frameErr);
727 }
728 UINTPTR userData = (UINTPTR)component->ctx;
729 int32_t acquireFd = 1;
730 component->pCallbacks->OutputBufferAvailable(userData, outInfo, &acquireFd);
731 }
732
HandleDecodedFrame(RKHdiBaseComponent * component,MppFrame frame,MppCtx ctx,int32_t frm_eos,CodecBuffer * outInfo)733 int32_t HandleDecodedFrame(RKHdiBaseComponent* component, MppFrame frame, MppCtx ctx,
734 int32_t frm_eos, CodecBuffer *outInfo)
735 {
736 RKMppApi *mppApi = component->mppApi;
737 if (frame) {
738 if (mppApi->HdiMppFrameGetInfoChange(frame)) {
739 if (HandleDecodeFrameInfoChange(component, frame, ctx) != HDF_SUCCESS) {
740 HDF_LOGE("%{public}s: func failed!", __func__);
741 mppApi->HdiMppFrameDeinit(&frame);
742 return HDF_FAILURE;
743 }
744 } else {
745 HandleDecodeFrameOutput(component, frame, frm_eos, outInfo);
746 }
747 mppApi->HdiMppFrameDeinit(&frame);
748 }
749
750 // try get runtime frame memory usage
751 if (component->frmGrp) {
752 size_t usage = mppApi->HdiMppBufferGroupUsage(component->frmGrp);
753 if (usage > component->maxUsage)
754 component->maxUsage = usage;
755 }
756 return HDF_SUCCESS;
757 }
758
CodecDecodeGetFrameLoop(RKHdiBaseComponent * component,MppCtx ctx,RK_U32 pkt_done,RK_U32 pkt_eos,CodecBuffer * outInfo)759 RK_U32 CodecDecodeGetFrameLoop(RKHdiBaseComponent* component, MppCtx ctx, RK_U32 pkt_done,
760 RK_U32 pkt_eos, CodecBuffer *outInfo)
761 {
762 MPP_RET ret = MPP_OK;
763 RKMppApi *mppApi = component->mppApi;
764 RK_U32 frm_eos = 0;
765 MppFrame frame = NULL;
766
767 do {
768 RK_S32 get_frm = 0;
769 ret = DecodeGetFrame(component, ctx, &frame);
770 if (ret != MPP_OK) {
771 HDF_LOGE("%{public}s: decode_get_frame failed, ret:%{public}d", __func__, ret);
772 break;
773 }
774 if (frame) {
775 frm_eos = mppApi->HdiMppFrameGetEos(frame);
776 get_frm = 1;
777 if (HandleDecodedFrame(component, frame, ctx, frm_eos, outInfo) != HDF_SUCCESS) {
778 break;
779 }
780 }
781 if (pkt_eos != 0 && pkt_done != 0 && frm_eos == 0) {
782 usleep(SLEEP_INTERVAL_MICROSECONDS);
783 continue;
784 }
785 if (frm_eos) {
786 break;
787 }
788
789 if ((component->frameNum > 0 && (component->frameCount >= component->frameNum)) ||
790 ((component->frameNum == 0) && frm_eos != 0)) {
791 break;
792 }
793 if (get_frm) {
794 continue;
795 }
796 break;
797 } while (1);
798
799 return frm_eos;
800 }
801
CodecDecode(CODEC_HANDLETYPE handle,CodecBuffer * inputData,CodecBuffer * outInfo,uint32_t timeoutMs)802 int32_t CodecDecode(CODEC_HANDLETYPE handle, CodecBuffer* inputData, CodecBuffer* outInfo, uint32_t timeoutMs)
803 {
804 MPP_RET ret = MPP_OK;
805 MppCtx ctx = handle;
806 RK_U32 loop_end = 0;
807 RK_U32 frm_eos;
808 RK_U32 pkt_done = 0;
809 RK_U32 pkt_eos = (inputData->flag == STREAM_FLAG_EOS) ? 1 : 0;
810
811 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
812 if (component == NULL) {
813 HDF_LOGE("%{public}s: component is NULL", __func__);
814 return HDF_FAILURE;
815 }
816 MppApi *mpi = component->mpi;
817 MppPacket packet = component->packet;
818
819 if (DecodeInitPacket(component, &packet, inputData, pkt_eos) != HDF_SUCCESS) {
820 HDF_LOGE("%{public}s: Init packet failed!", __func__);
821 return HDF_FAILURE;
822 }
823
824 do {
825 if (!pkt_done) {
826 ret = mpi->decode_put_packet(ctx, packet);
827 if (MPP_OK == ret) {
828 pkt_done = 1;
829 }
830 }
831
832 frm_eos = CodecDecodeGetFrameLoop(component, ctx, pkt_done, pkt_eos, outInfo);
833 if ((component->frameNum > 0 && (component->frameCount >= component->frameNum)) ||
834 ((component->frameNum == 0) && frm_eos != 0)) {
835 loop_end = 1;
836 break;
837 }
838 if (pkt_done) {
839 break;
840 }
841 usleep(SLEEP_INTERVAL_MICROSECONDS);
842 } while (1);
843 UINTPTR userData = (UINTPTR)component->ctx;
844 int32_t acquireFd = 1;
845 component->pCallbacks->InputBufferAvailable(userData, inputData, &acquireFd);
846
847 if (loop_end != 1) {
848 return HDF_FAILURE;
849 }
850 return HDF_SUCCESS;
851 }
852
GetEncodeFrameFromInput(RKHdiBaseComponent * component,MppFrame frame,MppBuffer mppBuffer,CodecBuffer * inputInfo)853 static IM_STATUS GetEncodeFrameFromInput(RKHdiBaseComponent* component, MppFrame frame,
854 MppBuffer mppBuffer, CodecBuffer *inputInfo)
855 {
856 RKMppApi *mppApi = component->mppApi;
857 rga_buffer_t src;
858 rga_buffer_t dst;
859 im_rect rect;
860
861 int32_t err = memset_s(&src, sizeof(src), 0, sizeof(src));
862 if (err != EOK) {
863 HDF_LOGE("%{public}s: memset_s src failed, error code: %{public}d", __func__, err);
864 return IM_STATUS_FAILED;
865 }
866 err = memset_s(&dst, sizeof(dst), 0, sizeof(dst));
867 if (err != EOK) {
868 HDF_LOGE("%{public}s: memset_s dst failed, error code: %{public}d", __func__, err);
869 return IM_STATUS_FAILED;
870 }
871 if (inputInfo->buffer[0].buf == 0) {
872 HDF_LOGE("%{public}s: output buf invalid", __func__);
873 return IM_STATUS_INVALID_PARAM;
874 }
875
876 dst.fd = mppApi->HdiMppBufferGetFdWithCaller(mppBuffer, __func__);
877 dst.wstride = mppApi->HdiMppFrameGetHorStride(frame);
878 dst.hstride = mppApi->HdiMppFrameGetVerStride(frame);
879 dst.width = mppApi->HdiMppFrameGetWidth(frame);
880 dst.height = mppApi->HdiMppFrameGetHeight(frame);
881 dst.format = ConvertMppFormat2RgaFormat(component->fmt);
882
883 if (inputInfo->buffer[0].type == BUFFER_TYPE_HANDLE) {
884 BufferHandle *bufferHandle = (BufferHandle *)inputInfo->buffer[0].buf;
885 src.fd = bufferHandle->fd;
886 } else {
887 src.vir_addr = (void *)inputInfo->buffer[0].buf;
888 }
889 src.width = dst.width;
890 src.height = dst.height;
891 src.wstride = component->setup.stride.horStride;
892 src.hstride = component->setup.stride.verStride;
893 src.format = ConvertHdiFormat2RgaFormat(component->setup.fmt);
894
895 rect.x = 0;
896 rect.y = 0;
897 rect.width = dst.width;
898 rect.height = dst.height;
899 return imcrop(src, dst, rect);
900 }
901
EncodeInitFrame(RKHdiBaseComponent * component,MppFrame * pFrame,RK_U32 frm_eos,CodecBuffer * inputData)902 int32_t EncodeInitFrame(RKHdiBaseComponent* component, MppFrame *pFrame, RK_U32 frm_eos, CodecBuffer *inputData)
903 {
904 MPP_RET ret = MPP_OK;
905 RKMppApi *mppApi = component->mppApi;
906
907 if (frm_eos != 0) {
908 HDF_LOGI("%{public}s: receive eos frame", __func__);
909 }
910 ret = mppApi->HdiMppFrameInit(pFrame);
911 if (ret != MPP_OK) {
912 HDF_LOGE("%{public}s: mpp_frame_init failed", __func__);
913 return HDF_FAILURE;
914 }
915 mppApi->HdiMppFrameSetWidth(*pFrame, component->setup.width);
916 mppApi->HdiMppFrameSetHeight(*pFrame, component->setup.height);
917 mppApi->HdiMppFrameSetHorStride(*pFrame, component->horStride);
918 mppApi->HdiMppFrameSetVerStride(*pFrame, component->verStride);
919 mppApi->HdiMppFrameSetFormat(*pFrame, component->fmt);
920 mppApi->HdiMppFrameSetEos(*pFrame, frm_eos);
921
922 IM_STATUS status = GetEncodeFrameFromInput(component, *pFrame, component->frmBuf, inputData);
923 if (status == IM_STATUS_SUCCESS) {
924 mppApi->HdiMppFrameSetBuffer(*pFrame, component->frmBuf);
925 } else {
926 mppApi->HdiMppFrameDeinit(&pFrame);
927 HDF_LOGE("%{public}s: copy encode input data failed, error code: %{public}d", __func__, ret);
928 return HDF_FAILURE;
929 }
930
931 return HDF_SUCCESS;
932 }
933
HandleEncodedPacket(RKHdiBaseComponent * component,MppPacket packet,RK_U32 pkt_eos,CodecBuffer * outInfo)934 int32_t HandleEncodedPacket(RKHdiBaseComponent* component, MppPacket packet, RK_U32 pkt_eos, CodecBuffer *outInfo)
935 {
936 RKMppApi *mppApi = component->mppApi;
937 void *ptr = mppApi->HdiMppPacketGetPos(packet);
938 size_t len = mppApi->HdiMppPacketGetLength(packet);
939 pkt_eos = mppApi->HdiMppPacketGetEos(packet);
940
941 // call back have out data
942 UINTPTR userData = (UINTPTR)component->ctx;
943 int32_t acquireFd = 1;
944 uint8_t *outBuffer = (uint8_t *)outInfo->buffer[0].buf;
945 uint32_t outBufferSize = outInfo->buffer[0].capacity;
946 if (outBuffer != NULL && outBufferSize != 0 && ptr != NULL && len != 0) {
947 int32_t ret = memcpy_s(outBuffer, outBufferSize, ptr, len);
948 if (ret == EOK) {
949 outInfo->buffer[0].length = len;
950 } else {
951 HDF_LOGE("%{public}s: copy output data failed, error code: %{public}d", __func__, ret);
952 HDF_LOGE("%{public}s: dst bufferSize:%{public}d, src data len: %{public}d", __func__, outBufferSize, len);
953 }
954 } else {
955 HDF_LOGE("%{public}s: output data not copy, buffer incorrect!", __func__);
956 }
957 if (pkt_eos != 0) {
958 outInfo->flag |= STREAM_FLAG_EOS;
959 HDF_LOGI("%{public}s: enc reach STREAM_FLAG_EOS, frame count : %{public}d",
960 __func__, component->frameCount);
961 }
962 component->pCallbacks->OutputBufferAvailable(userData, outInfo, &acquireFd);
963
964 return HDF_SUCCESS;
965 }
966
CodecEncodeGetPacketLoop(RKHdiBaseComponent * component,MppCtx ctx,CodecBuffer * outInfo)967 RK_U32 CodecEncodeGetPacketLoop(RKHdiBaseComponent* component, MppCtx ctx, CodecBuffer *outInfo)
968 {
969 MPP_RET ret = MPP_OK;
970 MppApi *mpi = component->mpi;
971 RKMppApi *mppApi = component->mppApi;
972 MppPacket packet = component->packet;
973 RK_U32 eoi = 1;
974 RK_U32 pkt_eos = 0;
975
976 do {
977 ret = mpi->encode_get_packet(ctx, &packet);
978 if (ret != MPP_OK) {
979 HDF_LOGE("%{public}s: mpp encode get packet failed", __func__);
980 return HDF_FAILURE;
981 }
982
983 if (packet) {
984 pkt_eos = mppApi->HdiMppPacketGetEos(packet);
985 HandleEncodedPacket(component, packet, pkt_eos, outInfo);
986
987 /* for low delay partition encoding */
988 if (mppApi->HdiMppPacketIsPartition(packet)) {
989 eoi = mppApi->HdiMppPacketIsEoi(packet);
990 }
991
992 mppApi->HdiMppPacketDeinit(&packet);
993 component->frameCount += eoi;
994
995 if (pkt_eos != 0) {
996 HDF_LOGI("%{public}s: find eos packet", __func__);
997 break;
998 }
999 }
1000 } while (!eoi);
1001
1002 return pkt_eos;
1003 }
1004
CodecEncode(CODEC_HANDLETYPE handle,CodecBuffer * inputData,CodecBuffer * outInfo,uint32_t timeoutMs)1005 int32_t CodecEncode(CODEC_HANDLETYPE handle, CodecBuffer *inputData, CodecBuffer *outInfo, uint32_t timeoutMs)
1006 {
1007 MPP_RET ret = MPP_OK;
1008 MppFrame frame = NULL;
1009 MppCtx ctx = handle;
1010 RK_U32 pkt_eos = 0;
1011 RK_U32 loop_end = 0;
1012 RK_U32 frm_eos = 0;
1013 UINTPTR userData = NULL;
1014 int32_t acquireFd = 1;
1015
1016 if (inputData == NULL || inputData->bufferCnt == 0) {
1017 HDF_LOGE("%{public}s: inputData param invalid!", __func__);
1018 return HDF_FAILURE;
1019 }
1020 frm_eos = (inputData->flag == STREAM_FLAG_EOS) ? 1 : 0;
1021
1022 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
1023 if (component == NULL) {
1024 HDF_LOGE("%{public}s: component is NULL", __func__);
1025 return HDF_FAILURE;
1026 }
1027 MppApi *mpi = component->mpi;
1028 RKMppApi *mppApi = component->mppApi;
1029
1030 if (EncodeInitFrame(component, &frame, frm_eos, inputData) != HDF_SUCCESS) {
1031 return HDF_FAILURE;
1032 }
1033
1034 ret = mpi->encode_put_frame(ctx, frame);
1035 if (ret != MPP_OK) {
1036 HDF_LOGE("%{public}s: mpp encode put frame failed", __func__);
1037 mppApi->HdiMppFrameDeinit(&frame);
1038 return HDF_FAILURE;
1039 }
1040 mppApi->HdiMppFrameDeinit(&frame);
1041 pkt_eos = CodecEncodeGetPacketLoop(component, ctx, outInfo);
1042
1043 userData = (UINTPTR)component->ctx;
1044 component->pCallbacks->InputBufferAvailable(userData, inputData, &acquireFd);
1045 if (component->frameNum > 0 && component->frameCount >= component->frameNum) {
1046 loop_end = 1;
1047 }
1048
1049 if (frm_eos != 0 && pkt_eos != 0) {
1050 loop_end = 1;
1051 }
1052
1053 if (loop_end != 1) {
1054 return HDF_FAILURE;
1055 }
1056 return HDF_SUCCESS;
1057 }
1058
CodecEncodeHeader(CODEC_HANDLETYPE handle,CodecBuffer outInfo,uint32_t timeoutMs)1059 int32_t CodecEncodeHeader(CODEC_HANDLETYPE handle, CodecBuffer outInfo, uint32_t timeoutMs)
1060 {
1061 MPP_RET ret = MPP_OK;
1062 MppCtx ctx = handle;
1063 MppPacket packet = NULL;
1064
1065 RKHdiBaseComponent* component = FindInMppComponentManager(handle);
1066 if (component == NULL) {
1067 HDF_LOGE("%{public}s: component is NULL", __func__);
1068 return HDF_FAILURE;
1069 }
1070 RKMppApi *mppApi = component->mppApi;
1071
1072 mppApi->HdiMppPacketInitWithBuffer(&packet, component->pktBuf);
1073 // NOTE: It is important to clear output packet length!!
1074 mppApi->HdiMppPacketSetLength(packet, 0);
1075
1076 ret = component->mpi->control(ctx, MPP_ENC_GET_HDR_SYNC, packet);
1077 if (ret != MPP_OK) {
1078 HDF_LOGE("%{public}s: mpi control enc get extra info failed", __func__);
1079 return HDF_FAILURE;
1080 } else {
1081 void *ptr = mppApi->HdiMppPacketGetPos(packet);
1082 size_t len = mppApi->HdiMppPacketGetLength(packet);
1083
1084 // call back have out data
1085 UINTPTR userData = (UINTPTR)component->ctx;
1086 int32_t acquireFd = 1;
1087 uint8_t *outBuffer = (uint8_t *)outInfo.buffer[0].buf;
1088 uint32_t outBufferSize = outInfo.buffer[0].capacity;
1089 outInfo.buffer[0].length = len;
1090 if (outBuffer != NULL && outBufferSize != 0 && ptr != NULL && len != 0) {
1091 int32_t ret = memcpy_s(outBuffer, len, ptr, len);
1092 if (ret != EOK) {
1093 HDF_LOGE("%{public}s: copy output data failed, error code: %{public}d", __func__, ret);
1094 }
1095 }
1096 component->pCallbacks->OutputBufferAvailable(userData, &outInfo, &acquireFd);
1097 }
1098
1099 mppApi->HdiMppPacketDeinit(&packet);
1100 return HDF_SUCCESS;
1101 }
1102