Merge branch 'upstream/1.19' into tizen_gst_1.19.2
authorHyunsoo Park <hance.park@samsung.com>
Wed, 19 Jan 2022 08:45:53 +0000 (17:45 +0900)
committerHyunsoo Park <hance.park@samsung.com>
Mon, 24 Jan 2022 03:59:09 +0000 (12:59 +0900)
Change-Id: I15fb3b678d79b5210e01a5b21b5ddf02c3e5ddab

15 files changed:
1  2 
NEWS
gst-rtsp-server.doap
gst/rtsp-server/meson.build
gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-client.h
gst/rtsp-server/rtsp-media-factory-uri.c
gst/rtsp-server/rtsp-media.c
gst/rtsp-server/rtsp-media.h
gst/rtsp-server/rtsp-server-object.h
gst/rtsp-server/rtsp-server.c
gst/rtsp-server/rtsp-stream.c
gst/rtsp-server/rtsp-stream.h
gst/rtsp-sink/gstrtspclientsink.c
packaging/gst-rtsp-server.manifest
packaging/gst-rtsp-server.spec

diff --cc NEWS
index 98dc512,0e581c3..0e581c3
mode 100755,100644..100755
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
Simple merge
@@@ -23,6 -23,6 +23,13 @@@ rtsp_server_sources = 
    'rtsp-onvif-client.c',
    'rtsp-onvif-media-factory.c',
    'rtsp-onvif-media.c',
++  'rtsp-media-ext.c',
++  'rtsp-media-factory-wfd.c',
++  'gstwfdmessage-ext.c',
++  'gstwfdmessage.c',
++  'rtsp-client-ext.c',
++  'rtsp-client-wfd.c',
++  'rtsp-server-wfd.c',
  ]
  
  rtsp_server_headers = [
    'rtsp-onvif-client.h',
    'rtsp-onvif-media-factory.h',
    'rtsp-onvif-media.h',
++  'rtsp-media-ext.h',
++  'rtsp-media-factory-wfd.h',
++  'gstwfdmessage-ext.h',
++  'gstwfdmessage.h',
++  'rtsp-client-ext.h',
++  'rtsp-client-wfd.h',
++  'rtsp-server-wfd.h',
  ]
  
  install_headers(rtsp_server_headers, subdir : 'gstreamer-1.0/gst/rtsp-server')
@@@ -1741,8 -1833,212 +1847,212 @@@ make_base_url (GstRTSPClient * client, 
    return result;
  }
  
+ /* Check if the given header of type double is present and, if so,
+  * put it's value in the supplied variable.
+  */
+ static GstRTSPStatusCode
+ parse_header_value_double (GstRTSPClient * client, GstRTSPContext * ctx,
+     GstRTSPHeaderField header, gboolean * present, gdouble * value)
+ {
+   GstRTSPResult res;
+   gchar *str;
+   gchar *end;
+   res = gst_rtsp_message_get_header (ctx->request, header, &str, 0);
+   if (res == GST_RTSP_OK) {
+     *value = g_ascii_strtod (str, &end);
+     if (end == str)
+       goto parse_header_failed;
+     GST_DEBUG ("client %p: got '%s', value %f", client,
+         gst_rtsp_header_as_text (header), *value);
+     *present = TRUE;
+   } else {
+     *present = FALSE;
+   }
+   return GST_RTSP_STS_OK;
+ parse_header_failed:
+   {
+     GST_ERROR ("client %p: failed parsing '%s' header", client,
+         gst_rtsp_header_as_text (header));
+     return GST_RTSP_STS_BAD_REQUEST;
+   }
+ }
+ /* Parse scale and speed headers, if present, and set the rate to
+  * (rate * scale * speed) */
+ static GstRTSPStatusCode
+ parse_scale_and_speed (GstRTSPClient * client, GstRTSPContext * ctx,
+     gboolean * scale_present, gboolean * speed_present, gdouble * rate,
+     GstSeekFlags * flags)
+ {
+   gdouble scale = 1.0;
+   gdouble speed = 1.0;
+   GstRTSPStatusCode status;
+   GST_DEBUG ("got rate %f", *rate);
+   status = parse_header_value_double (client, ctx, GST_RTSP_HDR_SCALE,
+       scale_present, &scale);
+   if (status != GST_RTSP_STS_OK)
+     return status;
+   if (*scale_present) {
+     GST_DEBUG ("got Scale %f", scale);
+     if (scale == 0)
+       goto bad_scale_value;
+     *rate *= scale;
+     if (ABS (scale) != 1.0)
+       *flags |= GST_SEEK_FLAG_TRICKMODE;
+   }
+   GST_DEBUG ("rate after parsing Scale %f", *rate);
+   status = parse_header_value_double (client, ctx, GST_RTSP_HDR_SPEED,
+       speed_present, &speed);
+   if (status != GST_RTSP_STS_OK)
+     return status;
+   if (*speed_present) {
+     GST_DEBUG ("got Speed %f", speed);
+     if (speed <= 0)
+       goto bad_speed_value;
+     *rate *= speed;
+   }
+   GST_DEBUG ("rate after parsing Speed %f", *rate);
+   return status;
+ bad_scale_value:
+   {
+     GST_ERROR ("client %p: bad 'Scale' header value (%f)", client, scale);
+     return GST_RTSP_STS_BAD_REQUEST;
+   }
+ bad_speed_value:
+   {
+     GST_ERROR ("client %p: bad 'Speed' header value (%f)", client, speed);
+     return GST_RTSP_STS_BAD_REQUEST;
+   }
+ }
+ static GstRTSPStatusCode
+ setup_play_mode (GstRTSPClient * client, GstRTSPContext * ctx,
+     GstRTSPRangeUnit * unit, gboolean * scale_present, gboolean * speed_present)
+ {
+   gchar *str;
+   GstRTSPResult res;
+   GstRTSPTimeRange *range = NULL;
+   gdouble rate = 1.0;
+   GstSeekFlags flags = GST_SEEK_FLAG_NONE;
+   GstRTSPClientClass *klass = GST_RTSP_CLIENT_GET_CLASS (client);
+   GstRTSPStatusCode rtsp_status_code;
+   GstClockTime trickmode_interval = 0;
+   gboolean enable_rate_control = TRUE;
+   /* parse the range header if we have one */
+   res = gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_RANGE, &str, 0);
+   if (res == GST_RTSP_OK) {
+     gchar *seek_style = NULL;
+     res = gst_rtsp_range_parse (str, &range);
+     if (res != GST_RTSP_OK)
+       goto parse_range_failed;
+     *unit = range->unit;
+     /* parse seek style header, if present */
+     res = gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_SEEK_STYLE,
+         &seek_style, 0);
+     if (res == GST_RTSP_OK) {
+       if (g_strcmp0 (seek_style, "RAP") == 0)
+         flags = GST_SEEK_FLAG_ACCURATE;
+       else if (g_strcmp0 (seek_style, "CoRAP") == 0)
+         flags = GST_SEEK_FLAG_KEY_UNIT;
+       else if (g_strcmp0 (seek_style, "First-Prior") == 0)
+         flags = GST_SEEK_FLAG_KEY_UNIT & GST_SEEK_FLAG_SNAP_BEFORE;
+       else if (g_strcmp0 (seek_style, "Next") == 0)
+         flags = GST_SEEK_FLAG_KEY_UNIT & GST_SEEK_FLAG_SNAP_AFTER;
+       else
+         GST_FIXME_OBJECT (client, "Add support for seek style %s", seek_style);
+     } else if (range->min.type == GST_RTSP_TIME_END) {
+       flags = GST_SEEK_FLAG_ACCURATE;
+     } else {
+       flags = GST_SEEK_FLAG_KEY_UNIT;
+     }
+     if (seek_style)
+       gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_SEEK_STYLE,
+           seek_style);
+   } else {
+     flags = GST_SEEK_FLAG_ACCURATE;
+   }
+   /* check for scale and/or speed headers
+    * we will set the seek rate to (speed * scale) and let the media decide
+    * the resulting scale and speed. in the response we will use rate and applied
+    * rate from the resulting segment as values for the speed and scale headers
+    * respectively */
+   rtsp_status_code = parse_scale_and_speed (client, ctx, scale_present,
+       speed_present, &rate, &flags);
+   if (rtsp_status_code != GST_RTSP_STS_OK)
+     goto scale_speed_failed;
+   /* give the application a chance to tweak range, flags, or rate */
+   if (klass->adjust_play_mode != NULL) {
+     rtsp_status_code =
+         klass->adjust_play_mode (client, ctx, &range, &flags, &rate,
+         &trickmode_interval, &enable_rate_control);
+     if (rtsp_status_code != GST_RTSP_STS_OK)
+       goto adjust_play_mode_failed;
+   }
+   gst_rtsp_media_set_rate_control (ctx->media, enable_rate_control);
+   /* now do the seek with the seek options */
+   gst_rtsp_media_seek_trickmode (ctx->media, range, flags, rate,
+       trickmode_interval);
+   if (range != NULL)
+     gst_rtsp_range_free (range);
+   if (gst_rtsp_media_get_status (ctx->media) == GST_RTSP_MEDIA_STATUS_ERROR)
+     goto seek_failed;
+   return GST_RTSP_STS_OK;
+ parse_range_failed:
+   {
+     GST_ERROR ("client %p: failed parsing range header", client);
+     return GST_RTSP_STS_BAD_REQUEST;
+   }
+ scale_speed_failed:
+   {
+     if (range != NULL)
+       gst_rtsp_range_free (range);
+     GST_ERROR ("client %p: failed parsing Scale or Speed headers", client);
+     return rtsp_status_code;
+   }
+ adjust_play_mode_failed:
+   {
+     GST_ERROR ("client %p: sub class returned bad code (%d)", client,
+         rtsp_status_code);
+     if (range != NULL)
+       gst_rtsp_range_free (range);
+     return rtsp_status_code;
+   }
+ seek_failed:
+   {
+     GST_ERROR ("client %p: seek failed", client);
+     return GST_RTSP_STS_SERVICE_UNAVAILABLE;
+   }
+ }
  static gboolean
 -handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
 +default_handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
  {
    GstRTSPSession *session;
    GstRTSPClientClass *klass;
@@@ -125,10 -131,15 +131,19 @@@ struct _GstRTSPClientClass 
    GstRTSPResult   (*params_set) (GstRTSPClient *client, GstRTSPContext *ctx);
    GstRTSPResult   (*params_get) (GstRTSPClient *client, GstRTSPContext *ctx);
    gchar *         (*make_path_from_uri) (GstRTSPClient *client, const GstRTSPUrl *uri);
 +  gboolean        (*handle_options_request) (GstRTSPClient * client, GstRTSPContext * ctx, GstRTSPVersion version);
 +  gboolean        (*handle_set_param_request) (GstRTSPClient * client, GstRTSPContext * ctx);
 +  gboolean        (*handle_get_param_request) (GstRTSPClient * client, GstRTSPContext * ctx);
 +  gboolean        (*handle_play_request) (GstRTSPClient * client, GstRTSPContext * ctx);
+   GstRTSPStatusCode (*adjust_play_mode) (GstRTSPClient * client,
+                                          GstRTSPContext * context,
+                                          GstRTSPTimeRange ** range,
+                                          GstSeekFlags * flags,
+                                          gdouble * rate,
+                                          GstClockTime * trickmode_interval,
+                                          gboolean * enable_rate_control);
+   GstRTSPStatusCode (*adjust_play_response) (GstRTSPClient * client,
+                                             GstRTSPContext * context);
  
    /* signals */
    void     (*closed)                  (GstRTSPClient *client);
@@@ -433,21 -448,9 +452,21 @@@ gst_rtsp_media_class_init (GstRTSPMedia
  
    gst_rtsp_media_signals[SIGNAL_NEW_STATE] =
        g_signal_new ("new-state", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-       G_STRUCT_OFFSET (GstRTSPMediaClass, new_state), NULL, NULL,
-       g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_INT);
+       G_STRUCT_OFFSET (GstRTSPMediaClass, new_state), NULL, NULL, NULL,
+       G_TYPE_NONE, 1, G_TYPE_INT);
  
 +  gst_rtsp_media_signals[SIGNAL_PREPARING] =
 +      g_signal_new ("preparing", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
 +      G_STRUCT_OFFSET (GstRTSPMediaClass, preparing), NULL, NULL,
 +      g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_RTSP_STREAM,
 +      G_TYPE_UINT);
 +
 +  gst_rtsp_media_signals[SIGNAL_UNPREPARING] =
 +      g_signal_new ("unpreparing", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
 +      G_STRUCT_OFFSET (GstRTSPMediaClass, unpreparing), NULL, NULL,
 +      g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_RTSP_STREAM,
 +      G_TYPE_UINT);
 +
    GST_DEBUG_CATEGORY_INIT (rtsp_media_debug, "rtspmedia", 0, "GstRTSPMedia");
  
    klass->handle_message = default_handle_message;
@@@ -2614,27 -2776,12 +2794,12 @@@ media_streams_set_blocked (GstRTSPMedi
    GST_DEBUG ("media %p set blocked %d", media, blocked);
    priv->blocked = blocked;
    g_ptr_array_foreach (priv->streams, (GFunc) stream_update_blocked, media);
- }
  
- static void
- stream_unblock (GstRTSPStream * stream, GstRTSPMedia * media)
- {
-   gst_rtsp_stream_unblock_linked (stream);
- }
- static void
- media_unblock_linked (GstRTSPMedia * media)
- {
-   GstRTSPMediaPrivate *priv = media->priv;
-   GST_DEBUG ("media %p unblocking linked streams", media);
-   /* media is not blocked any longer, as it contains active streams,
-    * streams that are complete */
-   priv->blocked = FALSE;
-   g_ptr_array_foreach (priv->streams, (GFunc) stream_unblock, media);
+   if (!blocked)
+     priv->blocking_msg_received = 0;
  }
  
 -static void
 +void
  gst_rtsp_media_set_status (GstRTSPMedia * media, GstRTSPMediaStatus status)
  {
    GstRTSPMediaPrivate *priv = media->priv;
@@@ -3377,19 -3672,10 +3699,11 @@@ request_fec_decoder (GstElement * rtpbi
    return res;
  }
  
- static void
- new_storage_cb (GstElement * rtpbin, GObject * storage, guint sessid,
-     GstRTSPMedia * media)
- {
-   g_object_set (storage, "size-time", (media->priv->latency + 50) * GST_MSECOND,
-       NULL);
- }
  static gboolean
 -start_prepare (GstRTSPMedia * media)
 +default_start_prepare (GstRTSPMedia * media)
  {
    GstRTSPMediaPrivate *priv = media->priv;
 +  GstRTSPMediaClass *klass;
    guint i;
    GList *walk;
  
@@@ -4312,11 -4652,11 +4692,12 @@@ default_unsuspend (GstRTSPMedia * media
        gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
        /* at this point the media pipeline has been updated and contain all
         * specific transport parts: all active streams contain at least one sink
-        * element and it's safe to unblock any blocked streams that are active */
-       media_unblock_linked (media);
-       if (klass->start_preroll)
+        * element and it's safe to unblock all blocked streams */
+       media_streams_set_blocked (media, FALSE);
 -      if (!start_preroll (media))
 -        goto start_failed;
++       if (klass->start_preroll)
 +        if (!klass->start_preroll (media))
 +          goto start_failed;
        g_rec_mutex_unlock (&priv->state_lock);
        preroll_ok = wait_preroll (media);
        g_rec_mutex_lock (&priv->state_lock);
@@@ -4395,7 -4753,13 +4794,13 @@@ media_set_pipeline_state_locked (GstRTS
      gst_rtsp_media_unprepare (media);
    } else {
      GST_INFO ("state %s media %p", gst_element_state_get_name (state), media);
 -    set_target_state (media, state, FALSE);
 +    gst_rtsp_media_set_target_state (media, state, FALSE);
+     if (state == GST_STATE_PLAYING) {
+       /* make sure pads are not blocking anymore when going to PLAYING */
+       media_streams_set_blocked (media, FALSE);
+     }
      /* when we are buffering, don't update the state yet, this will be done
       * when buffering finishes */
      if (priv->buffering) {
@@@ -4728,35 -5108,88 +5149,121 @@@ gst_rtsp_media_is_receive_only (GstRTSP
    return receive_only;
  }
  
+ /**
+  * gst_rtsp_media_has_completed_sender:
+  *
+  * See gst_rtsp_stream_is_complete(), gst_rtsp_stream_is_sender().
+  *
+  * Returns: whether @media has at least one complete sender stream.
+  * Since: 1.18
+  */
+ gboolean
+ gst_rtsp_media_has_completed_sender (GstRTSPMedia * media)
+ {
+   GstRTSPMediaPrivate *priv = media->priv;
+   gboolean sender = FALSE;
+   guint i;
+   g_mutex_lock (&priv->lock);
+   for (i = 0; i < priv->streams->len; i++) {
+     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
+     if (gst_rtsp_stream_is_complete (stream))
+       if (gst_rtsp_stream_is_sender (stream) ||
+           !gst_rtsp_stream_is_receiver (stream)) {
+         sender = TRUE;
+         break;
+       }
+   }
+   g_mutex_unlock (&priv->lock);
+   return sender;
+ }
+ /**
+  * gst_rtsp_media_set_rate_control:
+  *
+  * Define whether @media will follow the Rate-Control=no behaviour as specified
+  * in the ONVIF replay spec.
+  *
+  * Since: 1.18
+  */
+ void
+ gst_rtsp_media_set_rate_control (GstRTSPMedia * media, gboolean enabled)
+ {
+   GstRTSPMediaPrivate *priv;
+   guint i;
+   g_return_if_fail (GST_IS_RTSP_MEDIA (media));
+   GST_LOG_OBJECT (media, "%s rate control", enabled ? "Enabling" : "Disabling");
+   priv = media->priv;
+   g_mutex_lock (&priv->lock);
+   priv->do_rate_control = enabled;
+   for (i = 0; i < priv->streams->len; i++) {
+     GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
+     gst_rtsp_stream_set_rate_control (stream, enabled);
+   }
+   g_mutex_unlock (&priv->lock);
+ }
+ /**
+  * gst_rtsp_media_get_rate_control:
+  *
+  * Returns: whether @media will follow the Rate-Control=no behaviour as specified
+  * in the ONVIF replay spec.
+  *
+  * Since: 1.18
+  */
+ gboolean
+ gst_rtsp_media_get_rate_control (GstRTSPMedia * media)
+ {
+   GstRTSPMediaPrivate *priv;
+   gboolean res;
+   g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
+   priv = media->priv;
+   g_mutex_lock (&priv->lock);
+   res = priv->do_rate_control;
+   g_mutex_unlock (&priv->lock);
+   return res;
+ }
++
 +GstElement *
 +gst_rtsp_media_get_pipeline (GstRTSPMedia * media)
 +{
 +  GstRTSPMediaPrivate *priv;
 +
 +  g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
 +
 +  priv = media->priv;
 +
 +  g_mutex_lock (&priv->lock);
 +  g_object_ref (priv->pipeline);
 +  g_mutex_unlock (&priv->lock);
 +
 +  return priv->pipeline;
 +}
 +
 +
 +GstElement *
 +gst_rtsp_media_get_rtpbin (GstRTSPMedia * media)
 +{
 +  GstRTSPMediaPrivate *priv;
 +
 +  g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
 +
 +  priv = media->priv;
 +
 +  g_mutex_lock (&priv->lock);
 +  g_object_ref (priv->rtpbin);
 +  g_mutex_unlock (&priv->lock);
 +
 +  return priv->rtpbin;
 +}
@@@ -408,20 -426,20 +430,32 @@@ void                  gst_rtsp_media_se
                                                           GstState state);
  
  GST_RTSP_SERVER_API
 +GstStateChangeReturn  gst_rtsp_media_set_target_state (GstRTSPMedia * media, GstState state, gboolean do_state);
 +
 +GST_RTSP_SERVER_API
 +void                  gst_rtsp_media_set_status (GstRTSPMedia * media, GstRTSPMediaStatus status);
 +
 +GST_RTSP_SERVER_API
 +GstElement *          gst_rtsp_media_get_pipeline     (GstRTSPMedia * media);
 +
 +GST_RTSP_SERVER_API
 +GstElement *          gst_rtsp_media_get_rtpbin       (GstRTSPMedia * media);
 +
 +GST_RTSP_SERVER_API
  gboolean              gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports);
  
+ GST_RTSP_SERVER_API
+ gboolean              gst_rtsp_media_is_receive_only (GstRTSPMedia * media);
+ GST_RTSP_SERVER_API
+ gboolean              gst_rtsp_media_has_completed_sender (GstRTSPMedia * media);
+ GST_RTSP_SERVER_API
+ void                  gst_rtsp_media_set_rate_control (GstRTSPMedia * media, gboolean enabled);
+ GST_RTSP_SERVER_API
+ gboolean              gst_rtsp_media_get_rate_control (GstRTSPMedia * media);
  #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
  G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstRTSPMedia, gst_object_unref)
  #endif
Simple merge
@@@ -226,11 -243,9 +243,10 @@@ gst_rtsp_server_class_init (GstRTSPServ
    gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED] =
        g_signal_new ("client-connected", G_TYPE_FROM_CLASS (gobject_class),
        G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPServerClass, client_connected),
-       NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
-       GST_TYPE_RTSP_CLIENT);
+       NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_RTSP_CLIENT);
  
    klass->create_client = default_create_client;
 +  klass->create_socket = gst_rtsp_server_create_socket;
  
    GST_DEBUG_CATEGORY_INIT (rtsp_server_debug, "rtspserver", 0, "GstRTSPServer");
  }
@@@ -267,14 -314,8 +315,13 @@@ gst_rtsp_stream_class_init (GstRTSPStre
  
    gst_rtsp_stream_signals[SIGNAL_NEW_RTP_RTCP_DECODER] =
        g_signal_new ("new-rtp-rtcp-decoder", G_TYPE_FROM_CLASS (klass),
-       G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
-       G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
  
 +  gst_rtsp_stream_signals[SIGNAL_RTCP_STATS] =
 +      g_signal_new ("rtcp-statistics", G_TYPE_FROM_CLASS (klass),
 +      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
 +      G_TYPE_NONE, 1, GST_TYPE_STRUCTURE);
 +
    GST_DEBUG_CATEGORY_INIT (rtsp_stream_debug, "rtspstream", 0, "GstRTSPStream");
  
    ssrc_stream_map_key = g_quark_from_static_string ("GstRTSPServer.stream");
Simple merge
Simple merge
index a76fdba,0000000..a76fdba
mode 100644,000000..100644
--- /dev/null
index d1b9d12,0000000..3c1e450
mode 100644,000000..100644
--- /dev/null
@@@ -1,76 -1,0 +1,80 @@@
- Version:    1.16.2
- Release:    9
 +Name:       gst-rtsp-server
 +Summary:    Multimedia Framework Library
- Source100:  common.tar.bz2
++Version:    1.19.2
++Release:    0
 +Url:        http://gstreamer.freedesktop.org/
 +Group:      System/Libraries
 +License:    LGPL-2.0+
 +Source:     http://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-%{version}.tar.xz
- BuildRequires:  pkgconfig(gstreamer-1.0)
- BuildRequires:  pkgconfig(gstreamer-plugins-base-1.0)
++Source1001: %{name}.manifest
 +Requires(post):  /sbin/ldconfig
 +Requires(postun):  /sbin/ldconfig
- %setup -q -T -D -a 100
++#BuildRequires:  pkgconfig(gstreamer-1.0)
++#BuildRequires:  pkgconfig(gstreamer-plugins-base-1.0)
++BuildRequires:  gstreamer-devel >= %{version}
++BuildRequires:  gst-plugins-base-devel >= %{version}
++BuildRequires:  meson >= 0.48.0
 +
 +BuildRoot:  %{_tmppath}/%{name}-%{version}-build
 +
 +%description
 +
 +%package devel
 +Summary:    Multimedia Framework RTSP server library (DEV)
 +Group:      Development/Libraries
 +Requires:   %{name} = %{version}-%{release}
 +
 +%description devel
 +
 +%package factory
 +Summary:    Multimedia Framework RTSP server Library (Factory)
 +Group:      Development/Libraries
 +Requires:   %{name} = %{version}-%{release}
 +
 +%description factory
 +
 +%prep
 +%setup -q -n gst-rtsp-server-%{version}
- NOCONFIGURE=1 ./autogen.sh
++cp %{SOURCE1001} .
 +
 +%build
- %configure --disable-static --disable-examples
++mkdir -p build
 +
 +CFLAGS+=" -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS
 +LDFLAGS+="-Wl,--rpath=%{_prefix}/lib -Wl,--hash-style=both -Wl,--as-needed"; export LDFLAGS
 +
 +# always enable sdk build. This option should go away
 +# disable build examples.
- make %{?jobs:-j%jobs}
++export CXXFLAGS+=" -Wno-error"
++
++meson --prefix=/usr --libdir=%{_libdir} --datadir=%{_datadir} build
 +
 +# Call make instruction with smp support
- rm -rf %{buildroot}
- %make_install
++ninja -C build all %{?jobs:-j%jobs}
 +
 +%install
- %manifest gst-rtsp-server.manifest
++export DESTDIR=%{buildroot}
++ninja -C build install
 +
 +%clean
 +rm -rf %{buildroot}
 +
 +%post
 +/sbin/ldconfig
 +
 +%postun
 +/sbin/ldconfig
 +
 +%files
++%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%license COPYING
 +%{_libdir}/*.so.*
 +%{_libdir}/gstreamer-1.0/libgstrtspclientsink.so
 +
 +%files devel
 +%defattr(-,root,root,-)
 +%{_libdir}/*.so
 +%{_includedir}/gstreamer-1.0/gst/rtsp-server/rtsp-*.h
 +%{_includedir}/gstreamer-1.0/gst/rtsp-server/gstwfd*.h
 +%{_libdir}/pkgconfig/*