[英]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_h264
和videorate
之間-它不接受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.