繁体   English   中英

向H264-ES视频流gstreamer添加时间戳

[英]Add timestamps to H264-ES video stream gstreamer

我有一个文件(可能是mplayer -identify所说的) H264-ES流。

可以使用以下gstreamer管道进行播放:

gst-launch-1.0 filesrc location=vid.H264 ! h264parse ! avdec_h264 ! autovideosink

(我在示例中使用了autovideosink ,但是管道更加复杂-这是“最小的工作示例”)它播放非常快,可能与我的CPU允许的速度一样快。 如果我使用任何需要时间戳的元素,它将失败,因为流的帧速率为0/1

我认为流完全不包含任何帧率信息。

看到:

$ mplayer -identify vid.H264 2>&1 | grep -i fps
FPS not specified in the header or invalid, use the -fps option.
ID_VIDEO_FPS=0.000

我知道正确的帧速率应该是多少(假设是25fps),并且我希望能够将正确的时间戳记放入视频帧设置正确的流帧速率

我试过的

我以为可以为此使用videorate

gst-launch-1.0 filesrc location=vid.H264 ! h264parse ! avdec_h264 \
               ! videorate ! video/x-raw,framerate=25/1 ! autovideosink

但是我错了videorate尝试将传入流转换为固定帧率,有时看起来像我想要的那样工作,但是当下游任何元素出现最小延迟时,它都会产生“冻结帧”视频-许多重复帧-所以我以为我可以使用drop-only=true选项,但这根本不起作用:

$ GST_DEBUG=3 gst-launch-1.0 filesrc location=vid.H264 ! h264parse ! avdec_h264 \
        ! videorate drop-only=true ! video/x-raw,framerate=25/1 ! autovideosink

Setting pipeline to PAUSED ...
0:00:00.030550249 31831      0x2094e10 WARN                 basesrc gstbasesrc.c:3470:gst_base_src_start_complete:<filesrc0> pad not activated yet
Pipeline is PREROLLING ...
0:00:00.044233138 31831      0x207d450 WARN                   libav gstavcodecmap.c:2408:gst_ffmpeg_caps_to_pixfmt: ignoring insane framerate 1/0
0:00:00.045314795 31831      0x207d450 WARN                GST_PADS gstpad.c:3742:gst_pad_peer_query:<avdec_h264-0:src> could not send sticky events
0:00:00.070760684 31831      0x207d450 WARN               baseparse gstbaseparse.c:3262:gst_base_parse_loop:<h264parse0> error: streaming stopped, reason not-negotiated
ERROR: from element /GstPipeline:pipeline0/GstH264Parse:h264parse0: GStreamer encountered a general stream error.
Additional debug info:
gstbaseparse.c(3262): gst_base_parse_loop (): /GstPipeline:pipeline0/GstH264Parse:h264parse0:
streaming stopped, reason not-negotiated
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

问题出在avdec_h264videorate之间-它不接受videorate framerate=0/1 caps。

我想我需要的是(虚构管道):

$ GST_DEBUG=3 gst-launch-1.0 filesrc location=vid.H264 ! h264parse ! avdec_h264 \
        ! force_timestamps framerate=25/1 ! autovideosink

恐怕我必须自己编写force_timestamps元素,但是因为我之前确实写过一些元素,而且这是我做过的最困难,最不愉快的事情之一,所以我尽可能使用现有的元素。

所以我的问题是这样的:

是否有某种方法(最好是使用现有元素)以固定的帧速率在视频帧(或gstreamer缓冲区)上强制时间戳?

从技术上讲,这不是答案,因为这样会丢失原始的h264流。

这是一个丑陋的骇客,但是我需要视频,这给了我一些我可以用的质量不错的东西:

fn="$1"

mkdir images

gst-launch-1.0 filesrc location=$fn ! h264parse ! avdec_h264 \
    ! videoconvert ! jpegenc \
    ! multifilesink location=images/img%06d.jpg

gst-launch-1.0 multifilesrc location=images/img%06d.jpg \
    caps="image/jpeg,framerate=25/1,pixel-aspect-ratio=1/1" \
    ! jpegdec ! videoconvert ! video/x-raw \
    ! x264enc rc-lookahead=5 pass=quant quantizer=20 \
    ! avimux ! filesink location=${fn}.avi

rm -rf images

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM