peter 发表于 2020-10-16 10:35:03

rk3399pro硬解码(vpu,rtsp)使用

源文地址:https://www.jianshu.com/p/6e86980aa563
系统debian10,摄像头:海康;
鉴于瑞芯微官网论坛介绍硬解码使用不够详细,在踩了许多坑的情况下总结如下,供大家参考。
系统软件包升级
[*]更新源:sudo apt update --fix-missing
[*]升级软件包:sudo apt -y upgrade
注意:升级过去中会有提示确认是否提供/etc/apt/sources.list.d/toybrick.list,请输入"Y"
[*]再次更新源:sudo apt update
说明:上述步骤只需要执行一次即可,后续软件包升级只需要执行命令
sudo apt update; sudo apt upgrade
参考:
瑞芯微社区关于toybrick系列debian10系统软件包升级说明
一、 python方式install toybrick-0.3.0-py3-none-any.whl   下载地址:链接: https://pan.baidu.com/s/1AkJ70nTTIIXbgDYbF6IPUQ 提取码: b54n
安装以下依赖

sudo apt-get install g++ binutils-gold xorg-dev libglu1-mesa-dev
sudo apt install libgbm-dev
sudo apt install rockchip-mpp
sudo apt install toybrick-gbm-dev
sudo toybrick-mali.sh link   

sudo pip3 install toybrick-0.3.0-py3-none-any.whl验证安装是否成功

import toybrick as toyhttps://upload-images.jianshu.io/upload_images/1702706-3cb3c61abf0b9640.png?imageMogr2/auto-orient/strip|imageView2/2/w/503/format/webp
python掉用代码
import toybrick as toy
import time
import cv2

url = "rtsp://admin:123456@192.168.1.200:554/h264/ch1/main/av_stream"
username = "admin"
pwd = "123456"
#rtsp = toy.input.createRtspClient(url, username, pwd, False)
rtsp = toy.input.createRtspClient(url)
rtsp.connect()
last = time.time()
gl = toy.output.createGLDrmDisplay(toy.DisplayPort.HDMI_A)
idx0 = gl.add_view(50, 600, 768, 432)
frame_index = 0
while rtsp.is_opened():
    frame = rtsp.read_rgb(768, 432)
    now = time.time()
    gl.show(idx0, frame)
    print (frame_index, "----------------------------",now - last)
    frame = frame.array()
    cv2.imwrite("images/4_" + str(frame_index) + ".jpg", frame)
    # cv2.imshow('Carplate demo', cv2.resize(frame, (960, 540)))#
    frame_index += 1
    last = now
运行效果
https://upload-images.jianshu.io/upload_images/1702706-75ba0c011a6b997b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp

参考:
瑞芯微社区RK3399Pro入门教程(8)6路1080P30帧解码显示范例
二.、C++方式安装依赖sudo apt-get install curl
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libopencv-dev
sudo apt install rockchip-drm-dev libdrm-dev
sudo apt install rockchip-rtsp-dev
sudo apt install rockchip-mpp-dev
sudo apt install rockchip-rga-devrtsp_ssd .cpp#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <thread>
#include <memory.h>
#include <sys/time.h>
#include <queue>

using namespace std;

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <rockchip/rockchip_rtsp.h>
#include <rockchip/rockchip_mpp.h>
extern "C" {
#include <rockchip/rockchip_rga.h>
}

#define RTSP_URL    "rtsp://192.168.1.200/h264/ch1/main/av_stream"
#define RTSP_USER   "admin"
#define RTSP_PWD    "123456"

static MppDecoder *mpp_dec = NULL;
static std::queue<DecFrame *> frame_queue;
static int run_flag = 0;

unsigned long get_time(void)
{
    struct timeval ts;
    gettimeofday(&ts, NULL);
    return (ts.tv_sec * 1000 + ts.tv_usec / 1000);
}

void onRtspHandle(unsigned char *buf, size_t len)
{
    std::cout << "frame recived " << len << std::endl;

    mpp_dec->ops->enqueue(mpp_dec, buf, len);
}

void inference_thread(RockchipRga *rga, int width, int height)
{
    int ret;
    int resize_w = 1920, resize_h = 1080;
    static int frame_size = 0;
    unsigned char *frame_rgb = NULL;

    rga->ops->initCtx(rga);
    rga->ops->setRotate(rga, RGA_ROTATE_NONE);
    rga->ops->setSrcFormat(rga, V4L2_PIX_FMT_NV12, width, height);
    rga->ops->setDstFormat(rga, V4L2_PIX_FMT_BGR24, resize_w, resize_h);
   
    frame_size = resize_w * resize_h * 3;
    frame_rgb = (unsigned char *)malloc(frame_size);
    cv::Mat img(resize_h , resize_w , CV_8UC3, frame_rgb);
    if (!frame_rgb)
      goto exit;
   
    rga->ops->setDstBufferPtr(rga, frame_rgb);

    while (run_flag) {
      if (frame_queue.empty()) {
            usleep(1000);
            continue;
      }

      auto frame = frame_queue.front();

      rga->ops->setSrcBufferPtr(rga, frame->data);

      ret = rga->ops->go(rga);
      printf("inference_thread ................\n");
      if (!ret) {
            ///do something with frame_rgb

            cv::imshow("test", img);
            cv::waitKey(10);
      }

      frame_queue.pop();
      mpp_dec->ops->freeFrame(frame);
    }

exit:
    run_flag = 0;

    while (!frame_queue.empty()) {
      auto frame = frame_queue.front();
      mpp_dec->ops->freeFrame(frame);
      frame_queue.pop();
    }

    if (frame_rgb)
      free(frame_rgb);
}

void decode_thread(RockchipRga *rga)
{
    int ret;
    int first_frame = 0;
    std::thread t_inference;

    while (run_flag) {
      DecFrame *frame = mpp_dec->ops->dequeue_timeout(mpp_dec, 300);
      if (frame != NULL) {
            std::cout << "decode frame" << frame->width << "x" << frame->height << std::endl;
      
            if (!first_frame) {
                std::cout << "first_frame" << std::endl;
                t_inference = std::thread(inference_thread, rga, frame->width, frame->height);
                first_frame = 1;
            }

            if (frame_queue.size() < 30)
                frame_queue.push(frame);
            else
                mpp_dec->ops->freeFrame(frame);
      }
    }

exit:
    run_flag = 0;

    t_inference.join();

    while (!frame_queue.empty()) {
      auto frame = frame_queue.front();
      mpp_dec->ops->freeFrame(frame);
      frame_queue.pop();
    }

}

int main(int argc, char **argv)
{
    int ret;
    RockchipRga *rga;
    unsigned char ready = {'r', 'e', 'a', 'd', 'y'};
    RtspClient rtsp_client(RTSP_URL, RTSP_USER, RTSP_PWD);

    rtsp_client.setDataCallback(onRtspHandle);

    mpp_dec = MppDecoderCreate(DECODE_TYPE_H264);
    if (!mpp_dec) {
      std::cout << "MppDecoderCreate error!\n" << std::endl;
      return -1;
    }

    rga = RgaCreate();
    if (!rga) {
      MppDecoderDestroy(mpp_dec);
      std::cout << "rgaCreate error!\n" << std::endl;
      return -1;
    }

    run_flag = 1;

    rtsp_client.enable();

    std::thread t_decode(decode_thread, rga);

    while (run_flag) {
      usleep(10000);
    }

    rtsp_client.disable();

    run_flag = 0;

    t_decode.join();

    RgaDestroy(rga);

    MppDecoderDestroy(mpp_dec);

    return 0;
}
CMakeLists.txtcmake_minimum_required(VERSION 2.8)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_BUILD_TYPE Release)

set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)

find_package(CURL REQUIRED)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(link_libs rockchip_rtsp rockchip_mpp curl rockchip_rga pthread
opencv_core opencv_highgui opencv_imgcodecs)

add_executable(rtsp_ssd rtsp_ssd.cpp)
target_link_libraries(rtsp_ssd ${link_libs})编译cd local_rtsp/build
cmake ..
make
./rtsp_ssd运行效果https://upload-images.jianshu.io/upload_images/1702706-19b5a83d502366d8.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp
参考:
[*]瑞芯微社区Toybrick Debian 10用户指南
[*]瑞芯微社区RK3399Pro入门教程(7)RTSP库的使用
页: [1]
查看完整版本: rk3399pro硬解码(vpu,rtsp)使用