Сигнал конвейера Gstreamer для rtspclientsink - PullRequest
1 голос
/ 21 февраля 2020

Я давно пользуюсь gstreamer - я впечатлен тем, насколько хорошо он работает. Но недавно появилось требование изучить содержание запросов и ответов RTSP. Я думал, что я мог бы использовать функцию обратного вызова дескриптора запроса дескриптора rtspclientsink - поправьте меня, если я ошибаюсь. Но я не смог заставить работать обратный вызов вообще. Вот пример кода, с которым я играл. Любые идеи?

static void handle_request_callback (GstElement  rtsp_client_sink,
                         gpointer  request,
                         gpointer  response,
                         gpointer  udata)
{
    printf("here\n\r");
}

int main (int   argc,   char *argv[])
{
    GMainLoop *loop;
    GstElement *pipeline, *videosrc, *sink, *videofilter, *videoencoder, *encoderfilter, *h264parse;
    GstCaps *filtercaps;
    GstPad *pad;

    /* init GStreamer */
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    /* build */
    pipeline = gst_pipeline_new ("my-pipeline");
    videosrc = gst_element_factory_make ("v4l2src", "videosrc");
    if (videosrc == NULL)
        g_error ("Could not create 'v4l2src' element");

    videofilter = gst_element_factory_make ("capsfilter", "videofilter");
    g_assert (videofilter != NULL); /* should always exist */

    encoderfilter = gst_element_factory_make ("capsfilter", "encoderfilter");
    g_assert (encoderfilter != NULL); /* should always exist */

    h264parse = gst_element_factory_make ("h264parse", "parser");
    if (h264parse == NULL)
        g_error ("Could not create 'h264parse' element");

    videoencoder = gst_element_factory_make ("omxh264enc", "videoencoder");
    if (videoencoder == NULL)
        g_error ("Could not create 'omxh264enc' element");

    sink = gst_element_factory_make ("rtspclientsink", "sink");
    if (sink == NULL)
        g_error ("Could not create 'rtspclientsink' element");


    g_object_set(G_OBJECT(sink), "protocols", 0x00000004, NULL);
    g_object_set(G_OBJECT(sink), "latency", "100", NULL);
    g_object_set(G_OBJECT(sink), "location", "rtspt://192.169.1.2:1935/video", NULL);
    g_object_set(G_OBJECT(sink), "name", "rtspsink", NULL);
    //g_object_set(G_OBJECT(sink), "debug", true, NULL);


    gst_bin_add_many (GST_BIN (pipeline), videosrc, videofilter, videoencoder, h264parse, sink, NULL);
    gst_element_link_many (videosrc, videofilter, videoencoder, h264parse, sink, NULL);
    filtercaps = gst_caps_new_simple ("video/x-raw",
           "width", G_TYPE_INT, 1280,
           "height", G_TYPE_INT, 720,
           "framerate", GST_TYPE_FRACTION, 30, 1,
           NULL);
    g_object_set (G_OBJECT (videofilter), "caps", filtercaps, NULL);
    gst_caps_unref (filtercaps);

    filtercaps = gst_caps_new_simple ("video/x-h264",
           "width", G_TYPE_INT, 1280,
           "height", G_TYPE_INT, 720,
           "framerate", GST_TYPE_FRACTION, 30, 1,
           "profile", G_TYPE_STRING, "high",
           NULL);
    g_object_set (G_OBJECT (encoderfilter), "caps", filtercaps, NULL);
    gst_caps_unref (filtercaps);    

    gulong ret = g_signal_connect(sink, "handle-request", G_CALLBACK(handle_request_callback), sink);
    printf("%d\r\n", ret);

    /* run */
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    /* wait until it's up and running or failed */
    if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
        g_error ("Failed to go into PLAYING state");
    }

    g_print ("Running ...\n");
    g_main_loop_run (loop);

    /* exit */
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    return 0;
}

Вот информация rtspclientsink:

$ gst-inspect-1.0 rtspclientsink 
Factory Details:
  Rank                     none (0)
  Long-name                RTSP RECORD client
  Klass                    Sink/Network
  Description              Send data over the network via RTSP RECORD(RFC 2326)
  Author                   Jan Schmidt <jan@centricular.com>

Plugin Details:
  Name                     rtspclientsink
  Description              RTSP client sink element
  Filename                 /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/libgstrtspclientsink.so
  Version                  1.14.4
  License                  LGPL
  Source module            gst-rtsp-server
  Source release date      2018-10-02
  Binary package           GStreamer RTSP Server Library source release
  Origin URL               Unknown package origin

1 Ответ

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

Я понял это, посмотрев файл gstrtspclientsink. c (https://github.com/GStreamer/gst-rtsp-server/blob/master/tests/check/gst/rtspclientsink.c). Функция передачи сигнала для handle-request вызывается из части кода, предназначенной для работы в качестве сервера rtsp, в то время как rtspclientsink является клиентом RTSP, который начинает с отправки ANNOUNCE + sdp (вместо DESCRIBE).

В основном сигнал "handle-request" rtspclientsink работает только для запросов, исходящих с сервера. В контексте RTSP ANNOUNCE, когда первоначальный запрос генерируется на устройстве, производящем мультимедийный контент, этот сигнал никогда не будет запущен. обработка логик c команд RTSP, чтобы позволить манипулировать запросами RTSP и отслеживать ответы RTSP.

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