rk3588 MPI测试程序

一. RK3588的SDK源码下的external目录

你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
在RK3588的SDK源码目录下,有一个external 目录,里面存放的是一些应用测试代码,其中external/rockit 目录存放的是Rockchip提供的媒体处理接口(Rockchip Media Process Interface,简称 RK MPI),可支持应用软件快速开发。包含硬件的编解码器,视频输出输入等软件开发。

二. 硬件解码程序 rk_mpi_vdec_test

external/rockit/mpi/example/mod/test_mpi_vdec.cpp 文件里面是一个RK编写的视频解码播放demo,源码test_mpi_vdec.cpp 编译后生成的可执行文件是 rk_mpi_vdec_test 。 RK3588有4个vp,分别是vp0~vp3。这个demo默认绑定显示控制器是vp0,使用HDMI进行视频播放。
比如播放一个1080P的H265视频文件可以如下:

./rk_mpi_vdec_test -i 00.h265 -C 12 -w 1920 -h 1080

-i 指定的是待解码的文件
-C 指定解码的格式 8:h264, 9:mjpeg, 12:h265
-w 是解码的视频宽
-h 是解码的视频高

视频播放的效果如下:
在这里插入图片描述
demo源码写的并不是很完善,比较多参数是直接在源码中写死的,比如分辨率固定是1920x1080,有些命令行参数并不起效,需要手动修改源码。

三. 修改播放视频为MIPI接口

由于我这边项目使用的是MIPI显示屏,使用的vop2中的vp2 进行视频输出,并且分辨率是2560x1536,需要修改程序中的部分代码:

修改代码 rockit/mpi/example/mod/test_mpi_vdec.cpp 中下面函数:

static RK_S32 create_vo(RK_U32 ChCnt) {
    /* Enable VO */
    VO_PUB_ATTR_S VoPubAttr;
    VO_VIDEO_LAYER_ATTR_S stLayerAttr;
    RK_S32 s32Ret = RK_SUCCESS;
    VO_CHN_ATTR_S stChnAttr;
    VO_LAYER VoLayer = 2; //更改为vp2
    VO_DEV VoDev = 2; //更改为vp2

    RK_MPI_VO_DisableLayer(VoLayer);
    RK_MPI_VO_DisableLayer(4);
    RK_MPI_VO_DisableLayer(5);
    RK_MPI_VO_DisableLayer(6);
    RK_MPI_VO_DisableLayer(7);
    RK_MPI_VO_Disable(VoDev); 

    memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
    memset(&stLayerAttr, 0, sizeof(VO_VIDEO_LAYER_ATTR_S));

    stLayerAttr.enPixFormat = RK_FMT_RGB888;
    stLayerAttr.stDispRect.s32X = 0;
    stLayerAttr.stDispRect.s32Y = 0;
    stLayerAttr.u32DispFrmRt = 30;
    stLayerAttr.stDispRect.u32Width = 2560; //分辨率改成2560x1536
    stLayerAttr.stDispRect.u32Height = 1536;
    stLayerAttr.stImageSize.u32Width = 2560;
    stLayerAttr.stImageSize.u32Height = 1536;

    s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
    if (s32Ret != RK_SUCCESS) {
        return s32Ret;
    } 
    VoPubAttr.enIntfType = VO_INTF_MIPI; /* 更改输出设备MIPI */
    VoPubAttr.enIntfSync = VO_OUTPUT_DEFAULT;
    ..... 省略

    RK_S32 unit_test_mpi_vdec(TEST_VDEC_CTX_S *ctx) {
    MPP_CHN_S stSrcChn, stDestChn;
    RK_S32 s32Ret = RK_FAILURE;
    RK_U32 u32Ch = 0;
    TEST_VDEC_CTX_S vdecCtx[VDEC_MAX_CHN_NUM];
    pthread_t vdecThread[VDEC_MAX_CHN_NUM];
    pthread_t getPicThread[VDEC_MAX_CHN_NUM];

    for (u32Ch = 0; u32Ch < ctx->u32ChNum; u32Ch++) {
        if (ctx->u32ChNum > 1) {
            ctx->u32ChnIndex = u32Ch;
        }
        memcpy(&(vdecCtx[u32Ch]), ctx, sizeof(TEST_VDEC_CTX_S));

        // Does not support JPEG stream framing, read the size of one picture at a time
        // and send it to the decoder.
        if (ctx->u32InputMode == VIDEO_MODE_STREAM || ctx->enCodecId == RK_VIDEO_ID_MJPEG ||
            ctx->enCodecId == RK_VIDEO_ID_JPEG) {
            mpi_create_stream_mode(&vdecCtx[u32Ch], u32Ch);
            pthread_create(&vdecThread[u32Ch], 0, mpi_send_stream, reinterpret_cast<void *>(&vdecCtx[u32Ch]));
        } else  {
            return -1;
        }

         //pthread_create(&getPicThread[u32Ch], 0, mpi_get_pic, reinterpret_cast<void *>(&vdecCtx[u32Ch]));
    }

    s32Ret = create_vo(ctx->u32ChNum);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("create vo ch failed");
        return -1;
    }
    // bind vi to vo
    for (int i = 0; i < ctx->u32ChNum; i++) {
        stSrcChn.enModId    = RK_ID_VDEC;
        stSrcChn.s32DevId   = 0;
        stSrcChn.s32ChnId   = i;

        stDestChn.enModId   = RK_ID_VO;
        stDestChn.s32DevId  = 2; //修改为vp2
        stDestChn.s32ChnId  = i;

        s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
        if (s32Ret != RK_SUCCESS) {
            RK_LOGE("vi band vo fail:%x", s32Ret);
            return -1;
        }

        // enable vo
        s32Ret = RK_MPI_VO_EnableChn(2, i);/* 启用vp2 */
        if (s32Ret != RK_SUCCESS) {
            RK_LOGE("Enalbe vo chn failed, s32Ret = %d\n", s32Ret);
            return -1;
        }
    }

    for (u32Ch = 0; u32Ch < ctx->u32ChNum; u32Ch++) {
        pthread_join(vdecThread[u32Ch], RK_NULL);
        pthread_join(getPicThread[u32Ch], RK_NULL);

        vdecCtx[u32Ch].threadExit = RK_TRUE;
        if (ctx->u32ChNum > 1) {
            mpi_destory_vdec(&vdecCtx[u32Ch], u32Ch);
        } else {
            mpi_destory_vdec(&vdecCtx[u32Ch], ctx->u32ChnIndex);
        }
    }

    return RK_SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值