libva中的DRM模块

发布时间:2026/10/23 4:03:51

libva中的DRM模块 主要内容本文主要就libva中的DRM的流程进行简单说明libva版本为libva-2.11.0(版本号为1.11.0)Digital Rights Management(DRM)指的是数字版权管理用以保护具有版权的数字产品包括视频音乐电子书等等。关于Digital Rights Management(DRM)(数字版权管理)的基础内容本文不做介绍可以参考链接:DRM基础介绍AES加密原理AES加密模式RSA加密原理数字签名和数字证书X.509证书目前常见的的DRM标准有以下几种PlayReady by MicrosoftFairPlay by AppleMerlin by Sony除此之外还有google的widewine相关术语DRM: Digital Rights Management, 数字版权管理TEE: Trust Excute Environment,可信任执行环境IHV: Independent Hardware Vendor,独立硬件厂商相关接口和结构体libva中的DRM接口从libva2.11引入主要是在va_pro.h中。VAProtectedSessionBuffertypedef struct _VAProtectedSessionBuffer { //作为输入的buffer不使用该值但是作为输出buffermax_data_size可以输出driver所 //返回的输出buffer的数据量的最大值 uint32_t max_data_size; //作为输入bufferr使用data_size指的是输入buffer的数据量大小 //作为输出bufferr使用data_size指的是driver写入data的数据量大小 uint32_t data_size; //数据指针 void *data; //保留未使用 uint32_t va_reserved[VA_PADDING_LOW]; } VAProtectedSessionBuffer;VAProtectedSessionExecuteBuffertypedef struct _VAProtectedSessionExecuteBuffer { //指定执行的功能由IHV实现 uint32_t function_id; //输入buffer VAProtectedSessionBuffer input; //输出buffer VAProtectedSessionBuffer output; //返回函数执行结果由IHV实现 uint32_t status; //保留未使用 uint32_t va_reserved[VA_PADDING_LOW]; } VAProtectedSessionExecuteBuffer;VAEncryptionSegmentInfotypedef struct _VAEncryptionSegmentInfo { /** \brief The offset relative to the start of the bitstream input in * bytes of the start of the segment */ uint32_t segment_start_offset; /** \brief The length of the segments in bytes */ uint32_t segment_length; /** \brief The length in bytes of the remainder of an incomplete block * from a previous segment*/ uint32_t partial_aes_block_size; /** \brief The length in bytes of the initial clear data */ uint32_t init_byte_length; /** \brief This will be AES counter for secure decode and secure encode * when numSegments equals 1, valid size is specified by * \c key_blob_size */ uint8_t aes_cbc_iv_or_ctr[64]; /** \brief Reserved bytes for future use, must be zero */ uint32_t va_reserved[VA_PADDING_MEDIUM]; } VAEncryptionSegmentInfo;VAEncryptionParameterstypedef struct _VAEncryptionParameters { /** \brief Encryption type, refer to \c VA_ENCRYPTION_TYPE_FULLSAMPLE_CTR, * \c VA_ENCRYPTION_TYPE_FULLSAMPLE_CBC, \c VA_ENCRYPTION_TYPE_SUBSAMPLE_CTR, * or \c VA_ENCRYPTION_TYPE_SUBSAMPLE_CBC */ uint32_t encryption_type; /** \brief The number of sengments */ uint32_t num_segments; /** \brief Pointer of segments */ VAEncryptionSegmentInfo *segment_info; /** \brief The status report index reserved for CENC fullsample workload. * The related structures and definitions are vendor specific. */ uint32_t status_report_index; /** \brief CENC counter length */ uint32_t size_of_length; /** \brief Wrapped decrypt blob (Snd)kb, valid size is specified by * \c key_blob_size */ uint8_t wrapped_decrypt_blob[64]; /** \brief Wrapped Key blob info (Sne)kb, valid size is specified by * \c key_blob_size */ uint8_t wrapped_encrypt_blob[64]; /** \brief key blob size * It could be \c VA_PC_BLOCK_SIZE_128, \c VA_PC_BLOCK_SIZE_192, or * \c VA_PC_BLOCK_SIZE_256 */ uint32_t key_blob_size; /** \brief Indicates the number of 16-byte BLOCKS that are encrypted in any * given encrypted region of segments. * If this value is zero: * 1. All bytes in encrypted region of segments are encrypted, i.e. the * CENC or CBC1 scheme is being used * 2. blocks_stripe_clear must also be zero. * If this value is non-zero, blocks_stripe_clear must also be non-zero. */ uint32_t blocks_stripe_encrypted; /** \brief Indicates the number of 16-byte BLOCKS that are clear in any given * encrypted region of segments, as defined by the CENS and CBCS schemes in * the common encryption spec. * If this value is zero, all bytes in encrypted region of segments are * encrypted, i.e. the CENC or CBC1 scheme is being used. */ uint32_t blocks_stripe_clear; /** \brief Reserved bytes for future use, must be zero */ uint32_t va_reserved[VA_PADDING_MEDIUM]; } VAEncryptionParameters;配置配置属性值其他VAConfigAttribTEEType由厂商决定VAConfigAttribTEETypeClient由厂商决定VAConfigAttribProtectedContentCipherAlgorithmVA_PC_CIPHER_AES算法种类目前只支持AESVAConfigAttribProtectedContentCipherBlockSizeVA_PC_BLOCK_SIZE_128VA_PC_BLOCK_SIZE_192VA_PC_BLOCK_SIZE_256算法的大小安全性越好速度越慢VAConfigAttribProtectedContentCipherModeVA_PC_CIPHER_MODE_ECBVA_PC_CIPHER_MODE_CBCVA_PC_CIPHER_MODE_CTRAES密钥模式,目前只支持三种VAConfigAttribProtectedContentCipherSampleTypeVA_PC_SAMPLE_TYPE_FULLSAMPLE, VA_PC_SAMPLE_TYPE_SUBSAMPLE采样类型VAConfigAttribProtectedContentUsageVA_PC_USAGE_DEFAULT, VA_PC_USAGE_WIDEVINE使用的DRM标准默认或者widewineAPIAPI说明其他vaCreateProtectedSession创建一个被保护的对话vaDestroyProtectedSession销毁创建的对话vaAttachProtectedSession附着对话到一个VA context中使能加密保护vaDetachProtectedSession游离context中附着的对话失能加密保护vaProtectedSessionExecute执行被保护的对话使用流程查询entrypoint是否支持Content protection获取相关的配置属性创建config对象获取保护对话的buffer数据附着session到相关的context上按照正常的流程解码游离context上的session//查询相关的entrypoints VAEntrypoint entrypoints; int i, num_entrypoints, supportsProtectedContent 0; num_entrypoints vaMaxNumEntrypoints(); entrypoints malloc(num_entrypoints sizeof(entrypoints[0]); vaQueryConfigEntrypoints(va_dpy, VAProfileProtected, entrypoints, num_entrypoints); for (i 0; !supportsProtectedContent i num_entrypoints; i) { if (entrypoints[i] VAEntrypointProtectedContent) supportsProtectedContent 1; } //获取配置属性 VAConfigAttrib attribs; //获取密钥算法类型 attribs[0].type VAConfigAttribProtectedContentCipherAlgorithm; //获取密钥算发支持的块的尺寸 attribs[1].type VAConfigAttribProtectedContentCipherBlockSize; //获取密钥算法模式 attribs[2].type VAConfigAttribProtectedContentCipherMode; //获取密钥采样类型 attribs[3].type VAConfigAttribProtectedContentCipherSampleType; //获取使用DRM标准 attribs[4].type VAConfigAttribProtectedContentUsage; vaGetConfigAttributes(va_dpy, VAProfileProtected, VAEntrypointProtectedContent, attribs, 5); if ((attribs[1].value VA_PC_CIPHER_AES) 0) { // not find desired cipher algorithm assert(0); } if ((attribs[2].value VA_PC_BLOCK_SIZE_128) 0) { // not find desired block size assert(0); } if ((attribs[3].value VA_PC_CIPHER_MODE_CBC) 0) { // not find desired counter mode assert(0); } if ((attribs[4].value VA_PC_SAMPLE_TYPE_SUBSAMPLE) 0) { // not find desired sample type assert(0); } if ((attribs[5].value VA_PC_USAGE_WIDEVINE) 0) { // not find desired usage assert(0); } //创建配置对象 VAConfigID config_id; attribs[0].value VA_PC_CIPHER_AES; attribs[1].value VA_PC_BLOCK_SIZE_128; attribs[2].value VA_PC_CIPHER_MODE_CBC; attribs[3].value VA_PC_SAMPLE_TYPE_SUBSAMPLE; attribs[4].value VA_PC_USAGE_WIDEVINE; va_status vaCreateConfig(va_dpy, VAProfileProtected, VAEntrypointProtectedContent, attribs, 5, config_id); CHECK_VASTATUS(va_status, vaCreateConfig); //创建VAProtectedSessionExecuteBuffer 对象 uint32_t app_id 0xFF; VABufferID buffer; VAProtectedSessionExecuteBuffer exec_buff {0}; //GET_SESSION_ID只是函数的一种driver实现的功能由IHV决定可以实现很多功能 //指定不同的function_id来访问不同的功能 exec_buff.function_id GET_SESSION_ID; exec_buff.input.data nullptr; exec_buff.input.data_size 0; exec_buff.output.data app_id; exec_buff.output.max_data_size sizeof(app_id); va_status vaCreateBuffer( va_dpy, crypto_session, (VABufferType) VAProtectedSessionExecuteBufferType, sizeof(exec_buff), 1, exec_buff, buffer); //执行对话sesson传入或者获取数据如content key va_status vaProtectedSessionExecute(va_dpy, crypto_session, buffer); vaDestroyBuffer(va_dpy, buffer); //附着对话到session上 vaAttachProtectedSession(va_dpy, decode_ctx, crypto_session); foreach (iteration) { vaBeginPicture(va_dpy, decode_ctx, surface); ... vaRenderPicture(va_dpy, decode_ctx, buf_id1, 1); vaRenderPicture(va_dpy, decode_ctx, buf_id2, 1); // Buffer holding encryption parameters, i.e. VAEncryptionParameterBufferType buffer vaRenderPicture(va_dpy, decode_ctx, buf_id_enc_param, 1); ... vaEndPicture(va_dpy, decode_ctx); } //游离context的对话 vaDetachProtectedSession(va_dpy, decode_ctx); foreach (iteration) { if (encrypted) vaAttachProtectedSession(va_dpy, decode_ctx, crypto_session); vaBeginPicture(va_dpy, decode_ctx, surface); ... vaRenderPicture(va_dpy, decode_ctx, buf_id1, 1); vaRenderPicture(va_dpy, decode_ctx, buf_id2, 1); // Buffer holding encryption parameters, i.e. VAEncryptionParameterBufferType buffer vaRenderPicture(va_dpy, decode_ctx, buf_id_enc_param, 1); ... vaEndPicture(va_dpy, decode_ctx); if (encrypted) vaDetachProtectedSession(va_dpy, decode_ctx); // check encrypted variable for next frame }
延伸阅读

更多相关文章

2026/10/23 4:03:51

Java:54-Linux概述

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/23 4:03:50

linux软连接和硬链接

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/23 5:08:58

老显卡UEFI黑屏怎么办?GOPUpd v1.9.6.5注入GOP驱动教程

简介:面向DIY装机与电脑维修人员的AMD/NVIDIA显卡GOP更新工具GOPUpd 1.9.6.5压缩包,用于升级显卡图形输出协议组件;GOP是连接图形硬件与UEFI固件的重要接口,老旧显卡或主板常因GOP版本过旧导致开机黑屏、无法识别新显卡&#xff0…

2026/10/23 5:08:58

全国计算机等级考试一级选择题题库:25套真题考点与刷题技巧

简介:《2022年计算机等级考试一级试题及答案》是为全国计算机等级考试一级考生整理的练习文档,覆盖计算机基础核心知识点,适合考前刷题、查漏补缺。内容以选择题为主,包含多套试题及解析,涉及计算机发展历史、第四代计…

2026/10/23 5:08:58

老显卡UEFI黑屏怎么办?GOP模块更新实战指南

简介:一套面向AMD与NVIDIA显卡用户的UEFI GOP固件升级工具包,可解决老显卡在UEFI模式下启动黑屏、兼容性不足等问题,也能通过更新显卡BIOS提升稳定性和性能。包内共38个文件,压缩包约6.63MB,核心包含多个.efirom格式GO…

2026/10/23 5:08:58

数学建模电工杯:AI学习影响评价题的降维与综合评价拿分技巧

简介:这份资料是一份针对数学建模电工杯赛题的完整论文方案,围绕“人工智能对大学生学习影响的评价”展开,面向参赛学生与指导教师,既提供赛题解题流程,也可作为数据分析与综合评价类建模项目的参考样例。文档基于调查…

2026/10/23 5:08:58

VMware虚拟机安装Ubuntu零基础教程:小白也能安全上手

简介:本资源是一份面向Linux初学者与开发环境搭建需求者的VMware虚拟机安装Ubuntu系统实操指南,解决在Windows主机上零基础部署Ubuntu开发环境的核心问题。文档以图文并茂方式完整覆盖虚拟机选型对比、VMware安装配置、Ubuntu镜像下载选择、虚拟机创建、…

2026/10/23 5:03:58

9、Python基础之IO编程

前言IO就是Input/Output,输入输出。程序和外部数据交换都属于IO操作:读取文件、写入文件、网络传输等。IO操作有一个核心特点:速度远慢于CPU计算。 Python内置了丰富的IO支持,本篇包含:文件读写、StringIO/BytesIO、文…

2026/10/22 11:29:28

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/23 0:02:26

Verilog实现FPGA密码锁:矩阵键盘与状态机设计实战

说实话,这几年接触了不少想入门FPGA的朋友,如果你问哪个项目能一口气把Verilog的核心基本功串起来,我通常会推荐电子密码锁。这个项目看着不起眼,却把矩阵键盘扫描、按键消抖、状态机设计、动态显示刷新、外设控制这些数字逻辑里的…

2026/10/23 0:02:26

数据服务监控运维实战:从指标体系到告警治理与故障排查

周末凌晨两点,手机震了。第一反应是“数据服务挂了”。打开电脑看了下,果然,某张核心报表的数据产出时间已经超过SLA两小时,下游三个业务方连着发来问询。这种场景,做过大数据运维的人都不会陌生。数据服务的监控与运维…

2026/10/23 0:02:26

FreeRTOS任务通知实战详解:内核原理、API与避坑指南

裸机编程切到RTOS之后,任务之间的通信和同步永远是躲不开的坎。前面聊过队列、信号量、互斥锁、事件组,这次把FreeRTOS任务通知(Task Notification)单独拎出来讲透。原因很简单:任务通知是FreeRTOS里最容易用错、也最容…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑