gstrtpgstdepay.c 15.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* GStreamer
 * Copyright (C) <2010> 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
Tim-Philipp Müller's avatar
Tim-Philipp Müller committed
16 17
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
18 19 20 21 22 23 24
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
Wim Taymans's avatar
Wim Taymans committed
25 26
#include <stdlib.h>

27
#include "gstrtpgstdepay.h"
28
#include "gstrtputils.h"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

GST_DEBUG_CATEGORY_STATIC (rtpgstdepay_debug);
#define GST_CAT_DEFAULT (rtpgstdepay_debug)

static GstStaticPadTemplate gst_rtp_gst_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_rtp_gst_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"application\", "
        "clock-rate = (int) 90000, " "encoding-name = (string) \"X-GST\"")
    );

48
#define gst_rtp_gst_depay_parent_class parent_class
Wim Taymans's avatar
Wim Taymans committed
49
G_DEFINE_TYPE (GstRtpGSTDepay, gst_rtp_gst_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
50 51 52

static void gst_rtp_gst_depay_finalize (GObject * object);

53 54
static gboolean gst_rtp_gst_depay_handle_event (GstRTPBaseDepayload * depay,
    GstEvent * event);
Wim Taymans's avatar
Wim Taymans committed
55 56 57
static GstStateChangeReturn gst_rtp_gst_depay_change_state (GstElement *
    element, GstStateChange transition);

58 59
static void gst_rtp_gst_depay_reset (GstRtpGSTDepay * rtpgstdepay, gboolean
    full);
Wim Taymans's avatar
Wim Taymans committed
60
static gboolean gst_rtp_gst_depay_setcaps (GstRTPBaseDepayload * depayload,
61
    GstCaps * caps);
Wim Taymans's avatar
Wim Taymans committed
62
static GstBuffer *gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload,
63
    GstRTPBuffer * rtp);
64 65 66 67 68

static void
gst_rtp_gst_depay_class_init (GstRtpGSTDepayClass * klass)
{
  GObjectClass *gobject_class;
Wim Taymans's avatar
Wim Taymans committed
69
  GstElementClass *gstelement_class;
Wim Taymans's avatar
Wim Taymans committed
70
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
71

72 73 74
  GST_DEBUG_CATEGORY_INIT (rtpgstdepay_debug, "rtpgstdepay", 0,
      "Gstreamer RTP Depayloader");

75
  gobject_class = (GObjectClass *) klass;
Wim Taymans's avatar
Wim Taymans committed
76
  gstelement_class = (GstElementClass *) klass;
Wim Taymans's avatar
Wim Taymans committed
77
  gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
78 79 80

  gobject_class->finalize = gst_rtp_gst_depay_finalize;

Wim Taymans's avatar
Wim Taymans committed
81 82
  gstelement_class->change_state = gst_rtp_gst_depay_change_state;

83 84 85 86
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_gst_depay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_gst_depay_sink_template);
87

88
  gst_element_class_set_static_metadata (gstelement_class,
89 90 91 92
      "GStreamer depayloader", "Codec/Depayloader/Network",
      "Extracts GStreamer buffers from RTP packets",
      "Wim Taymans <wim.taymans@gmail.com>");

93
  gstrtpbasedepayload_class->handle_event = gst_rtp_gst_depay_handle_event;
Wim Taymans's avatar
Wim Taymans committed
94
  gstrtpbasedepayload_class->set_caps = gst_rtp_gst_depay_setcaps;
95
  gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_gst_depay_process;
96 97 98
}

static void
99
gst_rtp_gst_depay_init (GstRtpGSTDepay * rtpgstdepay)
100 101 102 103 104 105 106 107 108 109 110
{
  rtpgstdepay->adapter = gst_adapter_new ();
}

static void
gst_rtp_gst_depay_finalize (GObject * object)
{
  GstRtpGSTDepay *rtpgstdepay;

  rtpgstdepay = GST_RTP_GST_DEPAY (object);

111
  gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
112 113 114 115 116
  g_object_unref (rtpgstdepay->adapter);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

Wim Taymans's avatar
Wim Taymans committed
117 118 119 120 121 122 123 124 125
static void
store_cache (GstRtpGSTDepay * rtpgstdepay, guint CV, GstCaps * caps)
{
  if (rtpgstdepay->CV_cache[CV])
    gst_caps_unref (rtpgstdepay->CV_cache[CV]);
  rtpgstdepay->CV_cache[CV] = caps;
}

static void
126
gst_rtp_gst_depay_reset (GstRtpGSTDepay * rtpgstdepay, gboolean full)
Wim Taymans's avatar
Wim Taymans committed
127 128 129 130
{
  guint i;

  gst_adapter_clear (rtpgstdepay->adapter);
131 132 133 134
  if (full) {
    rtpgstdepay->current_CV = 0;
    for (i = 0; i < 8; i++)
      store_cache (rtpgstdepay, i, NULL);
135 136 137 138 139
    g_free (rtpgstdepay->stream_id);
    rtpgstdepay->stream_id = NULL;
    if (rtpgstdepay->tags)
      gst_tag_list_unref (rtpgstdepay->tags);
    rtpgstdepay->tags = NULL;
140
  }
Wim Taymans's avatar
Wim Taymans committed
141 142
}

143
static gboolean
Wim Taymans's avatar
Wim Taymans committed
144
gst_rtp_gst_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
{
  GstRtpGSTDepay *rtpgstdepay;
  GstStructure *structure;
  gint clock_rate;
  gboolean res;
  const gchar *capsenc;

  rtpgstdepay = GST_RTP_GST_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    clock_rate = 90000;
  depayload->clock_rate = clock_rate;

  capsenc = gst_structure_get_string (structure, "caps");
  if (capsenc) {
Wim Taymans's avatar
Wim Taymans committed
162
    GstCaps *outcaps;
163
    gsize out_len;
Wim Taymans's avatar
Wim Taymans committed
164 165 166
    gchar *capsstr;
    const gchar *capsver;
    guint CV;
167

Wim Taymans's avatar
Wim Taymans committed
168
    /* decode caps */
169 170 171 172
    capsstr = (gchar *) g_base64_decode (capsenc, &out_len);
    outcaps = gst_caps_from_string (capsstr);
    g_free (capsstr);

Wim Taymans's avatar
Wim Taymans committed
173 174 175 176 177 178 179 180 181 182
    /* parse version */
    capsver = gst_structure_get_string (structure, "capsversion");
    if (capsver) {
      CV = atoi (capsver);
    } else {
      /* no version, assume 0 */
      CV = 0;
    }
    /* store in cache */
    rtpgstdepay->current_CV = CV;
Wim Taymans's avatar
Wim Taymans committed
183
    gst_caps_ref (outcaps);
Wim Taymans's avatar
Wim Taymans committed
184 185 186 187
    store_cache (rtpgstdepay, CV, outcaps);

    res = gst_pad_set_caps (depayload->srcpad, outcaps);
    gst_caps_unref (outcaps);
188
  } else {
Wim Taymans's avatar
Wim Taymans committed
189 190 191
    GST_WARNING_OBJECT (depayload, "no caps given");
    rtpgstdepay->current_CV = -1;
    res = TRUE;
192 193 194 195 196
  }

  return res;
}

Wim Taymans's avatar
Wim Taymans committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
static gboolean
read_length (GstRtpGSTDepay * rtpgstdepay, guint8 * data, guint size,
    guint * length, guint * skip)
{
  guint b, len, offset;

  /* start reading the length, we need this to skip to the data later */
  len = offset = 0;
  do {
    if (offset >= size)
      return FALSE;
    b = data[offset++];
    len = (len << 7) | (b & 0x7f);
  } while (b & 0x80);

  /* check remaining buffer size */
  if (size - offset < len)
    return FALSE;

  *length = len;
  *skip = offset;

  return TRUE;
}

static GstCaps *
read_caps (GstRtpGSTDepay * rtpgstdepay, GstBuffer * buf, guint * skip)
{
  guint offset, length;
  GstCaps *caps;
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);

231
  GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %" G_GSIZE_FORMAT, map.size);
Wim Taymans's avatar
Wim Taymans committed
232 233 234 235

  if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
    goto too_small;

236 237 238
  if (length == 0 || map.data[offset + length - 1] != '\0')
    goto invalid_buffer;

Wim Taymans's avatar
Wim Taymans committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  GST_DEBUG_OBJECT (rtpgstdepay, "parsing caps %s", &map.data[offset]);

  /* parse and store in cache */
  caps = gst_caps_from_string ((gchar *) & map.data[offset]);
  gst_buffer_unmap (buf, &map);

  *skip = length + offset;

  return caps;

too_small:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("Buffer too small."), (NULL));
    gst_buffer_unmap (buf, &map);
    return NULL;
  }
256 257 258 259 260 261 262
invalid_buffer:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("caps string not 0-terminated."), (NULL));
    gst_buffer_unmap (buf, &map);
    return NULL;
  }
Wim Taymans's avatar
Wim Taymans committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
}

static GstEvent *
read_event (GstRtpGSTDepay * rtpgstdepay, guint type,
    GstBuffer * buf, guint * skip)
{
  guint offset, length;
  GstStructure *s;
  GstEvent *event;
  GstEventType etype;
  gchar *end;
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);

278
  GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %" G_GSIZE_FORMAT, map.size);
Wim Taymans's avatar
Wim Taymans committed
279 280 281 282

  if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
    goto too_small;

283 284 285
  if (length == 0)
    goto invalid_buffer;
  /* backward compat, old payloader did not put 0-byte at the end */
286 287
  if (map.data[offset + length - 1] != '\0'
      && map.data[offset + length - 1] != ';')
288 289
    goto invalid_buffer;

Wim Taymans's avatar
Wim Taymans committed
290 291 292 293 294 295
  GST_DEBUG_OBJECT (rtpgstdepay, "parsing event %s", &map.data[offset]);

  /* parse */
  s = gst_structure_from_string ((gchar *) & map.data[offset], &end);
  gst_buffer_unmap (buf, &map);

296 297 298
  if (s == NULL)
    goto parse_failed;

Wim Taymans's avatar
Wim Taymans committed
299 300 301 302 303 304 305 306 307 308
  switch (type) {
    case 1:
      etype = GST_EVENT_TAG;
      break;
    case 2:
      etype = GST_EVENT_CUSTOM_DOWNSTREAM;
      break;
    case 3:
      etype = GST_EVENT_CUSTOM_BOTH;
      break;
309 310 311
    case 4:
      etype = GST_EVENT_STREAM_START;
      break;
Wim Taymans's avatar
Wim Taymans committed
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
    default:
      goto unknown_event;
  }
  event = gst_event_new_custom (etype, s);

  *skip = length + offset;

  return event;

too_small:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("Buffer too small."), (NULL));
    gst_buffer_unmap (buf, &map);
    return NULL;
  }
328 329 330 331 332 333 334
invalid_buffer:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("event string not 0-terminated."), (NULL));
    gst_buffer_unmap (buf, &map);
    return NULL;
  }
335 336 337 338 339
parse_failed:
  {
    GST_WARNING_OBJECT (rtpgstdepay, "could not parse event");
    return NULL;
  }
Wim Taymans's avatar
Wim Taymans committed
340 341 342
unknown_event:
  {
    GST_DEBUG_OBJECT (rtpgstdepay, "unknown event type");
Wim Taymans's avatar
Wim Taymans committed
343
    gst_structure_free (s);
Wim Taymans's avatar
Wim Taymans committed
344 345 346 347
    return NULL;
  }
}

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
static void
store_event (GstRtpGSTDepay * rtpgstdepay, GstEvent * event)
{
  gboolean do_push = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      GstTagList *old, *tags;

      gst_event_parse_tag (event, &tags);

      old = rtpgstdepay->tags;
      if (!old || !gst_tag_list_is_equal (old, tags)) {
        do_push = TRUE;
        if (old)
          gst_tag_list_unref (old);
        rtpgstdepay->tags = gst_tag_list_ref (tags);
      }
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    case GST_EVENT_CUSTOM_BOTH:
      /* always push custom events */
      do_push = TRUE;
      break;
    case GST_EVENT_STREAM_START:
    {
      gchar *old;
      const gchar *stream_id = NULL;

      gst_event_parse_stream_start (event, &stream_id);

      old = rtpgstdepay->stream_id;
      if (!old || g_strcmp0 (old, stream_id)) {
        do_push = TRUE;
        g_free (old);
        rtpgstdepay->stream_id = g_strdup (stream_id);
      }
      break;
    }
    default:
      /* unknown event, don't push */
      break;
  }
  if (do_push)
    gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD (rtpgstdepay)->srcpad, event);
  else
    gst_event_unref (event);
}

399
static GstBuffer *
400
gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
401 402 403 404 405
{
  GstRtpGSTDepay *rtpgstdepay;
  GstBuffer *subbuf, *outbuf = NULL;
  gint payload_len;
  guint8 *payload;
Wim Taymans's avatar
Wim Taymans committed
406
  guint CV, frag_offset, avail, offset;
407 408 409

  rtpgstdepay = GST_RTP_GST_DEPAY (depayload);

410
  payload_len = gst_rtp_buffer_get_payload_len (rtp);
411 412 413 414

  if (payload_len <= 8)
    goto empty_packet;

415
  if (GST_BUFFER_IS_DISCONT (rtp->buffer)) {
416 417 418 419
    GST_WARNING_OBJECT (rtpgstdepay, "DISCONT, clear adapter");
    gst_adapter_clear (rtpgstdepay->adapter);
  }

420
  payload = gst_rtp_buffer_get_payload (rtp);
421 422 423 424 425 426

  /* strip off header
   *
   *  0                   1                   2                   3
   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Wim Taymans's avatar
Wim Taymans committed
427
   * |C| CV  |D|0|0|0|     ETYPE     |  MBZ                          |
428 429 430 431
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                          Frag_offset                          |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   */
432 433 434 435 436 437
  frag_offset =
      (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) | payload[7];

  avail = gst_adapter_available (rtpgstdepay->adapter);
  if (avail != frag_offset)
    goto wrong_frag;
438 439

  /* subbuffer skipping the 8 header bytes */
440
  subbuf = gst_rtp_buffer_get_payload_subbuffer (rtp, 8, -1);
441 442
  gst_adapter_push (rtpgstdepay->adapter, subbuf);

Wim Taymans's avatar
Wim Taymans committed
443
  offset = 0;
444
  if (gst_rtp_buffer_get_marker (rtp)) {
445 446 447 448 449 450 451 452 453 454
    guint avail;
    GstCaps *outcaps;

    /* take the buffer */
    avail = gst_adapter_available (rtpgstdepay->adapter);
    outbuf = gst_adapter_take_buffer (rtpgstdepay->adapter, avail);

    CV = (payload[0] >> 4) & 0x7;

    if (payload[0] & 0x80) {
Wim Taymans's avatar
Wim Taymans committed
455
      guint size;
456 457

      /* C bit, we have inline caps */
Wim Taymans's avatar
Wim Taymans committed
458 459 460
      outcaps = read_caps (rtpgstdepay, outbuf, &size);
      if (outcaps == NULL)
        goto no_caps;
461

Wim Taymans's avatar
Wim Taymans committed
462 463
      GST_DEBUG_OBJECT (rtpgstdepay,
          "inline caps %u, length %u, %" GST_PTR_FORMAT, CV, size, outcaps);
Wim Taymans's avatar
Wim Taymans committed
464

Wim Taymans's avatar
Wim Taymans committed
465
      store_cache (rtpgstdepay, CV, outcaps);
466 467

      /* skip caps */
Wim Taymans's avatar
Wim Taymans committed
468 469
      offset += size;
      avail -= size;
470
    }
Wim Taymans's avatar
Wim Taymans committed
471 472 473
    if (payload[1]) {
      guint size;
      GstEvent *event;
474

Wim Taymans's avatar
Wim Taymans committed
475 476 477 478
      /* we have an event */
      event = read_event (rtpgstdepay, payload[1], outbuf, &size);
      if (event == NULL)
        goto no_event;
479 480

      GST_DEBUG_OBJECT (rtpgstdepay,
Wim Taymans's avatar
Wim Taymans committed
481 482
          "inline event, length %u, %" GST_PTR_FORMAT, size, event);

483
      store_event (rtpgstdepay, event);
484

Wim Taymans's avatar
Wim Taymans committed
485 486
      /* no buffer after event */
      avail = 0;
487 488
    }

Wim Taymans's avatar
Wim Taymans committed
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
    if (avail) {
      if (offset != 0) {
        GstBuffer *temp;

        GST_DEBUG_OBJECT (rtpgstdepay, "sub buffer: offset %u, size %u", offset,
            avail);

        temp =
            gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, offset, avail);

        gst_buffer_unref (outbuf);
        outbuf = temp;
      }

      /* see what caps we need */
      if (CV != rtpgstdepay->current_CV) {
        /* we need to switch caps, check if we have the caps */
        if ((outcaps = rtpgstdepay->CV_cache[CV]) == NULL)
          goto missing_caps;

        GST_DEBUG_OBJECT (rtpgstdepay,
            "need caps switch from %u to %u, %" GST_PTR_FORMAT,
            rtpgstdepay->current_CV, CV, outcaps);

        /* and set caps */
        if (gst_pad_set_caps (depayload->srcpad, outcaps))
          rtpgstdepay->current_CV = CV;
      }

518 519
      if (payload[0] & 0x8)
        GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
Wim Taymans's avatar
Wim Taymans committed
520 521 522
    } else {
      gst_buffer_unref (outbuf);
      outbuf = NULL;
523 524
    }
  }
Wim Taymans's avatar
Wim Taymans committed
525

526 527 528 529
  if (outbuf) {
    gst_rtp_drop_meta (GST_ELEMENT_CAST (rtpgstdepay), outbuf, 0);
  }

530 531 532 533 534 535 536 537 538
  return outbuf;

  /* ERRORS */
empty_packet:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("Empty Payload."), (NULL));
    return NULL;
  }
539 540 541 542 543 544
wrong_frag:
  {
    gst_adapter_clear (rtpgstdepay->adapter);
    GST_LOG_OBJECT (rtpgstdepay, "wrong fragment, skipping");
    return NULL;
  }
Wim Taymans's avatar
Wim Taymans committed
545
no_caps:
546
  {
Wim Taymans's avatar
Wim Taymans committed
547 548 549 550 551 552 553 554
    GST_WARNING_OBJECT (rtpgstdepay, "failed to parse caps");
    gst_buffer_unref (outbuf);
    return NULL;
  }
no_event:
  {
    GST_WARNING_OBJECT (rtpgstdepay, "failed to parse event");
    gst_buffer_unref (outbuf);
555 556 557 558 559 560
    return NULL;
  }
missing_caps:
  {
    GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
        ("Missing caps %u.", CV), (NULL));
Wim Taymans's avatar
Wim Taymans committed
561
    gst_buffer_unref (outbuf);
562 563 564 565
    return NULL;
  }
}

566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
static gboolean
gst_rtp_gst_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * event)
{
  GstRtpGSTDepay *rtpgstdepay;

  rtpgstdepay = GST_RTP_GST_DEPAY (depay);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_rtp_gst_depay_reset (rtpgstdepay, FALSE);
      break;
    default:
      break;
  }

  return
      GST_RTP_BASE_DEPAYLOAD_CLASS (parent_class)->handle_event (depay, event);
}


Wim Taymans's avatar
Wim Taymans committed
586 587 588 589 590 591 592 593 594 595
static GstStateChangeReturn
gst_rtp_gst_depay_change_state (GstElement * element, GstStateChange transition)
{
  GstRtpGSTDepay *rtpgstdepay;
  GstStateChangeReturn ret;

  rtpgstdepay = GST_RTP_GST_DEPAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
596
      gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
Wim Taymans's avatar
Wim Taymans committed
597 598 599 600 601 602 603 604 605
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
606
      gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
Wim Taymans's avatar
Wim Taymans committed
607 608 609 610 611 612 613 614
      break;
    default:
      break;
  }
  return ret;
}


615 616 617 618 619 620
gboolean
gst_rtp_gst_depay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpgstdepay",
      GST_RANK_MARGINAL, GST_TYPE_RTP_GST_DEPAY);
}