GStreamer c ++ - поиск перед началом любого воспроизведения - PullRequest
1 голос
/ 12 февраля 2020

Я добавил опцию start-offset в свое приложение C ++, используя библиотеку GStreamer. По сути, оно говорит приложению запускать видео в середине, а не воспроизводить его с самого начала.

Конвейер создается следующим образом: filesrc location="file_path" ! qtdemux ! h264parse ! mppvideodec ! waylandsink. Это то, что дает мне лучшие результаты на моем оборудовании, и я работаю под Уэстоном (Wayland)

Я выполняю поиск с простым gst_element_seek на конвейере. Сначала я попытался дождаться, пока конвейер изменит состояние на PLAYING или PAUSED в шине, а затем выполнить поиск один раз. Это сработало, но на некоторых больших видео это привело к тому, что после запуска приложения первый видеокадр отображается на секунду, а затем видео фактически переходит на нужную позицию. Я не хочу этого, я хотел бы перейти туда, где я хочу, не показывая ничего другого раньше.

Поэтому я изменил свой метод поиска, чтобы он выполнялся еще до того, как я установил конвейер в состояние PLAYING, как this:

// seek if needed
  if(startTime > 0) {
      // First set pipeline to PAUSED and wait for async state change
      gst_element_set_state(m_pipeline, GST_STATE_PAUSED);
      gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
      if (!gst_element_seek (m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, startTime, GST_SEEK_TYPE_NONE, -1)) {
        g_print ("Seek failed!\n");
      }
      gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE); // wait for seek to finish and then set to PLAYING
  }
  m_ret = gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
  if (m_ret == GST_STATE_CHANGE_FAILURE) {
    g_printerr("Unable to set the pipeline to the playing state.\n");
    gst_object_unref(m_pipeline);
    exit(0);
  }

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

Как я могу убедиться, что ничего не отображается до тех пор, пока поиск фактически не будет выполнен?

Обновление Я не мог найти какой-либо метод поиска, чтобы работать так, как я хотел, но я достиг Эффект, установив show-preroll-frame на GstVideoSink перед построением конвейера, вот так:

m_sink = gst_element_factory_make("waylandsink", "sink");
g_object_set(m_sink, "show-preroll-frame", FALSE, NULL); // prevent preroll frame when seeking

И это работает! Я буду использовать это сейчас, если нет лучшего способа. Поиск все еще выполняется в состоянии PAUSED, но видео отображается непосредственно из точки поиска.

1 Ответ

0 голосов
/ 12 февраля 2020

Как указано в документации метода gst_element_seek_simple :

Некоторые элементы позволяют выполнять поиск в состоянии ГОТОВ ...

Это Значение true, если конвейер полностью предварительно проверен перед поиском. Тогда вы можете получить ожидаемый результат, показывая только те кадры, которые ожидаете.

 gst_element_set_state(m_pipeline, GST_STATE_READY);
 //make sure all the pipeline is prerolled (dynamic pads linked and other stuff)
 if (!gst_element_seek (m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, startTime, GST_SEEK_TYPE_NONE, -1)) {
    g_print ("Seek failed!\n");
  }
  gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
...