• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RK3399 ,播放RTSP流,使用QMediaPlayer,不使用FFMpeg方式

武飞扬头像
三石兄x
帮助1

rk3399 想要拉RTSP流并显示共有俩种显示方式

其中rk3399拥有mpp硬件解码器,能够解h264与h265码流

第一种方式为 FFmpeg qt MPP,方式进行解码

此种解码方式,前面的文章有阐述过,在此就不再过多阐述了

第二种方式是利用qt中的qMediaplayer方式进行播放,Qmediaplayer,自己并无解码器,rk3399中恰巧提供了GST(gstreamer)框架,Qt中的qmediaplayer 在linux下支持这种解码框架,能够自己调用,因此,我们只需要设置播放源即可,在本项目中,需要把显示的图像进行另外的处理,因此我们利用QVideoProbe 的方式的槽函数的方式进行获取

整体思路如下

1,确定rk3399 上有安装 gst ,可输入gst 按tab键进行补全命令进行查看,如图所示

学新通

2.

  1.  
    QMediaPlaylist *playlist = new QMediaPlaylist;
  2.  
    //playlist->addMedia(QUrl::fromLocalFile("/root/1.mp4"));
  3.  
    playlist->addMedia(QUrl(rtspUrl));
  4.  
    playlist->setCurrentIndex(1);
  5.  
    QMediaPlayer *cameraRtspPlayer = new QMediaPlayer(this);
  6.  
    cameraRtspPlayer->setPlaylist(playlist);
  7.  
     
  8.  
    QVideoWidget *rtspVideoMianWidget = new QVideoWidget;
  9.  
    rtspVideoMianWidget->setAspectRatioMode(Qt::IgnoreAspectRatio);
  10.  
     
  11.  
    connect(&VideoMianprobe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(slotGetRtspOneFrame(QVideoFrame)));
  12.  
     
  13.  
    connect(cameraRtspPlayer,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(slotOpenRtspUrlResult(QMediaPlayer::State)));
  14.  
     
  15.  
    QVideoProbe VideoMianprobe;
  16.  
    VideoMianprobe.setSource(cameraRtspPlayer);
  17.  
    cameraRtspPlayer->setVideoOutput(rtspVideoMianWidget);
  18.  
    cameraRtspPlayer->play();
学新通

QVideoProbe class允许你监控正在播放或者记录的视频

可以发出两个信号,其中比较重要的是后面一个videoFrameProbed

void flush()

void videoFrameProbed( const QVideoFrame &frame)

利用此函数我们可以接收rtsp流中的每一帧图像,再利用cpu或者rk3399中的rga模块进行转码,将nv12转为rgb888格式,

如下所示

  1.  
    if(!frame.isValid())
  2.  
    {
  3.  
    qDebug() << "frame is Valid";
  4.  
    return;
  5.  
    }
  6.  
    frame.map(QAbstractVideoBuffer::ReadOnly);
  7.  
     
  8.  
    if(rtspDecode.dst_buf == nullptr)
  9.  
    {
  10.  
    int srcWidth = frame.width();
  11.  
    int srcHight = frame.height();
  12.  
    int reallyWidth = frame.width();
  13.  
    int reallyHeight = frame.height();
  14.  
     
  15.  
    while(reallyWidth%6!=0)
  16.  
    {
  17.  
    reallyWidth ;
  18.  
    }
  19.  
    cropWidth = srcWidth - (reallyWidth - srcWidth);
  20.  
    cropHight = srcHight - (reallyHeight - srcHight);
  21.  
    rtspDecode.setSrcWidthHight(frame.width(),frame.height(),reallyWidth,reallyHeight);
  22.  
     
  23.  
    rtspDecode.dst_buf = (uchar*)malloc(frame.width() * frame.height() * get_bpp_from_format(DST_FORMAT)*2);
  24.  
    }
  25.  
     
  26.  
    rtspDecode.convertdata(frame.bits(),rtspDecode.dst_buf);
  27.  
    QImage qimg((uchar *)rtspDecode.dst_buf,frame.width(),frame.height(),QImage::Format_RGB888);
  28.  
    currRtspStopOldTimeMsTick = currMsTick;
  29.  
    aiCameraEnable = false;
  30.  
    sigAiCameraStart(qimg.copy(0,0,cropWidth,cropHight));
学新通

剩下部分为RGA解码,部分,注意这里要对图像的真实的分辨率进行计算,h264与h265,图像对齐方式并不一致,h264为16位对齐方式,h265对齐方式为265奇数对齐方式,直接设置用frame的宽高的方式,会导致rga解析的图像并不正确。因此我们这里要计算图像的正确的大小,还有一种方式,是利用ffmpeg拉流,获取图像正确的大小格式,这里我们直接计算图像的大小。为265整除即可,当图像转换完成后,即使宽高设置正确,也会存在绿边现象,这时我们可计算绿边的大小,用原始图像大小减去h265对齐之后的大小,就是绿边的大小,再利用Qimg的copy,拷贝正确的图像大小,即可。

rga 图像转换代码如下所示

  1.  
    im_rect src_rect;
  2.  
    im_rect dst_rect;
  3.  
    rga_buffer_t src;
  4.  
    rga_buffer_t dst;
  5.  
    IM_STATUS STATUS;
  6.  
     
  7.  
    int ret = 0;
  8.  
     
  9.  
    memset(&src_rect, 0, sizeof(src_rect));
  10.  
    memset(&dst_rect, 0, sizeof(dst_rect));
  11.  
    memset(&src, 0, sizeof(src));
  12.  
    memset(&dst, 0, sizeof(dst));
  13.  
     
  14.  
    src = wrapbuffer_virtualaddr(srcdata, reallyWidth, reallyHight, SRC_FORMAT);
  15.  
    dst = wrapbuffer_virtualaddr(dst_buf, srcWidth,srcHight, DST_FORMAT);
  16.  
     
  17.  
     
  18.  
    if(src.width == 0 || dst.width == 0) {
  19.  
    printf("%s, %s\n", __FUNCTION__, imStrError());
  20.  
    return -1;
  21.  
    }
  22.  
    src.format = SRC_FORMAT;
  23.  
    dst.format = DST_FORMAT;
  24.  
     
  25.  
    ret = imcheck(src, dst, src_rect, dst_rect);
  26.  
    if (IM_STATUS_NOERROR != ret) {
  27.  
    printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
  28.  
    return -1;
  29.  
    }
  30.  
    STATUS = imcvtcolor(src, dst, src.format, dst.format);
  31.  
    // qDebug("resizing .... %s\n", imStrError(STATUS));
  32.  
    return 0;
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbjihj
系列文章
更多 icon
同类精品
更多 icon
继续加载