簡體   English   中英

將管道設置為播放狀態后,Gstreamer的回叫沒有發生

[英]Gstreamer call backs are not hitting after setting pipeline to playing state

我正在編寫一個媒體應用程序,以從視頻文件中捕獲視頻幀。 為此,我想在從管道中提取樣本之前獲取視頻屬性。 因此,我在解碼器上添加了一個用於auto-plug信號的回調,並嘗試獲取屬性。 即使將管道置於播放狀態,也不會調用這些回調,但是如果我嘗試使用gst_app_sink_pull_sample從管道中提取樣本,則會調用這些gst_app_sink_pull_sample

我在這里想念什么嗎? 我的理解是,當我們將管道置於播放狀態時,將調用這些回調。

#include <gst/gst.h>
#include <stdio.h>

static void bus_callback (GstBus *bus, GstMessage *msg, gpointer data) 
{

  switch (GST_MESSAGE_TYPE (msg)) 
  {
    case GST_MESSAGE_ERROR: {
                  GError *err;
                  gchar *debug;
                  gst_message_parse_error (msg, &err, &debug);
                  g_print ("Error: %s\n", err->message);
                  g_error_free (err);
                  g_free (debug);
                  break;
                }
    default:
                /* Unhandled message */
                break;
  }
}

static void 
on_pad_added (GstElement *element, GstPad *pad, gpointer data)
{
  GstPad *sinkpad;
  GstElement *decoder = (GstElement *) data;

  /* We can now link this pad with the decoder sink pad */
  sinkpad           =  gst_element_get_static_pad (decoder, "sink");
  gst_pad_link (pad, sinkpad);
  gst_object_unref (sinkpad);
}

static void
auto_plug_select (GstElement *decoder, GstPad *pad, GstCaps *caps,
    GstElementFactory *factory, int *width )
{
  const gchar *klass   =  gst_element_factory_get_klass (factory);
/*  MW_customData *cdata =  (MW_customData*) data;*/
  GstCaps *scaps       =  gst_pad_query_caps (pad, NULL);
  GstStructure *str    =  gst_caps_get_structure (scaps, 0);
  const gchar *type    =  gst_structure_get_name (str);
  printf (" Pad cap: %s\n", type);

  if (g_strrstr(type,"video"))
  {
   gst_structure_get_int (str, "width", width);
   printf(" Width: %d\n", *width);
  }
}

int main (gint   argc,
      gchar *argv[])
{
  GstElement *pipeline, *filesrc, *decoder, *fakesink;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);

  /* check args */
  if (argc != 2) {
    g_print ("Usage: %s <filename>\n", argv[0]);
    return -1;
  }

  /* create a new pipeline to hold the elements */
  pipeline = gst_pipeline_new ("pipeline");

  /* Bus call back*/
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, bus_callback, NULL);
  gst_object_unref (bus);

  /* create file source and typefind element */
  filesrc = gst_element_factory_make ("filesrc", "source");
  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
  decoder = gst_element_factory_make ("decodebin", NULL);
  fakesink = gst_element_factory_make ("fakesink", "sink");

  int width = 0;
/* Connect the sink pad when decoder completes the operation */
  g_signal_connect (decoder, "pad-added", G_CALLBACK (on_pad_added), &width);
  g_signal_connect (decoder, "autoplug-select", G_CALLBACK (auto_plug_select), fakesink);

  /* setup */
  gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, fakesink, NULL);
  gst_element_link (filesrc, decoder);
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  printf(" Width: %d\n", width);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);

  return 0;
}

您無需隨時離開管道即可運行。 您可能在數據可以觸發解碼器的回調之前將其停止。

對於便宜的嘗試:

gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

g_usleep(100000000);

printf(" Width: %d\n", width);

gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);

但是更正確的方法是使用真實的GMainLoop並在特定事件上采取行動以再次停止管道。

編輯:PS為什么不GstDiscoverer https://gstreamer.freedesktop.org/documentation/pbutils/gstdiscoverer.html?gi-language=c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM