123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742 |
- /*
- * Copyright 2020 Rockchip Electronics Co. LTD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define MODULE_TAG "vcodec_service"
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <string.h>
- #include <unistd.h>
- #include "mpp_env.h"
- #include "mpp_mem.h"
- #include "mpp_time.h"
- #include "mpp_list.h"
- #include "mpp_debug.h"
- #include "mpp_common.h"
- #include "vpu.h"
- #include "mpp_soc.h"
- #include "mpp_platform.h"
- #include "vcodec_service.h"
- #include "vcodec_service_api.h"
- #define MAX_REGS_COUNT 3
- #define MPX_EXTRA_INFO_NUM 16
- #define MAX_INFO_COUNT 16
- #define INFO_FORMAT_TYPE 3
- typedef struct MppReq_t {
- RK_U32 *req;
- RK_U32 size;
- } MppReq;
- typedef struct VcodecExtraSlot_t {
- RK_U32 reg_idx;
- RK_U32 offset;
- } VcodecExtraSlot;
- typedef struct VcodecExtraInfo_t {
- RK_U32 magic; // Fix magic value 0x4C4A46
- RK_U32 count; // valid patch info count
- VcodecExtraSlot slots[MPX_EXTRA_INFO_NUM];
- } VcodecExtraInfo;
- typedef struct VcodecRegCfg_t {
- RK_U32 reg_size;
- VcodecExtraInfo extra_info;
- void *reg_set;
- void *reg_get;
- } VcodecRegCfg;
- typedef struct MppDevVcodecService_t {
- RK_S32 client_type;
- RK_U64 fmt;
- RK_S32 fd;
- RK_S32 max_regs;
- RK_U32 reg_size;
- RK_S32 reg_send_idx;
- RK_S32 reg_poll_idx;
- VcodecRegCfg regs[MAX_REGS_COUNT];
- RK_S32 info_count;
- MppDevInfoCfg info[MAX_INFO_COUNT];
- } MppDevVcodecService;
- /* For vpu1 / vpu2 */
- static const char *mpp_vpu_dev[] = {
- "/dev/vpu_service",
- "/dev/vpu-service",
- "/dev/mpp_service",
- };
- /* For hevc 4K decoder */
- static const char *mpp_hevc_dev[] = {
- "/dev/hevc_service",
- "/dev/hevc-service",
- "/dev/mpp_service",
- };
- /* For H.264/H.265/VP9 4K decoder */
- static const char *mpp_rkvdec_dev[] = {
- "/dev/rkvdec",
- "/dev/mpp_service",
- };
- /* For H.264 4K encoder */
- static const char *mpp_rkvenc_dev[] = {
- "/dev/rkvenc",
- "/dev/mpp_service",
- };
- /* For avs+ decoder */
- static const char *mpp_avsd_dev[] = {
- "/dev/avsd",
- "/dev/mpp_service",
- };
- /* For H.264 / jpeg encoder */
- static const char *mpp_vepu_dev[] = {
- "/dev/vepu",
- "/dev/mpp_service",
- };
- /* For H.265 encoder */
- static const char *mpp_h265e_dev[] = {
- "/dev/h265e",
- "/dev/mpp_service",
- };
- /* For jpeg decoder */
- static const char *mpp_jpegd_dev[] = {
- "/dev/mpp_service",
- };
- static const char *mpp_jpege_dev[] = {
- "/dev/mpp_service",
- };
- #define mpp_find_device(dev) _mpp_find_device(dev, MPP_ARRAY_ELEMS(dev))
- static const char *_mpp_find_device(const char **dev, RK_U32 size)
- {
- RK_U32 i;
- for (i = 0; i < size; i++)
- if (!access(dev[i], F_OK))
- return dev[i];
- return NULL;
- }
- const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform)
- {
- const char *dev = NULL;
- if ((platform & HAVE_RKVDEC) && (type == MPP_CTX_DEC) &&
- (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC ||
- coding == MPP_VIDEO_CodingAVS2 ||
- coding == MPP_VIDEO_CodingVP9)) {
- dev = mpp_find_device(mpp_rkvdec_dev);
- } else if ((platform & HAVE_HEVC_DEC) && (type == MPP_CTX_DEC) &&
- (coding == MPP_VIDEO_CodingHEVC)) {
- dev = mpp_find_device(mpp_hevc_dev);
- } else if ((platform & HAVE_AVSDEC) && (type == MPP_CTX_DEC) &&
- (coding == MPP_VIDEO_CodingAVS)) {
- dev = mpp_find_device(mpp_avsd_dev);
- } else if ((platform & HAVE_RKVENC) && (type == MPP_CTX_ENC) &&
- (coding == MPP_VIDEO_CodingAVC)) {
- dev = mpp_find_device(mpp_rkvenc_dev);
- } else if ((platform & HAVE_VEPU22) && (type == MPP_CTX_ENC) &&
- (coding == MPP_VIDEO_CodingHEVC)) {
- dev = mpp_find_device(mpp_h265e_dev);
- } else {
- if (type == MPP_CTX_ENC)
- dev = mpp_find_device(mpp_vepu_dev);
- if (dev == NULL)
- dev = mpp_find_device(mpp_vpu_dev);
- }
- return dev;
- }
- const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding)
- {
- const char *dev = NULL;
- RockchipSocType soc_type = mpp_get_soc_type();
- switch (soc_type) {
- case ROCKCHIP_SOC_RK3036 : {
- /* rk3036 do NOT have encoder */
- if (type == MPP_CTX_ENC)
- dev = NULL;
- else if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
- dev = mpp_find_device(mpp_hevc_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3066 :
- case ROCKCHIP_SOC_RK3188 : {
- /* rk3066/rk3188 have vpu1 only */
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3288 :
- case ROCKCHIP_SOC_RK312X :
- case ROCKCHIP_SOC_RK3368 :
- case ROCKCHIP_SOC_RK3326 :
- case ROCKCHIP_SOC_PX30 : {
- /*
- * rk3288/rk312x/rk3368 have codec:
- * 1 - vpu1
- * 2 - RK hevc decoder
- */
- if (coding == MPP_VIDEO_CodingHEVC && type == MPP_CTX_DEC)
- dev = mpp_find_device(mpp_hevc_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3128H : {
- /*
- * rk3128H have codec:
- * 1 - vpu2
- * 2 - RK H.264/H.265 1080p@60fps decoder
- * NOTE: rk3128H do NOT have jpeg encoder
- */
- if (type == MPP_CTX_DEC &&
- (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC))
- dev = mpp_find_device(mpp_rkvdec_dev);
- else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
- dev = NULL;
- else if (type == MPP_CTX_DEC && coding == MPP_VIDEO_CodingVP9)
- dev = NULL;
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3399 :
- case ROCKCHIP_SOC_RK3229 : {
- /*
- * rk3399/rk3229 have codec:
- * 1 - vpu2
- * 2 - RK H.264/H.265/VP9 4K decoder
- */
- if (type == MPP_CTX_DEC &&
- (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC ||
- coding == MPP_VIDEO_CodingVP9))
- dev = mpp_find_device(mpp_rkvdec_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3228 : {
- /*
- * rk3228 have codec:
- * 1 - vpu2
- * 2 - RK H.264/H.265 4K decoder
- * NOTE: rk3228 do NOT have jpeg encoder
- */
- if (type == MPP_CTX_DEC &&
- (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC))
- dev = mpp_find_device(mpp_rkvdec_dev);
- else if (type == MPP_CTX_ENC && coding == MPP_VIDEO_CodingMJPEG)
- dev = NULL;
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3228H : {
- /*
- * rk3228h has codec:
- * 1 - vpu2
- * 2 - RK H.264/H.265 4K decoder
- * 3 - avs+ decoder
- * 4 - H.265 encoder
- */
- if (type == MPP_CTX_ENC) {
- if (coding == MPP_VIDEO_CodingHEVC)
- dev = mpp_find_device(mpp_h265e_dev);
- else
- dev = mpp_find_device(mpp_vepu_dev);
- } else if (type == MPP_CTX_DEC) {
- if (coding == MPP_VIDEO_CodingAVS)
- dev = mpp_find_device(mpp_avsd_dev);
- else if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC)
- dev = mpp_find_device(mpp_rkvdec_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- }
- } break;
- case ROCKCHIP_SOC_RK3328 : {
- /*
- * rk3228 has codec:
- * 1 - vpu2
- * 2 - RK H.264/H.265/VP9 4K decoder
- * 4 - H.265 encoder
- */
- if (type == MPP_CTX_ENC) {
- if (coding == MPP_VIDEO_CodingHEVC)
- dev = mpp_find_device(mpp_h265e_dev);
- else
- dev = mpp_find_device(mpp_vepu_dev);
- } else if (type == MPP_CTX_DEC) {
- if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC ||
- coding == MPP_VIDEO_CodingVP9) {
- dev = mpp_find_device(mpp_rkvdec_dev);
- } else
- dev = mpp_find_device(mpp_vpu_dev);
- }
- } break;
- case ROCKCHIP_SOC_RV1108 : {
- /*
- * rv1108 has codec:
- * 1 - vpu2
- * 2 - RK H.264 4K decoder
- * 3 - RK H.264 4K encoder
- */
- if (coding == MPP_VIDEO_CodingAVC) {
- if (type == MPP_CTX_ENC)
- dev = mpp_find_device(mpp_rkvenc_dev);
- else
- dev = mpp_find_device(mpp_rkvdec_dev);
- } else if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RV1109 :
- case ROCKCHIP_SOC_RV1126 : {
- /*
- * rv1108 has codec:
- * 1 - vpu2 for jpeg encoder and decoder
- * 2 - RK H.264/H.265 4K decoder
- * 3 - RK H.264/H.265 4K encoder
- */
- if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) {
- if (type == MPP_CTX_ENC)
- dev = mpp_find_device(mpp_rkvenc_dev);
- else
- dev = mpp_find_device(mpp_rkvdec_dev);
- } else if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_vpu_dev);
- } break;
- case ROCKCHIP_SOC_RK3566 :
- case ROCKCHIP_SOC_RK3567 :
- case ROCKCHIP_SOC_RK3568 : {
- /*
- * rk3566/rk3568 has codec:
- * 1 - vpu2 for jpeg/vp8 encoder and decoder
- * 2 - RK H.264/H.265/VP9 4K decoder
- * 3 - RK H.264/H.265 4K encoder
- * 3 - RK jpeg decoder
- */
- if (type == MPP_CTX_DEC) {
- if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC ||
- coding == MPP_VIDEO_CodingVP9)
- dev = mpp_find_device(mpp_rkvdec_dev);
- else if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_jpegd_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } else if (type == MPP_CTX_ENC) {
- if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC)
- dev = mpp_find_device(mpp_rkvenc_dev);
- else if (coding == MPP_VIDEO_CodingMJPEG ||
- coding == MPP_VIDEO_CodingVP8)
- dev = mpp_find_device(mpp_vpu_dev);
- else
- dev = NULL;
- }
- } break;
- case ROCKCHIP_SOC_RK3588 : {
- /*
- * rk3588 has codec:
- * 1 - RK H.264/H.265/VP9/AVS2 8K decoder
- * 2 - RK H.264/H.265 8K encoder
- * 3 - vpu2 for jpeg/vp8 encoder and decoder
- * 4 - RK jpeg decoder
- */
- if (type == MPP_CTX_DEC) {
- if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC ||
- coding == MPP_VIDEO_CodingAVS2 ||
- coding == MPP_VIDEO_CodingVP9)
- dev = mpp_find_device(mpp_rkvdec_dev);
- else if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_jpegd_dev);
- else
- dev = mpp_find_device(mpp_vpu_dev);
- } else if (type == MPP_CTX_ENC) {
- if (coding == MPP_VIDEO_CodingAVC ||
- coding == MPP_VIDEO_CodingHEVC)
- dev = mpp_find_device(mpp_rkvenc_dev);
- else if (coding == MPP_VIDEO_CodingMJPEG ||
- coding == MPP_VIDEO_CodingVP8)
- dev = mpp_find_device(mpp_vpu_dev);
- else
- dev = NULL;
- }
- } break;
- case ROCKCHIP_SOC_RK3576 :
- case ROCKCHIP_SOC_RV1126B : {
- if (type == MPP_CTX_DEC) {
- if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_jpegd_dev);
- else
- dev = mpp_find_device(mpp_rkvdec_dev);
- } else if (type == MPP_CTX_ENC) {
- if (coding == MPP_VIDEO_CodingMJPEG)
- dev = mpp_find_device(mpp_jpege_dev);
- else
- dev = mpp_find_device(mpp_rkvenc_dev);
- }
- } break;
- default : {
- /* default case for unknown compatible */
- RK_U32 vcodec_type = mpp_get_vcodec_type();
- dev = mpp_get_platform_dev_name(type, coding, vcodec_type);
- } break;
- }
- return dev;
- }
- static RK_S32 vcodec_service_ioctl(RK_S32 fd, RK_S32 cmd, void *regs, RK_S32 size)
- {
- MppReq req;
- req.req = regs;
- req.size = size;
- return (RK_S32)ioctl(fd, cmd, &req);
- }
- static void extra_info_init(VcodecExtraInfo *info)
- {
- info->magic = EXTRA_INFO_MAGIC;
- info->count = 0;
- }
- static void update_extra_info(VcodecExtraInfo *info, char* fmt, VcodecRegCfg* send_cfg)
- {
- void *reg_set = send_cfg->reg_set;
- RK_U32 reg_size = send_cfg->reg_size;
- if (info->count) {
- if (!strstr(fmt, "mjpeg")) {
- RK_U32 *reg = (RK_U32*)reg_set;
- RK_U32 i = 0;
- for (i = 0; i < info->count; i++) {
- VcodecExtraSlot *slot = &info->slots[i];
- reg[slot->reg_idx] |= (slot->offset << 10);
- }
- info->count = 0;
- } else {
- void *extra_data = reg_set + reg_size;
- RK_S32 extra_size = sizeof(send_cfg->extra_info);
- memcpy(extra_data, info, extra_size);
- send_cfg->reg_size += extra_size;
- extra_info_init(info);
- }
- }
- }
- MPP_RET vcodec_service_init(void *ctx, MppClientType type)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- static RK_S32 vcodec_ioctl_version = -1;
- VPU_CLIENT_TYPE client_type;
- const char *name = NULL;
- RK_U32 reg_size = 0;
- RK_S32 max_regs = 2;
- MPP_RET ret = MPP_NOK;
- switch (type) {
- case VPU_CLIENT_VDPU1 : {
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_DEC;
- reg_size = VDPU1_REGISTERS;
- } break;
- case VPU_CLIENT_VDPU2 : {
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_DEC;
- reg_size = VDPU2_REGISTERS;
- } break;
- case VPU_CLIENT_VDPU1_PP : {
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_DEC_PP;
- if (ROCKCHIP_SOC_RK3036 == mpp_get_soc_type())
- reg_size = VDPU1_REGISTERS;
- else
- reg_size = VDPU1_PP_REGISTERS;
- } break;
- case VPU_CLIENT_VDPU2_PP : {
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_DEC_PP;
- reg_size = VDPU2_PP_REGISTERS;
- } break;
- case VPU_CLIENT_HEVC_DEC : {
- name = mpp_find_device(mpp_hevc_dev);
- client_type = VPU_DEC;
- reg_size = RKHEVC_REGISTERS;
- max_regs = 3;
- } break;
- case VPU_CLIENT_RKVDEC : {
- name = mpp_find_device(mpp_rkvdec_dev);
- client_type = VPU_DEC;
- reg_size = RKVDEC_REGISTERS;
- max_regs = 3;
- } break;
- case VPU_CLIENT_AVSPLUS_DEC : {
- name = mpp_find_device(mpp_avsd_dev);
- client_type = VPU_DEC;
- reg_size = AVSD_REGISTERS;
- } break;
- case VPU_CLIENT_RKVENC : {
- name = mpp_find_device(mpp_rkvenc_dev);
- client_type = VPU_ENC;
- reg_size = AVSD_REGISTERS;
- } break;
- case VPU_CLIENT_VEPU1 : {
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_ENC;
- reg_size = VEPU1_REGISTERS;
- } break;
- case VPU_CLIENT_VEPU2 : {
- name = mpp_find_device(mpp_vepu_dev);
- if (NULL == name)
- name = mpp_find_device(mpp_vpu_dev);
- client_type = VPU_ENC;
- reg_size = VEPU2_REGISTERS;
- } break;
- default : {
- mpp_err_f("unsupported client type %d\n", type);
- return ret;
- } break;
- }
- p->fd = open(name, O_RDWR | O_CLOEXEC);
- if (p->fd < 0) {
- mpp_err("open vcodec_service %s failed\n", name);
- return ret;
- }
- if (vcodec_ioctl_version < 0) {
- ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE, (unsigned long)client_type);
- if (!ret) {
- vcodec_ioctl_version = 0;
- } else {
- ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE_U32, (RK_U32)client_type);
- if (!ret)
- vcodec_ioctl_version = 1;
- }
- mpp_assert(ret == MPP_OK);
- } else {
- RK_U32 cmd = (vcodec_ioctl_version == 0) ?
- (VPU_IOC_SET_CLIENT_TYPE) :
- (VPU_IOC_SET_CLIENT_TYPE_U32);
- ret = (RK_S32)ioctl(p->fd, cmd, client_type);
- }
- p->max_regs = max_regs;
- p->reg_size = reg_size * sizeof(RK_U32);
- {
- RK_S32 i;
- for (i = 0; i < max_regs; i++) {
- VcodecRegCfg *reg = &p->regs[i];
- reg->reg_size = p->reg_size;
- extra_info_init(®->extra_info);
- }
- }
- return ret;
- }
- MPP_RET vcodec_service_deinit(void *ctx)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- if (p->fd)
- close(p->fd);
- return MPP_OK;
- }
- MPP_RET vcodec_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
- mpp_assert(cfg->offset == 0);
- send_cfg->reg_set = cfg->reg;
- send_cfg->reg_size = cfg->size;
- if (p->reg_size != cfg->size)
- mpp_err_f("reg size mismatch wr %d rd %d\n",
- p->reg_size, cfg->size);
- return MPP_OK;
- }
- MPP_RET vcodec_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
- mpp_assert(cfg->offset == 0);
- send_cfg->reg_get = cfg->reg;
- if (send_cfg->reg_size != cfg->size)
- mpp_err_f("reg size mismatch rd %d rd %d\n",
- send_cfg->reg_size, cfg->size);
- return MPP_OK;
- }
- MPP_RET vcodec_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg)
- {
- if (cfg->offset) {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
- VcodecExtraInfo *extra = &send_cfg->extra_info;
- VcodecExtraSlot *slot;
- RK_U32 i;
- for (i = 0; i < extra->count; i++) {
- slot = &extra->slots[i];
- if (slot->reg_idx == cfg->reg_idx) {
- mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n",
- slot->reg_idx, slot->offset, cfg->offset);
- slot->offset = cfg->offset;
- return MPP_OK;
- }
- }
- slot = &extra->slots[extra->count];
- slot->reg_idx = cfg->reg_idx;
- slot->offset = cfg->offset;
- extra->count++;
- }
- return MPP_OK;
- }
- MPP_RET vcodec_service_cmd_send(void *ctx)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
- VcodecExtraInfo *extra = &send_cfg->extra_info;
- void *reg_set = send_cfg->reg_set;
- char *fmt = (char*)&p->fmt;
- update_extra_info(extra, fmt, send_cfg);
- MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_SET_REG,
- reg_set, send_cfg->reg_size);
- if (ret) {
- mpp_err_f("ioctl VPU_IOC_SET_REG failed ret %d errno %d %s\n",
- ret, errno, strerror(errno));
- ret = errno;
- }
- p->reg_send_idx++;
- if (p->reg_send_idx >= p->max_regs)
- p->reg_send_idx = 0;
- p->info_count = 0;
- return ret;
- }
- MPP_RET vcodec_service_cmd_poll(void *ctx, MppDevPollCfg *cfg)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- VcodecRegCfg *poll_cfg = &p->regs[p->reg_poll_idx];
- void *reg_get = poll_cfg->reg_get;
- RK_S32 reg_size = poll_cfg->reg_size;
- MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_GET_REG,
- reg_get, reg_size);
- if (ret) {
- mpp_err_f("ioctl VPU_IOC_GET_REG failed ret %d errno %d %s\n",
- ret, errno, strerror(errno));
- ret = errno;
- }
- p->reg_poll_idx++;
- if (p->reg_poll_idx >= p->max_regs)
- p->reg_poll_idx = 0;
- (void)cfg;
- return ret;
- }
- MPP_RET vcodec_service_set_info(void *ctx, MppDevInfoCfg *cfg)
- {
- MppDevVcodecService *p = (MppDevVcodecService *)ctx;
- if (!p->info_count)
- memset(p->info, 0, sizeof(p->info));
- if (p->info_count >= MAX_INFO_COUNT) {
- mpp_err("info count reach max\n");
- return MPP_NOK;
- }
- memcpy(&p->info[p->info_count], cfg, sizeof(MppDevInfoCfg));
- p->info_count++;
- if (cfg->type == INFO_FORMAT_TYPE) {
- p->fmt = cfg->data;
- }
- return MPP_OK;
- }
- const MppDevApi vcodec_service_api = {
- "vcodec_service",
- sizeof(MppDevVcodecService),
- vcodec_service_init,
- vcodec_service_deinit,
- NULL,
- NULL,
- NULL,
- NULL,
- vcodec_service_reg_wr,
- vcodec_service_reg_rd,
- vcodec_service_reg_offset,
- NULL,
- NULL,
- vcodec_service_set_info,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- vcodec_service_cmd_send,
- vcodec_service_cmd_poll,
- };
|