• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Shenzhen Kaihong DID Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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