gst_plugins_good/gst/qtdemux/gstrtpxqtdepay.c
author hgs
Wed, 24 Mar 2010 18:04:17 -0500
changeset 16 8e837d1bf446
permissions -rw-r--r--
201009
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16
hgs
parents:
diff changeset
     1
/* GStreamer
hgs
parents:
diff changeset
     2
 * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
hgs
parents:
diff changeset
     3
 *
hgs
parents:
diff changeset
     4
 * This library is free software; you can redistribute it and/or
hgs
parents:
diff changeset
     5
 * modify it under the terms of the GNU Library General Public
hgs
parents:
diff changeset
     6
 * License as published by the Free Software Foundation; either
hgs
parents:
diff changeset
     7
 * version 2 of the License, or (at your option) any later version.
hgs
parents:
diff changeset
     8
 *
hgs
parents:
diff changeset
     9
 * This library is distributed in the hope that it will be useful,
hgs
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
hgs
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
hgs
parents:
diff changeset
    12
 * Library General Public License for more details.
hgs
parents:
diff changeset
    13
 *
hgs
parents:
diff changeset
    14
 * You should have received a copy of the GNU Library General Public
hgs
parents:
diff changeset
    15
 * License along with this library; if not, write to the
hgs
parents:
diff changeset
    16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
hgs
parents:
diff changeset
    17
 * Boston, MA 02111-1307, USA.
hgs
parents:
diff changeset
    18
 */
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
/*
hgs
parents:
diff changeset
    21
 * based on http://developer.apple.com/quicktime/icefloe/dispatch026.html
hgs
parents:
diff changeset
    22
 */
hgs
parents:
diff changeset
    23
#ifdef HAVE_CONFIG_H
hgs
parents:
diff changeset
    24
#  include "config.h"
hgs
parents:
diff changeset
    25
#endif
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
#include <gst/rtp/gstrtpbuffer.h>
hgs
parents:
diff changeset
    28
hgs
parents:
diff changeset
    29
#include <string.h>
hgs
parents:
diff changeset
    30
#include "gstrtpxqtdepay.h"
hgs
parents:
diff changeset
    31
hgs
parents:
diff changeset
    32
#define MAKE_TLV(a,b)  (((a)<<8)|(b))
hgs
parents:
diff changeset
    33
hgs
parents:
diff changeset
    34
#define TLV_sd	MAKE_TLV ('s','d')
hgs
parents:
diff changeset
    35
#define TLV_qt	MAKE_TLV ('q','t')
hgs
parents:
diff changeset
    36
#define TLV_ti	MAKE_TLV ('t','i')
hgs
parents:
diff changeset
    37
#define TLV_ly	MAKE_TLV ('l','y')
hgs
parents:
diff changeset
    38
#define TLV_vo	MAKE_TLV ('v','o')
hgs
parents:
diff changeset
    39
#define TLV_mx	MAKE_TLV ('m','x')
hgs
parents:
diff changeset
    40
#define TLV_tr	MAKE_TLV ('t','r')
hgs
parents:
diff changeset
    41
#define TLV_tw	MAKE_TLV ('t','w')
hgs
parents:
diff changeset
    42
#define TLV_th	MAKE_TLV ('t','h')
hgs
parents:
diff changeset
    43
#define TLV_la	MAKE_TLV ('l','a')
hgs
parents:
diff changeset
    44
#define TLV_rt	MAKE_TLV ('r','t')
hgs
parents:
diff changeset
    45
#define TLV_gm	MAKE_TLV ('g','m')
hgs
parents:
diff changeset
    46
#define TLV_oc	MAKE_TLV ('o','c')
hgs
parents:
diff changeset
    47
#define TLV_cr	MAKE_TLV ('c','r')
hgs
parents:
diff changeset
    48
#define TLV_du	MAKE_TLV ('d','u')
hgs
parents:
diff changeset
    49
#define TLV_po	MAKE_TLV ('p','o')
hgs
parents:
diff changeset
    50
hgs
parents:
diff changeset
    51
#define QT_UINT32(a)  (GST_READ_UINT32_BE(a))
hgs
parents:
diff changeset
    52
#define QT_UINT24(a)  (GST_READ_UINT32_BE(a) >> 8)
hgs
parents:
diff changeset
    53
#define QT_UINT16(a)  (GST_READ_UINT16_BE(a))
hgs
parents:
diff changeset
    54
#define QT_UINT8(a)   (GST_READ_UINT8(a))
hgs
parents:
diff changeset
    55
#define QT_FP32(a)    ((GST_READ_UINT32_BE(a))/65536.0)
hgs
parents:
diff changeset
    56
#define QT_FP16(a)    ((GST_READ_UINT16_BE(a))/256.0)
hgs
parents:
diff changeset
    57
#define QT_FOURCC(a)  (GST_READ_UINT32_LE(a))
hgs
parents:
diff changeset
    58
#define QT_UINT64(a)  ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4))
hgs
parents:
diff changeset
    59
hgs
parents:
diff changeset
    60
#define FOURCC_avc1     GST_MAKE_FOURCC('a','v','c','1')
hgs
parents:
diff changeset
    61
#define FOURCC_avcC     GST_MAKE_FOURCC('a','v','c','C')
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug);
hgs
parents:
diff changeset
    64
#define GST_CAT_DEFAULT (rtpxqtdepay_debug)
hgs
parents:
diff changeset
    65
hgs
parents:
diff changeset
    66
/* elementfactory information */
hgs
parents:
diff changeset
    67
static const GstElementDetails gst_rtp_xqtdepay_details =
hgs
parents:
diff changeset
    68
GST_ELEMENT_DETAILS ("RTP packet depayloader",
hgs
parents:
diff changeset
    69
    "Codec/Depayloader/Network",
hgs
parents:
diff changeset
    70
    "Extracts Quicktime audio/video from RTP packets",
hgs
parents:
diff changeset
    71
    "Wim Taymans <wim@fluendo.com>");
hgs
parents:
diff changeset
    72
hgs
parents:
diff changeset
    73
/* RtpXQTDepay signals and args */
hgs
parents:
diff changeset
    74
enum
hgs
parents:
diff changeset
    75
{
hgs
parents:
diff changeset
    76
  /* FILL ME */
hgs
parents:
diff changeset
    77
  LAST_SIGNAL
hgs
parents:
diff changeset
    78
};
hgs
parents:
diff changeset
    79
hgs
parents:
diff changeset
    80
enum
hgs
parents:
diff changeset
    81
{
hgs
parents:
diff changeset
    82
  ARG_0,
hgs
parents:
diff changeset
    83
};
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
static GstStaticPadTemplate gst_rtp_xqt_depay_src_template =
hgs
parents:
diff changeset
    86
GST_STATIC_PAD_TEMPLATE ("src",
hgs
parents:
diff changeset
    87
    GST_PAD_SRC,
hgs
parents:
diff changeset
    88
    GST_PAD_ALWAYS,
hgs
parents:
diff changeset
    89
    GST_STATIC_CAPS_ANY);
hgs
parents:
diff changeset
    90
hgs
parents:
diff changeset
    91
static GstStaticPadTemplate gst_rtp_xqt_depay_sink_template =
hgs
parents:
diff changeset
    92
GST_STATIC_PAD_TEMPLATE ("sink",
hgs
parents:
diff changeset
    93
    GST_PAD_SINK,
hgs
parents:
diff changeset
    94
    GST_PAD_ALWAYS,
hgs
parents:
diff changeset
    95
    GST_STATIC_CAPS ("application/x-rtp, "
hgs
parents:
diff changeset
    96
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
hgs
parents:
diff changeset
    97
        "media = (string) { \"audio\", \"video\" }, clock-rate = (int) [1, MAX], "
hgs
parents:
diff changeset
    98
        "encoding-name = (string) { \"X-QT\", \"X-QUICKTIME\" }")
hgs
parents:
diff changeset
    99
    );
hgs
parents:
diff changeset
   100
hgs
parents:
diff changeset
   101
GST_BOILERPLATE (GstRtpXQTDepay, gst_rtp_xqt_depay, GstBaseRTPDepayload,
hgs
parents:
diff changeset
   102
    GST_TYPE_BASE_RTP_DEPAYLOAD);
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
static void gst_rtp_xqt_depay_finalize (GObject * object);
hgs
parents:
diff changeset
   105
hgs
parents:
diff changeset
   106
static gboolean gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload,
hgs
parents:
diff changeset
   107
    GstCaps * caps);
hgs
parents:
diff changeset
   108
static GstBuffer *gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload,
hgs
parents:
diff changeset
   109
    GstBuffer * buf);
hgs
parents:
diff changeset
   110
hgs
parents:
diff changeset
   111
static GstStateChangeReturn gst_rtp_xqt_depay_change_state (GstElement *
hgs
parents:
diff changeset
   112
    element, GstStateChange transition);
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
static void
hgs
parents:
diff changeset
   115
gst_rtp_xqt_depay_base_init (gpointer klass)
hgs
parents:
diff changeset
   116
{
hgs
parents:
diff changeset
   117
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
  gst_element_class_add_pad_template (element_class,
hgs
parents:
diff changeset
   120
      gst_static_pad_template_get (&gst_rtp_xqt_depay_src_template));
hgs
parents:
diff changeset
   121
  gst_element_class_add_pad_template (element_class,
hgs
parents:
diff changeset
   122
      gst_static_pad_template_get (&gst_rtp_xqt_depay_sink_template));
hgs
parents:
diff changeset
   123
hgs
parents:
diff changeset
   124
  gst_element_class_set_details (element_class, &gst_rtp_xqtdepay_details);
hgs
parents:
diff changeset
   125
}
hgs
parents:
diff changeset
   126
hgs
parents:
diff changeset
   127
static void
hgs
parents:
diff changeset
   128
gst_rtp_xqt_depay_class_init (GstRtpXQTDepayClass * klass)
hgs
parents:
diff changeset
   129
{
hgs
parents:
diff changeset
   130
  GObjectClass *gobject_class;
hgs
parents:
diff changeset
   131
  GstElementClass *gstelement_class;
hgs
parents:
diff changeset
   132
  GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
  gobject_class = (GObjectClass *) klass;
hgs
parents:
diff changeset
   135
  gstelement_class = (GstElementClass *) klass;
hgs
parents:
diff changeset
   136
  gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
hgs
parents:
diff changeset
   137
hgs
parents:
diff changeset
   138
  parent_class = g_type_class_peek_parent (klass);
hgs
parents:
diff changeset
   139
hgs
parents:
diff changeset
   140
  gobject_class->finalize = gst_rtp_xqt_depay_finalize;
hgs
parents:
diff changeset
   141
hgs
parents:
diff changeset
   142
  gstelement_class->change_state = gst_rtp_xqt_depay_change_state;
hgs
parents:
diff changeset
   143
hgs
parents:
diff changeset
   144
  gstbasertpdepayload_class->set_caps = gst_rtp_xqt_depay_setcaps;
hgs
parents:
diff changeset
   145
  gstbasertpdepayload_class->process = gst_rtp_xqt_depay_process;
hgs
parents:
diff changeset
   146
hgs
parents:
diff changeset
   147
  GST_DEBUG_CATEGORY_INIT (rtpxqtdepay_debug, "rtpxqtdepay", 0,
hgs
parents:
diff changeset
   148
      "QT Media RTP Depayloader");
hgs
parents:
diff changeset
   149
}
hgs
parents:
diff changeset
   150
hgs
parents:
diff changeset
   151
static void
hgs
parents:
diff changeset
   152
gst_rtp_xqt_depay_init (GstRtpXQTDepay * rtpxqtdepay,
hgs
parents:
diff changeset
   153
    GstRtpXQTDepayClass * klass)
hgs
parents:
diff changeset
   154
{
hgs
parents:
diff changeset
   155
  rtpxqtdepay->adapter = gst_adapter_new ();
hgs
parents:
diff changeset
   156
}
hgs
parents:
diff changeset
   157
hgs
parents:
diff changeset
   158
static void
hgs
parents:
diff changeset
   159
gst_rtp_xqt_depay_finalize (GObject * object)
hgs
parents:
diff changeset
   160
{
hgs
parents:
diff changeset
   161
  GstRtpXQTDepay *rtpxqtdepay;
hgs
parents:
diff changeset
   162
hgs
parents:
diff changeset
   163
  rtpxqtdepay = GST_RTP_XQT_DEPAY (object);
hgs
parents:
diff changeset
   164
hgs
parents:
diff changeset
   165
  g_object_unref (rtpxqtdepay->adapter);
hgs
parents:
diff changeset
   166
  rtpxqtdepay->adapter = NULL;
hgs
parents:
diff changeset
   167
hgs
parents:
diff changeset
   168
  G_OBJECT_CLASS (parent_class)->finalize (object);
hgs
parents:
diff changeset
   169
}
hgs
parents:
diff changeset
   170
hgs
parents:
diff changeset
   171
static gboolean
hgs
parents:
diff changeset
   172
gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
hgs
parents:
diff changeset
   173
    guint data_len)
hgs
parents:
diff changeset
   174
{
hgs
parents:
diff changeset
   175
  gint len;
hgs
parents:
diff changeset
   176
  guint32 fourcc;
hgs
parents:
diff changeset
   177
hgs
parents:
diff changeset
   178
  if (data_len < 8)
hgs
parents:
diff changeset
   179
    goto too_short;
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
  len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
hgs
parents:
diff changeset
   182
  if (len > data_len)
hgs
parents:
diff changeset
   183
    goto too_short;
hgs
parents:
diff changeset
   184
hgs
parents:
diff changeset
   185
  fourcc = QT_FOURCC (data + 4);
hgs
parents:
diff changeset
   186
hgs
parents:
diff changeset
   187
  GST_DEBUG_OBJECT (rtpxqtdepay, "parsing %" GST_FOURCC_FORMAT,
hgs
parents:
diff changeset
   188
      GST_FOURCC_ARGS (fourcc));
hgs
parents:
diff changeset
   189
hgs
parents:
diff changeset
   190
  switch (fourcc) {
hgs
parents:
diff changeset
   191
    case FOURCC_avc1:
hgs
parents:
diff changeset
   192
    {
hgs
parents:
diff changeset
   193
      guint32 chlen;
hgs
parents:
diff changeset
   194
hgs
parents:
diff changeset
   195
      if (len < 0x56)
hgs
parents:
diff changeset
   196
        goto too_short;
hgs
parents:
diff changeset
   197
      len -= 0x56;
hgs
parents:
diff changeset
   198
      data += 0x56;
hgs
parents:
diff changeset
   199
hgs
parents:
diff changeset
   200
      /* find avcC */
hgs
parents:
diff changeset
   201
      while (len >= 8) {
hgs
parents:
diff changeset
   202
        chlen = QT_UINT32 (data);
hgs
parents:
diff changeset
   203
        fourcc = QT_FOURCC (data + 4);
hgs
parents:
diff changeset
   204
        if (fourcc == FOURCC_avcC) {
hgs
parents:
diff changeset
   205
          GstBuffer *buf;
hgs
parents:
diff changeset
   206
          gint size;
hgs
parents:
diff changeset
   207
          GstCaps *caps;
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
          GST_DEBUG_OBJECT (rtpxqtdepay, "found avcC codec_data in sd, %u",
hgs
parents:
diff changeset
   210
              chlen);
hgs
parents:
diff changeset
   211
hgs
parents:
diff changeset
   212
          /* parse, if found */
hgs
parents:
diff changeset
   213
          if (chlen < len)
hgs
parents:
diff changeset
   214
            size = chlen - 8;
hgs
parents:
diff changeset
   215
          else
hgs
parents:
diff changeset
   216
            size = len - 8;
hgs
parents:
diff changeset
   217
hgs
parents:
diff changeset
   218
          buf = gst_buffer_new_and_alloc (size);
hgs
parents:
diff changeset
   219
          memcpy (GST_BUFFER_DATA (buf), data + 8, size);
hgs
parents:
diff changeset
   220
          caps = gst_caps_new_simple ("video/x-h264",
hgs
parents:
diff changeset
   221
              "codec_data", GST_TYPE_BUFFER, buf, NULL);
hgs
parents:
diff changeset
   222
          gst_buffer_unref (buf);
hgs
parents:
diff changeset
   223
          gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD (rtpxqtdepay)->srcpad, caps);
hgs
parents:
diff changeset
   224
          gst_caps_unref (caps);
hgs
parents:
diff changeset
   225
          break;
hgs
parents:
diff changeset
   226
        }
hgs
parents:
diff changeset
   227
        len -= chlen;
hgs
parents:
diff changeset
   228
        data += chlen;
hgs
parents:
diff changeset
   229
      }
hgs
parents:
diff changeset
   230
      break;
hgs
parents:
diff changeset
   231
    }
hgs
parents:
diff changeset
   232
    default:
hgs
parents:
diff changeset
   233
      break;
hgs
parents:
diff changeset
   234
  }
hgs
parents:
diff changeset
   235
  return TRUE;
hgs
parents:
diff changeset
   236
hgs
parents:
diff changeset
   237
  /* ERRORS */
hgs
parents:
diff changeset
   238
too_short:
hgs
parents:
diff changeset
   239
  {
hgs
parents:
diff changeset
   240
    return FALSE;
hgs
parents:
diff changeset
   241
  }
hgs
parents:
diff changeset
   242
}
hgs
parents:
diff changeset
   243
hgs
parents:
diff changeset
   244
static gboolean
hgs
parents:
diff changeset
   245
gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
hgs
parents:
diff changeset
   246
{
hgs
parents:
diff changeset
   247
  GstStructure *structure;
hgs
parents:
diff changeset
   248
  gint clock_rate = 90000;      /* default */
hgs
parents:
diff changeset
   249
hgs
parents:
diff changeset
   250
  structure = gst_caps_get_structure (caps, 0);
hgs
parents:
diff changeset
   251
hgs
parents:
diff changeset
   252
  gst_structure_get_int (structure, "clock-rate", &clock_rate);
hgs
parents:
diff changeset
   253
  depayload->clock_rate = clock_rate;
hgs
parents:
diff changeset
   254
hgs
parents:
diff changeset
   255
  return TRUE;
hgs
parents:
diff changeset
   256
}
hgs
parents:
diff changeset
   257
hgs
parents:
diff changeset
   258
static GstBuffer *
hgs
parents:
diff changeset
   259
gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
hgs
parents:
diff changeset
   260
{
hgs
parents:
diff changeset
   261
  GstRtpXQTDepay *rtpxqtdepay;
hgs
parents:
diff changeset
   262
  GstBuffer *outbuf;
hgs
parents:
diff changeset
   263
  gboolean m;
hgs
parents:
diff changeset
   264
hgs
parents:
diff changeset
   265
  rtpxqtdepay = GST_RTP_XQT_DEPAY (depayload);
hgs
parents:
diff changeset
   266
hgs
parents:
diff changeset
   267
  if (!gst_rtp_buffer_validate (buf))
hgs
parents:
diff changeset
   268
    goto bad_packet;
hgs
parents:
diff changeset
   269
hgs
parents:
diff changeset
   270
  if (GST_BUFFER_IS_DISCONT (buf)) {
hgs
parents:
diff changeset
   271
    /* discont, clear adapter and try to find a new packet start */
hgs
parents:
diff changeset
   272
    gst_adapter_clear (rtpxqtdepay->adapter);
hgs
parents:
diff changeset
   273
    rtpxqtdepay->need_resync = TRUE;
hgs
parents:
diff changeset
   274
    GST_DEBUG_OBJECT (rtpxqtdepay, "we need resync");
hgs
parents:
diff changeset
   275
  }
hgs
parents:
diff changeset
   276
hgs
parents:
diff changeset
   277
  m = gst_rtp_buffer_get_marker (buf);
hgs
parents:
diff changeset
   278
  GST_LOG_OBJECT (rtpxqtdepay, "marker: %d", m);
hgs
parents:
diff changeset
   279
hgs
parents:
diff changeset
   280
  {
hgs
parents:
diff changeset
   281
    gint payload_len;
hgs
parents:
diff changeset
   282
    guint avail;
hgs
parents:
diff changeset
   283
    guint8 *payload;
hgs
parents:
diff changeset
   284
    guint32 timestamp;
hgs
parents:
diff changeset
   285
    guint8 ver, pck;
hgs
parents:
diff changeset
   286
    gboolean s, q, l, d;
hgs
parents:
diff changeset
   287
hgs
parents:
diff changeset
   288
    payload_len = gst_rtp_buffer_get_payload_len (buf);
hgs
parents:
diff changeset
   289
    payload = gst_rtp_buffer_get_payload (buf);
hgs
parents:
diff changeset
   290
hgs
parents:
diff changeset
   291
    /*                      1                   2                   3 
hgs
parents:
diff changeset
   292
     *  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
hgs
parents:
diff changeset
   293
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   294
     * | VER   |PCK|S|Q|L| RES         |D| QuickTime Payload ID        |
hgs
parents:
diff changeset
   295
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   296
     */
hgs
parents:
diff changeset
   297
    if (payload_len <= 4)
hgs
parents:
diff changeset
   298
      goto wrong_length;
hgs
parents:
diff changeset
   299
hgs
parents:
diff changeset
   300
    ver = (payload[0] & 0xf0) >> 4;
hgs
parents:
diff changeset
   301
    if (ver > 1)
hgs
parents:
diff changeset
   302
      goto wrong_version;
hgs
parents:
diff changeset
   303
hgs
parents:
diff changeset
   304
    pck = (payload[0] & 0x0c) >> 2;
hgs
parents:
diff changeset
   305
    if (pck == 0)
hgs
parents:
diff changeset
   306
      goto pck_reserved;
hgs
parents:
diff changeset
   307
hgs
parents:
diff changeset
   308
    s = (payload[0] & 0x02) != 0;       /* contains sync sample */
hgs
parents:
diff changeset
   309
    q = (payload[0] & 0x01) != 0;       /* has payload description */
hgs
parents:
diff changeset
   310
    l = (payload[1] & 0x80) != 0;       /* has packet specific information description */
hgs
parents:
diff changeset
   311
    d = (payload[2] & 0x80) != 0;       /* don't cache info for payload id */
hgs
parents:
diff changeset
   312
    /* id used for caching info */
hgs
parents:
diff changeset
   313
    rtpxqtdepay->current_id = ((payload[2] & 0x7f) << 8) | payload[3];
hgs
parents:
diff changeset
   314
hgs
parents:
diff changeset
   315
    GST_LOG_OBJECT (rtpxqtdepay,
hgs
parents:
diff changeset
   316
        "VER: %d, PCK: %d, S: %d, Q: %d, L: %d, D: %d, ID: %d", ver, pck, s, q,
hgs
parents:
diff changeset
   317
        l, d, rtpxqtdepay->current_id);
hgs
parents:
diff changeset
   318
hgs
parents:
diff changeset
   319
    if (rtpxqtdepay->need_resync) {
hgs
parents:
diff changeset
   320
      /* we need to find the boundary of a new packet after a DISCONT */
hgs
parents:
diff changeset
   321
      if (pck != 3 || q) {
hgs
parents:
diff changeset
   322
        /* non-fragmented packet or payload description present, packet starts
hgs
parents:
diff changeset
   323
         * here. */
hgs
parents:
diff changeset
   324
        rtpxqtdepay->need_resync = FALSE;
hgs
parents:
diff changeset
   325
      } else {
hgs
parents:
diff changeset
   326
        /* fragmented packet without description */
hgs
parents:
diff changeset
   327
        if (m) {
hgs
parents:
diff changeset
   328
          /* marker bit set, next packet is start of new one */
hgs
parents:
diff changeset
   329
          rtpxqtdepay->need_resync = FALSE;
hgs
parents:
diff changeset
   330
        }
hgs
parents:
diff changeset
   331
        goto need_resync;
hgs
parents:
diff changeset
   332
      }
hgs
parents:
diff changeset
   333
    }
hgs
parents:
diff changeset
   334
hgs
parents:
diff changeset
   335
    payload += 4;
hgs
parents:
diff changeset
   336
    payload_len -= 4;
hgs
parents:
diff changeset
   337
hgs
parents:
diff changeset
   338
    if (q) {
hgs
parents:
diff changeset
   339
      gboolean k, f, a, z;
hgs
parents:
diff changeset
   340
      guint pdlen, pdpadded;
hgs
parents:
diff changeset
   341
      gint padding;
hgs
parents:
diff changeset
   342
      guint32 media_type, timescale;
hgs
parents:
diff changeset
   343
hgs
parents:
diff changeset
   344
      /*                      1                   2                   3
hgs
parents:
diff changeset
   345
       *  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
hgs
parents:
diff changeset
   346
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   347
       * |K|F|A|Z| RES                   | QuickTime Payload Desc Length |
hgs
parents:
diff changeset
   348
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   349
       * . QuickTime Payload Desc Data ... . 
hgs
parents:
diff changeset
   350
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   351
       */
hgs
parents:
diff changeset
   352
      if (payload_len <= 4)
hgs
parents:
diff changeset
   353
        goto wrong_length;
hgs
parents:
diff changeset
   354
hgs
parents:
diff changeset
   355
      k = (payload[0] & 0x80) != 0;     /* keyframe */
hgs
parents:
diff changeset
   356
      f = (payload[0] & 0x40) != 0;     /* sparse */
hgs
parents:
diff changeset
   357
      a = (payload[0] & 0x20) != 0;     /* start of payload */
hgs
parents:
diff changeset
   358
      z = (payload[0] & 0x10) != 0;     /* end of payload */
hgs
parents:
diff changeset
   359
      pdlen = (payload[2] << 8) | payload[3];
hgs
parents:
diff changeset
   360
hgs
parents:
diff changeset
   361
      if (pdlen < 12)
hgs
parents:
diff changeset
   362
        goto wrong_length;
hgs
parents:
diff changeset
   363
hgs
parents:
diff changeset
   364
      /* calc padding */
hgs
parents:
diff changeset
   365
      pdpadded = pdlen + 3;
hgs
parents:
diff changeset
   366
      pdpadded -= pdpadded % 4;
hgs
parents:
diff changeset
   367
      if (payload_len < pdpadded)
hgs
parents:
diff changeset
   368
        goto wrong_length;
hgs
parents:
diff changeset
   369
hgs
parents:
diff changeset
   370
      padding = pdpadded - pdlen;
hgs
parents:
diff changeset
   371
      GST_LOG_OBJECT (rtpxqtdepay,
hgs
parents:
diff changeset
   372
          "K: %d, F: %d, A: %d, Z: %d, len: %d, padding %d", k, f, a, z, pdlen,
hgs
parents:
diff changeset
   373
          padding);
hgs
parents:
diff changeset
   374
hgs
parents:
diff changeset
   375
      payload += 4;
hgs
parents:
diff changeset
   376
      payload_len -= 4;
hgs
parents:
diff changeset
   377
      /*                      1                   2                   3
hgs
parents:
diff changeset
   378
       *  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
hgs
parents:
diff changeset
   379
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   380
       * | QuickTime Media Type                                          |
hgs
parents:
diff changeset
   381
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   382
       * | Timescale                                                     |
hgs
parents:
diff changeset
   383
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   384
       * . QuickTime TLVs ... .
hgs
parents:
diff changeset
   385
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   386
       */
hgs
parents:
diff changeset
   387
      media_type =
hgs
parents:
diff changeset
   388
          (payload[0] << 24) | (payload[1] << 16) | (payload[2] << 8) |
hgs
parents:
diff changeset
   389
          payload[3];
hgs
parents:
diff changeset
   390
      timescale =
hgs
parents:
diff changeset
   391
          (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) |
hgs
parents:
diff changeset
   392
          payload[7];
hgs
parents:
diff changeset
   393
hgs
parents:
diff changeset
   394
      GST_LOG_OBJECT (rtpxqtdepay, "media_type: %c%c%c%c, timescale %u",
hgs
parents:
diff changeset
   395
          payload[0], payload[1], payload[2], payload[3], timescale);
hgs
parents:
diff changeset
   396
hgs
parents:
diff changeset
   397
      payload += 8;
hgs
parents:
diff changeset
   398
      payload_len -= 8;
hgs
parents:
diff changeset
   399
      pdlen -= 12;
hgs
parents:
diff changeset
   400
hgs
parents:
diff changeset
   401
      /* parse TLV (type-length-value triplets */
hgs
parents:
diff changeset
   402
      while (pdlen > 3) {
hgs
parents:
diff changeset
   403
        guint16 tlv_len, tlv_type;
hgs
parents:
diff changeset
   404
hgs
parents:
diff changeset
   405
        /*                      1                   2                   3
hgs
parents:
diff changeset
   406
         *  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
hgs
parents:
diff changeset
   407
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   408
         * | QuickTime TLV Length          | QuickTime TLV Type            |
hgs
parents:
diff changeset
   409
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   410
         * . QuickTime TLV Value ... .
hgs
parents:
diff changeset
   411
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   412
         */
hgs
parents:
diff changeset
   413
        tlv_len = (payload[0] << 8) | payload[1];
hgs
parents:
diff changeset
   414
        tlv_type = (payload[2] << 8) | payload[3];
hgs
parents:
diff changeset
   415
        pdlen -= 4;
hgs
parents:
diff changeset
   416
        if (tlv_len > pdlen)
hgs
parents:
diff changeset
   417
          goto wrong_length;
hgs
parents:
diff changeset
   418
hgs
parents:
diff changeset
   419
        GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2],
hgs
parents:
diff changeset
   420
            payload[3], tlv_len);
hgs
parents:
diff changeset
   421
hgs
parents:
diff changeset
   422
        payload += 4;
hgs
parents:
diff changeset
   423
        payload_len -= 4;
hgs
parents:
diff changeset
   424
hgs
parents:
diff changeset
   425
        switch (tlv_type) {
hgs
parents:
diff changeset
   426
          case TLV_sd:
hgs
parents:
diff changeset
   427
            /* Session description */
hgs
parents:
diff changeset
   428
            if (!gst_rtp_quicktime_parse_sd (rtpxqtdepay, payload, tlv_len))
hgs
parents:
diff changeset
   429
              goto unknown_format;
hgs
parents:
diff changeset
   430
            rtpxqtdepay->have_sd = TRUE;
hgs
parents:
diff changeset
   431
            break;
hgs
parents:
diff changeset
   432
          case TLV_qt:
hgs
parents:
diff changeset
   433
          case TLV_ti:
hgs
parents:
diff changeset
   434
          case TLV_ly:
hgs
parents:
diff changeset
   435
          case TLV_vo:
hgs
parents:
diff changeset
   436
          case TLV_mx:
hgs
parents:
diff changeset
   437
          case TLV_tr:
hgs
parents:
diff changeset
   438
          case TLV_tw:
hgs
parents:
diff changeset
   439
          case TLV_th:
hgs
parents:
diff changeset
   440
          case TLV_la:
hgs
parents:
diff changeset
   441
          case TLV_rt:
hgs
parents:
diff changeset
   442
          case TLV_gm:
hgs
parents:
diff changeset
   443
          case TLV_oc:
hgs
parents:
diff changeset
   444
          case TLV_cr:
hgs
parents:
diff changeset
   445
          case TLV_du:
hgs
parents:
diff changeset
   446
          case TLV_po:
hgs
parents:
diff changeset
   447
          default:
hgs
parents:
diff changeset
   448
            break;
hgs
parents:
diff changeset
   449
        }
hgs
parents:
diff changeset
   450
hgs
parents:
diff changeset
   451
        pdlen -= tlv_len;
hgs
parents:
diff changeset
   452
        payload += tlv_len;
hgs
parents:
diff changeset
   453
        payload_len -= tlv_len;
hgs
parents:
diff changeset
   454
      }
hgs
parents:
diff changeset
   455
      payload += padding;
hgs
parents:
diff changeset
   456
      payload_len -= padding;
hgs
parents:
diff changeset
   457
    }
hgs
parents:
diff changeset
   458
hgs
parents:
diff changeset
   459
    if (l) {
hgs
parents:
diff changeset
   460
      guint ssilen, ssipadded;
hgs
parents:
diff changeset
   461
      gint padding;
hgs
parents:
diff changeset
   462
hgs
parents:
diff changeset
   463
      /*                      1                   2                   3
hgs
parents:
diff changeset
   464
       *  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
hgs
parents:
diff changeset
   465
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   466
       * | RES                           | Sample-Specific Info Length   |
hgs
parents:
diff changeset
   467
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   468
       * . QuickTime TLVs ... 
hgs
parents:
diff changeset
   469
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   470
       */
hgs
parents:
diff changeset
   471
      if (payload_len <= 4)
hgs
parents:
diff changeset
   472
        goto wrong_length;
hgs
parents:
diff changeset
   473
hgs
parents:
diff changeset
   474
      ssilen = (payload[2] << 8) | payload[3];
hgs
parents:
diff changeset
   475
      if (ssilen < 4)
hgs
parents:
diff changeset
   476
        goto wrong_length;
hgs
parents:
diff changeset
   477
hgs
parents:
diff changeset
   478
      /* calc padding */
hgs
parents:
diff changeset
   479
      ssipadded = ssilen + 3;
hgs
parents:
diff changeset
   480
      ssipadded -= ssipadded % 4;
hgs
parents:
diff changeset
   481
      if (payload_len < ssipadded)
hgs
parents:
diff changeset
   482
        goto wrong_length;
hgs
parents:
diff changeset
   483
hgs
parents:
diff changeset
   484
      padding = ssipadded - ssilen;
hgs
parents:
diff changeset
   485
      GST_LOG_OBJECT (rtpxqtdepay, "len: %d, padding %d", ssilen, padding);
hgs
parents:
diff changeset
   486
hgs
parents:
diff changeset
   487
      payload += 4;
hgs
parents:
diff changeset
   488
      payload_len -= 4;
hgs
parents:
diff changeset
   489
      ssilen -= 4;
hgs
parents:
diff changeset
   490
hgs
parents:
diff changeset
   491
      /* parse TLV (type-length-value triplets */
hgs
parents:
diff changeset
   492
      while (ssilen > 3) {
hgs
parents:
diff changeset
   493
        guint16 tlv_len, tlv_type;
hgs
parents:
diff changeset
   494
hgs
parents:
diff changeset
   495
        /*                      1                   2                   3
hgs
parents:
diff changeset
   496
         *  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
hgs
parents:
diff changeset
   497
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   498
         * | QuickTime TLV Length          | QuickTime TLV Type            |
hgs
parents:
diff changeset
   499
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   500
         * . QuickTime TLV Value ... .
hgs
parents:
diff changeset
   501
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   502
         */
hgs
parents:
diff changeset
   503
        tlv_len = (payload[0] << 8) | payload[1];
hgs
parents:
diff changeset
   504
        tlv_type = (payload[2] << 8) | payload[3];
hgs
parents:
diff changeset
   505
        ssilen -= 4;
hgs
parents:
diff changeset
   506
        if (tlv_len > ssilen)
hgs
parents:
diff changeset
   507
          goto wrong_length;
hgs
parents:
diff changeset
   508
hgs
parents:
diff changeset
   509
        GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2],
hgs
parents:
diff changeset
   510
            payload[3], tlv_len);
hgs
parents:
diff changeset
   511
hgs
parents:
diff changeset
   512
        payload += 4;
hgs
parents:
diff changeset
   513
        payload_len -= 4;
hgs
parents:
diff changeset
   514
hgs
parents:
diff changeset
   515
        switch (tlv_type) {
hgs
parents:
diff changeset
   516
          case TLV_sd:
hgs
parents:
diff changeset
   517
          case TLV_qt:
hgs
parents:
diff changeset
   518
          case TLV_ti:
hgs
parents:
diff changeset
   519
          case TLV_ly:
hgs
parents:
diff changeset
   520
          case TLV_vo:
hgs
parents:
diff changeset
   521
          case TLV_mx:
hgs
parents:
diff changeset
   522
          case TLV_tr:
hgs
parents:
diff changeset
   523
          case TLV_tw:
hgs
parents:
diff changeset
   524
          case TLV_th:
hgs
parents:
diff changeset
   525
          case TLV_la:
hgs
parents:
diff changeset
   526
          case TLV_rt:
hgs
parents:
diff changeset
   527
          case TLV_gm:
hgs
parents:
diff changeset
   528
          case TLV_oc:
hgs
parents:
diff changeset
   529
          case TLV_cr:
hgs
parents:
diff changeset
   530
          case TLV_du:
hgs
parents:
diff changeset
   531
          case TLV_po:
hgs
parents:
diff changeset
   532
          default:
hgs
parents:
diff changeset
   533
            break;
hgs
parents:
diff changeset
   534
        }
hgs
parents:
diff changeset
   535
hgs
parents:
diff changeset
   536
        ssilen -= tlv_len;
hgs
parents:
diff changeset
   537
        payload += tlv_len;
hgs
parents:
diff changeset
   538
        payload_len -= tlv_len;
hgs
parents:
diff changeset
   539
      }
hgs
parents:
diff changeset
   540
      payload += padding;
hgs
parents:
diff changeset
   541
      payload_len -= padding;
hgs
parents:
diff changeset
   542
    }
hgs
parents:
diff changeset
   543
hgs
parents:
diff changeset
   544
    timestamp = gst_rtp_buffer_get_timestamp (buf);
hgs
parents:
diff changeset
   545
    rtpxqtdepay->previous_id = rtpxqtdepay->current_id;
hgs
parents:
diff changeset
   546
hgs
parents:
diff changeset
   547
    switch (pck) {
hgs
parents:
diff changeset
   548
      case 1:
hgs
parents:
diff changeset
   549
      {
hgs
parents:
diff changeset
   550
        /* multiple samples per packet. */
hgs
parents:
diff changeset
   551
        outbuf = gst_buffer_new_and_alloc (payload_len);
hgs
parents:
diff changeset
   552
        memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
hgs
parents:
diff changeset
   553
        return outbuf;
hgs
parents:
diff changeset
   554
      }
hgs
parents:
diff changeset
   555
      case 2:
hgs
parents:
diff changeset
   556
      {
hgs
parents:
diff changeset
   557
        guint slen, timestamp;
hgs
parents:
diff changeset
   558
hgs
parents:
diff changeset
   559
        /* multiple samples per packet. 
hgs
parents:
diff changeset
   560
         *                      1                   2                   3
hgs
parents:
diff changeset
   561
         *  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
hgs
parents:
diff changeset
   562
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   563
         * |S| Reserved                    | Sample Length                 |
hgs
parents:
diff changeset
   564
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   565
         * | Sample Timestamp                                              |
hgs
parents:
diff changeset
   566
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   567
         * . Sample Data ...                                               .
hgs
parents:
diff changeset
   568
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   569
         * |S| Reserved                    | Sample Length                 |
hgs
parents:
diff changeset
   570
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   571
         * | Sample Timestamp                                              |
hgs
parents:
diff changeset
   572
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   573
         * . Sample Data ...                                               .
hgs
parents:
diff changeset
   574
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   575
         * . ......                                                        .
hgs
parents:
diff changeset
   576
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
hgs
parents:
diff changeset
   577
         */
hgs
parents:
diff changeset
   578
        while (payload_len > 8) {
hgs
parents:
diff changeset
   579
          s = (payload[0] & 0x80) != 0; /* contains sync sample */
hgs
parents:
diff changeset
   580
          slen = (payload[2] << 8) | payload[3];
hgs
parents:
diff changeset
   581
          timestamp =
hgs
parents:
diff changeset
   582
              (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) |
hgs
parents:
diff changeset
   583
              payload[7];
hgs
parents:
diff changeset
   584
hgs
parents:
diff changeset
   585
          payload += 8;
hgs
parents:
diff changeset
   586
          payload_len -= 8;
hgs
parents:
diff changeset
   587
hgs
parents:
diff changeset
   588
          if (slen > payload_len)
hgs
parents:
diff changeset
   589
            slen = payload_len;
hgs
parents:
diff changeset
   590
hgs
parents:
diff changeset
   591
          outbuf = gst_buffer_new_and_alloc (slen);
hgs
parents:
diff changeset
   592
          memcpy (GST_BUFFER_DATA (outbuf), payload, slen);
hgs
parents:
diff changeset
   593
          if (!s)
hgs
parents:
diff changeset
   594
            GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
hgs
parents:
diff changeset
   595
hgs
parents:
diff changeset
   596
          gst_base_rtp_depayload_push (depayload, outbuf);
hgs
parents:
diff changeset
   597
hgs
parents:
diff changeset
   598
          /* aligned on 32 bit boundary */
hgs
parents:
diff changeset
   599
          slen = GST_ROUND_UP_4 (slen);
hgs
parents:
diff changeset
   600
hgs
parents:
diff changeset
   601
          payload += slen;
hgs
parents:
diff changeset
   602
          payload_len -= slen;
hgs
parents:
diff changeset
   603
        }
hgs
parents:
diff changeset
   604
        break;
hgs
parents:
diff changeset
   605
      }
hgs
parents:
diff changeset
   606
      case 3:
hgs
parents:
diff changeset
   607
      {
hgs
parents:
diff changeset
   608
        /* one sample per packet, use adapter to combine based on marker bit. */
hgs
parents:
diff changeset
   609
        outbuf = gst_buffer_new_and_alloc (payload_len);
hgs
parents:
diff changeset
   610
        memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
hgs
parents:
diff changeset
   611
hgs
parents:
diff changeset
   612
        gst_adapter_push (rtpxqtdepay->adapter, outbuf);
hgs
parents:
diff changeset
   613
hgs
parents:
diff changeset
   614
        if (!m)
hgs
parents:
diff changeset
   615
          goto done;
hgs
parents:
diff changeset
   616
hgs
parents:
diff changeset
   617
        avail = gst_adapter_available (rtpxqtdepay->adapter);
hgs
parents:
diff changeset
   618
        outbuf = gst_adapter_take_buffer (rtpxqtdepay->adapter, avail);
hgs
parents:
diff changeset
   619
hgs
parents:
diff changeset
   620
        GST_DEBUG_OBJECT (rtpxqtdepay,
hgs
parents:
diff changeset
   621
            "gst_rtp_xqt_depay_chain: pushing buffer of size %u", avail);
hgs
parents:
diff changeset
   622
hgs
parents:
diff changeset
   623
        return outbuf;
hgs
parents:
diff changeset
   624
      }
hgs
parents:
diff changeset
   625
    }
hgs
parents:
diff changeset
   626
  }
hgs
parents:
diff changeset
   627
hgs
parents:
diff changeset
   628
done:
hgs
parents:
diff changeset
   629
  return NULL;
hgs
parents:
diff changeset
   630
hgs
parents:
diff changeset
   631
bad_packet:
hgs
parents:
diff changeset
   632
  {
hgs
parents:
diff changeset
   633
    GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
hgs
parents:
diff changeset
   634
        ("Packet did not validate."), (NULL));
hgs
parents:
diff changeset
   635
    return NULL;
hgs
parents:
diff changeset
   636
  }
hgs
parents:
diff changeset
   637
need_resync:
hgs
parents:
diff changeset
   638
  {
hgs
parents:
diff changeset
   639
    GST_DEBUG_OBJECT (rtpxqtdepay, "waiting for marker");
hgs
parents:
diff changeset
   640
    return NULL;
hgs
parents:
diff changeset
   641
  }
hgs
parents:
diff changeset
   642
wrong_version:
hgs
parents:
diff changeset
   643
  {
hgs
parents:
diff changeset
   644
    GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
hgs
parents:
diff changeset
   645
        ("Unknown payload version."), (NULL));
hgs
parents:
diff changeset
   646
    return NULL;
hgs
parents:
diff changeset
   647
  }
hgs
parents:
diff changeset
   648
pck_reserved:
hgs
parents:
diff changeset
   649
  {
hgs
parents:
diff changeset
   650
    GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
hgs
parents:
diff changeset
   651
        ("PCK reserved 0."), (NULL));
hgs
parents:
diff changeset
   652
    return NULL;
hgs
parents:
diff changeset
   653
  }
hgs
parents:
diff changeset
   654
wrong_length:
hgs
parents:
diff changeset
   655
  {
hgs
parents:
diff changeset
   656
    GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
hgs
parents:
diff changeset
   657
        ("Wrong payload length."), (NULL));
hgs
parents:
diff changeset
   658
    return NULL;
hgs
parents:
diff changeset
   659
  }
hgs
parents:
diff changeset
   660
unknown_format:
hgs
parents:
diff changeset
   661
  {
hgs
parents:
diff changeset
   662
    GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
hgs
parents:
diff changeset
   663
        ("Unknown payload format."), (NULL));
hgs
parents:
diff changeset
   664
    return NULL;
hgs
parents:
diff changeset
   665
  }
hgs
parents:
diff changeset
   666
}
hgs
parents:
diff changeset
   667
hgs
parents:
diff changeset
   668
static GstStateChangeReturn
hgs
parents:
diff changeset
   669
gst_rtp_xqt_depay_change_state (GstElement * element, GstStateChange transition)
hgs
parents:
diff changeset
   670
{
hgs
parents:
diff changeset
   671
  GstRtpXQTDepay *rtpxqtdepay;
hgs
parents:
diff changeset
   672
  GstStateChangeReturn ret;
hgs
parents:
diff changeset
   673
hgs
parents:
diff changeset
   674
  rtpxqtdepay = GST_RTP_XQT_DEPAY (element);
hgs
parents:
diff changeset
   675
hgs
parents:
diff changeset
   676
  switch (transition) {
hgs
parents:
diff changeset
   677
    case GST_STATE_CHANGE_READY_TO_PAUSED:
hgs
parents:
diff changeset
   678
      gst_adapter_clear (rtpxqtdepay->adapter);
hgs
parents:
diff changeset
   679
      rtpxqtdepay->previous_id = -1;
hgs
parents:
diff changeset
   680
      rtpxqtdepay->current_id = -1;
hgs
parents:
diff changeset
   681
      rtpxqtdepay->need_resync = TRUE;
hgs
parents:
diff changeset
   682
      rtpxqtdepay->have_sd = FALSE;
hgs
parents:
diff changeset
   683
      break;
hgs
parents:
diff changeset
   684
    default:
hgs
parents:
diff changeset
   685
      break;
hgs
parents:
diff changeset
   686
  }
hgs
parents:
diff changeset
   687
hgs
parents:
diff changeset
   688
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
hgs
parents:
diff changeset
   689
hgs
parents:
diff changeset
   690
  switch (transition) {
hgs
parents:
diff changeset
   691
    case GST_STATE_CHANGE_PAUSED_TO_READY:
hgs
parents:
diff changeset
   692
      gst_adapter_clear (rtpxqtdepay->adapter);
hgs
parents:
diff changeset
   693
    default:
hgs
parents:
diff changeset
   694
      break;
hgs
parents:
diff changeset
   695
  }
hgs
parents:
diff changeset
   696
  return ret;
hgs
parents:
diff changeset
   697
}
hgs
parents:
diff changeset
   698
hgs
parents:
diff changeset
   699
gboolean
hgs
parents:
diff changeset
   700
gst_rtp_xqt_depay_plugin_init (GstPlugin * plugin)
hgs
parents:
diff changeset
   701
{
hgs
parents:
diff changeset
   702
  return gst_element_register (plugin, "rtpxqtdepay",
hgs
parents:
diff changeset
   703
      GST_RANK_MARGINAL, GST_TYPE_RTP_XQT_DEPAY);
hgs
parents:
diff changeset
   704
}