Добавить метки времени в поток видео H264-ES gstreamer

У меня есть файл с (наверное, вот что mplayer -identify сказал) H264-ES поток.

В нее можно играть, используя следующие gstreamer трубопровод:

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

(Я использую autovideosink в примерах, но конвейер гораздо более сложный - это "минимальный рабочий пример") он играет очень быстро, вероятно, настолько быстро, насколько позволяет мой процессор. Если я использую какой-либо элемент, которому нужны временные метки, он терпит неудачу, потому что поток имеет частоту кадров 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

Я знаю, какой должна быть правильная частота кадров (скажем, 25 кадров в секунду), и я хотел бы иметь возможность вставлять правильные временные метки в видеокадры или устанавливать правильную частоту кадров потока.

Что я пробовал:

Я думал, что я мог бы использовать 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 - не примет framerate=0/1 шапки.

Я думаю, что мне нужно что-то вроде (воображаемый конвейер):

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

Боюсь, мне придется написать force_timestamps сам элемент, но так как раньше я писал некоторые элементы, и это было одной из самых сложных и неприятных вещей, которые я когда-либо делал, я бы предпочел использовать существующие элементы, если это возможно.

Итак, мой вопрос заключается в следующем:

Есть ли какой-нибудь способ (желательно с существующими элементами) для принудительной установки временных меток на видеокадрах (или буферах gstreamer) с некоторой фиксированной частотой кадров?

1 ответ

Технически, это не ответ, потому что при этом оригинальный поток 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
Другие вопросы по тегам