瑞芯微rv1126 rtsp+mpp+rga取流

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

瑞芯微rv1126 rtsp+mpp+rga取流


经过测试,使用rtsp+mpp+rga取流1920*1080图像一帧耗时60ms左右,基本可满足要求

一、mpp解码

void decoder_routine(QImage &img,bool &bOK)
{
    int ret;
    RK_U32 pkt_done = 0;
    // write data to packet
    mpp_packet_write(packet, 0, packet_buffer, packet_wpos);
    // reset pos and set valid length
    mpp_packet_set_pos(packet, packet_buffer);
    mpp_packet_set_length(packet, packet_wpos);
//    printf("packet_wpos = :%d\n",packet_wpos);
    packet_wpos = 0;
    // setup eos flag
    if (pkt_eos)
        mpp_packet_set_eos(packet);

    do {

        RK_S32 times = 5;
        // send the packet first if packet is not done
        if (!pkt_done)
        {
            ret = mpi->decode_put_packet(ctx, packet);
            if (MPP_OK == ret)
                pkt_done = 1;
        }

        // then get all available frame and release
        do {
            RK_S32 get_frm = 0;
            RK_U32 frm_eos = 0;

        try_again:
            ret = mpi->decode_get_frame(ctx, &frame);
            if (MPP_ERR_TIMEOUT == ret) {
                if (times > 0) {
                    times--;
                    msleep(MPP_H264_DECODE_TIMEOUT);
                    goto try_again;
                }
                mpp_err("decode_get_frame failed too much time\n");
            }
            if (MPP_OK != ret) {
                mpp_err("decode_get_frame failed ret %d\n", ret);
                break;
            }

            if (frame) {
                if (mpp_frame_get_info_change(frame))
                {
                    RK_U32 width = mpp_frame_get_width(frame);
                    RK_U32 height = mpp_frame_get_height(frame);
                    RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
                    RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);

                    mpp_log("decode_get_frame get info changed found\n");
                    mpp_log("decoder require buffer w:h [%d:%d] stride [%d:%d]\n",
                            width, height, hor_stride, ver_stride);

                    ret = mpp_buffer_group_get_internal(&frm_grp,MPP_BUFFER_TYPE_DRM);
                    if (ret) {
                        mpp_err("get mpp buffer group  failed ret %d\n", ret);
                        break;
                    }
                    mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, frm_grp);
                    mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);

                } else {
                    RK_U32 err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame);
                    if (err_info) {
                        frame_err++;
                        mpp_log("decoder_get_frame get err info:%d discard:%d.\n",
                                mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame));
                    }
                    else
                    {
                        /** Got a frame */
                        timeval start,end;
                        gettimeofday(&start,NULL);
                        frame_out(img);
                        bOK = true;
                        gettimeofday(&end,NULL);
                        float use_time = 1000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec)/1000;
                        qDebug() << "rgacvt use time ="<< use_time;

                        static timeval last,now;
                        gettimeofday(&now,NULL);
                        float t = 1000*(now.tv_sec - last.tv_sec) + (now.tv_usec - last.tv_usec)/1000;
                        printf("*******time******:%f\n",t);
                        last = now;

                    }
                }
                frm_eos = mpp_frame_get_eos(frame);
                mpp_frame_deinit(&frame);
                frame = NULL;
                get_frm = 1;
            }

            // if last packet is send but last frame is not found continue
            if (pkt_eos && pkt_done && !frm_eos) {
                msleep(MPP_H264_DECODE_TIMEOUT);
                qDebug() << "continue";
                continue;
            }

            if (frm_eos) {
                mpp_log("found last frame\n");
                break;
            }

            if (!get_frm)
                break;
        } while (1);

        if (pkt_done)
            break;

        /*
         * why sleep here:
         * mpi->decode_put_packet will failed when packet in internal queue is
         * full,waiting the package is consumed .
         */
        msleep(MPP_H264_DECODE_TIMEOUT);

    } while (1);
}

void frame_out()
{
//    MppFrameFormat fmt  = mpp_frame_get_fmt(frame);
    MppBuffer buff = mpp_frame_get_buffer(frame);
//    size_t size = mpp_frame_get_buf_size(frame);
    RK_U32 h = mpp_frame_get_height(frame);
    RK_U32 w = mpp_frame_get_width(frame);

    FrameData *framedata = convertdata((char*)mpp_buffer_get_ptr(buff),w,h);

    if(framedata->data == nullptr)
    {
        qDebug() << "frame->data = null";
        return;
    }
}

二、rga转换

char *dst_buf = nullptr;
char *dst_output_buf = nullptr;
char *dst_resize_output_buf = nullptr;

// read frame
struct FrameData *convertdata(char *srcdata,int width, int height)
{

    FrameData * data = new FrameData();

    // rga
    rga_buffer_t 	src;
    rga_buffer_t 	dst;
    rga_buffer_t  dst_output;
    rga_buffer_t  dst_resize_output;


    try {
        // h264 16bit 1920 * 1080 == 1920 * 1088
        int size = 1920 * 1088* 1.5;
        printf("size = %d",size);
        if (size == 3133440 || size == 4177920 )
        {
            src = wrapbuffer_virtualaddr(srcdata, 1920, 1088, RK_FORMAT_YCrCb_420_SP);
            if (dst_buf == NULL)
            {
                dst_buf = (char*)malloc(1920*1088*get_bpp_from_format(DST_FORMAT));
            }
            dst = wrapbuffer_virtualaddr(dst_buf, 1920, 1088, DST_FORMAT);
            if (dst_output_buf == NULL)
            {
                dst_output_buf = (char*)malloc(1920*1080*get_bpp_from_format(DST_FORMAT));
            }
            dst_output = wrapbuffer_virtualaddr(dst_output_buf, 1920, 1080, DST_FORMAT);
            if (dst_resize_output_buf == NULL)
            {
                dst_resize_output_buf = (char*)malloc(width*height*get_bpp_from_format(DST_FORMAT));
            }
            dst_resize_output = wrapbuffer_virtualaddr(dst_resize_output_buf, width, height, DST_FORMAT);

            if(src.width == 0 || dst.width == 0 || dst_output.width == 0)
            {
                printf("%s, %s\n", __FUNCTION__, imStrError());
                // return data;
            }
            else
            {
                imcvtcolor(src, dst, src.format, dst.format);
                im_rect src_rect = {0, 0, 1920, 1080};
                imcrop(dst,dst_output,src_rect);
                imresize(dst_output,dst_resize_output);
                data->width = width;
                data->height = height;
                data->data = dst_resize_output_buf;
                data->size = width*height*get_bpp_from_format(DST_FORMAT);
            }
        }
    }

    catch (...)
    {
        data->isRun = STATUS_DISCONNECT;
        data->size = 0;
        return data;
    }

    return data;

}

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值