使用Gstreamer拉取rtsp流,使用jeston硬件加速解码,并保存buffer为图片。

2023-05-16

编译:

g++  demo666.cc -o demo666 `pkg-config --cflags --libs gstreamer-1.0 opencv4`

运行:

./demo666

代码:


// author: Deepcong
// time: 2022/08/26

#include <gst/gst.h>
#include <opencv2/core/types_c.h>
#include <opencv2/highgui.hpp>
#include <time.h>
#include <string>
#include <iostream>
using namespace cv;
using namespace std;


/* Structure to contain all our information, so we can pass it to callbacks */
typedef struct _CustomData {
    GstElement *pipeline;
    GstElement *source;
    GstElement *depay;
    GstElement *queue;    
    GstElement *parse;
    GstElement *avdec;
    GstElement *conv;
    GstElement *encoder;
    GstElement *convert;
    GstElement *sink;
    GMainLoop *main_loop;  /* GLib's Main Loop */


    // GstElement *pipeline, *source, *depay, *parse, *avdec, *convert, *encoder, *sink;
} CustomData;

/* This function is called when an error message is posted on the bus */
static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
  GError *err;
  gchar *debug_info;

  /* Print error details on the screen */
  gst_message_parse_error (msg, &err, &debug_info);
  g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
  g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
  g_clear_error (&err);
  g_free (debug_info);

  g_main_loop_quit (data->main_loop);
}



/* Handler for the pad-added signal */
/* This function will be called by the pad-added signal */
static void pad_added_handler (GstElement *src, GstPad *new_pad, CustomData *data) {
    GstPad *sink_pad = gst_element_get_static_pad (data->depay, "sink");
    GstPadLinkReturn ret;
    GstCaps *new_pad_caps = NULL;
    GstStructure *new_pad_struct = NULL;
    const gchar *new_pad_type = NULL;
 
    g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
 
    /* If our converter is already linked, we have nothing to do here */
    if (gst_pad_is_linked (sink_pad)) {
        g_print ("We are already linked. Ignoring.\n");
        goto exit;
    }
 
    /* Check the new pad's type */
    new_pad_caps = gst_pad_get_current_caps (new_pad);
    new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
    new_pad_type = gst_structure_get_name (new_pad_struct);
 
    /* Attempt the link */
    ret = gst_pad_link (new_pad, sink_pad);
    if (GST_PAD_LINK_FAILED (ret)) {
        g_print ("Type is '%s' but link failed.\n", new_pad_type);
    } else {
        g_print ("Link succeeded (type '%s').\n", new_pad_type);
    }
 
exit:
    /* Unreference the new pad's caps, if we got them */
    if (new_pad_caps != NULL)
        gst_caps_unref (new_pad_caps);
 
    /* Unreference the sink pad */
    gst_object_unref (sink_pad);
} 


static GstFlowReturn new_sample (GstElement *sink, gpointer user_data){
 
        GstSample *sample;
        GstBuffer *buffer;
        GstCaps *caps;
        GstStructure *s;
        gint width, height;	//图片的尺寸
 
        /* Retrieve the buffer */
        g_signal_emit_by_name (sink, "pull-sample", &sample);
        if (sample){
            g_print ("*  ");
            caps = gst_sample_get_caps (sample);
            if (!caps) {
                g_print ("gst_sample_get_caps fail\n");
                gst_sample_unref (sample);
                return GST_FLOW_ERROR;
            }
            s = gst_caps_get_structure (caps, 0);
            gboolean res;
            res = gst_structure_get_int (s, "width", &width);		//获取图片的宽

            g_print ("width: %d,  ", width);
            res |= gst_structure_get_int (s, "height", &height);	//获取图片的高
            g_print ("height: %d \n", height);

            if (!res) {
                g_print ("gst_structure_get_int fail\n");
                gst_sample_unref (sample);
                return GST_FLOW_ERROR;
            }
 
            //获取视频的一帧buffer,注意,这个buffer是无法直接用的,它不是char类型
            buffer = gst_sample_get_buffer (sample);		
 
            if(!buffer){
                g_print ("gst_sample_get_buffer fail\n");
                gst_sample_unref (sample);
                return GST_FLOW_ERROR;
            }
 

        
            GstMapInfo map;
            //把buffer映射到map,这样我们就可以通过map.data取到buffer的数据
            if (gst_buffer_map (buffer, &map, GST_MAP_READ)){		
                    g_print("jpg size = %ld \n", map.size);
                    cv::Mat src(Size(width, height), CV_8UC3, (char*)map.data, Mat::AUTO_STEP);
                    //文件名  以获取当前时间作为文件命名

                    time_t timep;

                    time(&timep); /*获取time_t类型当前时间*/
                    /*转换为常见的字符串:Fri Jan 11 17:04:08 2008*/
                    printf("%s", ctime(&timep));   
                    string ss = ".jpg";
                    string filename =  ctime(&timep) + ss ;           
                    cv::imwrite(filename, src);

    
                    gst_buffer_unmap (buffer, &map);	//解除映射
                }
            gst_sample_unref (sample);	//释放资源
            return GST_FLOW_OK;
        }
    return GST_FLOW_OK ;
 
}


#define CAPS "video/x-raw,format=BGR"	//设置appsink输出的视频格式


int main(int argc, char *argv[]) {
    /* Configure appsink */
    CustomData data;
    GstBus *bus;
    GstMessage *msg;
    GstStateChangeReturn ret;
    gboolean terminate = FALSE;
 
    /* Initialize GStreamer */
    gst_init (&argc, &argv);
    g_printerr("gst_init \n");


    /* Create the elements 
      videotestsrc 是一个源元素(它生成数据),用于创建测试视频模式。
      此元素对于调试目的(和教程)非常有用,通常在实际应用程序中找不到。
      autovideosink是一个接收器元素(它消耗数据),在窗口上显示它接收的图像。
    */
    data.source = gst_element_factory_make ("rtspsrc", "source");
    g_object_set (G_OBJECT (data.source), "latency", 2000, NULL);
    data.depay = gst_element_factory_make ("rtph264depay", "depay");
    data.queue = gst_element_factory_make ("queue", "Queue");

    data.parse = gst_element_factory_make ("h264parse", "parse");
    data.avdec = gst_element_factory_make ("nvv4l2decoder", "decoder");
    data.conv = gst_element_factory_make ("nvvidconv", "convert");

    data.encoder = gst_element_factory_make("nvv4l2h264enc", "encoder");     // nv4l2h264enc、nv4l2vp9enc和nvjpegenc,omxh264enc,jpegenc

    data.convert = gst_element_factory_make("videoconvert","Videoconvert");
    data.sink = gst_element_factory_make ("appsink", "sink");   
    g_printerr("gst element factory make \n");

    
    GstCaps *video_caps;
    gchar *video_caps_text;
    video_caps_text = g_strdup_printf (CAPS);
    video_caps = gst_caps_from_string (video_caps_text);

    if(!video_caps){
    g_printerr("gst_caps_from_string fail\n");
    return -1;
    }




    g_object_set (data.source, "location", "rtsp://Deepcong:666@192.115.8.52:8554/0", NULL);
    // 因为rtsp和rtph264depay还没有连接,所以必须设置pad-added信号监听,在管道开始工作后,确定了数据格式,再把它们连接起来
    /* Connect to the pad-added signal */
    g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data);

    g_object_set (data.sink, "caps", video_caps, NULL);

    g_object_set (data.sink, "emit-signals", TRUE, NULL);
    g_signal_connect (data.sink, "new-sample", G_CALLBACK (new_sample), &data);
    g_printerr("gst signal connect \n");

    data.pipeline = gst_pipeline_new ("test-pipeline");



    //&& 如果两个操作数都非零,则条件为真;
    // || 如果两个操作数中有任意一个非零,则条件为真。
    if (!data.pipeline || !data.source ||!data.depay || !data.queue  ||!data.parse || !data.avdec || !data.conv  || !data.encoder ||!data.convert || !data.sink) {
        g_printerr ("Not all elements could be created.\n");
        return -1;
    }
 
    /* Build the pipeline. Note that we are NOT linking the source at this
    * point. We will do it later. */
    gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.depay, data.queue, data.parse, data.avdec, data.conv,  data.convert,data.sink, NULL);



    if (!gst_element_link_many ( data.depay,data.queue,data.parse, data.avdec,data.conv,  data.convert,data.sink,NULL)) {
        g_printerr ("Elements could not be linked.\n");
        gst_object_unref (data.pipeline);
        return -1;
    }



    /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
    bus = gst_element_get_bus (data.pipeline);
    gst_bus_add_signal_watch (bus);
    g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, &data);
    gst_object_unref (bus);



    /* Start playing */
    ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr ("Unable to set the pipeline to the playing state.\n");
        gst_object_unref (data.pipeline);
        return -1;
    }
 

    /* Create a GLib Main Loop and set it to run */
    data.main_loop = g_main_loop_new (NULL, FALSE);
    g_main_loop_run (data.main_loop);


    
 
    /* Free resources */
    gst_object_unref (bus);
    gst_element_set_state (data.pipeline, GST_STATE_NULL);
    gst_object_unref (data.pipeline);
    return 0;
}    







本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Gstreamer拉取rtsp流,使用jeston硬件加速解码,并保存buffer为图片。 的相关文章

  • 接口成员显示实现

    xff08 interface xff09 用来定义一种程序的协定 实现接口的类或者结构要与接口的定义严格一致 在前面的文章中 xff0c 我们已经对C 接口的概念 xff0c 如何定义接口以及如何对接口进行访问等问题进行了详细的讨论 在这
  • Oracle基础知识整理总结

    1 Oracle跟SQL Server 2005的区别 xff1f 宏观上 xff1a 1 最大的区别在于平台 xff0c oracle可以运行在不同的平台上 xff0c sql server只能运行在windows平台上 xff0c 由于
  • Javascript调用后台方法

    1 javaScript函数中执行C 代码中的函数 xff1a 方法一 xff1a 1 首先建立一个按钮 xff0c 在后台将调用或处理的内容写入button click中 2 在前台写一个js函数 xff0c 内容为document ge
  • Delphi设置某用户对文件(夹)的权限

    以下在代码在D7 43 2003和D7 43 XP中调试通过 unit NTSecurityU interface Uses Windows AclApi AccCtrl Const SECURITY NULL SID AUTHORITY
  • 关于VMWare压缩虚拟机的虚拟磁盘的问题

    随着我们使用虚拟系统的时间越长 xff0c Vmware创建的虚拟磁盘占用空间就越大 xff0c 即使将虚拟系统中的文件删除 xff0c 虚拟磁盘文件占用宿主系统硬盘空间也不会减少 xff0c 这个问题困扰了很多用户 a S 34 N 43
  • GB2312简体中文编码表

    const GB2312 中文编码 CHpb 61 B0 首页码 CHpe 61 F7 尾页码 CHab 61 A1 首地址 CHae 61 FE 尾地址 GB B 61 B0A1 GB E 61 F7FE ChCount 61 chpe
  • 自定义通信协议

    现在大部分的仪器设备都要求能过通过上位机软件来操作 xff0c 这样方便调试 xff0c 利于操作 其中就涉及到通信的过程 在实际制作的几个设备中 xff0c 笔者总结出了通信程序的通用写法 xff0c 包括上位机端和下位机端等 1 xff
  • vc的编译过程

    对VC 43 43 工程编译过程的梳理 VC 43 43 的项目和解决方案文件解读 xff0c 无非就是利用这些信息进行一个软件的编译 xff0c 这些文件里面是存放的项目的配置和工程的组织 xff0c 类似于makefile文件 但是只有
  • 用WSE在Web服务中验证用户身份

    一 Web服务安全与WS Security 毫无疑问 xff0c SOAP和XML Web服务在交互操作和标准上已经完全改变了电子商务领域的格局 然而直到最近 xff0c 在Web服务技术领域仍然存在着一些缺陷 xff0c 那就是处理消息级
  • 安装CUDA wget下载速度慢解决办法(天下无敌)

    因为墙的原因 xff0c 再加上英伟达工作人员脑筋不会急转弯 xff0c 以及wget是个弟中弟 xff0c 下载cuda时可能会很慢 断线 xff0c 翻墙又不方便 但是没关系 xff0c 谈笑间 xff0c 让我们用一分钟成交它 以ub
  • px4下载指定版本的固件、git用法

    https hub fastgit org PX4 PX4 Autopilot git describe tag 查看当前版本号 git tag l 查看所有版本 xff0c 也就是打个tag git checkout v1 9 1 跳转到
  • YOLOX网络结构

    本文为博主DaneAI原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 原文链接 xff1a https blog csdn net happyday d article detai
  • 阿木实验室P450无人机硬件接线图备忘录

    其中数传是定制的 xff0c 相当于是路由器 43 数传二合一 xff0c 既负责地面站计算机与pixhawk的通讯 xff0c 又负责发射WiFi信号 组建局域网 xff0c 使板载英伟达NX上位机和手机 平板 笔记本电脑等远程终端连接在
  • yolov3损失函数公式及代码位置,绝对良心(更新)

    版本 xff1a darknet yolov3 环境 xff1a ubuntu16 04 本人小白 xff0c 毕设正在做基于yolov3的目标检测系统研究 xff0c 在网上找了一万遍 xff0c 基本没有靠谱的损失函数 xff0c 全是
  • 使用http协议Header中的Authorization传递token

    1 span class token annotation punctuation 64 GetMapping span span class token punctuation span span class token string 3
  • Shell命令之终端打开网页

    一句话用Safari打开百度 span class hljs built in open span span class hljs operator a span span class hljs string 34 Applications
  • 数据结构期末复习五:内部排序

    排序的基本概念和分类 排序 xff1a 将杂乱无章的数据按关键字递增 xff08 或递减 xff09 有序排列 假设Ki 61 Kj xff0c 排序前Ri领先于Rj 稳定排序 xff1a 排序后的序列Ri仍领先于Rj 不稳定排序 xff1
  • 数据同步工具DataX从Mysql同步数据到HDFS实战

    目录 1 查看数据同步模板2 高可用HA的HDFS配置3 MysqlReader针对Mysql类型转换说明4 HdfsWriter支持大部分Hive类型5 Mysql准备数据如下6 新建job mysql2hdfs json7 执行job8
  • 目标检测yolov3+文字识别CRNN 实现文本检测和识别

    参考链接 xff1a https github com chineseocr chineseocr https zhuanlan zhihu com p 34757009 https wenku baidu com view f4ec95e
  • 关于51单片机串口通信的相关知识(寄存器)

    一 51单片机串口概念 1 51单片机的串行口 51单片机的串行口是一个可编程全双工的通信接口 xff0c 具有UART xff08 通用异步收发器 xff09 的全部功能 2 51单片机的硬件连接 简单双向串口通信有两根数据通信线 xff

随机推荐

  • Linux服务器--TCP协议详解

    1 TCP服务的特点 传输层协议主要有两个 xff1a TCP协议和UDP协议 TCP协议相对于UDP协议的特点是 xff1a 面向连接 字节流 可靠传输 使用TCP协议通信的双方必须先建立连接 xff0c 然后才能开始数据的读写 双方都必
  • strpbrk函数

    strpbrk函数 1 函数功能 xff1a strpbrk是在源字符串 xff08 s1 xff09 中找出最先含有搜索字符串 xff08 s2 xff09 中任一字符的位置并返回 xff0c 若找不到则返回空指针 2 头文件 span
  • win10自带的office365怎么找到安装目录+mathtype

    遇到问题 xff0c 因为我要安装mathtype xff0c 但是一直显示错误代码53 显示运行时未找到mathpage wll 一般都在office文件夹中 xff0c 但是365死活在files和data中都找不到 xff0c 运行目
  • 面试问题记录

    csdn https www cnblogs com yinrw p 10795210 html 问题比较全面 问卷星 https www wjx cn xz 109293287 aspx 简述你在以前的工作中做过哪些事情 xff0c 比较
  • 学习记录2

    这是一个名字 新版换了之后跟之前的完全不太一样了 shell相关 Shell字符串截取 xff08 非常详细 xff09 苍青浪 博客园 这是一个快引用 linux相关 查看内容占用情况 输出 free m sed n 39 2p 39 a
  • leetcode 100热题

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言标题easy问题合集1 有效括号问题 前言 提示 xff1a leetcode简单题目100题中的easy部分 xff1a
  • java小项目之成绩管理、排课软件、局域网聊天软件

    大三下 xff0c 想把上个学期的一些东西整理一下 可能是突然有点想法吧 我把答辩ppt以及文档要求还有项目文件夹全部都放在了我的github里面啦 点击打开链接 项目一 问题描述 xff1a 教师在教学过程中 xff0c 需要记录学生的成
  • LeetCode 114 二叉树转链表

    一 题目 分析 xff1a xff08 1 xff09 要求转化为先序遍历顺序 xff0c 这个很容易想到设置一个链表 xff0c 然后先序遍历二叉树 xff0c 把节点和指针记录在链表就好了 xff08 2 xff09 题目要求in pl
  • 使用gstreamer,rtsp拉流,保存图像, jeston,使用硬件加速nvdec/nvenc

    jeston xff0c 拉流 xff0c 使用硬件加速nvdec nvenc span class token macro property span class token directive hash span span class
  • LeetCoed 无重复字符的最长子串(java)

    一 题目分析 分析 xff1a 最长子串 xff0c 而不是最长子序列 子串是字符串连续的一段 xff0c 子序列是可以不连续的 所以有一种方法叫做滑动窗口法 xff0c 我记得左程云老师讲过 xff0c 那个题是计算窗口内最大或者最小值的
  • leetcode 127 单词接龙(搜索 java)

    就是给一个单词词典 xff0c 给一个开始词汇和结束词汇 xff0c 在词典中找出开始词汇转变成结束词汇的过程 xff0c 求转变次数 每次只能转变单词的一个字符 可能会有多条路径可以到达 xff0c 搜索问题可以用DFS BFS解决 xf
  • gtest单元测试配置+vs 2015+OpenCppCoverage输出测试覆盖率 || cmake命令构建项目以及编译以及命令行测试

    目录 一 仅使用gtest 43 vs2015 1 下载和编译gtest 2 创建具体的项目 3 gtest自带十个例子 二 使用gtest 43 vs2015 xff0c 并且输出测试覆盖率 1 使用vs 2015企业版 2 使用Open
  • Cmakelists配置多级目录的gtest项目(项目代码和测试代码分离)

    cmake一些语法定义 之前的博客主要写了怎么配置gtest项目 xff0c 但是一般项目代码和测试代码并不在一起 xff0c 所以尝试将代码分离 主要分成三个部分 xff0c 下面给出demo的分级目录 gtest demo CMakel
  • WGS-84 ECEF ENU 坐标系学习记录

    地球坐标系固定在地球上而随地球一起在空间做公转和自转运动 xff0c 因此地球上任一固定点在地球坐标系的坐标就不会由于地球旋转而变化 地心地固直角坐标系和大地坐标系都属于这种坐标系 一 几种坐标系 地心地固直角坐标系 xff08 ECEF
  • 关于大学生计算机未来发展的个人规划

    本人今年大二 xff0c 计算机专业 xff0c 和很多大学生一样 xff0c 在大一期间仍保持着高中的习惯 xff0c 每天只是上课听讲 xff0c 课后写作业 xff0c 复习与预习 可以说 xff0c 除了课堂上老师讲的知识和书本上有
  • 关于scanf的一些注意事项

    第一点 xff0c 设定的接受变量应以地址的方式出现在scanf内 xff0c 这是因为scanf本身是一个函数 xff0c 若不加地址相当于值传递 xff0c 无法改变对应变量的值 如 xff1a 规定输入类型是整形 xff08 d xf
  • 关于长度未知,输入几组数据之后如何终止输入

    首先 xff0c 应确定结束标准 xff0c 一般题目中会给出以输入 xffe5 或者负数之类的结束 xff0c 若题中没给 xff0c 正常情况下我们自己编码是习惯以回车作为结束符号 故可以用getchar xff08 xff09 接受一
  • 关于TortoiseGit的个人见解

    首先先放一个下载链接 xff1a Download TortoiseGit Windows Shell Interface to Git TortoiseGit是一个用于用户本身和gitee之间进行文件传输的中介 xff0c 本质上是用来简
  • c语言实现扫雷

    实现在9乘9的格子内实现扫雷游戏 xff0c 可修改格子的大小和雷的个数 思路 xff1a 初始利用随机数种子生成10个雷的位置 xff0c 通过输入x xff0c y坐标来显示当前格子是否是雷 xff0c 若是雷游戏结束 xff0c 显示
  • 使用Gstreamer拉取rtsp流,使用jeston硬件加速解码,并保存buffer为图片。

    编译 xff1a g 43 43 demo666 cc o demo666 span class token variable span class token variable 96 span pkg config cflags libs