当前位置: 首页 > 知识库问答 >
问题:

Gstreamer问题,在RTMP流上添加timeoverlay

钱钊
2023-03-14

我需要向rtmp流添加时间覆盖,并保存到磁盘。以下管道,没有覆盖,工作正常:

gst-launch-1.0 -v \
rtmpsrc location=rtmp://192.168.x.x/live/0 do-timestamp=true ! queue2 ! flvdemux name=demux \
flvmux name=mux \
demux.video ! queue ! decodebin \
    ! nvvidconv \
    ! 'video/x-raw(memory:NVMM),width=1920,height=1080, format=(string)I420, framerate=50/1' \
    ! nvv4l2h264enc ! h264parse \
    ! mux.video \
demux.audio ! queue name="dmx_aud_q" ! mux.audio \
mux.src ! queue name="mux_q" ! filesink location="rtmp.flv"

添加timeoverlay(甚至clockoverlay)后,管道不会运行:

gst-launch-1.0 -v \
rtmpsrc location=rtmp://192.168.0.168/x.x do-timestamp=true ! queue2 ! flvdemux name=demux \
flvmux name=mux \
demux.video ! queue ! decodebin \
    ! timeoverlay \
    ! nvvidconv \
    ! 'video/x-raw(memory:NVMM),width=1920,height=1080, format=(string)I420, framerate=50/1' \
    ! nvv4l2h264enc ! h264parse \
    ! mux.video \
demux.audio ! queue name="dmx_aud_q" ! mux.audio \
mux.src ! queue name="mux_q" ! filesink location="rtmp.flv"

GST\u DEBUG=3日志添加在末尾。管道图如下所示。

据我所知,在decodebin移交给timeoverlay时,caps谈判存在一些问题。我不知道如何让timeoverlay以管道可以继续多路复用的方式接受或输出数据。任何有助于了解这里发生了什么,以及如何找到解决方案的帮助都将是巨大的。

这是在Nvidia Jetson纳米板上,运行Ubuntu 18.0。(以“nv”开头的插件通常可以替换为其他系统上的常规插件,我相信-nvvidconv带有视频转换,nvv4l2h264enc带有omxh264enc等等。

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.065:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

14:19:35.066gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.066:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

14:19:35.066gst_caps_append_structure_full断言GST_IS_CAPS失败

14:19:35.066gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.066:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

14:19:35.067gst_caps_append_structure_full断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.067:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

14:19:35.068gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.068:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.068:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

14:19:35.068gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.068:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.069:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败0:00:00.942959420 834 0x55b9ce8a30 WARN gst\u PADS gstpad。c: 4226:gst\u pad\u peer\u查询:无法发送粘性事件0:00:00.943568965 834 0x55b9ce8a30警告。c: 1433:gst\U v4l2\U video\U dec\U DECEL\U分配:持续时间无效,未设置延迟0:00:00.944316482 834
0x55b9ce8a30 WARN v4l2bufferpool gstv4l2bufferpool。c: 1054:gst\u v4l2\u buffer\u pool\u start:缓冲区不确定或不足,启用复制阈值

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.073:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.074:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.074:gst\U structure\U copy:断言'结构!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.074:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.074:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.074:gst\U structure\U copy:断言'结构!=“NULL”失败

(gst-Launst-1.0:834): GStreamer-CRITAL**:14:19:35.074:gst_caps_append_structure_full:断言'GST_IS_CAPS(大写)'失败0:00:00.948613871 834 0x55b9ce8a30 WARN basetransform gstbasetransform. c: 1355:gst_base_transform_setcaps:变换无法转换视频/x-h264, Stream-form=(string)byte-stream,宽=(int)1920,高=(int)1080,帧速率=(分数)50/1,交错模式=(string)渐进式, chroma-form=(string)4:2:0, bit-diage-luma=(uint)8, bit-diage-chroma=(uint)8, parse=(boolean)true,对齐=(string)au,配置文件=(string)基线, level=(string)4.2在我们支持的任何0:00:00.948674601 834 0x55b9ce8a30 WARN basetransform gstbasetransform. c: 1415:gst_base_transform_reconfigure:警告:未协商0:00:00.948709446 834 0x55b9ce调试信息:gstbasetransform. c(1415):gst_base_transform_reconfigure(): /GstPipeline:Pipeline0/GstDecodeBin:decDebin0/GstCapsFilter:capsfilter1:未协商0:00:00.971426937 834 0x7f70004a80 WARN
basesrc gstbasesrc. c:3055:gst_base_src_loop:错误:内部数据流错误。0:00:00.971545793 834 0x7f70004a80 WARN
basesrc gstbasesrc. c:3055:gst_base_src_loop:错误:流停止,原因未协商(-4) 0:00:00.978535326 834 0x7f6807c8f0 WARN v4l2Bufferpool gstv4l2Bufferpool. c:1518:gst_v4l2_buffer_pool_dqbuf:驱动程序永远不应该将v4l2_buffer.field设置为任何

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.105:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

14:19:35.105gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.105:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.105:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

14:19:35.105gst_caps_get_structure断言GST_IS_CAPS失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.105:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.105:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.106:gst_structure_copy:断言'结构!=NULL'失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.106:gst_structure_copy:断言'结构!=NULL'失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.106:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败错误:来自元素/GstPipeline:pipeline0/GstRTMPSrc:rtmpsrc0:内部数据流错误。

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u mini\u object\u copy:断言“mini\u object!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.106:gst_structure_copy:断言'结构!=NULL'失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.106:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

14:19:35.107gst_caps_get_structure断言GST_IS_CAPS失败

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.107:gst_structure_copy:断言'结构!=NULL'失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.107:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败的其他调试信息:gstbasesrc。c(3055):gst\u base\u src\u loop():/gstpipline:pipeline0/GstRTMPSrc:rtmpsrc0:流停止,原因未协商(-4)错误:管道不想预滚。正在将管道设置为NULL。。。

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.107:gst_mini_object_copy:断言'mini_object!=NULL'失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.108:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.108:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

GST-Launtion-1.0:834): GStreamer-CRITAL**:14:19:35.108:gst_mini_object_copy:断言'mini_object!=NULL'失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.108:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.108:gst\u caps\u get\u结构:断言“gst\u IS\u caps(caps)”失败

(gst-launch-1.0:834):GStreamer-CRITICAL**:14:19:35.109:gst\u-structure\u-copy:assertion'structure!=“NULL”失败

(gst-launch-1.0:834):GStreamer CRITICAL**:14:19:35.109:gst\u caps\u append\u structure\u full:断言“gst\u IS\u caps(caps)”释放管道失败。。。

共有1个答案

颛孙信厚
2023-03-14

正如Aswin所说,它是通过在timeoverlay之前添加convert来解决的。这是因为timeoverlay不能与DMA缓冲区一起工作(这就是(memory:nvm)的意思),所以管道看起来像是原始的,除了以下更改:

... decodebin ! nvvidconv ! 'video/x-raw' !  timeoverlay ! nvvidconv ! 'video/x-raw(memory:NVMM)

错误基本上是关于timeoverlay无法链接到nvv4l2decder,该解码器将缓冲区输出为DMA。我们需要nvvidconv来复制这些缓冲区,以便我们可以在用户空间中使用它们。

详细的详细说明:

我对DMA/CPU缓冲区的理解很模糊(请更正)-所有nv*元素都可以使用DMA缓冲区(我想更直接),这会加快处理速度。但是在nvv4l2decoder和nvv4l2h264enc之间,我们添加了时间覆盖以将时间添加到视频中。。

但不幸的是,timeoverlay元素不能处理这些缓冲区。因此,我们添加了nvviddonv,它缓慢地将缓冲区(通过CPU)复制到用户空间,慢慢地进行更改,然后慢慢地返回到更快的“DMA缓冲区空间”。但我看不出有什么办法。除非有一些奇特的自定义元素可以直接使用缓冲区。

过去几年,GStreamer在更好地使用这些缓冲区方面做了一些工作-我看到了ndufresne关于DMAGeofence(异步使用DMA缓冲区)和零拷贝管道(不确定是否适用)的一些演示:零拷贝:https://youtu.be/kNaa1fPv_uoDMAGeofence:https://youtu.be/HpmzJGHqObs

一些通用Linux文章:https://01.org/linuxgraphics/gfx-docs/drm/driver-api/dma-buf.html

 类似资料:
  • 要将视频从IP cam流到Youtube,我使用的代码(通过Ubunu):ffmpeg-f lavfi-I anullsrc-rtsp\u transport tcp-Irtsp://user:psw@192.168.0.100:554-tune zerolatency-vcodec libx264-pix\u fmt-c:v copy-c:a aac-strict experimental-f

  • 硬件和软件:Raspberry PI4,IP camera,Raspbian Buster,Gstreamer 1.14.1(来自存储库)。覆盆子和摄像机都在本地网络上。 null 其他信息: > 我的相机在图像上方显示时间(时、分、秒)。回放总是在秒的某个值停止。相机重启时,这个数值随机变化--17、32、55……改变相机中的时间并不能解决问题。 Raspberry上的VLC播放器从该相机播放流

  • SRS(Simple RTMP Server)分发RTMP是核心功能,srs的主要定位就是分发RTMP低延时流媒体,同时支持分发HLS流。 RTMP和HLS的优势参考:HLS RTMP和HLS的比较参考:RTMP PK HLS 部署RTMP的实例参考:Usage: RTMP 应用场景 RTMP是PC-flash支持最完善的流分发方式,主要的应用场景包括: 无插件流媒体应用:十年前各种浏览器插件大行

  • 我在弄清楚如何使用gstreamer创建一个简单的rtp流并在vlc上显示它时遇到了一些困难。 我已经安装了GStreamer 0.10.30和VLC 1.1.3。我唯一的要求是使用MPEG4或H.264编解码器。 现在,我可以通过以下简单的管道传输GStreamer videotestsrc: 它输出客户端接收流所需的“上限”: 我还可以使用以下管道显示流: 但当我尝试用vlc接收流时: 我一无

  • 我尝试添加外部css,但不是work属性, 我正在使用prestashop版本1.7。4.3 在install()函数中,我调用钩子 在钩子里面,我注册了css和js文件 在hookBackOfficeHeader()中,我没有任何问题,但在hookDisplayHeader()中,我不想注册字体。 我尝试使用registerStylesheet()来添加CSS(),但根本不起作用。 为什么这两种

  • 问题内容: 大家好,我不是Json最好的。我试图通过循环将一些json对象添加到json数组中,但是问题是每次涉及到循环时,新数据也会遍历数组中的先前数据。这是我的代码: 给定X.size = 2的示例 我希望我的例子足够清楚。 如果有人能在这里帮助我,我将不胜感激。 问题答案: 您需要在循环的每次迭代中创建一个新的引用: 否则,您将一遍又一遍地更新同一实例,并将对同一对象的引用多次添加到数组中。