的架构、源码与验证)
TiXL D3D11VA 零拷贝视频解码实现解析GPU→GPU 硬件解码管道Pipeline B的架构、源码与验证【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3导读本文基于 TiXL 开源实时动态图形软件GitHub_Trending/t3/t3中Plan_VideoZeroCopyDecode.md技术方案结合仓库内 VideoServices 的真实实现源码深入解析其 D3D11VADirect3D 11 Video AccelerationGPU→GPU 零拷贝视频解码管道如何通过 FFmpeg 硬件解码在共享 D3D11 设备上产出 GPU 表面再用计算着色器将 NV12/P010 平面直接转换为 RGBA 纹理全程不经 CPU 回读。读完本文你将掌握 D3D11VA 设备共享的引用计数陷阱、解码/转换线程锁设计、纹理数组切片 SRV 构建、Optimize For双管道选择机制以及这套方案在 NVIDIA GPU 上端到端验证后沉淀的实战经验与已知边界。一、背景TiXL 的 A/B 双管道视频架构TiXL 的视频播放基础设施建立在 FFmpeg通过 Sdcb.FFmpeg 托管绑定之上完整方案见 Plan_FfmpegVideo.md。其 M2 里程碑提出了一个核心架构决策解码→转换核心共享但内存策略分叉重负载片段二选一即双管道模型管道 ASeeking面向 NLE 剪辑 / 程序化 VJ 场景延迟敏感、帧会被反复访问scrub、loop、step、reverse。采用软件解码 RAM GOP 缓存缓存是杠杆上传/解码成本是次要的。完全厂商中立、无 GPU 设备共享风险。该管道已随 M1 发布未做改动。管道 BHigh-res throughput面向 4K 高分辨率与多路并行流播放带宽受限每帧只播一次、只向前。采用D3D11VA 零拷贝转换后立即释放不建缓存保留巨大的一次性帧纯属浪费。吞吐量是杠杆缓存无关紧要。本方案文档即管道 B 的完整实施计划对应 Plan_FfmpegVideo.md M1 步骤 8 中推迟的硬件解码路径是 FFmpeg 迁移工作中风险最高的一块——设备共享与解码/转换加锁是其中最艰难的收获。两条管道对特定重负载片段而言近乎互斥缓存需要可保留的 RAM 帧⇒ 软件解码零拷贝需要解码器固定的硬件环形缓冲⇒ 不可保留。因此路径选择不是启发式、也不是全局模式而是显式的算子参数详见第七节。本方案的内部文档状态标注为 2026-06-07已在 NVIDIA 上端到端打通四个阶段全部接线共享ResourceManager.Device上的 D3D11VA 硬件解码 无 CPU 回读的 NV12/P010→RGBA 计算着色器转换图像正确、播放平滑。二、改造前的软件解码现状在管道 B 实施前TiXL 的视频解码全部走软件路径VideoDecoderSession.cs 打开 demuxer 解码器并解码到 CPUFrameNv12/Yuv420p/P010le平面当时没有IDecodeBackend、没有 hwaccel、没有get_format钩子——方案中设计的后端拆分从未构建。线程模型也与零拷贝需求完全相反工作线程既解码又用 swscale 转换成打包 RGBA 字节SoftwareFrameConverter.cs渲染线程仅把字节UpdateSubresource进输出Texture2DUploadPendingFrame交接是一个lock保护的单槽位待处理字节缓冲。而 VideoPlaybackEngine.cs 已经具备限制活跃解码器数量、驱逐空闲流、共享缓存预算的能力是后端无关的管道 B 无需改动它B 只是不填充缓存。三、D3D11VA 硬件解码序列五步关键流程零拷贝的实现位于 VideoDecoderSession.TryOpen。当请求硬件路径optimization VideoPlaybackOptimization.PlaybackPerformance且解码器宣称支持 D3D11VA时在codecContext.Open()之前依次执行以下五步。参考 TextureBgraReadAccess.cs 中的计算调度先例Sdcb 通过Sdcb.FFmpeg.Raw.ffmpeg.*暴露原生 APIVideoDecoderSession中已经用它调用avcodec_flush_buffers等并暴露原生 hwaccel 结构体AVHWDeviceContext、AVD3D11VADeviceContext、AVHWFramesContext、AVD3D11VAFramesContext。3.1 全局多线程保护一次性解码器的ID3D11VideoContext运行在工作线程而渲染线程驱动 immediate context因此必须先启用设备多线程保护。实现见 EnsureMultithreadProtectedResourceManager.Device.QueryInterfaceMultithread().SetMultithreadProtected(true)。Media Foundation 编码路径已经这样做过直接镜像即可不要重复切换。3.2 硬件设备上下文分配与设备共享核心实现在 TryOpenHardwareav_hwdevice_ctx_alloc(AVHWDeviceType.D3d11va)共享设备层级Phase 3设置AVD3D11VADeviceContext.device ResourceManager.Device.NativePointer并且Marshal.AddRef这个 COM 设备——FFmpeg 在 teardown 时会Release它引用计数失误会导致全局设备被双重释放、应用崩溃。初始化失败路径上也要Marshal.Release并置空d3d11-device使随后的av_buffer_unref不会释放 TiXL 的设备把 FFmpeg 的lock/unlock回调接到转换器也持有的共享互斥锁上见 LockDevice/UnlockDevice二者取HardwareFrameConverter.DeviceLockav_hwdevice_ctx_initcodecContext.hw_device_ctx av_buffer_ref(...)随后codecContext.Open()。从源码结构看方案文档中提到的自有设备层级Phases 1–2跳过.device让 FFmpeg 自建 D3D11 设备最终并未作为独立层级落地——Phase 2 的 GPU 转换要求解码表面必须与转换/输出在同一设备上跨设备资源建 SRV 会原生崩溃详见第九节因此 Phase 3 被提前拉入 Phase 2。当前实现直接走共享设备。此外 CodecSupportsD3d11va 会先遍历avcodec_get_hw_config确认解码器确实有 D3D11VA 的HW_DEVICE_CTX配置——没有 D3D11VA hwaccel 的解码器如 ProRes即使接受hw_device_ctx也会静默回退软件解码那会让会话看起来是硬件/零拷贝却输出 CPU 帧从而冻结零拷贝转换路径所以要先排除。3.3 帧上下文与 SHADER_RESOURCE BindFlags这是 D3D11VA 零拷贝的经典陷阱默认的解码器池纹理只有解码用途无法包装成 SRV。因此必须手动分配hw_frames_ctx让池纹理带上AVD3D11VAFramesContext.BindFlags | D3D11_BIND_SHADER_RESOURCE。实现见 SelectHardwareFormat在get_format回调中当解码器提供AV_PIX_FMT_D3D11时通过avcodec_get_hw_frames_parameters获取默认参数将D3D11BindShaderResource常量值8即D3D11_BIND_SHADER_RESOURCE或进BindFlags后再av_hwframe_ctx_init。若驱动拒绝驱动/配置档位限制则记录警告并退回只读回读路径——解码专用池上回读依然可用。日志中会出现SHADER_RESOURCE frames context ready或降级提示。一个重要的工程细节FFmpeg 在每次 flush即每次向后 seek / scrub时都会重调get_format实现会复用已有的hw_frames_ctxctx-hw_frames_ctx ! null直接返回而不是每次重新分配整个纹理池——池反复重建会丢帧。3.4 get_format 回调get_format回调返回AV_PIX_FMT_D3D11若解码器不提供该格式则回退软件像素格式。委托被保存在静态字段中避免 FFmpeg 持有函数指针期间托管委托被 GC 回收。3.5 解码帧的 GPU 形态硬件解码的AVFrame中data[0]ID3D11Texture2D数组data[1] 数组切片索引。帧全程驻留 GPU。TryReadNextFrame 在零拷贝模式下跳过av_hwframe_transfer_data回读_lastFrameReadBack仅当非零拷贝且格式为D3d11时置真。SupportsZeroCopy 通过位深判断 4:2:0 布局8 位 NV12 12 bpp10/12 位 P010/P016 最高 24 bpp落在 12 and 24区间才允许零拷贝其余布局4:2:2、4:4:4退回硬件回读。HardwareSurfaceFormat 则在sw_pix_fmt未就绪时按位深标注回读格式10 位 →P010le而非默认的Nv12保证缓存与转换器从第 0 帧起就拿到正确的格式标签。四、帧交接重构worker→render 的最新优先交接零拷贝反转了交接方向VideoPlaybackController.cs工作线程硬件模式TryReadNextFrame后CurrentFrame持有 GPU 表面。用av_frame_ref把帧引入待处理槽位最新优先若渲染线程消费前已有更新帧到达先av_frame_unref旧的。工作线程绝不触碰 immediate context。渲染线程Update()锁内取走待处理 GPU 帧在immediate context 上执行转换见第五节设置Texture然后av_frame_unref已消费帧。在 dispatch 提交前一直持有该帧的引用。源码中使用av_frame_move_ref在锁内把帧移给渲染侧私有帧对象VideoPlaybackController.cs锁外再运行HardwareFrameConverter.Convert。软件模式保持今天的路径原样worker 转字节、render 上传。待处理槽位变为一个小型带标签联合RGBA 字节软件或GPUAVFrame硬件。导出renderingToFile阻塞形式不变——WaitForRequestedFrame仍以 worker 产出目标帧为门槛只是载荷类型不同。源码中值得注意的细节零拷贝模式下一次只钉住约 2 个池切片_pendingGpuFrame_renderGpuFrame模式切换重开流时worker 会在_lock下丢弃未展示的待处理 GPU 帧防止渲染线程转换来自刚销毁会话的帧零拷贝转换包在 try/catch 中失败时保留最后的纹理而不是把算子打成错误态。五、GPU 转换器与计算着色器零拷贝转换核心转换器是 HardwareFrameConverter.cs着色器是 Nv12ToRgba-cs.hlslcs_5_0经ResourceManager.CreateShaderResourceComputeShader加载路径Lib:shaders/img/Nv12ToRgba-cs.hlsl。5.1 着色器数学着色器输入LumaTexturet0全分辨率、ChromaTexturet1半分辨率交错 Cb,Cr、输出 UAVResultu0[numthreads(16, 16, 1)]。核心转换采用BT.709 limitedstudiorange常量——HD/UHD H.264 与 HEVC 的常见情况10 位 limited-range 端点与 8 位相差 0.5%因此同一套常量可同时服务两者见 Nv12ToRgba-cs.hlsl 的注释。核心公式yp (luma - 16/255) * 255/219 cb (chroma.x - 128/255) * 255/224 cr (chroma.y - 128/255) * 255/224 r yp 1.5748*cr g yp - 0.1873*cb - 0.4681*cr b yp 1.8556*cbBT.601SD 内容矩阵选择与 PQ/HLG 色调映射为后续细化项。5.2 数组切片 SRV 的显式构建PlaneSrvDesc 显式构建ShaderResourceViewDescriptionDimension Texture2DArray、FirstArraySlice (int)data[1]、ArraySize 1、MipLevels 1。这是因为SrvManager.GetSrvForTexture只构建默认的非数组 SRV必须手工构建。方案要求按切片索引缓存 SRVFFmpeg 复用约 20 个切片尺寸/格式变化时失效重建。关键格式决策Phase 2 期间实测验证转换器读取解码器纹理的 DXGI 格式来区分位深——表面亮度平面 SRV色度平面 SRV输出 UAVNV128 位R8_UNormR8G8_UNormRGBA8P010/P01610/12 位R16_UNormR16G16_UNormRGBA16最初实现曾对 P010R16表面构建R8SRV导致 D3D11 在CreateShaderResourceView抛E_INVALIDARG原生崩溃详见第九节修复记录。BT.709 着色器本身无需改动——两个平面都以归一化浮点采样8/10 位 limited-range 端点差异 0.5%。5.3 调度与绑定保存/恢复Convert 的调度遵循 TextureBgraReadAccess.cs:235-265 的保存/恢复模式获取deviceContext.ComputeShader保存先前的 shader/SRV/UAV设置新绑定Dispatch((width15)/16, (height15)/16, 1)16×16 组然后恢复先前的计算阶段绑定并释放Get*返回的引用否则每帧泄漏。解码纹理通过Marshal.AddRef借用SharpDX 包装器 Dispose 时的 Release 与之一一对应FFmpeg 自身的引用不受影响。线程安全设计整个 dispatch 包裹在lock (DeviceLock)中而这个DeviceLock正是 FFmpeg 解码时lock/unlock回调取的同一把锁——解码worker与转换render在共享设备上互斥执行。方案文档明确记载若留空lock/unlockFFmpeg 不会自动安装 ID3D11Multithread 锁解码与转换会在共享设备上竞争出现解码失败→FFmpeg 重初始化 hwaccel→再失败的循环表现为反复打印SHADER_RESOURCE frames context ready且纹理指针不断变化17–50 帧后不确定地冻结。显式回调 SetMultithreadProtected(true)是最终修复。六、降级层级自动降级软件永远是最终保底方案设计了三级自动降级共享设备主路径Phase 3真正零拷贝单设备无跨设备拷贝。当前实现即此层级。自有设备 keyed-mutex 共享纹理Phases 1–2并作为永久降级FFmpeg 自建 D3D11 设备、在彼处解码把切片拷入Shared/KeyedMutex纹理再在ResourceManager.Device上打开并转换。多一次 GPU→GPU 拷贝仍无 CPU 回读。复用同一转换器与控制器。从源码看该层级当前未构建仅在 GPU 拒绝设备共享时才需要。软件已发布、保证的基线hwaccel 初始化失败或 GPU 缺乏编解码配置档位时透明回退。降级检测点av_hwdevice_ctx_init失败、get_format未提供AV_PIX_FMT_D3D11、或avcodec_open2失败。命中任一即回退并记录一次所选层级。另外即便硬件解码成功SupportsZeroCopy返回 false非 4:2:0 布局也会从零拷贝降级为硬件回读日志Zero-copy decode skipped: stream pixel format isnt a supported 4:2:0 surface...。七、Optimize For 算子参数A/B 管道选择器A/B 选择通过VideoPlaybackOptimization枚举实现定义于 Core 层 Core/Video/VideoPlayback.cs该文件只含 Core 类型无 FFmpeg 依赖因此非视频工程不会引入重量级依赖public enum VideoPlaybackOptimization { FastSeeking 0, // 软件解码 RAM 帧缓存即时 scrub-back / loop 重寻GPU 留给编辑器 PlaybackPerformance 1 // 零拷贝 GPU 解码、无缓存大/4K 帧最平滑随机 seek 需重解码 GOP }它作为PlayVideo和VideoClip算子上的Optimize For下拉参数默认FastSeekingC# 侧实现TiXL 自动调和.t3/.t3uiFastSeeking→ 管道 A软件解码 RAM GOP 缓存即今日路径。选择它还有一层实测依据硬件回读默认曾被尝试过即使 720p 也明显抖动——每帧 GPU→CPU 回读会同步阻塞而软件解码 缓存无每帧回读停顿播放平滑且 GPU 空闲给编辑器。PlaybackPerformance→ 管道 BD3D11VA 零拷贝无缓存hwaccel 初始化失败时回退软件无缓存。枚举表达的是意图控制器挑选可用后端且运行时值变化时重新初始化IVideoPlaybackEngine.RequestFrame的语义即流在首次请求时创建解码器optimization变化时重开控制器内mode ! _workerMode触发流重开。编解码器可以覆盖该参数如 HAP/全内帧 GPU 纹理编码始终走 GPU不在本文范围。只有FastSeeking消耗共享缓存预算简化预算模型。手动测试清单见 video-optimize-for-modes.md覆盖下拉两个选项、23.976 fps 节奏、模式切换重开、随机 seek 权衡与 video-playback-determinism.md帧精度、loop/clamp、导出。八、打包与许可证D3D11VA无需额外 DLL——它使用操作系统自带的 D3D11 运行时和 avcodec/avutil 内置的 hwaccel。但分发的FFmpeg.LGPLBtbNlgpl-shared构建必须带--enable-d3d11va许可证干净非 gpl/nonfree因此不影响 TiXL 的许可证护栏但存在性必须确认。Phase 0 验证已在运行时完成avcodec-61.dll内置h264_d3d11vad3d11va_alloc_contextd3d11vaframescontextavutil-59.dll内置d3d11vahwcontext。许可证文本与署名随 Dependencies/licenses/LGPL-v3-FFmpeg.txt 分发。九、分阶段实施与 GPU 验证记录方案按每步可独立构建与 GPU 验证、风险最高的最后做排序以下是每个阶段的状态与实战收获Phase 0后端接缝 打包探针完成打包探针通过Sdcb 托管绑定暴露av_hwdevice_ctx_alloc/_init、av_hwframe_transfer_data、av_buffer_ref、get_format以及AVD3D11VADeviceContext/AVD3D11VAFramesContext结构体。实际后端接缝比最初设想的更薄随 Phase 1 落地控制器交接直到 Phase 2 仍是字节级因此没有独立的重构步骤。Phase 1硬件解码 回读完成GPU 验证FFmpeg 自有设备上的 D3D11VAget_format → AV_PIX_FMT_D3D11解码到 GPU 后av_hwframe_transfer_data回读 CPU 并复用现有SoftwareFrameConverter。不需要SHADER_RESOURCEBindFlags回读不用 SRV用 FFmpeg 默认帧上下文即可。临时由TIXL_FFMPEG_FORCE_HW1门控。验证结果D3D11VA hardware (CPU read-back) — 2048x1080 Nv12帧正确VideoPlaybackController日志Video decode path: D3D11VA hardware (CPU read-back) | software …取消设置则逐字节等同旧软件路径零回归风险。速度仍慢于零拷贝——每帧有一次 GPU→CPU 回读提速是 Phase 2 的事。Phase 2GPU 转换零拷贝转换——含三个实战 Bug 修复四个组成部分(a)Nv12ToRgba-cs.hlslBT.709 着色器(b)get_format通过avcodec_get_hw_frames_parameters分配帧上下文并或入SHADER_RESOURCE(c)HardwareFrameConverter均衡 AddRef 借用解码器纹理、构建 R8/R8G8 数组切片 SRV、dispatch 到 UAV、恢复计算阶段绑定(d) worker→render 交接av_frame_ref进最新优先单槽、renderav_frame_move_ref锁外转换。GPU 验证图像正确、无丢帧、平滑无回读。P010 / 10-bit 崩溃修复真实 10 位 HEVC 文件P010首次原生崩溃——转换器对 P010R16表面构建了R8SRVD3D11 在CreateShaderResourceView抛E_INVALIDARG。修复后按解码器纹理的 DXGI 格式绑定 R16/R16G16 平面 SRV RGBA16 输出。SupportsZeroCopy读取码流位深sw_pix_fmt首次解码前未设置HardwareSurfaceFormat正确标注回读格式。HDR 仍是 stubPQ/HLGBT.2020的 P010 能解码但 BT.709 矩阵 无色调映射会发白bt709 10-bit常见 UHD-SDR 场景是正确的。无缓存暴露的 seek 策略缺陷修复真实长 GOP 4K约 250 帧 / 约 10 秒 GOP在播放中跳跃 seek 时软锁——播放时间跑在解码前面每个追赶帧都触发旧的 0.5 秒顺序阈值DecodeTo每次回 seek 到关键帧并重解码整个 GOP约 100 ms/帧永不收敛。缓存曾在软件路径上掩盖了这一点。修复在 DecodeTo仅当目标落后于解码器、或超出前向 seek 阈值时才 seek——当前 GOP 内的前向目标直接前向解码便宜得多且解码约 52 fps 跑赢 24 fps 播放自然收敛。阈值是自适应的增长到观测到的最深关键帧→目标跨度此处约 10 秒学习流的 GOP 深度。4 个并发同文件解码器在跳跃后全部收敛到稳定seq验证通过。Fast Seeking 抖动修复缓存键不匹配以软件 缓存Fast Seeking为默认时23.976 fps 片段严重卡顿而 60 fps 正常。每秒探测显示每帧都是全新解码decoded published解码耗时 22→340 ms 然后重置——每帧一次向后 seek GOP 重解码。根因缓存按原始解码 PTS存储渲染线程却按帧网格对齐目标SecondsToFramePts查找分数帧率下二者差约 1 ms目标 41 vs PTS 42每次查找全部未命中且预取已把解码器跑到前面强制DecodeTo看到负增量 → 向后 seek → GOP 重解码。60 fps 掩盖了它对齐目标与 PTS 恰好重合。修复FrameIndexForPts/FrameIndexForTime用同一套取整显示端 FLOOR、解码端 ROUND二者对同一帧收敛到同一索引见 VideoPlaybackController.cs。探测验证稳定播放变为published 25/s, decoded 0, maxDecode 0.0 ms尖峰只出现在真正的硬 seekGOP 重磨期间。Phase 3共享设备完整零拷贝——风险最高用ResourceManager.Device替换 FFmpeg 自有设备含 AddRef 小心的共享 SetMultithreadProtected lock/unlock 回调消除跨设备拷贝。阶段修正这并非可选的最后一拷贝优化——Phase 2 的 GPU 转换必须依赖它独立设备解码使表面留在错误设备上跨设备资源CreateShaderResourceView首次转换即原生崩溃。加锁是硬仗见 5.3 节。GPU 验证通过。仍待测重复开关下的 teardown设备 AddRef/Release 平衡与 AMD/Intel 等其它厂商NVIDIA 已验。Phase 4Optimize For 参数 自动降级接线完成枚举 下拉 A/B 选择 运行时重初始化 hwaccel 失败优雅降级。TIXL_FFMPEG_FORCE_HW/TIXL_FFMPEG_ZEROCOPY环境变量已移除。调用链算子线程化 →IVideoPlaybackEngine.RequestFrame→controller.Update→OpenSource→VideoDecoderSession.TryOpen(url, optimization, ...)。VideoStreamInput直播传FastSeeking。29 个 Video.Tests 全部通过测试宿主无 D3D 设备回退软件路径。模式切换 teardown 两个 Bug2026-06-08 修复切换 Fast Seeking ↔ Playback Performance尤其伴随分辨率变化会砖掉算子。(1) 重开时 worker 在_lock下丢弃待处理 GPU 帧防止渲染线程转换刚销毁会话的帧零拷贝转换包 try/catch保留最后纹理而非报算子错误。(2) 真正的砖控制器Texture与转换器_output曾是同一对象软件路径的UploadPendingFrame在尺寸变化时 Dispose 了Texture——把转换器的输出在背后释放了下一次EnsureOutput读取死纹理的Description抛COM object null永久异常。修复软件路径独占独立的_softwareTexture转换器独占拥有/释放_output。不变式绝不让两个所有者释放输出纹理。编辑器中仍需验证Optimize For下拉的标签/位置。十、风险与缓解风险缓解措施全局设备双重释放崩溃——共享ResourceManager.Device引用计数失误Phases 1–2 用自有设备共享设备仅 Phase 3显式 AddRef teardown 测试重复开关tier-2 降级从不触碰全局设备引用计数解码器池纹理仅解码用途无 SRV手动hw_frames_ctxBindFlags | SHADER_RESOURCE线程worker 的ID3D11VideoContext render 的 immediate contextSetMultithreadProtected(true) FFmpeg lock/unlock 回调序列化设备访问转换器 dispatch 取同一互斥锁各 GPU 编解码配置档位差异自动回退软件Phase 4记录所选层级渲染线程转换开销每显示帧一次全屏计算 dispatch开销小worker 不再跑 swscale净卸载无需阈值剔除十一、尚未完成的工作与已知边界HDR 全流程PQ/HLGBT.2020P010 可解码但需 BT.2020 矩阵 真实色调映射目前为 stub发白可接受bt709 10-bit 已正确。色彩矩阵选择将流的色彩空间BT.601 for SD / BT.709 / BT.2020与 full/limited range 传入着色器会话已通过ColorTrc/pixfmt 检测 HDRIsHdr属性ColorSpace/ColorRange的暴露与接线是待办。SRV 缓存失效池稳定时按切片索引缓存足够需确认 FFmpeg 不在流中途重分配数组尺寸/格式变化 → 重建。teardown 与多厂商验证重复开/关下的设备 AddRef/Release 平衡、AMD/Intel 的 GPU 验证当前 NVIDIA 已验keyed-mutex tier-2 降级未构建。完全异步隔离独立解码设备以重叠 NVDEC 与渲染decode 与 render 并行是更后期、更大的工作。其它厂商/编解码目标验证 GPU 厂商与编解码器的优先级清单待定。延伸阅读方案总纲.agentic/Plans/archive/Plan_FfmpegVideo.mdM2 双管道、GOP 缓存、VideoPlaybackEngine 全局媒体管理编码里程碑.agentic/Plans/archive/Plan_FfmpegEncode.md手动测试清单video-optimize-for-modes.md、video-playback-determinism.md核心源码VideoDecoderSession.cs、HardwareFrameConverter.cs、Nv12ToRgba-cs.hlsl、VideoPlaybackController.cs、Core/Video/VideoPlayback.cs【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考