我对
h264parse
的真正用途感到困惑。
我用这个命令进行了测试:
与
h264parse
:
gst-launch-1.0 videotestsrc num-buffers=10 ! x264enc ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
没有
h264parse
:
gst-launch-1.0 videotestsrc num-buffers=10 ! x264enc ! avdec_h264 ! videoconvert ! autovideosink
没有什么区别,两者都工作正常。
然后我尝试将h264保存到文件中,然后打开它。
将其保存到文件中:
gst-launch-1.0 videotestsrc num-buffers=10 ! x264enc ! filesink location=videotestsrc.h264
用h264parse打开它,工作正常,我可以看到视频:
gst-launch-1.0 filesrc location=videotestsrc.h264 ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
但是如果我在没有
h264parse
的情况下打开它:
gst-launch-1.0 filesrc location=videotestsrc.h264 ! avdec_h264 ! videoconvert ! autovideosink
它不起作用,错误消息如下:
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/avdec_h264:avdec_h264-0: GStreamer error: negotiation problem.
Additional debug info:
gstvideodecoder.c(2448): gst_video_decoder_chain (): /GstPipeline:pipeline0/avdec_h264:avdec_h264-0:
decoder not initialized
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
不知道怎么理解。
谢谢
根据 avdec_h264 的 documentation,他的接收器期望 h264 流的解析格式。 h264parse 的作用是,它只是以 avdec_h264 可以理解的方式解析 h264 的字节。
# avdec_h264 sink
video/x-h264:
alignment: au
stream-format: { (string)avc, (string)byte-stream }
video/x-h264:
alignment: nal
stream-format: byte-stream
# h264parse src
video/x-h264:
parsed: true
stream-format: { (string)avc, (string)avc3, (string)byte-stream }
alignment: { (string)au, (string)nal }
因此,h264parse不会将h264字节解码到原始视频流中,它只是以某种形式组装字节。
我在问自己同样的事情后发现了这个问题/答案。经过更多研究后,我认为我应该分享我的发现。
我发现
avdec_h264
中的“对齐”属性对应于gst_pad_push
中使用的框架。换句话说,如果对齐方式为“nal”,则 avdec_h264 期望单个 gst_pad_push
调用中的数据为单个“nal”。
因为
filesrc
元素不知道它正在处理什么,所以它不会在其期望的帧对齐中提供 avdec_h264
数据。
我创建了一个插件,可以解析数据流并分割任意字节序列。这可用于提供
avdec_h264
正确的帧。
插件的源代码可以在这里找到: https://github.com/redmcg/gst-buffer-splitter