#define GST_CAT_DEFAULT qtdemux_debug
typedef struct _QtDemuxCencSampleSetInfo QtDemuxCencSampleSetInfo;
+typedef struct _QtDemuxAavdEncryptionInfo QtDemuxAavdEncryptionInfo;
/* Macros for converting to/from timescale */
#define QTSTREAMTIME_TO_GSTTIME(stream, value) (gst_util_uint64_scale((value), GST_SECOND, (stream)->timescale))
GPtrArray *crypto_info;
};
+struct _QtDemuxAavdEncryptionInfo
+{
+ GstStructure *default_properties;
+};
+
static const gchar *
qt_demux_state_string (enum QtDemuxState state)
{
if (info->crypto_info)
g_ptr_array_free (info->crypto_info, TRUE);
}
+ if (stream->protection_scheme_type == FOURCC_aavd) {
+ QtDemuxAavdEncryptionInfo *info =
+ (QtDemuxAavdEncryptionInfo *) stream->protection_scheme_info;
+ if (info->default_properties)
+ gst_structure_free (info->default_properties);
+ }
g_free (stream->protection_scheme_info);
stream->protection_scheme_info = NULL;
}
GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_PAD_NAME (stream->pad));
+ if (stream->protected && stream->protection_scheme_type == FOURCC_aavd) {
+ GstStructure *crypto_info;
+ QtDemuxAavdEncryptionInfo *info =
+ (QtDemuxAavdEncryptionInfo *) stream->protection_scheme_info;
+
+ crypto_info = gst_structure_copy (info->default_properties);
+ if (!crypto_info || !gst_buffer_add_protection_meta (buf, crypto_info))
+ GST_ERROR_OBJECT (qtdemux, "failed to attach aavd metadata to buffer");
+ }
+
if (stream->protected && stream->protection_scheme_type == FOURCC_cenc) {
GstStructure *crypto_info;
QtDemuxCencSampleSetInfo *info =
g_return_val_if_fail (gst_caps_get_size (CUR_STREAM (stream)->caps) == 1,
FALSE);
+ if (stream->protection_scheme_type == FOURCC_aavd) {
+ s = gst_caps_get_structure (CUR_STREAM (stream)->caps, 0);
+ if (!gst_structure_has_name (s, "application/x-aavd")) {
+ gst_structure_set (s,
+ "original-media-type", G_TYPE_STRING, gst_structure_get_name (s),
+ NULL);
+ gst_structure_set_name (s, "application/x-aavd");
+ }
+ return TRUE;
+ }
+
if (stream->protection_scheme_type != FOURCC_cenc) {
GST_ERROR_OBJECT (qtdemux,
"unsupported protection scheme: %" GST_FOURCC_FORMAT,
}
}
+static gboolean
+qtdemux_parse_protection_aavd (GstQTDemux * qtdemux,
+ QtDemuxStream * stream, GNode * container, guint32 * original_fmt)
+{
+ GNode *adrm;
+ guint32 adrm_size;
+ GstBuffer *adrm_buf = NULL;
+ QtDemuxAavdEncryptionInfo *info;
+
+ adrm = qtdemux_tree_get_child_by_type (container, FOURCC_adrm);
+ if (G_UNLIKELY (!adrm)) {
+ GST_ERROR_OBJECT (qtdemux, "aavd box does not contain mandatory adrm box");
+ return FALSE;
+ }
+ adrm_size = QT_UINT32 (adrm->data);
+ adrm_buf =
+ gst_buffer_new_wrapped (g_memdup (adrm->data, adrm_size), adrm_size);
+
+ stream->protection_scheme_type = FOURCC_aavd;
+
+ if (!stream->protection_scheme_info)
+ stream->protection_scheme_info = g_new0 (QtDemuxAavdEncryptionInfo, 1);
+
+ info = (QtDemuxAavdEncryptionInfo *) stream->protection_scheme_info;
+
+ if (info->default_properties)
+ gst_structure_free (info->default_properties);
+ info->default_properties = gst_structure_new ("application/x-aavd",
+ "encrypted", G_TYPE_BOOLEAN, TRUE,
+ "adrm", GST_TYPE_BUFFER, adrm_buf, NULL);
+ gst_buffer_unref (adrm_buf);
+
+ *original_fmt = FOURCC_mp4a;
+ return TRUE;
+}
+
/* Parses the boxes defined in ISO/IEC 14496-12 that enable support for
* protected streams (sinf, frma, schm and schi); if the protection scheme is
* Common Encryption (cenc), the function will also parse the tenc box (defined
if ((fourcc == FOURCC_drms) || (fourcc == FOURCC_drmi))
goto error_encrypted;
+ if (fourcc == FOURCC_aavd) {
+ if (stream->subtype != FOURCC_soun) {
+ GST_ERROR_OBJECT (qtdemux,
+ "Unexpeced stsd type 'aavd' outside 'soun' track");
+ } else {
+ /* encrypted audio with sound sample description v0 */
+ GNode *enc = qtdemux_tree_get_child_by_type (stsd, fourcc);
+ stream->protected = TRUE;
+ if (!qtdemux_parse_protection_aavd (qtdemux, stream, enc, &fourcc))
+ GST_ERROR_OBJECT (qtdemux, "Failed to parse protection scheme info");
+ }
+ }
+
if (fourcc == FOURCC_encv || fourcc == FOURCC_enca) {
/* FIXME this looks wrong, there might be multiple children
* with the same type */
GST_TAG_BITRATE, bitrate, NULL);
}
+ esds = NULL;
mp4a = qtdemux_tree_get_child_by_index (stsd, stsd_index);
if (QTDEMUX_TREE_NODE_FOURCC (mp4a) != fourcc) {
- if (stream->protected && QTDEMUX_TREE_NODE_FOURCC (mp4a) != FOURCC_enca)
- mp4a = NULL;
- else if (!stream->protected)
+ if (stream->protected) {
+ if (QTDEMUX_TREE_NODE_FOURCC (mp4a) == FOURCC_aavd) {
+ esds = qtdemux_tree_get_child_by_type (mp4a, FOURCC_esds);
+ }
+ if (QTDEMUX_TREE_NODE_FOURCC (mp4a) != FOURCC_enca) {
+ mp4a = NULL;
+ }
+ } else {
mp4a = NULL;
+ }
}
wave = NULL;
- esds = NULL;
if (mp4a) {
wave = qtdemux_tree_get_child_by_type (mp4a, FOURCC_wave);
if (wave)