*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifndef __RTP_JITTER_BUFFER_H__
typedef struct _RTPJitterBuffer RTPJitterBuffer;
typedef struct _RTPJitterBufferClass RTPJitterBufferClass;
+typedef struct _RTPJitterBufferItem RTPJitterBufferItem;
#define RTP_TYPE_JITTER_BUFFER (rtp_jitter_buffer_get_type())
#define RTP_JITTER_BUFFER(src) (G_TYPE_CHECK_INSTANCE_CAST((src),RTP_TYPE_JITTER_BUFFER,RTPJitterBuffer))
#define RTP_JITTER_BUFFER_CAST(src) ((RTPJitterBuffer *)(src))
/**
- * RTPTailChanged:
- * @jbuf: an #RTPJitterBuffer
- * @user_data: user data specified when registering
+ * RTPJitterBufferMode:
*
- * This callback will be called when the tail buffer of @jbuf changed.
+ * RTP_JITTER_BUFFER_MODE_NONE: don't do any skew correction, outgoing
+ * timestamps are calculated directly from the RTP timestamps. This mode is
+ * good for recording but not for real-time applications.
+ * RTP_JITTER_BUFFER_MODE_SLAVE: calculate the skew between sender and receiver
+ * and produce smoothed adjusted outgoing timestamps. This mode is good for
+ * low latency communications.
+ * RTP_JITTER_BUFFER_MODE_BUFFER: buffer packets between low/high watermarks.
+ * This mode is good for streaming communication.
+ * RTP_JITTER_BUFFER_MODE_SYNCED: sender and receiver clocks are synchronized,
+ * like #RTP_JITTER_BUFFER_MODE_SLAVE but skew is assumed to be 0. Good for
+ * low latency communication when sender and receiver clocks are
+ * synchronized and there is thus no clock skew.
+ * RTP_JITTER_BUFFER_MODE_LAST: last buffer mode.
+ *
+ * The different buffer modes for a jitterbuffer.
*/
-typedef void (*RTPTailChanged) (RTPJitterBuffer *jbuf, gpointer user_data);
+typedef enum {
+ RTP_JITTER_BUFFER_MODE_NONE = 0,
+ RTP_JITTER_BUFFER_MODE_SLAVE = 1,
+ RTP_JITTER_BUFFER_MODE_BUFFER = 2,
+ /* FIXME 3 is missing because it was used for 'auto' in jitterbuffer */
+ RTP_JITTER_BUFFER_MODE_SYNCED = 4,
+ RTP_JITTER_BUFFER_MODE_LAST
+} RTPJitterBufferMode;
+
+#define RTP_TYPE_JITTER_BUFFER_MODE (rtp_jitter_buffer_mode_get_type())
+GType rtp_jitter_buffer_mode_get_type (void);
#define RTP_JITTER_BUFFER_MAX_WINDOW 512
/**
GQueue *packets;
+ RTPJitterBufferMode mode;
+
+ GstClockTime delay;
+
+ /* for buffering */
+ gboolean buffering;
+ guint64 low_level;
+ guint64 high_level;
+
/* for calculating skew */
+ gboolean need_resync;
GstClockTime base_time;
GstClockTime base_rtptime;
+ GstClockTime media_clock_base_time;
guint32 clock_rate;
GstClockTime base_extrtp;
GstClockTime prev_out_time;
gint64 window_min;
gint64 skew;
gint64 prev_send_diff;
+ gboolean buffering_disabled;
+
+ GMutex clock_lock;
+ GstClock *pipeline_clock;
+ GstClock *media_clock;
+ gulong media_clock_synced_id;
+ guint64 media_clock_offset;
+
+ gboolean rfc7273_sync;
};
struct _RTPJitterBufferClass {
GObjectClass parent_class;
};
+/**
+ * RTPJitterBufferItem:
+ * @data: the data of the item
+ * @next: pointer to next item
+ * @prev: pointer to previous item
+ * @type: the type of @data, used freely by caller
+ * @dts: input DTS
+ * @pts: output PTS
+ * @seqnum: seqnum, the seqnum is used to insert the item in the
+ * right position in the jitterbuffer and detect duplicates. Use -1 to
+ * append.
+ * @count: amount of seqnum in this item
+ * @rtptime: rtp timestamp
+ *
+ * An object containing an RTP packet or event.
+ */
+struct _RTPJitterBufferItem {
+ gpointer data;
+ GList *next;
+ GList *prev;
+ guint type;
+ GstClockTime dts;
+ GstClockTime pts;
+ guint seqnum;
+ guint count;
+ guint rtptime;
+};
+
GType rtp_jitter_buffer_get_type (void);
/* managing lifetime */
RTPJitterBuffer* rtp_jitter_buffer_new (void);
+RTPJitterBufferMode rtp_jitter_buffer_get_mode (RTPJitterBuffer *jbuf);
+void rtp_jitter_buffer_set_mode (RTPJitterBuffer *jbuf, RTPJitterBufferMode mode);
+
+GstClockTime rtp_jitter_buffer_get_delay (RTPJitterBuffer *jbuf);
+void rtp_jitter_buffer_set_delay (RTPJitterBuffer *jbuf, GstClockTime delay);
+
+void rtp_jitter_buffer_set_clock_rate (RTPJitterBuffer *jbuf, guint32 clock_rate);
+guint32 rtp_jitter_buffer_get_clock_rate (RTPJitterBuffer *jbuf);
+
+void rtp_jitter_buffer_set_media_clock (RTPJitterBuffer *jbuf, GstClock * clock, guint64 clock_offset);
+void rtp_jitter_buffer_set_pipeline_clock (RTPJitterBuffer *jbuf, GstClock * clock);
+
+gboolean rtp_jitter_buffer_get_rfc7273_sync (RTPJitterBuffer *jbuf);
+void rtp_jitter_buffer_set_rfc7273_sync (RTPJitterBuffer *jbuf, gboolean rfc7273_sync);
+
void rtp_jitter_buffer_reset_skew (RTPJitterBuffer *jbuf);
-gboolean rtp_jitter_buffer_insert (RTPJitterBuffer *jbuf, GstBuffer *buf,
- GstClockTime time,
- guint32 clock_rate,
- GstClockTime max_delay,
- gboolean *tail);
-GstBuffer * rtp_jitter_buffer_peek (RTPJitterBuffer *jbuf);
-GstBuffer * rtp_jitter_buffer_pop (RTPJitterBuffer *jbuf);
+gboolean rtp_jitter_buffer_insert (RTPJitterBuffer *jbuf,
+ RTPJitterBufferItem *item,
+ gboolean *head, gint *percent,
+ GstClockTime base_time);
+
+void rtp_jitter_buffer_disable_buffering (RTPJitterBuffer *jbuf, gboolean disabled);
+
+RTPJitterBufferItem * rtp_jitter_buffer_peek (RTPJitterBuffer *jbuf);
+RTPJitterBufferItem * rtp_jitter_buffer_pop (RTPJitterBuffer *jbuf, gint *percent);
+
+void rtp_jitter_buffer_flush (RTPJitterBuffer *jbuf,
+ GFunc free_func, gpointer user_data);
-void rtp_jitter_buffer_flush (RTPJitterBuffer *jbuf);
+gboolean rtp_jitter_buffer_is_buffering (RTPJitterBuffer * jbuf);
+void rtp_jitter_buffer_set_buffering (RTPJitterBuffer * jbuf, gboolean buffering);
+gint rtp_jitter_buffer_get_percent (RTPJitterBuffer * jbuf);
guint rtp_jitter_buffer_num_packets (RTPJitterBuffer *jbuf);
guint32 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer *jbuf);