Blame tests/check/libs/rtpbasedepayload.c

Packit 971217
/* GStreamer RTP base depayloader unit tests
Packit 971217
 * Copyright (C) 2014 Sebastian Rasmussen <sebras@hotmail.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General
Packit 971217
 * Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
#ifdef HAVE_CONFIG_H
Packit 971217
#include "config.h"
Packit 971217
#endif
Packit 971217
Packit 971217
#include <gst/gst.h>
Packit 971217
#include <gst/check/gstcheck.h>
Packit 971217
#include <gst/rtp/gstrtpbuffer.h>
Packit 971217
#include <gst/rtp/gstrtpbasedepayload.h>
Packit 971217
Packit 971217
#define DEFAULT_CLOCK_RATE (42)
Packit 971217
Packit 971217
/* GstRtpDummyDepay */
Packit 971217
Packit 971217
#define GST_TYPE_RTP_DUMMY_DEPAY \
Packit 971217
  (gst_rtp_dummy_depay_get_type())
Packit 971217
#define GST_RTP_DUMMY_DEPAY(obj) \
Packit 971217
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DUMMY_DEPAY,GstRtpDummyDepay))
Packit 971217
#define GST_RTP_DUMMY_DEPAY_CLASS(klass) \
Packit 971217
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DUMMY_DEPAY,GstRtpDummyDepayClass))
Packit 971217
#define GST_IS_RTP_DUMMY_DEPAY(obj) \
Packit 971217
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DUMMY_DEPAY))
Packit 971217
#define GST_IS_RTP_DUMMY_DEPAY_CLASS(klass) \
Packit 971217
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DUMMY_DEPAY))
Packit 971217
Packit 971217
typedef struct _GstRtpDummyDepay GstRtpDummyDepay;
Packit 971217
typedef struct _GstRtpDummyDepayClass GstRtpDummyDepayClass;
Packit 971217
Packit 971217
struct _GstRtpDummyDepay
Packit 971217
{
Packit 971217
  GstRTPBaseDepayload depayload;
Packit 971217
  guint64 rtptime;
Packit 971217
};
Packit 971217
Packit 971217
struct _GstRtpDummyDepayClass
Packit 971217
{
Packit 971217
  GstRTPBaseDepayloadClass parent_class;
Packit 971217
};
Packit 971217
Packit 971217
GType gst_rtp_dummy_depay_get_type (void);
Packit 971217
Packit 971217
G_DEFINE_TYPE (GstRtpDummyDepay, gst_rtp_dummy_depay,
Packit 971217
    GST_TYPE_RTP_BASE_DEPAYLOAD);
Packit 971217
Packit 971217
static GstBuffer *gst_rtp_dummy_depay_process (GstRTPBaseDepayload * depayload,
Packit 971217
    GstBuffer * buf);
Packit 971217
static gboolean gst_rtp_dummy_depay_set_caps (GstRTPBaseDepayload * filter,
Packit 971217
    GstCaps * caps);
Packit 971217
Packit 971217
static GstStaticPadTemplate gst_rtp_dummy_depay_sink_template =
Packit 971217
GST_STATIC_PAD_TEMPLATE ("sink",
Packit 971217
    GST_PAD_SINK,
Packit 971217
    GST_PAD_ALWAYS,
Packit 971217
    GST_STATIC_CAPS_ANY);
Packit 971217
Packit 971217
static GstStaticPadTemplate gst_rtp_dummy_depay_src_template =
Packit 971217
GST_STATIC_PAD_TEMPLATE ("src",
Packit 971217
    GST_PAD_SRC,
Packit 971217
    GST_PAD_ALWAYS,
Packit 971217
    GST_STATIC_CAPS_ANY);
Packit 971217
Packit 971217
static void
Packit 971217
gst_rtp_dummy_depay_class_init (GstRtpDummyDepayClass * klass)
Packit 971217
{
Packit 971217
  GstElementClass *gstelement_class;
Packit 971217
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
Packit 971217
Packit 971217
  gstelement_class = GST_ELEMENT_CLASS (klass);
Packit 971217
  gstrtpbasedepayload_class = GST_RTP_BASE_DEPAYLOAD_CLASS (klass);
Packit 971217
Packit 971217
  gst_element_class_add_static_pad_template (gstelement_class,
Packit 971217
      &gst_rtp_dummy_depay_sink_template);
Packit 971217
  gst_element_class_add_static_pad_template (gstelement_class,
Packit 971217
      &gst_rtp_dummy_depay_src_template);
Packit 971217
Packit 971217
  gstrtpbasedepayload_class->process = gst_rtp_dummy_depay_process;
Packit 971217
  gstrtpbasedepayload_class->set_caps = gst_rtp_dummy_depay_set_caps;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
gst_rtp_dummy_depay_init (GstRtpDummyDepay * depay)
Packit 971217
{
Packit 971217
  depay->rtptime = 0;
Packit 971217
}
Packit 971217
Packit 971217
static GstRtpDummyDepay *
Packit 971217
rtp_dummy_depay_new (void)
Packit 971217
{
Packit 971217
  return g_object_new (GST_TYPE_RTP_DUMMY_DEPAY, NULL);
Packit 971217
}
Packit 971217
Packit 971217
static GstBuffer *
Packit 971217
gst_rtp_dummy_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
Packit 971217
{
Packit 971217
  GstRTPBuffer rtp = { NULL };
Packit 971217
  GstBuffer *outbuf;
Packit 971217
  guint32 rtptime;
Packit 971217
  guint i;
Packit 971217
Packit 971217
  GST_LOG ("depayloading buffer pts=%" GST_TIME_FORMAT " offset=%"
Packit 971217
      G_GUINT64_FORMAT " memories=%d", GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
Packit 971217
      GST_BUFFER_OFFSET (buf), gst_buffer_n_memory (buf));
Packit 971217
Packit 971217
  for (i = 0; i < gst_buffer_n_memory (buf); i++) {
Packit 971217
    GstMemory *mem = gst_buffer_get_memory (buf, 0);
Packit 971217
    gsize size, offset, maxsize;
Packit 971217
    size = gst_memory_get_sizes (mem, &offset, &maxsize);
Packit 971217
    GST_LOG ("\tsize=%zd offset=%zd maxsize=%zd", size, offset, maxsize);
Packit 971217
    gst_memory_unref (mem);
Packit 971217
  }
Packit 971217
Packit 971217
  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp;;
Packit 971217
  outbuf = gst_rtp_buffer_get_payload_buffer (&rtp;;
Packit 971217
  rtptime = gst_rtp_buffer_get_timestamp (&rtp;;
Packit 971217
  gst_rtp_buffer_unmap (&rtp;;
Packit 971217
Packit 971217
  GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buf);
Packit 971217
  GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
Packit 971217
Packit 971217
  GST_LOG ("depayloaded buffer pts=%" GST_TIME_FORMAT " offset=%"
Packit 971217
      G_GUINT64_FORMAT " rtptime=%" G_GUINT32_FORMAT " memories=%d",
Packit 971217
      GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)),
Packit 971217
      GST_BUFFER_OFFSET (outbuf), rtptime, gst_buffer_n_memory (buf));
Packit 971217
Packit 971217
  for (i = 0; i < gst_buffer_n_memory (buf); i++) {
Packit 971217
    GstMemory *mem = gst_buffer_get_memory (buf, 0);
Packit 971217
    gsize size, offset, maxsize;
Packit 971217
    size = gst_memory_get_sizes (mem, &offset, &maxsize);
Packit 971217
    GST_LOG ("\tsize=%zd offset=%zd maxsize=%zd", size, offset, maxsize);
Packit 971217
    gst_memory_unref (mem);
Packit 971217
  }
Packit 971217
Packit 971217
  return outbuf;
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
gst_rtp_dummy_depay_set_caps (GstRTPBaseDepayload * filter, GstCaps * caps)
Packit 971217
{
Packit 971217
  GstEvent *event;
Packit 971217
  event = gst_event_new_caps (caps);
Packit 971217
  gst_pad_push_event (filter->srcpad, event);
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
/* Helper functions and global state */
Packit 971217
Packit 971217
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
Packit 971217
    GST_PAD_SRC,
Packit 971217
    GST_PAD_ALWAYS,
Packit 971217
    GST_STATIC_CAPS_ANY);
Packit 971217
Packit 971217
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
Packit 971217
    GST_PAD_SINK,
Packit 971217
    GST_PAD_ALWAYS,
Packit 971217
    GST_STATIC_CAPS_ANY);
Packit 971217
Packit 971217
typedef struct State State;
Packit 971217
Packit 971217
struct State
Packit 971217
{
Packit 971217
  GstElement *element;
Packit 971217
  GstPad *sinkpad;
Packit 971217
  GstPad *srcpad;
Packit 971217
};
Packit 971217
Packit 971217
static GList *events;
Packit 971217
Packit 971217
static gboolean
Packit 971217
event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
Packit 971217
{
Packit 971217
  events = g_list_append (events, gst_event_ref (event));
Packit 971217
  return gst_pad_event_default (pad, noparent, event);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
drop_events (void)
Packit 971217
{
Packit 971217
  while (events != NULL) {
Packit 971217
    gst_event_unref (GST_EVENT (events->data));
Packit 971217
    events = g_list_delete_link (events, events);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
validate_events_received (guint received)
Packit 971217
{
Packit 971217
  fail_unless_equals_int (g_list_length (events), received);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
validate_event (guint index, const gchar * name, const gchar * field, ...)
Packit 971217
{
Packit 971217
  GstEvent *event;
Packit 971217
  va_list var_args;
Packit 971217
Packit 971217
  fail_if (index >= g_list_length (events));
Packit 971217
  event = GST_EVENT (g_list_nth_data (events, index));
Packit 971217
  fail_if (event == NULL);
Packit 971217
Packit 971217
  GST_TRACE ("%" GST_PTR_FORMAT, event);
Packit 971217
Packit 971217
  fail_unless_equals_string (GST_EVENT_TYPE_NAME (event), name);
Packit 971217
Packit 971217
  va_start (var_args, field);
Packit 971217
  while (field) {
Packit 971217
    if (!g_strcmp0 (field, "timestamp")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      GstClockTime timestamp, duration;
Packit 971217
      gst_event_parse_gap (event, &timestamp, &duration);
Packit 971217
      fail_unless_equals_uint64 (timestamp, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "duration")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      GstClockTime timestamp, duration;
Packit 971217
      gst_event_parse_gap (event, &timestamp, &duration);
Packit 971217
      fail_unless_equals_uint64 (duration, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "time")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->time, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "start")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->start, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "stop")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->stop, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "applied-rate")) {
Packit 971217
      gdouble expected = va_arg (var_args, gdouble);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->applied_rate, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "rate")) {
Packit 971217
      gdouble expected = va_arg (var_args, gdouble);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->rate, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "base")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      const GstSegment *segment;
Packit 971217
      gst_event_parse_segment (event, &segment);
Packit 971217
      fail_unless_equals_uint64 (segment->base, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "media-type")) {
Packit 971217
      const gchar *expected = va_arg (var_args, const gchar *);
Packit 971217
      GstCaps *caps;
Packit 971217
      const gchar *media_type;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      media_type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
Packit 971217
      fail_unless_equals_string (media_type, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "npt-start")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      GstCaps *caps;
Packit 971217
      GstClockTime start;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
Packit 971217
                  0), "npt-start", &start));
Packit 971217
      fail_unless_equals_uint64 (start, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "npt-stop")) {
Packit 971217
      GstClockTime expected = va_arg (var_args, GstClockTime);
Packit 971217
      GstCaps *caps;
Packit 971217
      GstClockTime stop;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
Packit 971217
                  0), "npt-stop", &stop));
Packit 971217
      fail_unless_equals_uint64 (stop, expected);
Packit 971217
    } else if (!g_strcmp0 (field, "play-speed")) {
Packit 971217
      gdouble expected = va_arg (var_args, gdouble);
Packit 971217
      GstCaps *caps;
Packit 971217
      gdouble speed;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
Packit 971217
              "play-speed", &speed));
Packit 971217
      fail_unless (speed == expected);
Packit 971217
    } else if (!g_strcmp0 (field, "play-scale")) {
Packit 971217
      gdouble expected = va_arg (var_args, gdouble);
Packit 971217
      GstCaps *caps;
Packit 971217
      gdouble scale;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
Packit 971217
              "play-scale", &scale));
Packit 971217
      fail_unless (scale == expected);
Packit 971217
    } else if (!g_strcmp0 (field, "clock-base")) {
Packit 971217
      guint expected = va_arg (var_args, guint);
Packit 971217
      GstCaps *caps;
Packit 971217
      guint clock_base;
Packit 971217
      gst_event_parse_caps (event, &caps);
Packit 971217
      fail_unless (gst_structure_get_uint (gst_caps_get_structure (caps, 0),
Packit 971217
              "clock-base", &clock_base));
Packit 971217
      fail_unless (clock_base == expected);
Packit 971217
Packit 971217
    } else {
Packit 971217
      fail ("test cannot validate unknown event field '%s'", field);
Packit 971217
    }
Packit 971217
    field = va_arg (var_args, const gchar *);
Packit 971217
  }
Packit 971217
  va_end (var_args);
Packit 971217
}
Packit 971217
Packit 971217
#define push_rtp_buffer(state, field, ...) \
Packit 971217
	push_rtp_buffer_full ((state), GST_FLOW_OK, (field), __VA_ARGS__)
Packit 971217
#define push_rtp_buffer_fails(state, error, field, ...) \
Packit 971217
        push_rtp_buffer_full ((state), (error), (field), __VA_ARGS__)
Packit 971217
Packit 971217
static void
Packit 971217
push_rtp_buffer_full (State * state, GstFlowReturn expected,
Packit 971217
    const gchar * field, ...)
Packit 971217
{
Packit 971217
  GstBuffer *buf = gst_rtp_buffer_new_allocate (0, 0, 0);
Packit 971217
  GstRTPBuffer rtp = { NULL };
Packit 971217
  gboolean mapped = FALSE;
Packit 971217
  gboolean extra_ref = FALSE;
Packit 971217
  va_list var_args;
Packit 971217
Packit 971217
  va_start (var_args, field);
Packit 971217
  while (field) {
Packit 971217
    if (!g_strcmp0 (field, "pts")) {
Packit 971217
      GstClockTime pts = va_arg (var_args, GstClockTime);
Packit 971217
      GST_BUFFER_PTS (buf) = pts;
Packit 971217
    } else if (!g_strcmp0 (field, "offset")) {
Packit 971217
      guint64 offset = va_arg (var_args, guint64);
Packit 971217
      GST_BUFFER_OFFSET (buf) = offset;
Packit 971217
    } else if (!g_strcmp0 (field, "discont")) {
Packit 971217
      gboolean discont = va_arg (var_args, gboolean);
Packit 971217
      if (discont) {
Packit 971217
        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
Packit 971217
      } else {
Packit 971217
        GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
Packit 971217
      }
Packit 971217
    } else {
Packit 971217
      if (!mapped) {
Packit 971217
        gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp;;
Packit 971217
        mapped = TRUE;
Packit 971217
      }
Packit 971217
      if (!g_strcmp0 (field, "rtptime")) {
Packit 971217
        guint32 rtptime = va_arg (var_args, guint64);
Packit 971217
        gst_rtp_buffer_set_timestamp (&rtp, rtptime);
Packit 971217
      } else if (!g_strcmp0 (field, "payload-type")) {
Packit 971217
        guint payload_type = va_arg (var_args, guint);
Packit 971217
        gst_rtp_buffer_set_payload_type (&rtp, payload_type);
Packit 971217
      } else if (!g_strcmp0 (field, "seq")) {
Packit 971217
        guint seq = va_arg (var_args, guint);
Packit 971217
        gst_rtp_buffer_set_seq (&rtp, seq);
Packit 971217
      } else if (!g_strcmp0 (field, "ssrc")) {
Packit 971217
        guint32 ssrc = va_arg (var_args, guint);
Packit 971217
        gst_rtp_buffer_set_ssrc (&rtp, ssrc);
Packit 971217
      } else if (!g_strcmp0 (field, "extra-ref")) {
Packit 971217
        extra_ref = va_arg (var_args, gboolean);
Packit 971217
      } else {
Packit 971217
        fail ("test cannot set unknown buffer field '%s'", field);
Packit 971217
      }
Packit 971217
    }
Packit 971217
    field = va_arg (var_args, const gchar *);
Packit 971217
  }
Packit 971217
  va_end (var_args);
Packit 971217
Packit 971217
  if (mapped) {
Packit 971217
    gst_rtp_buffer_unmap (&rtp;;
Packit 971217
  }
Packit 971217
Packit 971217
  if (extra_ref)
Packit 971217
    gst_buffer_ref (buf);
Packit 971217
Packit 971217
  fail_unless_equals_int (gst_pad_push (state->srcpad, buf), expected);
Packit 971217
Packit 971217
  if (extra_ref)
Packit 971217
    gst_buffer_unref (buf);
Packit 971217
}
Packit 971217
Packit 971217
#define push_buffer(state, field, ...) \
Packit 971217
	push_buffer_full ((state), GST_FLOW_OK, (field), __VA_ARGS__)
Packit 971217
Packit 971217
static void
Packit 971217
push_buffer_full (State * state, GstFlowReturn expected,
Packit 971217
    const gchar * field, ...)
Packit 971217
{
Packit 971217
  GstBuffer *buf = gst_buffer_new_allocate (0, 0, 0);
Packit 971217
  va_list var_args;
Packit 971217
Packit 971217
  va_start (var_args, field);
Packit 971217
  while (field) {
Packit 971217
    if (!g_strcmp0 (field, "pts")) {
Packit 971217
      GstClockTime pts = va_arg (var_args, GstClockTime);
Packit 971217
      GST_BUFFER_PTS (buf) = pts;
Packit 971217
    } else if (!g_strcmp0 (field, "offset")) {
Packit 971217
      guint64 offset = va_arg (var_args, guint64);
Packit 971217
      GST_BUFFER_OFFSET (buf) = offset;
Packit 971217
    } else if (!g_strcmp0 (field, "discont")) {
Packit 971217
      gboolean discont = va_arg (var_args, gboolean);
Packit 971217
      if (discont) {
Packit 971217
        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
Packit 971217
      } else {
Packit 971217
        GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
Packit 971217
      }
Packit 971217
    } else {
Packit 971217
      fail ("test cannot set unknown buffer field '%s'", field);
Packit 971217
    }
Packit 971217
    field = va_arg (var_args, const gchar *);
Packit 971217
  }
Packit 971217
  va_end (var_args);
Packit 971217
Packit 971217
  fail_unless_equals_int (gst_pad_push (state->srcpad, buf), expected);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
validate_buffers_received (guint received)
Packit 971217
{
Packit 971217
  fail_unless_equals_int (g_list_length (buffers), received);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
validate_buffer (guint index, const gchar * field, ...)
Packit 971217
{
Packit 971217
  GstBuffer *buf;
Packit 971217
  va_list var_args;
Packit 971217
Packit 971217
  fail_if (index >= g_list_length (buffers));
Packit 971217
  buf = GST_BUFFER (g_list_nth_data (buffers, (index)));
Packit 971217
  fail_if (buf == NULL);
Packit 971217
Packit 971217
  GST_TRACE ("%" GST_PTR_FORMAT, buf);
Packit 971217
Packit 971217
  va_start (var_args, field);
Packit 971217
  while (field) {
Packit 971217
    if (!g_strcmp0 (field, "pts")) {
Packit 971217
      GstClockTime pts = va_arg (var_args, GstClockTime);
Packit 971217
      fail_unless_equals_uint64 (GST_BUFFER_PTS (buf), pts);
Packit 971217
    } else if (!g_strcmp0 (field, "offset")) {
Packit 971217
      guint64 offset = va_arg (var_args, guint64);
Packit 971217
      fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buf), offset);
Packit 971217
    } else if (!g_strcmp0 (field, "discont")) {
Packit 971217
      gboolean discont = va_arg (var_args, gboolean);
Packit 971217
      if (discont) {
Packit 971217
        fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
Packit 971217
      } else {
Packit 971217
        fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
Packit 971217
      }
Packit 971217
    } else {
Packit 971217
      fail ("test cannot validate unknown buffer field '%s'", field);
Packit 971217
    }
Packit 971217
    field = va_arg (var_args, const gchar *);
Packit 971217
  }
Packit 971217
  va_end (var_args);
Packit 971217
}
Packit 971217
Packit 971217
static State *
Packit 971217
create_depayloader (const gchar * caps_str, const gchar * property, ...)
Packit 971217
{
Packit 971217
  va_list var_args;
Packit 971217
  GstCaps *caps;
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = g_new0 (State, 1);
Packit 971217
Packit 971217
  state->element = GST_ELEMENT (rtp_dummy_depay_new ());
Packit 971217
  fail_unless (GST_IS_RTP_DUMMY_DEPAY (state->element));
Packit 971217
Packit 971217
  va_start (var_args, property);
Packit 971217
  g_object_set_valist (G_OBJECT (state->element), property, var_args);
Packit 971217
  va_end (var_args);
Packit 971217
Packit 971217
  state->srcpad = gst_check_setup_src_pad (state->element, &srctemplate);
Packit 971217
  state->sinkpad = gst_check_setup_sink_pad (state->element, &sinktemplate);
Packit 971217
Packit 971217
  fail_unless (gst_pad_set_active (state->srcpad, TRUE));
Packit 971217
  fail_unless (gst_pad_set_active (state->sinkpad, TRUE));
Packit 971217
Packit 971217
  if (caps_str) {
Packit 971217
    caps = gst_caps_from_string (caps_str);
Packit 971217
  } else {
Packit 971217
    caps = NULL;
Packit 971217
  }
Packit 971217
  gst_check_setup_events (state->srcpad, state->element, caps, GST_FORMAT_TIME);
Packit 971217
  if (caps) {
Packit 971217
    gst_caps_unref (caps);
Packit 971217
  }
Packit 971217
Packit 971217
  gst_pad_set_chain_function (state->sinkpad, gst_check_chain_func);
Packit 971217
  gst_pad_set_event_function (state->sinkpad, event_func);
Packit 971217
Packit 971217
  return state;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
set_state (State * state, GstState new_state)
Packit 971217
{
Packit 971217
  fail_unless_equals_int (gst_element_set_state (state->element, new_state),
Packit 971217
      GST_STATE_CHANGE_SUCCESS);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
packet_lost (State * state, GstClockTime timestamp, GstClockTime duration)
Packit 971217
{
Packit 971217
  GstEvent *event;
Packit 971217
  guint seqnum = 0x4243;
Packit 971217
  gboolean late = TRUE;
Packit 971217
  guint retries = 42;
Packit 971217
Packit 971217
  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
Packit 971217
      gst_structure_new ("GstRTPPacketLost",
Packit 971217
          "seqnum", G_TYPE_UINT, seqnum,
Packit 971217
          "timestamp", G_TYPE_UINT64, timestamp,
Packit 971217
          "duration", G_TYPE_UINT64, duration,
Packit 971217
          "late", G_TYPE_BOOLEAN, late, "retry", G_TYPE_UINT, retries, NULL));
Packit 971217
Packit 971217
  fail_unless (gst_pad_push_event (state->srcpad, event));
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
reconfigure_caps (State * state, const gchar * caps_str)
Packit 971217
{
Packit 971217
  GstCaps *newcaps;
Packit 971217
  GstEvent *event;
Packit 971217
  newcaps = gst_caps_from_string (caps_str);
Packit 971217
  event = gst_event_new_caps (newcaps);
Packit 971217
  gst_caps_unref (newcaps);
Packit 971217
  fail_unless (gst_pad_push_event (state->srcpad, event));
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
flush_pipeline (State * state)
Packit 971217
{
Packit 971217
  GstEvent *event;
Packit 971217
  GstSegment segment;
Packit 971217
  event = gst_event_new_flush_start ();
Packit 971217
  fail_unless (gst_pad_push_event (state->srcpad, event));
Packit 971217
  event = gst_event_new_flush_stop (TRUE);
Packit 971217
  fail_unless (gst_pad_push_event (state->srcpad, event));
Packit 971217
  gst_segment_init (&segment, GST_FORMAT_TIME);
Packit 971217
  event = gst_event_new_segment (&segment);
Packit 971217
  fail_unless (gst_pad_push_event (state->srcpad, event));
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
destroy_depayloader (State * state)
Packit 971217
{
Packit 971217
  gst_check_teardown_sink_pad (state->element);
Packit 971217
  gst_check_teardown_src_pad (state->element);
Packit 971217
Packit 971217
  gst_check_drop_buffers ();
Packit 971217
  drop_events ();
Packit 971217
Packit 971217
  g_object_unref (state->element);
Packit 971217
Packit 971217
  g_free (state);
Packit 971217
}
Packit 971217
Packit 971217
/* Tests */
Packit 971217
Packit 971217
/* send two RTP packets having sequential sequence numbers and timestamps
Packit 971217
 * differing by DEFAULT_CLOCK_RATE. the depayloader first pushes the normal
Packit 971217
 * stream-start, caps and segment events downstream before processing each RTP
Packit 971217
 * packet and pushing a corresponding buffer. PTS will be carried over from the
Packit 971217
 * RTP packets by the payloader to the buffers. because the sequence numbers are
Packit 971217
 * sequential then GST_BUFFER_FLAG_DISCONT will not be set for either buffer.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_buffer_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* the intent with this test is to provide the depayloader with a buffer that
Packit 971217
 * does not contain an RTP header. this makes it impossible for the depayloader
Packit 971217
 * to depayload the incoming RTP packet, yet the stream-start and caps events
Packit 971217
 * will still be pushed.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_invalid_rtp_packet_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (0);
Packit 971217
Packit 971217
  validate_events_received (2);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* validate what happens when a depayloader is provided with two RTP packets
Packit 971217
 * sent after each other that do not have sequential sequence numbers. in this
Packit 971217
 * case the depayloader should be able to depayload both first and the second
Packit 971217
 * buffer, but the second buffer will have GST_BUFFER_FLAG_DISCONT set to
Packit 971217
 * indicate that the was a discontinuity in the stream. the initial events are
Packit 971217
 * pushed prior to the buffers arriving so they should be unaffected by the gap
Packit 971217
 * in sequence numbers.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_with_gap_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 2, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* two RTP packets are pushed in this test, and while the sequence numbers are
Packit 971217
 * sequential they are reversed. the expectation is that the depayloader will be
Packit 971217
 * able to depayload the first RTP packet, but once the second RTP packet
Packit 971217
 * arrives it will be discarded because it arrived too late. the initial events
Packit 971217
 * should be unaffected by the reversed buffers.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_reversed_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 - 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (1);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* The same scenario as in rtp_base_depayload_reversed_test
Packit 971217
 * except that SSRC is changed for the 2nd packet that is why
Packit 971217
 * it should not be discarded.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_ssrc_changed_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321),
Packit 971217
      "seq", 0x4242, "ssrc", 0xabe2b0b, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 - 1, "ssrc", 0xcafebabe, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* the intent of this test is to push two RTP packets that have reverse sequence
Packit 971217
 * numbers that differ significantly. the depayloader will consider RTP packets
Packit 971217
 * where the sequence numbers differ by more than 1000 to indicate that the
Packit 971217
 * source of the RTP packets has been restarted. therefore it will let both
Packit 971217
 * depayloaded buffers through, but the latter buffer marked
Packit 971217
 * GST_BUFFER_FLAG_DISCONT to indicate the discontinuity in the stream. the
Packit 971217
 * initial events should be unaffected by the reversed buffers.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_old_reversed_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 - 1000, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* a depayloader that has not received any caps event will not be able to
Packit 971217
 * process any incoming RTP packet. instead pushing an RTP packet should result
Packit 971217
 * in the expected error.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_without_negotiation_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader (NULL, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer_fails (state, GST_FLOW_NOT_NEGOTIATED,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (0);
Packit 971217
Packit 971217
  validate_events_received (1);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* a depayloader that receives the downstream event GstRTPPacketLost should
Packit 971217
 * respond by emitting a gap event with the corresponding timestamp and
Packit 971217
 * duration. the initial events are unaffected, but are succeeded by the added
Packit 971217
 * gap event.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_packet_lost_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  packet_lost (state, 1 * GST_SECOND, GST_SECOND);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 2 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 2 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 2, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 2 * GST_SECOND, "discont", TRUE, NULL);
Packit 971217
Packit 971217
  validate_events_received (4);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  validate_event (3, "gap",
Packit 971217
      "timestamp", 1 * GST_SECOND, "duration", GST_SECOND, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* rtp base depayloader should set DISCONT flag on buffer in case of a large
Packit 971217
 * sequence number gap, and it's not set already by upstream. This tests a
Packit 971217
 * certain code path where the buffer needs to be made writable to set the
Packit 971217
 * DISCONT flag.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_seq_discont_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 1, NULL);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "extra-ref", TRUE,
Packit 971217
      "pts", 2 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + DEFAULT_CLOCK_RATE / 2,
Packit 971217
      "seq", 33333, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 2 * GST_SECOND, "discont", TRUE, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* a depayloader that receives identical caps events simply ignores the latter
Packit 971217
 * events without propagating them downstream.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_repeated_caps_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  reconfigure_caps (state, "application/x-rtp");
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (3);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* when a depayloader receives new caps events with npt-start and npt-stop times
Packit 971217
 * it should save these timestamps as they should affect the next segment event
Packit 971217
 * being pushed by the depayloader. a new segment event is not pushed by the
Packit 971217
 * depayloader until a flush_stop event and a succeeding segment event are
Packit 971217
 * received. of course the intial event are unaffected, as is the incoming caps
Packit 971217
 * event.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_npt_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  reconfigure_caps (state,
Packit 971217
      "application/x-rtp, npt-start=(guint64)1234, npt-stop=(guint64)4321");
Packit 971217
Packit 971217
  flush_pipeline (state);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (7);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  validate_event (3, "caps",
Packit 971217
      "media-type", "application/x-rtp",
Packit 971217
      "npt-start", G_GUINT64_CONSTANT (1234),
Packit 971217
      "npt-stop", G_GUINT64_CONSTANT (4321), NULL);
Packit 971217
Packit 971217
  validate_event (4, "flush-start", NULL);
Packit 971217
Packit 971217
  validate_event (5, "flush-stop", NULL);
Packit 971217
Packit 971217
  validate_event (6, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (1234),
Packit 971217
      "start", G_GUINT64_CONSTANT (0),
Packit 971217
      "stop", G_GUINT64_CONSTANT (4321 - 1234), NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* when a depayloader receives a new caps event with play-scale it should save
Packit 971217
 * this rate as it should affect the next segment event being pushed by the
Packit 971217
 * depayloader. a new segment event is not pushed by the depayloader until a
Packit 971217
 * flush_stop event and a succeeding segment event are received. of course the
Packit 971217
 * intial event are unaffected, as is the incoming caps event.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_play_scale_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  reconfigure_caps (state, "application/x-rtp, play-scale=(double)2.0");
Packit 971217
Packit 971217
  flush_pipeline (state);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (7);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  validate_event (3, "caps",
Packit 971217
      "media-type", "application/x-rtp", "play-scale", 2.0, NULL);
Packit 971217
Packit 971217
  validate_event (4, "flush-start", NULL);
Packit 971217
Packit 971217
  validate_event (5, "flush-stop", NULL);
Packit 971217
Packit 971217
  validate_event (6, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0),
Packit 971217
      "stop", G_MAXUINT64, "rate", 1.0, "applied-rate", 2.0, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* when a depayloader receives a new caps event with play-speed it should save
Packit 971217
 * this rate as it should affect the next segment event being pushed by the
Packit 971217
 * depayloader. a new segment event is not pushed by the depayloader until a
Packit 971217
 * flush_stop event and a succeeding segment event are received. of course the
Packit 971217
 * intial event are unaffected, as is the incoming caps event.
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_play_speed_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  reconfigure_caps (state, "application/x-rtp, play-speed=(double)2.0");
Packit 971217
Packit 971217
  flush_pipeline (state);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (7);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  validate_event (3, "caps",
Packit 971217
      "media-type", "application/x-rtp", "play-speed", 2.0, NULL);
Packit 971217
Packit 971217
  validate_event (4, "flush-start", NULL);
Packit 971217
Packit 971217
  validate_event (5, "flush-stop", NULL);
Packit 971217
Packit 971217
  validate_event (6, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0),
Packit 971217
      "stop", G_MAXUINT64, "rate", 2.0, "applied-rate", 1.0, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST
Packit 971217
/* when a depayloader receives new caps events with npt-start, npt-stop and
Packit 971217
 * clock-base it should save these timestamps as they should affect the next
Packit 971217
 * segment event being pushed by the depayloader. the produce segment should
Packit 971217
 * make the positon of the stream reflect the postion form clock-base instead
Packit 971217
 * of reflecting the running time (for RTSP).
Packit 971217
 */
Packit 971217
GST_START_TEST (rtp_base_depayload_clock_base_test)
Packit 971217
{
Packit 971217
  State *state;
Packit 971217
Packit 971217
  state = create_depayloader ("application/x-rtp", NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 0 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (1234), "seq", 0x4242, NULL);
Packit 971217
Packit 971217
  reconfigure_caps (state,
Packit 971217
      "application/x-rtp, npt-start=(guint64)1234, npt-stop=(guint64)4321, clock-base=(guint)1234");
Packit 971217
Packit 971217
  flush_pipeline (state);
Packit 971217
Packit 971217
  push_rtp_buffer (state,
Packit 971217
      "pts", 1 * GST_SECOND,
Packit 971217
      "rtptime", G_GUINT64_CONSTANT (1234) + 1 * DEFAULT_CLOCK_RATE,
Packit 971217
      "seq", 0x4242 + 1, NULL);
Packit 971217
Packit 971217
  set_state (state, GST_STATE_NULL);
Packit 971217
Packit 971217
  validate_buffers_received (2);
Packit 971217
Packit 971217
  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
Packit 971217
Packit 971217
  validate_events_received (7);
Packit 971217
Packit 971217
  validate_event (0, "stream-start", NULL);
Packit 971217
Packit 971217
  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
Packit 971217
Packit 971217
  validate_event (2, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (0),
Packit 971217
      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
Packit 971217
Packit 971217
  validate_event (3, "caps",
Packit 971217
      "media-type", "application/x-rtp",
Packit 971217
      "npt-start", G_GUINT64_CONSTANT (1234),
Packit 971217
      "npt-stop", G_GUINT64_CONSTANT (4321), "clock-base", 1234, NULL);
Packit 971217
Packit 971217
  validate_event (4, "flush-start", NULL);
Packit 971217
Packit 971217
  validate_event (5, "flush-stop", NULL);
Packit 971217
Packit 971217
  validate_event (6, "segment",
Packit 971217
      "time", G_GUINT64_CONSTANT (1234),
Packit 971217
      "start", GST_SECOND,
Packit 971217
      "stop", GST_SECOND + G_GUINT64_CONSTANT (4321 - 1234),
Packit 971217
      "base", GST_SECOND, NULL);
Packit 971217
Packit 971217
  destroy_depayloader (state);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST static Suite *
Packit 971217
rtp_basepayloading_suite (void)
Packit 971217
{
Packit 971217
  Suite *s = suite_create ("rtp_base_depayloading_test");
Packit 971217
  TCase *tc_chain = tcase_create ("depayloading tests");
Packit 971217
Packit 971217
  tcase_set_timeout (tc_chain, 60);
Packit 971217
Packit 971217
  suite_add_tcase (s, tc_chain);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_buffer_test);
Packit 971217
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_invalid_rtp_packet_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_with_gap_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_reversed_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_ssrc_changed_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_old_reversed_test);
Packit 971217
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_without_negotiation_test);
Packit 971217
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_packet_lost_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_seq_discont_test);
Packit 971217
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_repeated_caps_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_npt_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_play_scale_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_play_speed_test);
Packit 971217
  tcase_add_test (tc_chain, rtp_base_depayload_clock_base_test);
Packit 971217
Packit 971217
  return s;
Packit 971217
}
Packit 971217
Packit 971217
GST_CHECK_MAIN (rtp_basepayloading)