gst_plugins_base/gst-libs/gst/rtp/gstbasertppayload.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
15:4b0c6ed43234 16:8e837d1bf446
    43 {
    43 {
    44   gboolean ts_offset_random;
    44   gboolean ts_offset_random;
    45   gboolean seqnum_offset_random;
    45   gboolean seqnum_offset_random;
    46   gboolean ssrc_random;
    46   gboolean ssrc_random;
    47   guint16 next_seqnum;
    47   guint16 next_seqnum;
    48 
       
    49   GstClockTime rt_base;
       
    50 };
    48 };
    51 
    49 
    52 /* BaseRTPPayload signals and args */
    50 /* BaseRTPPayload signals and args */
    53 enum
    51 enum
    54 {
    52 {
    88 static void gst_basertppayload_base_init (GstBaseRTPPayloadClass * klass);
    86 static void gst_basertppayload_base_init (GstBaseRTPPayloadClass * klass);
    89 static void gst_basertppayload_init (GstBaseRTPPayload * basertppayload,
    87 static void gst_basertppayload_init (GstBaseRTPPayload * basertppayload,
    90     gpointer g_class);
    88     gpointer g_class);
    91 static void gst_basertppayload_finalize (GObject * object);
    89 static void gst_basertppayload_finalize (GObject * object);
    92 
    90 
    93 static gboolean gst_basertppayload_setcaps (GstPad * pad, GstCaps * caps);
    91 static gboolean gst_basertppayload_sink_setcaps (GstPad * pad, GstCaps * caps);
    94 static GstCaps *gst_basertppayload_getcaps (GstPad * pad);
    92 static GstCaps *gst_basertppayload_sink_getcaps (GstPad * pad);
    95 static gboolean gst_basertppayload_event (GstPad * pad, GstEvent * event);
    93 static gboolean gst_basertppayload_event (GstPad * pad, GstEvent * event);
    96 static GstFlowReturn gst_basertppayload_chain (GstPad * pad,
    94 static GstFlowReturn gst_basertppayload_chain (GstPad * pad,
    97     GstBuffer * buffer);
    95     GstBuffer * buffer);
    98 
    96 
    99 static void gst_basertppayload_set_property (GObject * object, guint prop_id,
    97 static void gst_basertppayload_set_property (GObject * object, guint prop_id,
   161   gobject_class->get_property = gst_basertppayload_get_property;
   159   gobject_class->get_property = gst_basertppayload_get_property;
   162 
   160 
   163   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
   161   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
   164       g_param_spec_uint ("mtu", "MTU",
   162       g_param_spec_uint ("mtu", "MTU",
   165           "Maximum size of one packet",
   163           "Maximum size of one packet",
   166           28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
   164           28, G_MAXUINT, DEFAULT_MTU,
       
   165           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   167   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
   166   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
   168       g_param_spec_uint ("pt", "payload type",
   167       g_param_spec_uint ("pt", "payload type",
   169           "The payload type of the packets",
   168           "The payload type of the packets", 0, 0x80, DEFAULT_PT,
   170           0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
   169           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   171   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
   170   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
   172       g_param_spec_uint ("ssrc", "SSRC",
   171       g_param_spec_uint ("ssrc", "SSRC",
   173           "The SSRC of the packets (default == random)",
   172           "The SSRC of the packets (default == random)", 0, G_MAXUINT32,
   174           0, G_MAXUINT32, DEFAULT_SSRC, G_PARAM_READWRITE));
   173           DEFAULT_SSRC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   175   g_object_class_install_property (G_OBJECT_CLASS (klass),
   174   g_object_class_install_property (G_OBJECT_CLASS (klass),
   176       PROP_TIMESTAMP_OFFSET, g_param_spec_uint ("timestamp-offset",
   175       PROP_TIMESTAMP_OFFSET, g_param_spec_uint ("timestamp-offset",
   177           "Timestamp Offset",
   176           "Timestamp Offset",
   178           "Offset to add to all outgoing timestamps (default = random)", 0,
   177           "Offset to add to all outgoing timestamps (default = random)", 0,
   179           G_MAXUINT32, DEFAULT_TIMESTAMP_OFFSET, G_PARAM_READWRITE));
   178           G_MAXUINT32, DEFAULT_TIMESTAMP_OFFSET,
       
   179           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   180   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM_OFFSET,
   180   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM_OFFSET,
   181       g_param_spec_int ("seqnum-offset", "Sequence number Offset",
   181       g_param_spec_int ("seqnum-offset", "Sequence number Offset",
   182           "Offset to add to all outgoing seqnum (-1 = random)", -1, G_MAXUINT16,
   182           "Offset to add to all outgoing seqnum (-1 = random)", -1, G_MAXUINT16,
   183           DEFAULT_SEQNUM_OFFSET, G_PARAM_READWRITE));
   183           DEFAULT_SEQNUM_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   184   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_PTIME,
   184   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_PTIME,
   185       g_param_spec_int64 ("max-ptime", "Max packet time",
   185       g_param_spec_int64 ("max-ptime", "Max packet time",
   186           "Maximum duration of the packet data in ns (-1 = unlimited up to MTU)",
   186           "Maximum duration of the packet data in ns (-1 = unlimited up to MTU)",
   187           -1, G_MAXINT64, DEFAULT_MAX_PTIME, G_PARAM_READWRITE));
   187           -1, G_MAXINT64, DEFAULT_MAX_PTIME,
       
   188           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   188   /**
   189   /**
   189    * GstBaseRTPAudioPayload:min-ptime:
   190    * GstBaseRTPAudioPayload:min-ptime:
   190    *
   191    *
   191    * Minimum duration of the packet data in ns (can't go above MTU)
   192    * Minimum duration of the packet data in ns (can't go above MTU)
   192    *
   193    *
   193    * Since: 0.10.13
   194    * Since: 0.10.13
   194    **/
   195    **/
   195   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MIN_PTIME,
   196   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MIN_PTIME,
   196       g_param_spec_int64 ("min-ptime", "Min packet time",
   197       g_param_spec_int64 ("min-ptime", "Min packet time",
   197           "Minimum duration of the packet data in ns (can't go above MTU)",
   198           "Minimum duration of the packet data in ns (can't go above MTU)",
   198           0, G_MAXINT64, DEFAULT_MIN_PTIME, G_PARAM_READWRITE));
   199           0, G_MAXINT64, DEFAULT_MIN_PTIME,
       
   200           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   199 
   201 
   200   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMESTAMP,
   202   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMESTAMP,
   201       g_param_spec_uint ("timestamp", "Timestamp",
   203       g_param_spec_uint ("timestamp", "Timestamp",
   202           "The RTP timestamp of the last processed packet",
   204           "The RTP timestamp of the last processed packet",
   203           0, G_MAXUINT32, 0, G_PARAM_READABLE));
   205           0, G_MAXUINT32, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   204   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM,
   206   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM,
   205       g_param_spec_uint ("seqnum", "Sequence number",
   207       g_param_spec_uint ("seqnum", "Sequence number",
   206           "The RTP sequence number of the last processed packet",
   208           "The RTP sequence number of the last processed packet",
   207           0, G_MAXUINT16, 0, G_PARAM_READABLE));
   209           0, G_MAXUINT16, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   208 
   210 
   209   gstelement_class->change_state = gst_basertppayload_change_state;
   211   gstelement_class->change_state = gst_basertppayload_change_state;
   210 
   212 
   211   GST_DEBUG_CATEGORY_INIT (basertppayload_debug, "basertppayload", 0,
   213   GST_DEBUG_CATEGORY_INIT (basertppayload_debug, "basertppayload", 0,
   212       "Base class for RTP Payloaders");
   214       "Base class for RTP Payloaders");
   232       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
   234       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
   233   g_return_if_fail (templ != NULL);
   235   g_return_if_fail (templ != NULL);
   234 
   236 
   235   basertppayload->sinkpad = gst_pad_new_from_template (templ, "sink");
   237   basertppayload->sinkpad = gst_pad_new_from_template (templ, "sink");
   236   gst_pad_set_setcaps_function (basertppayload->sinkpad,
   238   gst_pad_set_setcaps_function (basertppayload->sinkpad,
   237       gst_basertppayload_setcaps);
   239       gst_basertppayload_sink_setcaps);
   238   gst_pad_set_getcaps_function (basertppayload->sinkpad,
   240   gst_pad_set_getcaps_function (basertppayload->sinkpad,
   239       gst_basertppayload_getcaps);
   241       gst_basertppayload_sink_getcaps);
   240   gst_pad_set_event_function (basertppayload->sinkpad,
   242   gst_pad_set_event_function (basertppayload->sinkpad,
   241       gst_basertppayload_event);
   243       gst_basertppayload_event);
   242   gst_pad_set_chain_function (basertppayload->sinkpad,
   244   gst_pad_set_chain_function (basertppayload->sinkpad,
   243       gst_basertppayload_chain);
   245       gst_basertppayload_chain);
   244   gst_element_add_pad (GST_ELEMENT (basertppayload), basertppayload->sinkpad);
   246   gst_element_add_pad (GST_ELEMENT (basertppayload), basertppayload->sinkpad);
   286 
   288 
   287   G_OBJECT_CLASS (parent_class)->finalize (object);
   289   G_OBJECT_CLASS (parent_class)->finalize (object);
   288 }
   290 }
   289 
   291 
   290 static gboolean
   292 static gboolean
   291 gst_basertppayload_setcaps (GstPad * pad, GstCaps * caps)
   293 gst_basertppayload_sink_setcaps (GstPad * pad, GstCaps * caps)
   292 {
   294 {
   293   GstBaseRTPPayload *basertppayload;
   295   GstBaseRTPPayload *basertppayload;
   294   GstBaseRTPPayloadClass *basertppayload_class;
   296   GstBaseRTPPayloadClass *basertppayload_class;
   295   gboolean ret = TRUE;
   297   gboolean ret = TRUE;
   296 
   298 
   305 
   307 
   306   return ret;
   308   return ret;
   307 }
   309 }
   308 
   310 
   309 static GstCaps *
   311 static GstCaps *
   310 gst_basertppayload_getcaps (GstPad * pad)
   312 gst_basertppayload_sink_getcaps (GstPad * pad)
   311 {
   313 {
   312   GstBaseRTPPayload *basertppayload;
   314   GstBaseRTPPayload *basertppayload;
   313   GstBaseRTPPayloadClass *basertppayload_class;
   315   GstBaseRTPPayloadClass *basertppayload_class;
   314   GstCaps *caps = NULL;
   316   GstCaps *caps = NULL;
   315 
   317 
   475 gboolean
   477 gboolean
   476 gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload, gchar * fieldname,
   478 gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload, gchar * fieldname,
   477     ...)
   479     ...)
   478 {
   480 {
   479   GstCaps *srccaps, *peercaps;
   481   GstCaps *srccaps, *peercaps;
   480 
   482   gboolean res;
   481   /* fill in the defaults, there properties cannot be negotiated. */
   483 
       
   484   /* fill in the defaults, their properties cannot be negotiated. */
   482   srccaps = gst_caps_new_simple ("application/x-rtp",
   485   srccaps = gst_caps_new_simple ("application/x-rtp",
   483       "media", G_TYPE_STRING, payload->media,
   486       "media", G_TYPE_STRING, payload->media,
   484       "clock-rate", G_TYPE_INT, payload->clock_rate,
   487       "clock-rate", G_TYPE_INT, payload->clock_rate,
   485       "encoding-name", G_TYPE_STRING, payload->encoding_name, NULL);
   488       "encoding-name", G_TYPE_STRING, payload->encoding_name, NULL);
   486 
   489 
   589     gst_caps_unref (temp);
   592     gst_caps_unref (temp);
   590 
   593 
   591     GST_DEBUG_OBJECT (payload, "with peer caps: %" GST_PTR_FORMAT, srccaps);
   594     GST_DEBUG_OBJECT (payload, "with peer caps: %" GST_PTR_FORMAT, srccaps);
   592   }
   595   }
   593 
   596 
   594   gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload), srccaps);
   597   res = gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload), srccaps);
   595   gst_caps_unref (srccaps);
   598   gst_caps_unref (srccaps);
   596 
   599 
   597   return TRUE;
   600   return res;
   598 }
   601 }
   599 
   602 
   600 /**
   603 /**
   601  * gst_basertppayload_is_filled:
   604  * gst_basertppayload_is_filled:
   602  * @payload: a #GstBaseRTPPayload
   605  * @payload: a #GstBaseRTPPayload
   603  * @size: the size of the packet
   606  * @size: the size of the packet
   604  * @duration: the duration of the packet
   607  * @duration: the duration of the packet
   605  *
   608  *
   606  * Check if the packet with @size and @duration would exceed the configure
   609  * Check if the packet with @size and @duration would exceed the configured
   607  * maximum size.
   610  * maximum size.
   608  *
   611  *
   609  * Returns: %TRUE if the packet of @size and @duration would exceed the
   612  * Returns: %TRUE if the packet of @size and @duration would exceed the
   610  * configured MTU or max_ptime.
   613  * configured MTU or max_ptime.
   611  */
   614  */
   624     return TRUE;
   627     return TRUE;
   625 
   628 
   626   return FALSE;
   629   return FALSE;
   627 }
   630 }
   628 
   631 
       
   632 typedef struct
       
   633 {
       
   634   GstBaseRTPPayload *payload;
       
   635   guint32 ssrc;
       
   636   guint16 seqnum;
       
   637   guint8 pt;
       
   638   GstCaps *caps;
       
   639   GstClockTime timestamp;
       
   640   guint32 rtptime;
       
   641 } HeaderData;
       
   642 
       
   643 static GstBufferListItem
       
   644 find_timestamp (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
       
   645 {
       
   646   data->timestamp = GST_BUFFER_TIMESTAMP (*buffer);
       
   647 
       
   648   /* stop when we find a timestamp */
       
   649   if (data->timestamp != -1)
       
   650     return GST_BUFFER_LIST_END;
       
   651   else
       
   652     return GST_BUFFER_LIST_CONTINUE;
       
   653 }
       
   654 
       
   655 static GstBufferListItem
       
   656 set_headers (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
       
   657 {
       
   658   gst_rtp_buffer_set_ssrc (*buffer, data->ssrc);
       
   659   gst_rtp_buffer_set_payload_type (*buffer, data->pt);
       
   660   gst_rtp_buffer_set_seq (*buffer, data->seqnum);
       
   661   gst_rtp_buffer_set_timestamp (*buffer, data->rtptime);
       
   662   gst_buffer_set_caps (*buffer, data->caps);
       
   663   data->seqnum++;
       
   664 
       
   665   return GST_BUFFER_LIST_SKIP_GROUP;
       
   666 }
       
   667 
       
   668 /* Updates the SSRC, payload type, seqnum and timestamp of the RTP buffer
       
   669  * before the buffer is pushed. */
       
   670 static GstFlowReturn
       
   671 gst_basertppayload_prepare_push (GstBaseRTPPayload * payload,
       
   672     gpointer obj, gboolean is_list)
       
   673 {
       
   674   GstBaseRTPPayloadPrivate *priv;
       
   675   HeaderData data;
       
   676 
       
   677   if (payload->clock_rate == 0)
       
   678     goto no_rate;
       
   679 
       
   680   priv = payload->priv;
       
   681 
       
   682   /* update first, so that the property is set to the last
       
   683    * seqnum pushed */
       
   684   payload->seqnum = priv->next_seqnum;
       
   685 
       
   686   /* fill in the fields we want to set on all headers */
       
   687   data.payload = payload;
       
   688   data.seqnum = payload->seqnum;
       
   689   data.ssrc = payload->current_ssrc;
       
   690   data.pt = payload->pt;
       
   691   data.caps = GST_PAD_CAPS (payload->srcpad);
       
   692   data.timestamp = -1;
       
   693 
       
   694   /* find the first buffer with a timestamp */
       
   695   if (is_list) {
       
   696     gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj),
       
   697         (GstBufferListFunc) find_timestamp, &data);
       
   698   } else {
       
   699     data.timestamp = GST_BUFFER_TIMESTAMP (GST_BUFFER_CAST (obj));
       
   700   }
       
   701 
       
   702   /* convert to RTP time */
       
   703   if (GST_CLOCK_TIME_IS_VALID (data.timestamp)) {
       
   704     gint64 rtime;
       
   705 
       
   706     rtime = gst_segment_to_running_time (&payload->segment, GST_FORMAT_TIME,
       
   707         data.timestamp);
       
   708 
       
   709     rtime = gst_util_uint64_scale_int (rtime, payload->clock_rate, GST_SECOND);
       
   710 
       
   711     /* add running_time in clock-rate units to the base timestamp */
       
   712     data.rtptime = payload->ts_base + rtime;
       
   713   } else {
       
   714     /* no timestamp to convert, take previous timestamp */
       
   715     data.rtptime = payload->timestamp;
       
   716   }
       
   717 
       
   718   /* set ssrc, payload type, seq number, caps and rtptime */
       
   719   if (is_list) {
       
   720     gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj),
       
   721         (GstBufferListFunc) set_headers, &data);
       
   722   } else {
       
   723     GstBuffer *buf = GST_BUFFER_CAST (obj);
       
   724     set_headers (&buf, 0, 0, &data);
       
   725   }
       
   726 
       
   727   priv->next_seqnum = data.seqnum;
       
   728   payload->timestamp = data.rtptime;
       
   729 
       
   730   GST_LOG_OBJECT (payload,
       
   731       "Preparing to push packet with size %d, seq=%d, rtptime=%u, timestamp %"
       
   732       GST_TIME_FORMAT, (is_list) ? -1 :
       
   733       GST_BUFFER_SIZE (GST_BUFFER (obj)), payload->seqnum, data.rtptime,
       
   734       GST_TIME_ARGS (data.timestamp));
       
   735 
       
   736   return GST_FLOW_OK;
       
   737 
       
   738   /* ERRORS */
       
   739 no_rate:
       
   740   {
       
   741     GST_ELEMENT_ERROR (payload, STREAM, NOT_IMPLEMENTED, (NULL),
       
   742         ("subclass did not specify clock-rate"));
       
   743     return GST_FLOW_ERROR;
       
   744   }
       
   745 }
       
   746 
       
   747 /**
       
   748  * gst_basertppayload_push_list:
       
   749  * @payload: a #GstBaseRTPPayload
       
   750  * @list: a #GstBufferList
       
   751  *
       
   752  * Push @list to the peer element of the payloader. The SSRC, payload type,
       
   753  * seqnum and timestamp of the RTP buffer will be updated first.
       
   754  *
       
   755  * This function takes ownership of @list.
       
   756  *
       
   757  * Returns: a #GstFlowReturn.
       
   758  *
       
   759  * Since: 0.10.24
       
   760  */
       
   761  
       
   762 #ifdef __SYMBIAN32__
       
   763 EXPORT_C
       
   764 #endif
       
   765 
       
   766 GstFlowReturn
       
   767 gst_basertppayload_push_list (GstBaseRTPPayload * payload, GstBufferList * list)
       
   768 {
       
   769   GstFlowReturn res;
       
   770 
       
   771   res = gst_basertppayload_prepare_push (payload, list, TRUE);
       
   772 
       
   773   if (G_LIKELY (res == GST_FLOW_OK))
       
   774     res = gst_pad_push_list (payload->srcpad, list);
       
   775   else
       
   776     gst_buffer_list_unref (list);
       
   777 
       
   778   return res;
       
   779 }
       
   780 
   629 /**
   781 /**
   630  * gst_basertppayload_push:
   782  * gst_basertppayload_push:
   631  * @payload: a #GstBaseRTPPayload
   783  * @payload: a #GstBaseRTPPayload
   632  * @buffer: a #GstBuffer
   784  * @buffer: a #GstBuffer
   633  *
   785  *
   644 
   796 
   645 GstFlowReturn
   797 GstFlowReturn
   646 gst_basertppayload_push (GstBaseRTPPayload * payload, GstBuffer * buffer)
   798 gst_basertppayload_push (GstBaseRTPPayload * payload, GstBuffer * buffer)
   647 {
   799 {
   648   GstFlowReturn res;
   800   GstFlowReturn res;
   649   GstClockTime timestamp;
   801 
   650   guint32 rtptime;
   802   res = gst_basertppayload_prepare_push (payload, buffer, FALSE);
   651   GstBaseRTPPayloadPrivate *priv;
   803 
   652 
   804   if (G_LIKELY (res == GST_FLOW_OK))
   653   if (payload->clock_rate == 0)
   805     res = gst_pad_push (payload->srcpad, buffer);
   654     goto no_rate;
   806   else
   655 
   807     gst_buffer_unref (buffer);
   656   priv = payload->priv;
       
   657 
       
   658   gst_rtp_buffer_set_ssrc (buffer, payload->current_ssrc);
       
   659 
       
   660   gst_rtp_buffer_set_payload_type (buffer, payload->pt);
       
   661 
       
   662   /* update first, so that the property is set to the last
       
   663    * seqnum pushed */
       
   664   payload->seqnum = priv->next_seqnum;
       
   665   gst_rtp_buffer_set_seq (buffer, payload->seqnum);
       
   666 
       
   667   /* can wrap around, which is perfectly fine */
       
   668   priv->next_seqnum++;
       
   669 
       
   670   /* add our random offset to the timestamp */
       
   671   rtptime = payload->ts_base;
       
   672 
       
   673   timestamp = GST_BUFFER_TIMESTAMP (buffer);
       
   674   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
       
   675     gint64 rtime;
       
   676 
       
   677     rtime = gst_segment_to_running_time (&payload->segment, GST_FORMAT_TIME,
       
   678         timestamp);
       
   679 
       
   680     /* take first timestamp as base, we want to calculate the RTP timestamp
       
   681      * starting from the ts_base */
       
   682     if (priv->rt_base == -1) {
       
   683       priv->rt_base = rtime;
       
   684       GST_LOG_OBJECT (payload, "first timestamp %" GST_TIME_FORMAT,
       
   685           GST_TIME_ARGS (rtime));
       
   686     }
       
   687     rtime -= priv->rt_base;
       
   688 
       
   689     rtime = gst_util_uint64_scale_int (rtime, payload->clock_rate, GST_SECOND);
       
   690 
       
   691     /* add running_time in clock-rate units to the base timestamp */
       
   692     rtptime += rtime;
       
   693   } else {
       
   694     /* no timestamp to convert, take previous timestamp */
       
   695     rtptime = payload->timestamp;
       
   696   }
       
   697   gst_rtp_buffer_set_timestamp (buffer, rtptime);
       
   698 
       
   699   payload->timestamp = rtptime;
       
   700 
       
   701   /* set caps */
       
   702   gst_buffer_set_caps (buffer, GST_PAD_CAPS (payload->srcpad));
       
   703 
       
   704   GST_LOG_OBJECT (payload,
       
   705       "Pushing packet size %d, seq=%d, rtptime=%u, timestamp %" GST_TIME_FORMAT,
       
   706       GST_BUFFER_SIZE (buffer), payload->seqnum, rtptime,
       
   707       GST_TIME_ARGS (timestamp));
       
   708 
       
   709   res = gst_pad_push (payload->srcpad, buffer);
       
   710 
   808 
   711   return res;
   809   return res;
   712 
       
   713   /* ERRORS */
       
   714 no_rate:
       
   715   {
       
   716     GST_ELEMENT_ERROR (payload, STREAM, NOT_IMPLEMENTED, (NULL),
       
   717         ("subclass did not specify clock-rate"));
       
   718     gst_buffer_unref (buffer);
       
   719     return GST_FLOW_ERROR;
       
   720   }
       
   721 }
   810 }
   722 
   811 
   723 static void
   812 static void
   724 gst_basertppayload_set_property (GObject * object, guint prop_id,
   813 gst_basertppayload_set_property (GObject * object, guint prop_id,
   725     const GValue * value, GParamSpec * pspec)
   814     const GValue * value, GParamSpec * pspec)
   841         basertppayload->seqnum_base =
   930         basertppayload->seqnum_base =
   842             g_rand_int_range (basertppayload->seq_rand, 0, G_MAXUINT16);
   931             g_rand_int_range (basertppayload->seq_rand, 0, G_MAXUINT16);
   843       else
   932       else
   844         basertppayload->seqnum_base = basertppayload->seqnum_offset;
   933         basertppayload->seqnum_base = basertppayload->seqnum_offset;
   845       priv->next_seqnum = basertppayload->seqnum_base;
   934       priv->next_seqnum = basertppayload->seqnum_base;
       
   935       basertppayload->seqnum = basertppayload->seqnum_base;
   846 
   936 
   847       if (priv->ssrc_random)
   937       if (priv->ssrc_random)
   848         basertppayload->current_ssrc = g_rand_int (basertppayload->ssrc_rand);
   938         basertppayload->current_ssrc = g_rand_int (basertppayload->ssrc_rand);
   849       else
   939       else
   850         basertppayload->current_ssrc = basertppayload->ssrc;
   940         basertppayload->current_ssrc = basertppayload->ssrc;
   851 
   941 
   852       if (priv->ts_offset_random)
   942       if (priv->ts_offset_random)
   853         basertppayload->ts_base = g_rand_int (basertppayload->ts_rand);
   943         basertppayload->ts_base = g_rand_int (basertppayload->ts_rand);
   854       else
   944       else
   855         basertppayload->ts_base = basertppayload->ts_offset;
   945         basertppayload->ts_base = basertppayload->ts_offset;
   856 
   946       basertppayload->timestamp = basertppayload->ts_base;
   857       priv->rt_base = -1;
       
   858       break;
   947       break;
   859     default:
   948     default:
   860       break;
   949       break;
   861   }
   950   }
   862 
   951