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; }
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; } }