Merge branch 'upstream/1.16' into tizen_gst_1.16.2
[platform/upstream/gst-plugins-good.git] / gst / rtpmanager / gstrtpbin.c
index 8b68266..fbed414 100644 (file)
@@ -1,21 +1,21 @@
-/* GStreamer
- * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
+ /* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
 
 /**
  * SECTION:element-rtpbin
@@ -408,7 +408,9 @@ struct _GstRtpBinStream
   gulong buffer_ptreq_sig;
   gulong buffer_ntpstop_sig;
   gint percent;
-
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  gint prev_percent;
+#endif
   /* the PT demuxer of the SSRC */
   GstElement *demux;
   gulong demux_newpad_sig;
@@ -1690,6 +1692,9 @@ static GstRtpBinStream *
 create_stream (GstRtpBinSession * session, guint32 ssrc)
 {
   GstElement *buffer, *demux = NULL;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  GstElement *queue2 = NULL;
+#endif
   GstRtpBinStream *stream;
   GstRtpBin *rtpbin;
   GstState target;
@@ -1706,7 +1711,11 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
     if (!(demux = gst_element_factory_make ("rtpptdemux", NULL)))
       goto no_demux;
   }
-
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  if (session->bin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE)
+    if (!(queue2 = gst_element_factory_make ("queue2", NULL)))
+      goto no_queue2;
+#endif
   stream = g_new0 (GstRtpBinStream, 1);
   stream->ssrc = ssrc;
   stream->bin = rtpbin;
@@ -1718,6 +1727,9 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
   stream->rt_delta = 0;
   stream->rtp_delta = 0;
   stream->percent = 100;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  stream->prev_percent = 0;
+#endif
   stream->clock_base = -100 * GST_SECOND;
   session->streams = g_slist_prepend (session->streams, stream);
 
@@ -1744,6 +1756,14 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
   g_object_set (buffer, "max-ts-offset-adjustment",
       rtpbin->max_ts_offset_adjustment, NULL);
 
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  /* configure queue2 to use live buffering */
+  if (queue2) {
+    g_object_set_data (G_OBJECT (queue2), "GstRTPBin.stream", stream);
+    g_object_set (queue2, "use-buffering", TRUE, NULL);
+    g_object_set (queue2, "buffer-mode", GST_BUFFERING_LIVE, NULL);
+  }
+#endif
   /* need to sink the jitterbufer or otherwise signal handlers from bindings will
    * take ownership of it and we don't own it anymore */
   gst_object_ref_sink (buffer);
@@ -1752,6 +1772,12 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
 
   if (!rtpbin->ignore_pt)
     gst_bin_add (GST_BIN_CAST (rtpbin), demux);
+
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  if (queue2)
+    gst_bin_add (GST_BIN_CAST (rtpbin), queue2);
+#endif
+
   gst_bin_add (GST_BIN_CAST (rtpbin), buffer);
 
   /* unref the jitterbuffer again, the bin has a reference now and
@@ -1759,10 +1785,24 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
   gst_object_unref (buffer);
 
   /* link stuff */
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  if (queue2) {
+    gst_element_link_pads_full (buffer, "src", queue2, "sink",
+        GST_PAD_LINK_CHECK_NOTHING);
+    if (demux) {
+      gst_element_link_pads_full (queue2, "src", demux, "sink",
+          GST_PAD_LINK_CHECK_NOTHING);
+    }
+  } else if (demux) {
+    gst_element_link_pads_full (buffer, "src", demux, "sink",
+        GST_PAD_LINK_CHECK_NOTHING);
+  }
+#else
   if (demux)
     gst_element_link_pads_full (buffer, "src", demux, "sink",
         GST_PAD_LINK_CHECK_NOTHING);
 
+#endif
   if (rtpbin->buffering) {
     guint64 last_out;
 
@@ -1782,6 +1822,11 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
 
   gst_element_set_state (buffer, target);
 
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+  if (queue2)
+    gst_element_set_state (queue2, target);
+#endif
+
   return stream;
 
   /* ERRORS */
@@ -1802,6 +1847,15 @@ no_demux:
     g_warning ("rtpbin: could not create rtpptdemux element");
     return NULL;
   }
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+no_queue2:
+  {
+    gst_object_unref (buffer);
+    gst_object_unref (demux);
+    g_warning ("rtpbin: could not create queue2 element");
+    return NULL;
+  }
+#endif
 }
 
 /* called with RTP_BIN_LOCK */
@@ -3033,6 +3087,9 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
       gint min_percent = 100;
       GSList *sessions, *streams;
       GstRtpBinStream *stream;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+      gboolean buffering_flag = FALSE, update_buffering_status = TRUE;
+#endif
       gboolean change = FALSE, active = FALSE;
       GstClockTime min_out_time;
       GstBufferingMode mode;
@@ -3065,13 +3122,52 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
             for (streams = session->streams; streams;
                 streams = g_slist_next (streams)) {
               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
-
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+              GstPad *temp_pad_src = NULL;
+              GstCaps *temp_caps_src = NULL;
+              GstStructure *caps_structure;
+              const gchar *caps_str_media = NULL;
+              temp_pad_src = gst_element_get_static_pad (stream->buffer, "src");
+              temp_caps_src = gst_pad_get_current_caps (temp_pad_src);
+              GST_DEBUG_OBJECT (bin,
+                  "stream %p percent %d : temp_caps_src=%" GST_PTR_FORMAT,
+                  stream, stream->percent, temp_caps_src);
+              if (temp_caps_src) {
+                caps_structure = gst_caps_get_structure (temp_caps_src, 0);
+                caps_str_media =
+                    gst_structure_get_string (caps_structure, "media");
+                if (caps_str_media != NULL) {
+                  if ((strcmp (caps_str_media, "video") != 0)
+                      && (strcmp (caps_str_media, "audio") != 0)) {
+                    GST_DEBUG_OBJECT (bin,
+                        "Non Audio/Video Stream.. ignoring the same !!");
+                    gst_caps_unref (temp_caps_src);
+                    gst_object_unref (temp_pad_src);
+                    continue;
+                  } else if (stream->percent >= 100) {
+                    /* Most of the time buffering icon displays in rtsp playback.
+                       Optimizing the buffering updation code. Whenever any stream percentage
+                       reaches 100 do not post buffering messages. */
+                    if (stream->prev_percent < 100)
+                      buffering_flag = TRUE;
+                    else
+                      update_buffering_status = FALSE;
+                  }
+                }
+                gst_caps_unref (temp_caps_src);
+              }
+              gst_object_unref (temp_pad_src);
+#else
               GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream,
                   stream->percent);
-
+#endif
               /* find min percent */
               if (min_percent > stream->percent)
                 min_percent = stream->percent;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+              /* Updating prev stream percentage */
+              stream->prev_percent = stream->percent;
+#endif
             }
           } else {
             GST_INFO_OBJECT (bin,
@@ -3081,7 +3177,24 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
           GST_RTP_SESSION_UNLOCK (session);
         }
         GST_DEBUG_OBJECT (bin, "min percent %d", min_percent);
-
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+        if (rtpbin->buffer_mode != RTP_JITTER_BUFFER_MODE_SLAVE) {
+          if (rtpbin->buffering) {
+            if (min_percent == 100) {
+              rtpbin->buffering = FALSE;
+              active = TRUE;
+              change = TRUE;
+            }
+          } else {
+            if (min_percent < 100) {
+              /* pause the streams */
+              rtpbin->buffering = TRUE;
+              active = FALSE;
+              change = TRUE;
+            }
+          }
+        }
+#else
         if (rtpbin->buffering) {
           if (min_percent == 100) {
             rtpbin->buffering = FALSE;
@@ -3096,16 +3209,31 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
             change = TRUE;
           }
         }
+#endif
         GST_RTP_BIN_UNLOCK (rtpbin);
 
         gst_message_unref (message);
 
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+        if (rtpbin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE) {
+          if (update_buffering_status == FALSE)
+            break;
+          if (buffering_flag) {
+            min_percent = 100;
+            GST_DEBUG_OBJECT (bin, "forcefully change min_percent to 100!!!");
+          }
+        }
+#endif
         /* make a new buffering message with the min value */
         message =
             gst_message_new_buffering (GST_OBJECT_CAST (bin), min_percent);
         gst_message_set_buffering_stats (message, mode, avg_in, avg_out,
             buffering_left);
 
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+        if (rtpbin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE)
+          goto slave_buffering;
+#endif
         if (G_UNLIKELY (change)) {
           GstClock *clock;
           guint64 running_time = 0;
@@ -3183,6 +3311,9 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
           GST_RTP_BIN_UNLOCK (rtpbin);
         }
       }
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+slave_buffering:
+#endif
       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
       break;
     }