如何编写 GstSamples 的特定时间间隔(RTP over UDP H264 数据包)?
How to write specific time interval of GstSamples (RTP over UDP H264 packets)?
设置
我正在通过以下 Gstreamer CLI 管道通过 RTP UDP 发送 H.264 编码数据包:
gst-launch-1.0 videotestsrc is-live=true ! video/x-raw,framerate=30/1 ! timeoverlay ! videoconvert ! x264enc ! h264parse ! rtph264pay pt=96 ! udpsink host=127.0.0.1 port=5000
请注意,timeoverlay
元素稍后会派上用场!
在接收端,仅用于描述(这不是从 CLI 启动的),我使用以下管道:
gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp,clock-rate=90000,payload=96 ! queue ! appsink
请注意,udpsrc
的 do-timestamp
的 属性 默认设置为 true。所以实际上是在此处为缓冲区添加时间戳的元素。
使用 Gstreamer 的 appsink
元素,我提取 GstSample*
并手动为它们添加 unix 时间戳,并将它们保存在队列中。我所做的时间戳与示例缓冲区的显示时间戳无关,因为 GST_BUFFER_PTS(buffer)
它的实现方式如下:
struct MyGstSample {
GstSample* sample_;
long unix_time_ns_;
}
在请求特定的 unix 时间间隔时,我应该提供相应的
通过 Gstreamer 的 appsrc
从队列采样 GstSample*
通过以下管道(仅供描述)并在 .mp4
文件中记录间隔:
gst-launch-1.0 appsrc ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 ! rtph264depay ! h264parse ! mp4mux ! queue ! filesink
问题
我好像不能准确地写出所需的时间间隔,你可以根据录制视频中显示的时间来判断,感谢timeoverlay
。例如,如果用户请求(为简单起见,从 运行 时间 5s 到 运行 时间 15s)我只得到 10s 到 15s。我想这与关键帧问题或其他问题有关。
有没有一种方法可以在保持帧编码的同时确保精确的点播视频录制?
所以问题实际上与关键帧有关,因为录制管道只会从它找到的第一个关键帧开始写入视频,所有增量帧都会被丢弃。而我在请求的间隔中错过了很多秒的原因是因为发送管道每 300 帧发送一个关键帧的配置,这个 属性 与 x264enc
.
正在调整发送管道以每 30 帧发送一次关键帧:
gst-launch-1.0 videotestsrc is-live=true ! video/x-raw,framerate=30/1 ! timeoverlay ! videoconvert ! x264enc key-int-max=30 ! h264parse ! rtph264pay pt=96 ! udpsink host=127.0.0.1 port=5000
接下来我们需要找出哪些缓冲区GstBuffer *
对应于关键帧。这可以通过检查缓冲区是否具有 GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)
设置的 GST_BUFFER_FLAG_DELTA_UNIT
来完成
在接收端,在探测来自 udpsrc
的缓冲区时,您会发现 GST_BUFFER_FLAG_DELTA_UNIT
始终设置为 false,因为数据是 application/x-rtp
。在这里您需要使用 rtph264depay
并检查从中产生的缓冲区。您将开始看到一些关键帧和增量帧。话虽如此,接收方应如下所示:
gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp,clock-rate=90000,payload=96 ! rtph264depay ! queue ! appsink
最后,为了让录音管道正常工作,您需要从接收端获取 rtph264depay
的 src pad 的 GstCaps*
,并将其用作 appsrc
在记录管道中,因为它包含重要的特定于编解码器的数据。否则解析器 h264parse
将无法正常运行。这是管道(仅供描述,您仍然需要将上限添加到 appsrc)
gst-launch-1.0 appsrc ! h264parse ! mp4mux ! queue ! filesink
话虽如此,每当我们收到请求的间隔时,实际上都会在队列中搜索最近的关键帧,并开始将相应的样本提供给记录管道。
设置
我正在通过以下 Gstreamer CLI 管道通过 RTP UDP 发送 H.264 编码数据包:
gst-launch-1.0 videotestsrc is-live=true ! video/x-raw,framerate=30/1 ! timeoverlay ! videoconvert ! x264enc ! h264parse ! rtph264pay pt=96 ! udpsink host=127.0.0.1 port=5000
请注意,timeoverlay
元素稍后会派上用场!
在接收端,仅用于描述(这不是从 CLI 启动的),我使用以下管道:
gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp,clock-rate=90000,payload=96 ! queue ! appsink
请注意,udpsrc
的 do-timestamp
的 属性 默认设置为 true。所以实际上是在此处为缓冲区添加时间戳的元素。
使用 Gstreamer 的 appsink
元素,我提取 GstSample*
并手动为它们添加 unix 时间戳,并将它们保存在队列中。我所做的时间戳与示例缓冲区的显示时间戳无关,因为 GST_BUFFER_PTS(buffer)
它的实现方式如下:
struct MyGstSample {
GstSample* sample_;
long unix_time_ns_;
}
在请求特定的 unix 时间间隔时,我应该提供相应的
通过 Gstreamer 的 appsrc
从队列采样 GstSample*
通过以下管道(仅供描述)并在 .mp4
文件中记录间隔:
gst-launch-1.0 appsrc ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 ! rtph264depay ! h264parse ! mp4mux ! queue ! filesink
问题
我好像不能准确地写出所需的时间间隔,你可以根据录制视频中显示的时间来判断,感谢timeoverlay
。例如,如果用户请求(为简单起见,从 运行 时间 5s 到 运行 时间 15s)我只得到 10s 到 15s。我想这与关键帧问题或其他问题有关。
有没有一种方法可以在保持帧编码的同时确保精确的点播视频录制?
所以问题实际上与关键帧有关,因为录制管道只会从它找到的第一个关键帧开始写入视频,所有增量帧都会被丢弃。而我在请求的间隔中错过了很多秒的原因是因为发送管道每 300 帧发送一个关键帧的配置,这个 属性 与 x264enc
.
正在调整发送管道以每 30 帧发送一次关键帧:
gst-launch-1.0 videotestsrc is-live=true ! video/x-raw,framerate=30/1 ! timeoverlay ! videoconvert ! x264enc key-int-max=30 ! h264parse ! rtph264pay pt=96 ! udpsink host=127.0.0.1 port=5000
接下来我们需要找出哪些缓冲区GstBuffer *
对应于关键帧。这可以通过检查缓冲区是否具有 GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)
GST_BUFFER_FLAG_DELTA_UNIT
来完成
在接收端,在探测来自 udpsrc
的缓冲区时,您会发现 GST_BUFFER_FLAG_DELTA_UNIT
始终设置为 false,因为数据是 application/x-rtp
。在这里您需要使用 rtph264depay
并检查从中产生的缓冲区。您将开始看到一些关键帧和增量帧。话虽如此,接收方应如下所示:
gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp,clock-rate=90000,payload=96 ! rtph264depay ! queue ! appsink
最后,为了让录音管道正常工作,您需要从接收端获取 rtph264depay
的 src pad 的 GstCaps*
,并将其用作 appsrc
在记录管道中,因为它包含重要的特定于编解码器的数据。否则解析器 h264parse
将无法正常运行。这是管道(仅供描述,您仍然需要将上限添加到 appsrc)
gst-launch-1.0 appsrc ! h264parse ! mp4mux ! queue ! filesink
话虽如此,每当我们收到请求的间隔时,实际上都会在队列中搜索最近的关键帧,并开始将相应的样本提供给记录管道。