Извлечение GIF-кадров с помощью gstreamer - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь извлечь кадры из любого видео (включая GIF) с помощью gstreamer с AppSrc и AppSink.Мой минимальный неисправный конвейер в Rust (с использованием gstreamer crate):

let buf = /* All in memory for the moment */;

let app_src = ElementFactory::make("appsrc", None).unwrap();
let decodebin = ElementFactory::make("decodebin", None).unwrap();
let app_sink = ElementFactory::make("appsink", None).unwrap();
let pipeline = Pipeline::new();

pipeline.add_many(&[&app_src, &decodebin, &app_sink]).unwrap();
app_src.link(&decodebin).unwrap();

let buf = GstRc::from_slice(buf).unwrap();
let app_src = app_src.downcast::<AppSrc>().unwrap();
app_src.push_buffer(buf).into_result().unwrap();
app_src.end_of_stream().into_result().unwrap();

let app_sink = app_sink.downcast::<AppSink>().unwrap();
app_sink.set_caps(Some(&Caps::from_str(&"video/x-raw")).unwrap()));
app_sink.set_sync(false);
app_sink.set_wait_on_eos(true);

let app_sink2 = app_sink.clone();
decodebin.connect_pad_added(move |decodebin, _| {
    let _ = decodebin.link(&app_sink2);
});

pipeline.set_state(State::Playing).into_result().unwrap();
pipeline
    .get_state(CLOCK_TIME_NONE)
    .0
    .into_result()
    .unwrap()

 /* Pull each frame through with app_sink.pull_sample() */

Это работает с различными видео и даже изображениями, которые я тестировал, но для любого GIF просто выдает ошибку на pipeline.get_state().GST_DEBUG=4 показывает:

0:00:18.929304768 27027 0x7f48746d8050 INFO                   libav gstavdemux.c:1314:gst_ffmpegdemux_open:<avdemux_gif0:video_0> stream tags: taglist, video-codec=(string)"GIF\ \(Graphics\ Interchange\ Format\)";
0:00:18.929353999 27027 0x7f48746d8050 WARN                   libav gstavdemux.c:1603:gst_ffmpegdemux_loop:<avdemux_gif0> av_read_frame returned -5
0:00:18.929370474 27027 0x7f48746d8050 WARN                   libav gstavdemux.c:1590:gst_ffmpegdemux_loop:<avdemux_gif0> error: Internal data stream error.
0:00:18.929383308 27027 0x7f48746d8050 WARN                   libav gstavdemux.c:1590:gst_ffmpegdemux_loop:<avdemux_gif0> error: streaming stopped, reason error (-5)
0:00:18.929371274 27027 0x7f48746d8680 INFO            videodecoder gstvideodecoder.c:1330:gst_video_decoder_sink_event_default:<avdec_gif0> upstream tags: taglist, video-codec=(string)"GIF\ \(Graphics\ Interchange\ Format\)";
0:00:18.929406505 27027 0x7f48746d8050 INFO        GST_ERROR_SYSTEM gstelement.c:2145:gst_element_message_full_with_details:<avdemux_gif0> posting message: Internal data stream error.
0:00:18.929462537 27027 0x7f48746d8050 INFO        GST_ERROR_SYSTEM gstelement.c:2172:gst_element_message_full_with_details:<avdemux_gif0> posted error message: Internal data stream error.

Ошибка av_read_frame returned -5.GST_DEBUG=5 не печатает ничего более подробного об ошибке.Как ни странно, gst-launch работает:

gst-launch-1.0 filesrc location=test.gif ! decodebin ! video/x-raw ! fakesink

Запуск этого с GST_DEBUG=4 не показывает ничего удивительного, за исключением того, что нет ошибки.Я пробовал несколько разных вещей, таких как предварительная подготовка перед игрой, но у меня есть идея, почему она не работает в этом конкретном случае.Кто-нибудь может дать мне несколько советов?

У меня установлены все gst-plugins- * плюс gst-libav.Я использую gstreamer 1.14.2 на ArchLinux.

1 Ответ

0 голосов
/ 01 сентября 2018

Для тех, кто сталкивается с подобными проблемами: GIF-декодирование работает только с AppSrc на основе pull.GIF, похоже, является единственным популярным веб-форматом (таким как jpgs, pngs, webms, mp4s и т. Д.), Который не работает с API-интерфейсами AppSrc на основе push.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...