예제 #1
0
static ImageDescription *
image_description_from_stsd_buffer (GstBuffer * buf)
{
  ImageDescription *desc = NULL;
  guint8 *content;
  guint size;
  gint imds;

  GST_LOG ("buffer %p, size:%u", buf, GST_BUFFER_SIZE (buf));

  /* The buffer contains a full atom, we only need the contents */
  /* This buffer has data in big-endian, we need to read it as such.
   * except for the fourcc which are ALWAYS big-endian. */
  content = GST_BUFFER_DATA (buf) + 16;
  size = GST_BUFFER_SIZE (buf) - 16;

#if DEBUG_DUMP
  GST_LOG ("incoming data in big-endian");
  gst_util_dump_mem (content, size);
#endif

  desc = g_malloc0 (size);
  desc->idSize = size;
  desc->cType = GST_READ_UINT32_BE (content + 4);
  desc->version = QT_UINT16 (content + 16);
  desc->revisionLevel = QT_UINT16 (content + 18);
  desc->vendor = GST_READ_UINT32_BE (content + 20);
  desc->temporalQuality = QT_UINT32 (content + 24);
  desc->spatialQuality = QT_UINT32 (content + 24);
  desc->dataSize = QT_UINT32 (content + 44);
  desc->frameCount = QT_UINT16 (content + 48);
  desc->depth = QT_UINT16 (content + 82);
  desc->clutID = QT_UINT16 (content + 84);

  imds = 86;                    /* sizeof (ImageDescription); */

  if (desc->idSize > imds) {
    GST_LOG ("Copying %d bytes from %p to %p",
        size - imds, content + imds, desc + imds);
    memcpy ((guint8 *) desc + imds, (guint8 *) content + imds, size - imds);
  }
#if DEBUG_DUMP
  GST_LOG ("outgoing data in machine-endian");
  dump_image_description (desc);
#endif

  return desc;
}
예제 #2
0
static gboolean
gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
    guint data_len)
{
  gint len;
  guint32 fourcc;

  if (data_len < 8)
    goto too_short;

  len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
  if (len > data_len)
    goto too_short;

  fourcc = QT_FOURCC (data + 4);

  GST_DEBUG_OBJECT (rtpxqtdepay, "parsing %" GST_FOURCC_FORMAT,
      GST_FOURCC_ARGS (fourcc));

  switch (fourcc) {
    case FOURCC_avc1:
    {
      guint32 chlen;

      if (len < 0x56)
        goto too_short;
      len -= 0x56;
      data += 0x56;

      /* find avcC */
      while (len >= 8) {
        chlen = QT_UINT32 (data);
        fourcc = QT_FOURCC (data + 4);
        if (fourcc == FOURCC_avcC) {
          GstBuffer *buf;
          gint size;
          GstCaps *caps;

          GST_DEBUG_OBJECT (rtpxqtdepay, "found avcC codec_data in sd, %u",
              chlen);

          /* parse, if found */
          if (chlen < len)
            size = chlen - 8;
          else
            size = len - 8;

          buf = gst_buffer_new_and_alloc (size);
          gst_buffer_fill (buf, 0, data + 8, size);
          caps = gst_caps_new_simple ("video/x-h264",
              "codec_data", GST_TYPE_BUFFER, buf, NULL);
          gst_buffer_unref (buf);
          gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD (rtpxqtdepay)->srcpad, caps);
          gst_caps_unref (caps);
          break;
        }
        len -= chlen;
        data += chlen;
      }
      break;
    }
    default:
      break;
  }
  return TRUE;

  /* ERRORS */
too_short:
  {
    return FALSE;
  }
}