예제 #1
0
static bool_t
dash_packager_compare_tracks(uintptr_t bitrate_threshold, const media_info_t* mi1, const media_info_t* mi2)
{
	if (mi1->bitrate == 0 ||
		mi2->bitrate == 0 ||
		mi1->bitrate + bitrate_threshold <= mi2->bitrate ||
		mi2->bitrate + bitrate_threshold <= mi1->bitrate)
	{
		return FALSE;
	}

	if (mi1->codec_name.len != mi2->codec_name.len ||
		vod_memcmp(mi1->codec_name.data, mi2->codec_name.data, mi2->codec_name.len) != 0)
	{
		return FALSE;
	}

	if (mi1->media_type == MEDIA_TYPE_VIDEO)
	{
		return (mi1->u.video.width == mi2->u.video.width) &&
			(mi1->u.video.height == mi2->u.video.height);
	}

	return TRUE;
}
예제 #2
0
static u_char* 
edash_packager_write_content_protection(void* ctx, u_char* p, media_track_t* track)
{
	write_content_protection_context_t* context = ctx;
	drm_info_t* drm_info = (drm_info_t*)track->file_info.drm_info;
	drm_system_info_t* cur_info;
	vod_str_t base64;
	vod_str_t pssh;

	p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC) - 1);
	for (cur_info = drm_info->pssh_array.first; cur_info < drm_info->pssh_array.last; cur_info++)
	{
		if (vod_memcmp(cur_info->system_id, edash_playready_system_id, sizeof(edash_playready_system_id)) == 0)
		{
			if (context->write_playready_kid)
			{
				p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART1, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART1) - 1);
				p = mp4_encrypt_write_guid(p, cur_info->system_id);
				p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART2, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART2) - 1);
				p = mp4_encrypt_write_guid(p, drm_info->key_id);
			}
			else
			{
				p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART1, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART1) - 1);
				p = mp4_encrypt_write_guid(p, cur_info->system_id);
			}
			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART3, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART3) - 1);

			base64.data = p;
			vod_encode_base64(&base64, &cur_info->data);
			p += base64.len;

			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART4, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART4) - 1);
		}
		else
		{
			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART1, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART1) - 1);
			p = mp4_encrypt_write_guid(p, cur_info->system_id);
			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART2, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART2) - 1);
			p = mp4_encrypt_write_guid(p, drm_info->key_id);
			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART3, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART3) - 1);

			pssh.data = context->temp_buffer;
			pssh.len = edash_packager_write_pssh(pssh.data, cur_info) - pssh.data;

			base64.data = p;
			vod_encode_base64(&base64, &pssh);
			p += base64.len;

			p = vod_copy(p, VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART4, sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART4) - 1);
		}
	}
	return p;
}
예제 #3
0
static int
track_group_key_compare(track_group_key_t* key1, track_group_key_t* key2)
{
	if (key1->codec_id != key2->codec_id)
	{
		return key1->codec_id < key2->codec_id ? -1 : 1;
	}

	if (key1->label.len != key2->label.len)
	{
		return key1->label.len < key2->label.len ? -1 : 1;
	}

	if (key1->label.data != key2->label.data)
	{
		return vod_memcmp(key1->label.data, key2->label.data, key1->label.len);
	}

	return 0;
}
vod_status_t
edash_packager_build_mpd(
	request_context_t* request_context,
	dash_manifest_config_t* conf,
	vod_str_t* base_url,
	media_set_t* media_set,
	vod_str_t* result)
{
	media_sequence_t* cur_sequence;
	drm_system_info_t* cur_info;
	drm_info_t* drm_info;
	u_char* pssh_temp_buffer = NULL;
	size_t representation_tags_size;
	size_t cur_drm_tags_size;
	size_t cur_pssh_size;
	size_t max_pssh_size = 0;
	vod_status_t rc;

	representation_tags_size = 0;

	for (cur_sequence = media_set->sequences; cur_sequence < media_set->sequences_end; cur_sequence++)
	{
		drm_info = (drm_info_t*)cur_sequence->drm_info;

		cur_drm_tags_size = sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC) - 1;

		for (cur_info = drm_info->pssh_array.first; cur_info < drm_info->pssh_array.last; cur_info++)
		{
			if (vod_memcmp(cur_info->system_id, edash_playready_system_id, sizeof(edash_playready_system_id)) == 0)
			{
				cur_drm_tags_size +=
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART1) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART2) - 1 +
					vod_base64_encoded_length(cur_info->data.len) +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART3) - 1;
			}
			else
			{
				cur_pssh_size = ATOM_HEADER_SIZE + sizeof(pssh_atom_t) + cur_info->data.len;
				if (cur_pssh_size > max_pssh_size)
				{
					max_pssh_size = cur_pssh_size;
				}

				cur_drm_tags_size +=
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART1) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART2) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART3) - 1 +
					vod_base64_encoded_length(cur_pssh_size) +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART4) - 1;

				continue;
			}
		}

		representation_tags_size += cur_drm_tags_size * cur_sequence->total_track_count;
	}

	if (max_pssh_size > 0)
	{
		pssh_temp_buffer = vod_alloc(request_context->pool, max_pssh_size);
		if (pssh_temp_buffer == NULL)
		{
			vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
				"edash_packager_build_mpd: vod_alloc failed");
			return VOD_ALLOC_FAILED;
		}
	}

	rc = dash_packager_build_mpd(
		request_context,
		conf,
		base_url,
		media_set,
		representation_tags_size,
		edash_packager_write_content_protection,
		pssh_temp_buffer,
		result);
	if (rc != VOD_OK)
	{
		vod_log_debug1(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
			"edash_packager_build_mpd: dash_packager_build_mpd failed %i", rc);
		return rc;
	}

	return VOD_OK;
}
예제 #5
0
vod_status_t
edash_packager_build_mpd(
	request_context_t* request_context,
	dash_manifest_config_t* conf,
	vod_str_t* base_url,
	media_set_t* media_set,
	bool_t drm_single_key,
	vod_str_t* result)
{
	write_content_protection_context_t context;
	dash_manifest_extensions_t extensions;
	media_sequence_t* cur_sequence;
	drm_system_info_t* cur_info;
	tags_writer_t content_prot_writer;
	drm_info_t* drm_info;
	size_t representation_tags_size;
	size_t cur_drm_tags_size;
	size_t cur_pssh_size;
	size_t max_pssh_size = 0;
	vod_status_t rc;

	representation_tags_size = 0;

	for (cur_sequence = media_set->sequences; cur_sequence < media_set->sequences_end; cur_sequence++)
	{
		drm_info = (drm_info_t*)cur_sequence->drm_info;

		cur_drm_tags_size = sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC) - 1;

		for (cur_info = drm_info->pssh_array.first; cur_info < drm_info->pssh_array.last; cur_info++)
		{
			if (vod_memcmp(cur_info->system_id, edash_playready_system_id, sizeof(edash_playready_system_id)) == 0)
			{
				cur_drm_tags_size +=
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART1) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_V2_PART2) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART3) - 1 +
					vod_base64_encoded_length(cur_info->data.len) +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_PLAYREADY_PART4) - 1;
			}
			else
			{
				cur_pssh_size = ATOM_HEADER_SIZE + sizeof(pssh_atom_t) + cur_info->data.len;
				if (cur_pssh_size > max_pssh_size)
				{
					max_pssh_size = cur_pssh_size;
				}

				cur_drm_tags_size +=
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART1) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART2) - 1 +
					VOD_GUID_LENGTH +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART3) - 1 +
					vod_base64_encoded_length(cur_pssh_size) +
					sizeof(VOD_EDASH_MANIFEST_CONTENT_PROTECTION_CENC_PART4) - 1;

				continue;
			}
		}

		representation_tags_size += cur_drm_tags_size * cur_sequence->total_track_count;
	}

	context.write_playready_kid = conf->write_playready_kid;
	if (max_pssh_size > 0)
	{
		context.temp_buffer = vod_alloc(request_context->pool, max_pssh_size);
		if (context.temp_buffer == NULL)
		{
			vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
				"edash_packager_build_mpd: vod_alloc failed");
			return VOD_ALLOC_FAILED;
		}
	}

	content_prot_writer.size = representation_tags_size;
	content_prot_writer.write = edash_packager_write_content_protection;
	content_prot_writer.context = &context;

	if (drm_single_key)
	{
		// write the ContentProtection tags under AdaptationSet
		extensions.adaptation_set = content_prot_writer;
		vod_memzero(&extensions.representation, sizeof(extensions.representation));
	}
	else
	{
		// write the ContentProtection tags under Representation
		vod_memzero(&extensions.adaptation_set, sizeof(extensions.adaptation_set));
		extensions.representation = content_prot_writer;
	}

	rc = dash_packager_build_mpd(
		request_context,
		conf,
		base_url,
		media_set,
		&extensions,
		result);
	if (rc != VOD_OK)
	{
		vod_log_debug1(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
			"edash_packager_build_mpd: dash_packager_build_mpd failed %i", rc);
		return rc;
	}

	return VOD_OK;
}