Toybrick

rk3399 mpp库使用问题

kevin

注册会员

积分
80
楼主
发表于 2020-7-27 13:16:42    查看: 6612|回复: 3 | [复制链接]    打印 | 只看该作者
本帖最后由 kevin 于 2020-7-27 13:15 编辑

系统:Android8.1  应用:底层C++  库:libmpp.so
1、从v4l2获取摄像头mjpeg格式数据经过libjpeg-turbo转换为yuv422数据,显示正常(图一)
2、使用mpp库对转换来的yuv数据进行编码后得到的h264数据打开后异常(图二)
mpp设置:
void CameraReader::init_mpp()
{
    MPP_RET ret = MPP_OK;
    memset(&mpp_enc_data, 0, sizeof(mpp_enc_data));

    mpp_enc_data.width = CAMERA_WIDTH;
    mpp_enc_data.height = CAMERA_HEIGHT;
    mpp_enc_data.hor_stride = MPP_ALIGN(mpp_enc_data.width, 16);
    mpp_enc_data.ver_stride = MPP_ALIGN(mpp_enc_data.height, 16);
    mpp_enc_data.fmt = MPP_FMT_YUV422_YUYV;//经过转换后格式为yuv422
    mpp_enc_data.frame_size = MPP_ALIGN(mpp_enc_data.hor_stride, 64) * MPP_ALIGN(mpp_enc_data.ver_stride, 64) * 2;
     
    mpp_enc_data.type = MPP_VIDEO_CodingAVC;
    mpp_enc_data.num_frames = 2000;
    ret = mpp_buffer_get(NULL, &mpp_enc_data.frm_buf, mpp_enc_data.frame_size);
    if (ret)
    {
        printf("failed to get buffer for input frame ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    ret = mpp_create(&mpp_enc_data.ctx, &mpp_enc_data.mpi);
    if (ret)
    {
        printf("mpp_create failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    ret = mpp_init(mpp_enc_data.ctx, MPP_CTX_ENC, mpp_enc_data.type);
    if (ret)
    {
        printf("mpp_init failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    mpp_enc_data.fps = 30;//帧率
    mpp_enc_data.gop = 60;
    mpp_enc_data.bps = mpp_enc_data.width * mpp_enc_data.height / 8 * mpp_enc_data.fps;

    mpp_enc_data.prep_cfg.change        = MPP_ENC_PREP_CFG_CHANGE_INPUT |
                                          MPP_ENC_PREP_CFG_CHANGE_ROTATION |
                                          MPP_ENC_PREP_CFG_CHANGE_FORMAT;
    mpp_enc_data.prep_cfg.width         = mpp_enc_data.width;
    mpp_enc_data.prep_cfg.height        = mpp_enc_data.height;
    mpp_enc_data.prep_cfg.hor_stride    = mpp_enc_data.hor_stride;
    mpp_enc_data.prep_cfg.ver_stride    = mpp_enc_data.ver_stride;
    mpp_enc_data.prep_cfg.format        = mpp_enc_data.fmt;         
    mpp_enc_data.prep_cfg.rotation      = MPP_ENC_ROT_0;            
    ret = mpp_enc_data.mpi->control(mpp_enc_data.ctx, MPP_ENC_SET_PREP_CFG, &mpp_enc_data.prep_cfg);
    if (ret)
    {
        printf("mpi control enc set prep cfg failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    mpp_enc_data.rc_cfg.change  = MPP_ENC_RC_CFG_CHANGE_ALL;
    mpp_enc_data.rc_cfg.rc_mode = MPP_ENC_RC_MODE_CBR;   
    mpp_enc_data.rc_cfg.quality = MPP_ENC_RC_QUALITY_MEDIUM;
    if (mpp_enc_data.rc_cfg.rc_mode == MPP_ENC_RC_MODE_CBR)
    {
        /* constant bitrate has very small bps range of 1/16 bps */
        mpp_enc_data.rc_cfg.bps_target   = mpp_enc_data.bps;            
        mpp_enc_data.rc_cfg.bps_max      = mpp_enc_data.bps * 17 / 16;  
        mpp_enc_data.rc_cfg.bps_min      = mpp_enc_data.bps * 15 / 16;
    }
    else if (mpp_enc_data.rc_cfg.rc_mode ==  MPP_ENC_RC_MODE_VBR)
    {
        if (mpp_enc_data.rc_cfg.quality == MPP_ENC_RC_QUALITY_CQP)
        {
            /* constant QP does not have bps */
            mpp_enc_data.rc_cfg.bps_target   = -1;
            mpp_enc_data.rc_cfg.bps_max      = -1;
            mpp_enc_data.rc_cfg.bps_min      = -1;
        }
        else
        {
            /* variable bitrate has large bps range */
            mpp_enc_data.rc_cfg.bps_target   = mpp_enc_data.bps;
            mpp_enc_data.rc_cfg.bps_max      = mpp_enc_data.bps * 17 / 16;
            mpp_enc_data.rc_cfg.bps_min      = mpp_enc_data.bps * 1 / 16;
        }
    }

    /* fix input / output frame rate */
    mpp_enc_data.rc_cfg.fps_in_flex      = 0;
    mpp_enc_data.rc_cfg.fps_in_num       = mpp_enc_data.fps;
    mpp_enc_data.rc_cfg.fps_in_denorm    = 1;              
    mpp_enc_data.rc_cfg.fps_out_flex     = 0;               
    mpp_enc_data.rc_cfg.fps_out_num      = mpp_enc_data.fps;
    mpp_enc_data.rc_cfg.fps_out_denorm   = 1;
    mpp_enc_data.rc_cfg.gop              = mpp_enc_data.gop;
    mpp_enc_data.rc_cfg.skip_cnt         = 0;

    ret = mpp_enc_data.mpi->control(mpp_enc_data.ctx, MPP_ENC_SET_RC_CFG, &mpp_enc_data.rc_cfg);
    if (ret)
    {
        printf("mpi control enc set rc cfg failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    mpp_enc_data.codec_cfg.coding = mpp_enc_data.type;
    switch (mpp_enc_data.codec_cfg.coding)
    {
        case MPP_VIDEO_CodingAVC :
        {
            mpp_enc_data.codec_cfg.h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE |
                    MPP_ENC_H264_CFG_CHANGE_ENTROPY |
                    MPP_ENC_H264_CFG_CHANGE_TRANS_8x8;
            /*
            * H.264 profile_idc parameter
            * 66  - Baseline profile
            * 77  - Main profile
            * 100 - High profile
            */
            mpp_enc_data.codec_cfg.h264.profile  = 70;
            /*
            * H.264 level_idc parameter
            * 10 / 11 / 12 / 13    - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
            * 20 / 21 / 22         - cif@30fps / half-D1@@25fps / [url=mailto1@12.5fps]D1@12.5fps[/url]
            * 30 / 31 / 32         - D1@25fps / 720p@30fps / 720p@60fps
            * 40 / 41 / 42         - 1080p@30fps / 1080p@30fps / 1080p@60fps
            * 50 / 51 / 52         - 4K@30fps
            */
            mpp_enc_data.codec_cfg.h264.level    = 40;
            mpp_enc_data.codec_cfg.h264.entropy_coding_mode  = 1;
            mpp_enc_data.codec_cfg.h264.cabac_init_idc  = 0;
            mpp_enc_data.codec_cfg.h264.transform8x8_mode = 1;
        }
        break;

        case MPP_VIDEO_CodingMJPEG :
        {
            mpp_enc_data.codec_cfg.jpeg.change  = MPP_ENC_JPEG_CFG_CHANGE_QP;
            mpp_enc_data.codec_cfg.jpeg.quant   = 10;
        }
        break;

        case MPP_VIDEO_CodingVP8 :

        case MPP_VIDEO_CodingHEVC :

        default :
        {
            printf("support encoder coding type %d\n", mpp_enc_data.codec_cfg.coding);
        }
        break;
    }

    ret = mpp_enc_data.mpi->control(mpp_enc_data.ctx, MPP_ENC_SET_CODEC_CFG, &mpp_enc_data.codec_cfg);
    if (ret)
    {
        printf("mpi control enc set codec cfg failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    /* optional */
    mpp_enc_data.sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
    ret = mpp_enc_data.mpi->control(mpp_enc_data.ctx, MPP_ENC_SET_SEI_CFG, &mpp_enc_data.sei_mode);
    if (ret)
    {
        printf("mpi control enc set sei cfg failed ret %d\n", ret);
        goto MPP_INIT_OUT;
    }

    mpp_enc_data.fp_output = fopen(OUTPUTPATH, "wb+");
    if (mpp_enc_data.type == MPP_VIDEO_CodingAVC)
    {
        MppPacket packet = NULL;
        ret = mpp_enc_data.mpi->control(mpp_enc_data.ctx, MPP_ENC_GET_EXTRA_INFO, &packet);
        if (ret)
        {
            printf("mpi control enc get extra info failed\n");
            goto MPP_INIT_OUT;
        }

        /* get and write sps/pps for H.264 */
        if (packet)
        {
            void *ptr   = mpp_packet_get_pos(packet);
            size_t len  = mpp_packet_get_length(packet);

            if (mpp_enc_data.fp_output)
                fwrite(ptr, 1, len, mpp_enc_data.fp_output);

            packet = NULL;
        }
    }

    return;

MPP_INIT_OUT:

    if (mpp_enc_data.ctx)
    {
        mpp_destroy(mpp_enc_data.ctx);
        mpp_enc_data.ctx = NULL;
    }

    if (mpp_enc_data.frm_buf)
    {
        mpp_buffer_put(mpp_enc_data.frm_buf);
        mpp_enc_data.frm_buf = NULL;
    }

    printf("init mpp failed!\n");
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

kevin

注册会员

积分
80
沙发
 楼主| 发表于 2020-7-27 13:18:24 | 只看该作者
请问是否是设置问题还是说转换后的格式不对?
回复

使用道具 举报

jefferyzhang

版主

积分
12983
板凳
发表于 2020-7-29 08:29:03 | 只看该作者
kevin 发表于 2020-7-27 13:18
请问是否是设置问题还是说转换后的格式不对?

明显是后处理的格式和参数问题
回复

使用道具 举报

kevin

注册会员

积分
80
地板
 楼主| 发表于 2020-7-29 13:06:06 | 只看该作者
已做好,先使用7yuv等工具确认了mjpeg转yuv后的数据正常再编码就肯定不会出问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表