当前位置: 首页 > news >正文

视频编解码学习十二之Android疑点

一、android.view.SurfaceControl.setDisplaySurface的作用

android.view.SurfaceControl.setDisplaySurface 是 Android 系统中一个 native 层级别的 API,主要用于 设置某个物理显示屏(Display)的输出 Surface,属于 SurfaceFlinger 的一部分功能。这个 API 并不是应用开发常用的接口,而是系统或原始设备制造商(OEM)用于控制显示输出的低层接口。


🔧 作用解析

SurfaceControl.setDisplaySurface(SurfaceControl displayToken, Surface surface) 的主要作用是:

将一个 Surface 与特定的 Display(显示设备)绑定,使该 Surface 成为该 Display 的渲染目标。

也就是说,这个接口决定了 某个显示屏最终画面要显示到哪个 Surface 上,可以理解为是 SurfaceFlinger 告诉硬件:“你应该把图像输出到这个 Surface 对应的物理设备上。”


📦 参数说明

  • displayToken: 一个代表物理 Display 的 token,通常通过 SurfaceControl.getInternalDisplayToken() 或类似接口获得。

  • surface: 目标 Surface,用于接收最终的图像内容。比如一个 SurfaceTextureSurfaceView 所提供的 Surface


📍 使用场景

此函数多用于系统级的图像输出控制,比如:

  1. 投屏系统(屏幕镜像):系统想要将主屏内容输出到一个 HDMI 显示器或虚拟显示上。

  2. 多屏协作/扩展显示:比如一台 Android 设备连接多个显示器时,需要绑定每个显示器的输出 Surface。

  3. 截图或录屏:系统通过一个 Surface 捕获整个 Display 的输出内容。

  4. 系统 UI 渲染控制:用于系统引导期间或锁屏、开机动画等控制显示。


🧪 注意事项

  • 这个 API 是 隐藏的、系统级别的,普通应用无法直接调用。

  • 使用它需要 系统权限,并且通常配合 SurfaceComposerClientSurfaceFlinger 或 AIDL 接口工作。

  • 设置错误或参数异常可能会导致显示黑屏、卡死或输出内容不正常。


📚 相关源码路径(AOSP)

在 AOSP 源码中,你可以看到它的实现大致在以下路径中:

 

plaintext

复制编辑

frameworks/base/core/java/android/view/SurfaceControl.java frameworks/native/libs/gui/SurfaceComposerClient.cpp frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

具体来说,Java 层只是包装,最终会调用到 native 层通过 binder 调用 SurfaceFlingersetDisplaySurface.

二、Display是物理显示设备吗?

是的,在 SurfaceControl.setDisplaySurface 的上下文中,Display 是指物理显示设备(physical display device)。


📌 详细说明

✅ 在这个上下文中的 Display 含义:

  • 指的是一个实际存在的硬件输出设备,比如:

    • 内置屏幕(手机、平板的主屏)

    • 外接 HDMI 显示器

    • 无线显示器(Miracast、WiDi)

    • 虚拟显示设备(在系统看来也被当成一个“显示”,但可能是用于录屏或投屏)

  • Android 系统中的 DisplayToken(在 native 层)代表的就是这种显示设备的引用,和 Java 层 Display 类不是同一个概念,但都是为了描述某个显示目标。


🎯 举个例子:

你可以通过 native 层(比如 C++ 中的 SurfaceComposerClient)调用:

 

cpp

复制编辑

sp<IBinder> display = SurfaceComposerClient::getInternalDisplayToken();

这个 display 就是系统主屏幕的 display token,它在调用:

 

java

复制编辑

SurfaceControl.setDisplaySurface(display, surface);

时被用来绑定输出 surface。

这表示:“我希望把主屏幕的输出,显示到这个 surface 上。”


🔁 对比:Java 层的 Display

在 Java 层中,也有一个 android.view.Display 类,这个类通常是代表系统中抽象出来的显示输出,常用于多窗口、投屏等,但它和 SurfaceControl.setDisplaySurface 所用的 displayToken 并不直接等价。


🧠 补充:物理 Display 的获取

在系统或 native 开发中,可以通过如下方式获取 display:

 

cpp

复制编辑

sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken(); // 主屏幕 sp<IBinder> token = SurfaceComposerClient::getExternalDisplayToken(); // 外接屏幕


✅ 结论

是的,DisplaysetDisplaySurface() 中指的是 一个物理或系统级的显示设备,通常代表的是 硬件屏幕输出接口,比如内屏、HDMI、虚拟显示等。

三、display和surface是什么关系?

这是个很核心的问题,在 Android 图形系统(特别是 SurfaceFlingerSurfaceControl)中:


🎯 简明结论:

Display 是“输出目标”(比如屏幕),而
Surface 是“内容来源”(谁要被显示)。

通过 setDisplaySurface(display, surface),你告诉系统:

“请把这个 Surface 的内容,作为这个 Display 的显示输出。”


🧱 各自的定义和角色

概念定义在图形系统中的作用
Display代表一个物理显示设备或虚拟显示目标。最终图像的去处(输出目标)
Surface一个可以被写入图像内容的缓冲区,比如由应用或系统提供图像内容的来源(输入图层或缓冲区)


📦 具体关系理解:

在 Android 中,一个典型的图像渲染流程是这样的:

  1. 应用或系统绘制内容 → 写入某个 Surface

  2. SurfaceFlinger 收集所有 Surface → 合成(Compose)

  3. 合成好的最终图像 → 输出到某个 Display

这个流程可以简化为:

 

rust

复制编辑

多个 Surface(图层) --合成--> 最终帧图像 --送出--> Display


🧩 setDisplaySurface() 的作用

这个函数的作用是:

“把这个显示设备(Display)的最终输出图像放入这个 Surface 中。”

常用于这些场景:

  • 录屏:你把一个 Surface 设置为显示的输出,这样它会收到完整的画面内容

  • 投屏:将主显示的画面输出到一个外接 HDMI/无线显示的 Surface

  • 多显示系统:为每个显示设备配置自己的输出 Surface


🖼️ 举个实际例子

比如你在开发一个系统级的投屏功能:

  1. 你创建一个虚拟显示 Display(比如通过 SurfaceComposerClient.createDisplay()

  2. 你创建一个 Surface(比如基于 SurfaceTexture 或 BufferQueue)

  3. 你用 setDisplaySurface(display, surface) 将两者绑定

这表示:这个虚拟显示产生的画面,将写入这个 Surface 中,你可以用这个 Surface 编码、传输或其他处理。


🧠 类比理解

可以把它类比为:

  • Display电视机

  • SurfaceHDMI 线接口的输入源

你可以把某个视频源(Surface)接到电视(Display)上,让它显示出来。


✅ 总结:

项目DisplaySurface
是什么显示目标(物理或虚拟屏幕)内容缓冲区(应用写图像的地方)
作用显示画面的“去向”提供画面的“来源”或“容器”
使用位置输出、目标端输入、内容端

SurfaceControl.setDisplaySurface(display, surface)
就是连接两者的桥梁 —— 把 谁要显示的内容(surface) 输出到 哪个屏幕(display) 上。

四、setDisplaySurface()中,当display是主屏,surface是虚拟屏的surface,是相当于把主屏的内容复制到虚拟屏上,还是会影响主屏的显示?

下面我来给你准确、深入地解析。


✅ 简要回答:

setDisplaySurface(display=主屏, surface=虚拟屏的 surface) 表示:你将主屏的最终图像输出到这个 surface 中,
是复制主屏内容(画面镜像),而不是影响主屏显示。

即:

  • 主屏继续正常显示

  • 你只是在“拷贝”它的画面到另一个 Surface,用于录制、投屏等目的


🧠 更详细解释:

📌 setDisplaySurface() 的行为是什么?

它不是把 surface 当作某个图层,而是把它当成 Display 的输出缓冲区(Framebuffer)
这意味着:

  • Display 原本输出是发到物理屏的,现在你通过这个 API 拦截了这个输出,让它 输出到你指定的 Surface

  • 被指定的 surface 会接收到合成后的整帧图像(就是用户当前看到的整个屏幕),相当于屏幕的“镜像帧”拷贝


📊 举个例子(场景对照)

场景displaysurface结果
录屏主屏一个 Surface(比如 MediaProjection 提供的)你会收到主屏的内容帧,但不影响主屏显示
投屏主屏外接设备的 buffer(通过网络或 HDMI 虚拟)外设看到主屏内容,主屏依然显示
反例主屏App 提供的 Surface,并作为图层提交你会替换部分图层内容,不是复制


🚧 注意事项(系统开发中):

  • 你是在设置合成后的结果的输出目标,不是控制图层。

  • 这个操作通常 需要系统权限或 Root 权限

  • 如果你只想“显示”某个 Surface 的内容,应该用 SurfaceControl.setLayer() 之类的 API,而不是 setDisplaySurface()

  • 不能频繁更改 setDisplaySurface(),它是低频、系统级的配置操作。


📚 对应 Android 系统中的用法:

比如 Android 的录屏、投屏服务(如 SurfaceFlinger::doComposition() 的输出流程),就是:

  1. 使用一个虚拟 Surface 作为输出

  2. 设置主屏的 Display 输出到该 Surface

  3. 继续正常渲染主屏,不会影响物理屏幕的显示

这种方式是目前 Android 中录屏、无线投屏的基础机制。


✅ 结论重申:

setDisplaySurface(主屏, 虚拟 Surface) 是一种不影响主屏显示的“画面复制”操作
你只是“截获”了主屏的合成输出结果,输出到了另一个 Surface 中。

五、像这样把主屏内容复制到另一个surface中通常需要花多长时间?

这个问题非常关键,尤其涉及 性能时延帧同步。我们来拆解一下:


✅ 简短答案:

把主屏内容复制到另一个 Surface(如录屏、投屏用的)通常不需要额外的耗时,拷贝几乎是“零成本”的 DMA 或硬件合成输出操作。延迟一般控制在 1~2 帧内(16~33ms 左右)甚至更低。


🧠 为什么这么快?背后发生了什么?

这并不是“CPU 上逐像素拷贝”,而是:

🔧 GPU/HWComposer/SurfaceFlinger 一体完成:

  • SurfaceFlinger 将所有 Layer 合成为一帧时,会根据设置:

    • 将这一帧输出给物理 Display(正常显示)

    • 同时输出到你指定的 Surface(投屏、录屏)

✅ 输出操作不是“复制”,而是“多路输出”

  • 通常使用 硬件层的双输出/双写 DMA(Dual-Write DMA)GPU多目标渲染

  • 输出到显示器 + 输出到 Surface 可以并行进行

  • 所以这个操作几乎不会增加帧合成的总时长(不会影响 UI 响应)


📉 实测延迟范围(参考值):

场景输出方式延迟(帧)延迟(毫秒)
系统级录屏(MediaProjection)framebuffer copy / virtual display1~2 帧~16ms - 33ms
Wireless Display(Miracast)surface + 编码 + 网络发送2~4 帧~30ms - 60ms
HDMI 拓展屏幕复制多路输出接近 0 帧< 10ms


🔍 有哪些因素可能拖慢这个操作?

虽然复制本身快,但以下环节可能造成延迟:

  1. Surface 所连接的 BufferQueue 阻塞

    • 如果下游(编码器、网络)处理慢,surface 的消费端来不及消费,就会卡住生产者

  2. 图像格式转换

    • 如果目标 Surface 只接受某种格式(如 YUV),而主屏是 RGB,系统需要转换格式,会增加 GPU 负担

  3. 目标 Surface 在另一个进程或 Binder 中跨进程通信

    • 会带来一次内核用户态上下文切换,产生 1~2ms 延迟

  4. 设备性能差、GPU 压力大

    • 可能会造成合成时间整体变慢(但这是系统问题)


🔧 优化建议(如你在开发系统服务):

  • 使用 硬件合成直出路径(如通过 HWC2 设置 Dual output)

  • 减少 Surface Buffer 格式转换(保持与 Display 相同)

  • 为目标 Surface 设置较高的 BufferCount(避免生产端等待)

  • 使用 setDisplaySurface() 而非 copyLayer(),避免 CPU 拷贝


✅ 总结

问题回答
会不会影响主屏显示?❌ 不会,属于多路输出,不干扰主屏
是 CPU 复制吗?❌ 不是,是 GPU 或 DMA 输出
速度有多快?✅ 通常在 1 帧内完成,约 16~33ms 延迟
有哪些性能影响因素?Surface 堵塞、格式转换、跨进程通信等

六、延迟在什么范围内,才可以玩实时游戏?

你正在触及实时图像传输(如投屏游戏、云游戏、远程控制等)系统中的核心指标之一:端到端延迟


✅ 简明结论

🎮 要实现“可玩”的实时游戏体验,总延迟应控制在 60ms 以下,理想情况在 30ms 以内。


🎯 延迟的等级划分(针对实时交互游戏)

延迟范围用户感知游戏体验
< 30ms几乎无感知,媲美本地✅ 理想、顺畅
30~60ms有轻微感觉,但可接受✅ 可玩、流畅
60~100ms有明显延迟感⚠️ 勉强能玩
> 100ms明显卡顿/延迟严重❌ 不适合玩游戏


🧱 实时游戏延迟的组成部分(链路分析)

以“把主屏画面复制到另一个 surface 上用于远程实时游戏”为例,总延迟来自多个阶段:

阶段操作典型耗时
🖼️ 渲染阶段游戏帧在主屏被绘制完成16ms(60fps)
📤 复制阶段主屏内容复制到目标 Surface12ms(DMA/GPU)
🎞️ 编码阶段H.264/H.265 视频编码5~15ms(硬编)
🌐 传输阶段网络发送(局域网或无线)1~20ms
📥 解码阶段接收方解码画面5~15ms
🖥️ 显示阶段解码后帧显示到屏幕16ms(60fps)
总计30~80ms


✅ 如何优化以达成实时游戏体验?

系统设计角度:

项目推荐做法
Surface 数据复制方式使用 setDisplaySurface(),避免 CPU 复制
编码方式使用 硬件编码器(MediaCodec) 并调成低延迟模式
编码参数使用低 GOP(关键帧间隔)、低缓存
网络传输避免 Wi-Fi 干扰,使用 5GHz Wi-Fi,支持 QoS
解码端使用硬解码 + 提前渲染机制
显示刷新机制使用 SurfaceView + Choreographer 提前预渲染


🎮 示例:Steam Link / Moonlight 等系统的延迟设计

系统/协议理想延迟技术手段
Moonlight + NVIDIA GameStream~30msH.265 硬编 + UDP + 低延迟模式
Steam Link4060ms软件优化 + 局域网传输 + 减缓压缩
Android 无线投屏50100mssetDisplaySurface() + MediaProjection
云游戏系统(如Xbox云游戏)80120ms云端计算 + 网络优化


✅ 结论

🎮 如果你希望在屏幕复制(主屏 -> surface -> 编码传输)场景中实现可玩级别的实时游戏体验:

  • 必须确保 端到端延迟 ≤ 60ms

  • 系统设计上建议使用:

    • SurfaceControl.setDisplaySurface()(高效复制)

    • 硬件编码(低延迟 H.264/H.265)

    • 局域网(如 5GHz Wi-Fi)

    • 减少 BufferQueue 滞后与双缓冲

七、渲染和显示的区别

这是一个图形系统(无论是 Android、游戏引擎,还是桌面系统)中非常基础但又极易混淆的两个概念


✅ 简明区分:

概念渲染(Rendering)显示(Display)
作用生成图像(把场景变成一帧帧像素)将生成的图像呈现在屏幕上
阶段图像 生产 阶段图像 消费 阶段
发生位置GPU(或 CPU 渲染引擎)显示控制器 / SurfaceFlinger / HWC
产物Frame Buffer(帧缓冲)屏幕上的像素内容
频率游戏引擎控制(如 60fps、120fps)通常与屏幕刷新率同步(如 60Hz VSync)


🧠 更深入解释

🖼️ 渲染(Rendering)是什么?

  • 是“画图”的过程,把游戏场景、UI、视频帧等“抽象内容”变成 具体像素

  • 这个过程可能由:

    • 应用(Canvas、Skia、OpenGL、Vulkan)

    • 系统组件(WindowManager、SurfaceFlinger)

    • 游戏引擎(Unity、UE)

举例:

把一个按钮绘制成图像,把 3D 场景变成一帧 1080p 图像帧,这都是渲染。


📺 显示(Display)是什么?

  • 是把“已经生成好的像素”送到屏幕上、肉眼可见的过程。

  • 通常通过:

    • SurfaceFlinger 合成所有图层 → 输出一帧

    • 通过 HWC / DRM 驱动 → 输出到显示设备

    • 屏幕扫描刷新一次(VSync)

举例:

游戏已经生成了一帧图像,但要等到下一次屏幕刷新(比如 16.6ms 后)才能真正出现在屏幕上。


🎯 类比理解:做 PPT 的比喻

  • 渲染 = 你在 PowerPoint 中画了一张幻灯片

  • 显示 = 你按下播放键,让观众在投影仪上看到它


🔁 在 Android 中的对应:

流程阶段渲染还是显示?说明
App 使用 Skia 绘制 UI渲染使用 GPU 或 CPU 绘制到 Surface 的缓冲区中
Surface 被提交渲染图像还没显示,只是准备好了
SurfaceFlinger 合成渲染(最后阶段)多个图层合成为一帧
Frame 输出到屏幕显示真正肉眼可见,需要 VSync 配合


🔄 典型延迟链(从渲染到显示)

  1. App 发起 draw call → RenderThread 开始渲染 → Surface 中 buffer 填满

  2. buffer 被提交给 SurfaceFlinger

  3. 等待下一次 VSync 时机,SurfaceFlinger 合成所有图层

  4. 合成帧提交给显示控制器 → 屏幕刷新 → 用户看到内容

通常这整个过程叫做 "Frame pipeline",耗时约为 16.6ms ~ 33ms。


✅ 总结:

问题渲染显示
是干什么的?画出图像把图像呈现出来
谁负责?App / GPU / 系统组件SurfaceFlinger + HWC + 屏幕
图像状态“生成了但未显示”“显示出来了”
是否可见?❌ 不可见(存在于内存)✅ 可见(出现在屏幕)

八、如此看来,投屏做不到延迟低于30ms

你说得很敏锐 —— 常规的投屏系统确实很难做到低于 30ms 的延迟。但是否**“做不到”**,要具体看实现方式、硬件支持程度、网络状况等。


✅ 简明结论:

🎯 传统投屏系统(如 Miracast、AirPlay、Cast)难以低于 30ms
高度优化的投屏方案(例如 NVIDIA GameStream + Moonlight)在特定条件下可以做到 20~30ms 延迟,但也极为挑剔环境和实现。


📉 为什么传统投屏难低于 30ms?

投屏链路必须经过以下阶段(每步都吃延迟):

阶段典型耗时说明
渲染16ms游戏/系统生成一帧图像(60fps)
复制到 Surface1~2ms使用 setDisplaySurface 或虚拟 Display
编码(硬编)5~10ms通常是 H.264 baseline
网络传输5~15ms取决于 Wi-Fi / LAN 稳定性
解码(硬解)5~10ms通常使用 MediaCodec 或 GPU
显示刷新~16ms等下一次 vsync,才真正看到帧

🔗 总计:约 40~70ms(这是典型系统投屏的真实表现)


🎯 有哪些场景“接近”或“突破”30ms延迟?

系统 / 技术条件延迟范围
Moonlight + NVIDIA GameStream局域网、RTX GPU、优化参数20~35ms
Steam Link(局域网)5GHz Wi-Fi + 硬编 + TV 硬解30~45ms
⚠️ Android MediaProjection + 硬编基于 setDisplaySurface()50~80ms
⚠️ AirPlay / Miracast无优化70~120ms

👉 注意:

  • 即使你用最快的编码器,显示刷新(VSync)+网络波动会拖住延迟底线。

  • 编码器通常也需要一些 帧缓存,比如 2 帧(就是额外 30ms)。


✅ 结论:能不能做到低于 30ms?

问题答案
普通投屏能否低于 30ms?❌ 几乎不可能(Miracast、AirPlay 等)
特定方案能否做到?✅ 有条件可行(如 Moonlight + 局域网)
需要什么支持?- 低延迟编码(快速帧间编码)
- 高带宽低干扰 Wi-Fi(最好是 5GHz)
- 最小化 buffer、VSync 对齐
- 接收端支持快速解码和低延迟渲染


🛠️ 补充建议:如果你自己做投屏系统

你可以考虑如下策略来尽量压缩延迟:

  1. 使用 setDisplaySurface() 拦截主屏输出,避免在应用层采集

  2. 使用 MediaCodec 硬编,开启 low-latency profile

  3. GOP 设置为 1~2(低 B 帧甚至无 B 帧)

  4. 目标帧率拉高到 90fps(加快帧传递频率)

  5. 接收端用 SurfaceView + async 解码路径

  6. 推流协议使用 RTP over UDP(而非 RTSP/TCP)

九、高分辨率的原始图像,通过低分辨率的设备用setDisplaySurface投屏到高分辨率的设备,会丢失吗?

触及到了 分辨率适配像素数据保真度 的核心。


✅ 简短回答:

是的,如果你使用 setDisplaySurface() 将一个低分辨率设备的原始图像投屏到高分辨率显示器,最终投出的画面分辨率将受限于原设备的显示分辨率,会失真或模糊,并不会自动变得高清。


📌 为什么会“丢失”高分辨率?

情况还原:

  • 你在一个 低分辨率设备(比如 720p 手机)上运行应用

  • 使用 setDisplaySurface()主屏输出投到一个高分辨率设备(比如 4K 显示器或虚拟屏)

  • 你以为能在高分屏上显示更清晰图像,但结果发现仍然是 720p 放大后的效果

原因在于:

解释
setDisplaySurface() 拷贝的是合成结果它不会重新渲染或生成高分图像,而是复制低分屏渲染完的最终帧
⚠️ 原始渲染内容已是低分辨率Android 上应用或系统界面是基于设备 DPI 和屏幕大小渲染的,渲染目标分辨率就是低的
❌ 不会自动“高清化”除非你在原设备上以更高分辨率渲染图像(通常不可能)


🧠 类比理解:

这就像你拿一个 720p 的截图,在 4K 显示器上全屏播放 —— 画面还是糊的,像素已经定死了。


✅ 如何判断你最终的投屏分辨率是多少?

你可以通过以下方式验证:

方法 1:查看系统的实际显示分辨率

 

bash

复制编辑

adb shell dumpsys SurfaceFlinger

在输出中查找你绑定的 Surface 的显示分辨率,以及主屏的 DisplayDevice 信息。

方法 2:通过 MediaCodec 编码时查看输入帧大小

  • 如果你设置 setDisplaySurface(surface) 给一个 MediaCodecinput surface,那编码器收到的帧分辨率就是源设备的屏幕分辨率,不会自动 upscale


✅ 如何实现“清晰的高分辨率投屏”?

如果你希望:

“用低分辨率设备运行 App,但在高分屏上看到更清晰的图像”

你需要 重新设计渲染路径,如下:

方法效果代价
❌ 直接 setDisplaySurface()画面模糊简单,低分辨率限制
✅ 使用虚拟 Display 并指定高分辨率高清可行要求应用支持多分屏
✅ App 主动渲染到高分辨率 Surface高清需改造 App 或引擎
✅ 投送原始图像数据(非屏幕采集)原始质量通常用于图像类 App


🎯 示例场景

场景是否可获得高清图像?原因
setDisplaySurface() 投屏手机 UI❌ 模糊,低分限制源图像已是低分
用虚拟 Display 指定 1080p 渲染✅ 高清(如果 App 支持)渲染目标是高分
游戏使用 Vulkan 渲染到 4K Surface✅ 高清自定义渲染控制


✅ 总结:

问题答案
setDisplaySurface() 会丢失分辨率吗?✅ 是,受限于源屏幕的分辨率
会自动高清化吗?❌ 不会
如何获得高清效果?✅ 使用虚拟 display 或高分渲染

十、创建了高分的虚拟设备,同时虚拟设备要和低分的主设备同步,会有什么影响?

这个问题触及到了系统合成路径、刷新策略、buffer同步等多个 Android 图形子系统的核心点。我们分步骤来讲:


🎯 场景还原

你现在有两个 Display:

  1. 主屏(低分辨率,比如 1280x720)

  2. 虚拟屏(高分辨率,比如 1920x1080 或 4K)

你希望这两个屏幕同步显示相同内容(例如镜像主屏到虚拟屏),但由于它们分辨率不同,系统需要做缩放或重新合成。


✅ 会产生的主要影响

类别影响情况原因说明
📉 性能开销明显增加 GPU/合成压力系统需要额外执行一次 缩放或 re-composite
⏱️ 延迟✅ 可能 增加 1 帧以上延迟同步时需要等待 buffer/合成对齐
🔁 同步⚠️ 不一定能做到真正的帧级同步两个 Display 的 VSync 信号可能不同步
📐 清晰度✅ 虚拟屏虽是高分,但内容是低分缩放上去除非应用对虚拟屏单独高分渲染
🌀 帧率差异⚠️ 如果两个屏幕刷新率不同,会导致卡顿或撕裂例如主屏 60Hz,虚拟屏 30Hz 或 90Hz


🔍 细节分析:SurfaceFlinger 是怎么处理的?

👉 当你开启镜像模式(或自己同步绘制两个屏幕):

  1. App 渲染的是 720p 分辨率

  2. 系统将这帧图像:

    • 输出到主屏,照常显示

    • 同时缩放到虚拟屏的分辨率(如 1080p)并显示

SurfaceFlinger 面临的问题:

问题表现
Buffer 尺寸不匹配需要 GPU 或硬件合成器执行 scale
两屏 vsync 不一致可能导致 tearing、掉帧
Buffer 填充与提交延迟合成管线拉长,丢帧概率升高


🧪 举个真实例子

比如你有个 App,渲染一帧 720p 界面,显示在两个屏幕上:

  • 主屏 720p:完美适配

  • 虚拟屏 4K:SurfaceFlinger 要将内容拉伸到 3840x2160,GPU 消耗上升,部分设备甚至用软件做缩放,非常慢


✅ 如何减少影响?

方法效果说明
使用虚拟 Display 单独渲染高分内容✅ 真正高清、不卡顿代价是需要 App 支持多分屏
限制虚拟屏分辨率接近主屏⚠️ 清晰度受限,性能轻保证合成路径一致性
不做镜像,而是单独推流内容到虚拟屏✅ 更灵活适合投屏/游戏/视频场景
使用硬件合成模块(HWC2 + Display HAL)⚠️ 设备依赖强一些 SoC 有 mirror support


✅ 总结结论

问题是否会发生?说明
会不会增加合成和性能开销?✅ 明显会多一次缩放、双屏合成开销
会不会导致同步问题、撕裂?⚠️ 可能会两屏 vsync 不同步是常态
虚拟屏内容会更清晰吗?❌ 如果仅是镜像渲染内容决定清晰度
虚拟屏能不能独立显示高分图像?✅ 可以需要专门渲染逻辑


🎯 建议你考虑的问题:

  • 你是做 UI 镜像?游戏镜像?视频推送?

  • 你控制的是 App 层,还是系统层?能不能控制合成/渲染方式?

  • 虚拟 Display 是用 DisplayManager.createVirtualDisplay() 创建的吗?

十一、如果不要求虚拟屏和主屏同步,只是把高分的虚拟屏投屏到高分的显示设备上呢

如果你不要求主屏和虚拟屏同步,而是:

只在高分虚拟屏上渲染内容,并把它独立投屏到一个高分显示设备上

那么,你可以做到:


高清显示、低延迟、高质量输出

这实际上是最推荐的方式,比“主屏镜像+缩放”更清晰、更高效,尤其适合:

  • 无线投屏(如 DLNA / 自研协议)

  • 扩展屏应用(演示模式、PPT、游戏)

  • 自研图形应用输出到远程大屏幕


🔧 实现逻辑(推荐路径):

  1. 使用 DisplayManager#createVirtualDisplay() 创建一个高分辨率虚拟显示设备

     

    java

    复制编辑

    VirtualDisplay virtualDisplay = displayManager.createVirtualDisplay( "MyVirtualDisplay", 1920, 1080, 320, surface, // 用于接收该显示内容的 Surface(可用于编码) DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC );

  2. 指定该 VirtualDisplaySurface 作为编码输入,使用 MediaCodec 进行实时硬编码(比如 H.264)

  3. 将编码结果通过你自己的网络协议(比如 RTP / RTMP / WebRTC / Socket)发送到远端设备

  4. 在高分显示设备上解码并显示该视频流(1080p / 4K)


✅ 好处对比

主屏镜像 + 缩放独立高分虚拟屏
图像清晰度❌ 受限于主屏分辨率✅ 高分原始渲染
渲染控制❌ 无法分离✅ 可单独绘制
多屏逻辑❌ 共用 UI 配置✅ 独立 UI、逻辑
延迟控制❌ 被系统帧同步影响✅ 渲染→编码直通
可扩展性(多屏)❌ 很难✅ 可以创建多个虚拟屏


🎮 举个典型例子

假设你做一个“云游戏客户端”:

  • 主屏只显示菜单,不参与画面渲染

  • 游戏画面渲染到虚拟屏(比如 1080p 60fps)

  • 编码后推流到远端显示设备(如电视)

🟢 结果是:

  • 主屏不卡顿、不发热

  • 虚拟屏保持高清、高帧率、高效率传输


⚠️ 注意事项

问题解决方法或注意点
如何让 App 渲染到虚拟屏?创建新的 Context.createDisplayContext() 或用 Presentation
虚拟屏没有输入事件?正常,不需要交互;如需交互可虚拟输入注入
虚拟屏能 4K 吗?✅ 可指定 3840x2160,但 GPU 带宽和编码器要跟得上


✅ 总结

你的目标可行性建议
高分虚拟屏 → 投屏到高分设备✅ 完全可行推荐使用 VirtualDisplay + MediaCodec 路径
不同步主屏,独立渲染内容✅ 高效、清晰不走主屏镜像,性能更优
高清投屏,适配远端显示✅ 控制渲染分辨率即可编码传输控制帧率、码率

十二、点亮虚拟屏能达到像点亮主屏一样防止手机休眠的效果吗?

你的关注点是:

点亮虚拟屏是否可以像点亮主屏一样,防止手机进入休眠状态(Doze / Suspend / 黑屏)?


✅ 简短结论:

不可以直接等效防止休眠虚拟屏本身不能阻止系统休眠,但可以通过特定方法间接达到防止休眠的效果。


📌 为什么虚拟屏不能自动防止休眠?

原因解释
虚拟 Display 不被视为物理屏幕它不会像主屏一样参与电源管理策略
系统休眠判断基于主屏状态即使虚拟屏在“输出内容”,主屏息屏或用户无操作,仍可能触发 Doze 或 Suspend
虚拟屏没有“用户可见性”信号没有接触/亮度/唤醒事件驱动系统保持活跃状态


✅ 怎么样才能 真正防止休眠

你需要组合使用 系统唤醒机制,比如:

方法是否推荐原理
PowerManager.WakeLock✅ 推荐阻止 CPU 或屏幕休眠(需权限)
FLAG_KEEP_SCREEN_ON⚠️ 仅限主屏有效虚拟屏不生效
ForegroundService + WakeLock✅ 常见做法在后台长时间保持活跃
播放音频或 MediaProjection⚠️ 非常规方法一些厂商限制少时有效


✅ 推荐实现方式:使用 WakeLock

 

java

复制编辑

PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); WakeLock wakeLock = powerManager.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "YourApp:VirtualDisplayWakeLock" ); wakeLock.acquire(); // 可选超时参数

如果你只需要防止 CPU 休眠而不需要点亮屏幕:

 

java

复制编辑

PowerManager.PARTIAL_WAKE_LOCK

记得使用完后 wakeLock.release(),否则会造成耗电。


🧠 示例场景:你在开发投屏服务

场景是否能阻止休眠?备注
只创建虚拟屏 + 开始编码推流❌ 不能虽然图像在输出,但主屏休眠会中断编码
虚拟屏 + WakeLock + 前台服务✅ 可以这是推荐做法,适配性最强
虚拟屏 + 屏幕共享(MediaProjection)⚠️ 不一定部分系统可阻止休眠,但不可依赖


❗ 特别提醒:Doze 模式下不保证行为稳定

某些厂商(如华为、小米)在电池策略中,会强制挂起后台虚拟屏服务,除非:

  • 你是前台服务(通知栏常驻)

  • App 被加入电池白名单

  • 获取了 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限(需要手动授权)


✅ 总结

问题是否成立建议方案
虚拟屏会自动阻止系统休眠吗?❌ 不会加 WakeLock
虚拟屏保持内容输出会延长设备唤醒时间吗?⚠️ 不一定不稳定,视厂商实现
如何确保系统不黑屏 / 不挂起 App?✅ 前台服务 + WakeLock
虚拟屏是否能用于长时间输出到显示设备?✅ 可以,但需配合防休眠机制

十三、通过电脑adb命令,用app_process拉起的进程,系统休眠后也会不工作,加 WakeLock确定能解决吗?

涉及到 app_process 启动的进程是否能在系统休眠后继续运行 —— 我们来深入拆解


🎯 问题背景总结:

你用的是类似如下命令:

 

bash

复制编辑

adb shell app_process /system/bin com.example.YourMainClass

  • 这种方式绕过了普通 Activity / Service 启动路径

  • 通常不受 Android 应用生命周期限制,但也不受系统 power manager 自动保护

现在你想确认:

如果系统休眠(息屏 / Doze / Suspend),这个进程是否会停止?如果加 WakeLock,能否解决?


✅ 简洁结论:

是的,理论上你可以使用 WakeLock 保持 CPU 运行,即使系统休眠,app_process 启动的进程也可以持续工作。

⚠️ 但前提是:

  • 你必须获取 正确类型的 WakeLock

  • 运行环境有权限申请 WakeLock

  • 该进程没有被 SELinux 限制调用 PowerManager


✅ 你该怎么做?

🧩 步骤一:让进程获取 WakeLock

即使你通过 app_process 启动,只要你创建了 Java 进程并能访问系统服务,你可以这样写代码:

 

java

复制编辑

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::KeepAlive"); wakeLock.acquire();

  • PARTIAL_WAKE_LOCK 是关键!它不要求屏幕亮,但能防止 CPU 进入休眠。

  • 你不需要 SCREEN_DIM_WAKE_LOCK 等类型,因为你可能没有界面。

🔐 权限要求:

你必须在代码中拥有:

 

xml

复制编辑

<uses-permission android:name="android.permission.WAKE_LOCK"/>

但对于 app_process 启动的进程,没有 AndroidManifest.xml,所以你需要:

  • 在 shell 用户或 system 用户下运行(拥有 WAKE_LOCK 权限)

  • 或使用 pm grant 赋予权限(如果你用 app 包运行)

 

bash

复制编辑

adb shell pm grant com.example.yourapp android.permission.WAKE_LOCK


⚠️ 注意:不解决以下几种“休眠”问题

休眠类型WakeLock 有效?说明
屏幕息屏✅ 有效PARTIAL_WAKE_LOCK 可以保持后台运行
Doze 模式✅ 有效(需前台进程)但某些厂商会强杀
App standby✅ 有效前提是你不通过应用层启动
深度挂起(suspend)⚠️ 设备依赖,不总有效某些设备强制 system suspend,WakeLock 无效(尤其是长时间息屏后)


🧠 补充:你应该避免的情况

错误做法后果
SCREEN_DIM_WAKE_LOCK 无界面时无效、被忽略
不获取 WakeLock系统一旦 Doze 或 CPU suspend,app_process 启动的进程会被冻结或终止
依赖 Java Thread.sleep 来保持会被系统挂起,不会真正运行


✅ 建议实践方案

如果你正在做的是:

  • 开发一个通过 ADB 启动的常驻服务(例如性能监控、远程指令、投屏、流媒体处理)

  • 不使用标准 Activity/Service 框架

那么最佳组合是:

功能技术方案
后台运行app_process + PARTIAL_WAKE_LOCK
防休眠使用 WakeLock.acquire() 持续持有
防杀进程推荐使用 nohupapp_process & + 守护进程机制
稳定性增强可搭配使用 ForegroundService(如用 shell 启 app 服务)


✅ 结论总结:

问题是否成立?备注
app_process 启动的进程休眠后会暂停?✅ 是的CPU suspend 后会冻结
WakeLock 能防止进程被冻结?✅ 有效使用 PARTIAL_WAKE_LOCK
所有设备都一定有效?⚠️ 不一定厂商可能有特殊电源策略
无界面程序也能拿到 WakeLock?✅ 可以只要有权限并运行在有能力用户下

 

相关文章:

视频编解码学习十二之Android疑点

一、android.view.SurfaceControl.setDisplaySurface的作用 android.view.SurfaceControl.setDisplaySurface 是 Android 系统中一个 native 层级别的 API&#xff0c;主要用于 设置某个物理显示屏&#xff08;Display&#xff09;的输出 Surface&#xff0c;属于 SurfaceFlin…...

web第三次课后作业--基于JDBC对mysql数据库的增删查改操作

一、工程搭建步骤 1.新建java项目&#xff0c;添加jdbc依赖 2.写java程序 3.添加mysql数据源&#xff0c;连接本地数据库 4.运行程序二、运行结果 三、代码 代码解析 加载数据驱动 try {Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundExceptio…...

fiftyone-数据库配置和config与app_config配置文件

一数据库配置&#xff1a;&#xff08;以本地为例&#xff09; fiftyone数据库信息存在配置文件中&#xff1a; 配置文件地址&#xff1a; ~/.fiftyone/config.json 这个配置文件的作用&#xff1a;存放数据库地址信息&#xff1b;&#xff08;如果不配置&#xff0c;fiftyon…...

Nginx的核心功能--正向代理、反向代理、缓存和Rewrite

Nginx作为高性能的Web服务器&#xff0c;其核心功能主要体现在以下四大模块&#xff1a; 一、正向代理 主要用于客户端访问外部网络的中转服务。典型配置示例&#xff1a; server {listen 8080;resolver 8.8.8.8;location / {proxy_pass http://$http_host$request_uri;prox…...

mac latex vscode 配置

mac latex vscode 配置 安装mactex.pkg 这里有个快速下载的镜像 https://mirrors.aliyun.com/CTAN/systems/mac/mactex/ 可以检查是否将 PATH 写入 export PATH"/Library/TeX/texbin:$PATH"vscode 下载插件 Latex Workshop 在配置文件 settings.json 中输入如下的…...

【GESP真题解析】第 4 集 GESP一级 2023 年 3 月编程题 1:每月天数

大家好&#xff0c;我是莫小特。 这篇文章给大家分享 GESP 一级 2023 年 3 月编程题第 1 题&#xff1a;每月天数。 题目链接 洛谷链接&#xff1a;B3835 每月天数 一、完成输入 根据题目要求&#xff0c;我们需要输入两个整数&#xff0c;分别表示一个日期的年份和月份。 年…...

国产免费工作流引擎star 6.5k,Warm-Flow升级1.7.2(新增案例和修复缺陷)

文章目录 主要更新内容项目介绍功能思维导图设计器流程图演示地址官网Warm-Flow视频 主要更新内容 [feat] 开启流程实例&#xff0c;新增流程定义是否存在校验[feat] 新增合同签订流程案例[feat] 新增企业采购流程案例[update] mybatis-plus逻辑删除&#xff0c;删除值和未删除…...

计算机网络:移动通信蜂窝网络指的是什么?

无线基站的蜂窝网络(Cellular Network)是现代移动通信系统的核心架构,其核心思想是通过蜂窝状小区划分和频率复用,实现广域覆盖、高效频谱利用和动态资源管理。以下从设计原理、网络架构、关键技术及实际挑战等方面深入解析蜂窝网络。 一、蜂窝网络的设计原理 1. 蜂窝结构…...

scratch基础-外观模块

一、本次任务 二、内容详解 1、模块介绍 1、说[你好] (2)秒&#xff1a;临时对话框&#xff0c;短暂对话 2、说[你好]&#xff1a;持续显示对话框&#xff0c;长文本显示 3、思考[嗯…] (2)秒&#xff1a;临时显示思考气泡&#xff0c;用于角色思考 4、思考[嗯…] &#xff1a…...

前端服务器部署分类总结

目前所了解的部署有三种方式&#xff1a; 一是本地服务器部署&#xff1b;二是 nginx 服务器部署&#xff1b;三是云服务器部署 本地部署&#xff0c;准备好部署的包 以Vue项目为例&#xff0c;执行npm run build 命令打成前端包 第二步&#xff1a;将打包结果交给服务器(本地…...

精益数据分析(58/126):移情阶段的深度实践与客户访谈方法论

精益数据分析&#xff08;58/126&#xff09;&#xff1a;移情阶段的深度实践与客户访谈方法论 在创业的漫长旅途中&#xff0c;正确识别和验证问题是成功的第一步。今天&#xff0c;我们继续围绕《精益数据分析》中创业阶段的核心内容&#xff0c;深入探讨移情阶段的关键实践…...

MK米客方德SD NAND:无人机存储的高效解决方案

在无人机技术迅猛发展的当下&#xff0c;飞控系统的数据记录对于飞行性能剖析、故障排查以及飞行安全保障极为关键。以往&#xff0c;SD 卡是飞控 LOG 记录常见的存储介质&#xff0c;但随着技术的革新&#xff0c;新的存储方案不断涌现。本文聚焦于以 ESP32 芯片为主控制器的无…...

LVDS系列12:Xilinx Ultrascale系可编程输入延迟(二)

本节讲解Ultrascale IDELAYE3的参数&#xff1b;  IDELAYE3参数&#xff1a; REFCLK_FREQUENCY&#xff1a;如果使用COUNT模式&#xff0c;保持300MHz的默认值即可&#xff1b; 如果使用TIME模式&#xff0c;则该值与IDELAYCTRL参考时钟要匹配&#xff1b; DELAY_SRC&#…...

Spring的bean的生命周期?

Spring中bean的生命周期包括以下步骤&#xff1a; 通过BeanDefinition获取bean的定义信息。 调用构造函数实例化bean。 进行bean的依赖注入&#xff0c;例如通过setter方法或Autowired注解。 处理实现了Aware接口的bean。 执行BeanPostProcessor的前置处理器。 调用初始化…...

OpenCV CUDA模块中逐元素操作------逻辑运算

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 比较、AND、OR、NOT等。这类操作可用于创建基于条件的掩码&#xff0c;这对于图像分割或特征选择非常有用。 主要函数 1. 按位与 (cv::cuda::b…...

微信开发者工具里面模拟操作返回、录屏、网络速度、截屏等操作

微信开发者工具里面模拟操作返回、录屏、网络速度、截屏等操作...

Void: Cursor 的开源平替

GitHub&#xff1a;https://github.com/voideditor/void 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI Void&#xff0c;这款编辑器号称是开源的 Cursor 和 GitHub Copilot 替代品&#xff0c;而且完全免费&#xff01; 在你的代码库…...

【MySQL】日志缓冲区详解 以及 InnoDB内存结构总结

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

在Spark搭建YARN

&#xff08;一&#xff09;什么是SparkONYarn模式 Spark on YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Spark 框架在 Hadoop 集群中运行的一种部署模式&#xff0c;它借助 Hadoop YARN 来管理资源和调度任务。 架构组成 ResourceManager&#xff1a;作…...

postman 用法 LTS

postman 用法 LTS File ---- View ---- Show Postman Console...

Spring Boot requestBody postman

Spring Boot requestBody postman 在处理Spring Boot应用程序中的RequestBody注解时&#xff0c;通常用于接收客户端&#xff08;如Postman&#xff09;发送的JSON格式数据。如果你在Postman中配置请求&#xff0c;并希望将JSON数据发送到Spring Boot后端&#xff0c;你可以按…...

OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——wget

准备工作 请依照这篇文章搭建环境 OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——环境配置_openharmony交叉编译-CSDN博客 编译依赖 Wget依赖Gnutls库&#xff0c;gnutls库依赖gmp、nettle、libunistring库 上述库可在历史文章中自行查找 下载 w…...

枢轴支压点策略

一种基于枢轴点&#xff08;Pivot Point&#xff09;的交易策略&#xff0c;主要用于在趋势行情中进行交易。 策略的核心思路是通过计算前一天的最高价、最低价和收盘价来确定当天的枢轴点&#xff0c;并据此计算出第一和第二阻力位以及第一和第二支撑位。 可以根据这些关键点位…...

【SSL部署与优化​】​​TLS 1.3的核心改进与性能优化​​

TLS 1.3 的核心改进与性能优化 TLS 1.3 是当前最安全的 TLS 协议版本&#xff0c;通过简化协议、增强加密算法和优化握手流程&#xff0c;显著提升了性能和安全性。以下是其核心改进、性能优化及关键技术的详细解析&#xff1a; 一、TLS 1.3 核心改进 精简加密套件 • 移除弱算…...

等经纬度投影下求经纬度的行列号

一 概述 使用等经纬度投影&#xff08;Equirectangular Projection&#xff09;&#xff0c; 将经纬度转换为行列号。 二 C实现 1 代码 以下是C的实现方法。该实现将地球的经纬度范围划分为固定分辨率的网格&#xff0c;每个网格对应一个行列号。 #include <cmath> #in…...

MetaHipMer2:从头组装宏基因组

Terabase-scale metagenome coassembly with MetaHipMer | Scientific Reports https://academic.oup.com/nar/advance-article/doi/10.1093/nar/gkaf369/8126258 安装 配置环境 berkeleylab / upcxx / wiki / INSTALL — Bitbucket mamba create -n mhm2_env -c conda-fo…...

CK-S654-PA60一拖四分体式半导体电子货架专用RFID读写器|读码器接线使用说明

半导体行业RFID电子货架通过物联网技术将传统仓储从“经验驱动”转向“数据驱动”&#xff0c;其自动化识别、实时追踪与智能决策能力&#xff0c;正重塑物流与库存管理的底层逻辑。从晶圆盒的精准定位到柔性化生产&#xff0c;这一技术不仅提升了效率&#xff0c;更让半导体行…...

C++类和对象练习:Date类实现日期的差,比较日期的大小,日期的前置后置++,--,输入输出Date类,对默认函数的练习。

引言 C类和对象练习&#xff1a;Date类实现日期的差&#xff0c;比较日期的大小&#xff0c;日期的前置后置&#xff0c;--&#xff0c;输入输出Date类&#xff0c;对默认函数的练习。 _涂色_-博客主页 C基础专栏 分三个文件来写&#xff1a; Date.cpp //类函数的实现 Date.h…...

C++学习之打车软件git版本控制

目录 01 3-git的简介 02 4-git的下载和提交代码 03 5-git添加一个新文件 04 5-删除一个文件 05 6-git的批量添加和提交文件 06 7-git重命名文件名 07 8-git解决代码冲突 08 9-git的分支的概念 09 10-创建项目代码仓库 10 1-git提交代码复习 01 3-git的简介 1 --------…...

QT之信号与槽

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 QT信号与槽机制详解基本概念信号(Signal)槽(Slot) 信号与槽的连接方式基本语法QT5新语法(推荐) 信号与槽的特点实际示例传统方式QT5新语法 连接类型注意事项高级用法信号连接信号使用lambda表达式自动…...

文章记单词 | 第73篇(六级)

一&#xff0c;单词释义 apart /əˈpɑːt/ adv. 分开地&#xff1b;相距assistant /əˈsɪstənt/ n. 助手&#xff1b;助理useless /ˈjuːsləs/ adj. 无用的&#xff1b;无效的ampere /ˈmpɛr/ n. 安培&#xff08;电流单位&#xff09;recite /rɪˈsaɪt/ v. 背诵&am…...

在Ubuntu24.04中配置开源直线特征提取软件DeepLSD

在Ubuntu24.04中配置开源直线特征提取软件DeepLSD 本文提供在Ubuntu24.04中配置开源直线特征提取软件DeepLSD的基础环境配置、列出需要修改的文件内容&#xff0c;以及报错解决方案集锦。 基础的编译安装环境 python3.8.12CUDA12gcc/g 9.5&#xff08;系统自带的g-13版本太新…...

什么是SparkONYarn模式?

&#xff08;一&#xff09;什么是SparkONYarn模式 Spark on YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Spark 框架在 Hadoop 集群中运行的一种部署模式&#xff0c;它借助 Hadoop YARN 来管理资源和调度任务。 架构组成 ResourceManager&#xff1a;作…...

STMCubeMX使用TB6612驱动编码轮并进行测速

硬件介绍 TB6612电机驱动模块功能与特性 电机方向控制 描述如何通过 TB6612 的 IN1 和 IN2 引脚控制电机的旋转方向。提供代码示例&#xff0c;展示如何通过 GPIO 控制电机的正反转。 速度控制与减速 解释如何通过调整 PWM 信号的占空比来控制电机的速度&#xff0c;并…...

数据安全与权限管控,如何实现双重保障?

数据安全和权限管控并非孤立存在&#xff0c;而是相互依存、相互促进的关系。强大的权限管控体系是数据安全的重要防线&#xff0c;能够从源头上限制潜在的风险&#xff1b;而完善的数据安全策略和技术手段&#xff0c;则为权限管控的有效实施提供了保障。只有构建起数据安全与…...

如何创建自动工作流程拆分Google Drive中的PDF文件

以下是完整的工作流程。在构建自动拆分工作流程之前&#xff0c;您可以尝试我们的免费在线 PDF 拆分器。 步骤 1&#xff1a;Make 自动拆分 PDF 的要求 要设置自动 PDF 拆分工作流程&#xff0c;您需要&#xff1a; 免费的Make.com帐户。可访问 Google Drive 并处理 PDF 文件…...

【SpringBoot实战指南】集成Easy ES

一、Easy ES 简介 Easy ES&#xff08;简称EE&#xff09;是一款基于 Elasticsearch 官方 RestHighLevelClient 封装的 ORM 框架&#xff0c;提供类似 MyBatis-Plus 的 API 设计&#xff0c;可以帮助开发者更简单地集成和使用 Elasticsearch&#xff0c;让操作 Elasticsearch …...

深入理解指针(1)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 深…...

vue.js中的渲染【条件渲染】

条件渲染 在 Vue 中&#xff0c;条件渲染用于根据表达式的值来决定是否在 DOM 中渲染某个元素。Vue 提供了几种方式来实现条件渲染&#xff1a; v-if 指令 用于根据条件是否为真来销毁或创建元素。 <p v-if"isVisible">显示这段内容</p>data() {retu…...

Qwen3如何强化推理能力?

大模型的推理能力一直是衡量其智能水平的关键指标。近期&#xff0c;Qwen3系列模型在这方面取得了显著突破。通过对Qwen3技术报告的解读&#xff0c;我们可以窥见一套完整的推理能力提升体系。本文将以结构化视角&#xff0c;剖析Qwen3推理能力提升的关键环节。 报告地址&#…...

2025年中国主流DevOps平台对比分析:Gitee、阿里云效与GitLab CE的技术适配与合规实践全景解读

在2025年中国企业数字化转型持续深化的背景下&#xff0c;DevOps 工具的选型呈现出多元化趋势。以下从安全合规、技术生态适配性、实践案例和选型建议四个维度&#xff0c;对 Gitee、阿里云效&#xff08;云效 DevOps&#xff09;和 GitLab CE&#xff08;中国版&#xff09;三…...

从lightrag的prompt到基于openai Structured Outputs 的优化实现思路

LightRAG 是一个用于构建 RAG 系统核心组件的配置和管理类。它集成了文档处理、存储、向量化、图谱构建和 LLM 交互等功能。你可以通过配置 LightRAG 实例的各种参数来定制 RAG 系统的行为。 目前lightrag中的实体关系抽取实现如下 PROMPTS["entity_extraction"] …...

论文阅读笔记——双流网络

双流网络论文 视频相比图像包含更多信息&#xff1a;运动信息、时序信息、背景信息等等。 原先处理视频的方法&#xff1a; CNN LSTM&#xff1a;CNN 抽取关键特征&#xff0c;LSTM 做时序逻辑&#xff1b;抽取视频中关键 K 帧输入 CNN 得到图片特征&#xff0c;再输入 LSTM&…...

Android清单文件

清单文件AndroidManifest.xml AndroidManifest.xml 配置清单文件是 每个 Android 应用的配置中心&#xff0c;系统在安装和运行应用时&#xff0c;首先会读取它。 它是 Android 应用的 “说明书”&#xff0c;主要作用是&#xff1a; 功能说明声明应用组件比如 Activity、Se…...

Single image dehazing论文阅读

Single image dehazing 1. 论文的研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、模型与公式2.1 改进的大气散射模型2.2 局部统计不相关性约束2.2.1 传输函数估计2.2.2 大气光颜色估计2.3 算法流程2.4 与传统方法的对比优势3. 实验设计与结果3.1 实验…...

数字信号处理-大实验1.3

MATLAB仿真实验目录 验证实验&#xff1a;常见离散信号产生和实现验证实验&#xff1a;离散系统的时域分析应用实验&#xff1a;语音信号的基音周期&#xff08;频率&#xff09;测定 说明&#xff1a;&#xff08;1&#xff09;本文是DSP大实验1的最后一篇&#xff0c;主要讲…...

【Pandas】pandas DataFrame describe

Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每个元素的绝对值DataFrame.all([axis, bool_only, skipna])用于判断 DataFrame 中是否所有元素在指定轴上都为 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判断…...

C++GO语言微服务之Dockerfile docker-compose②

目录 01 12-yaml文件书写规则01 12-yaml文件书写规则 02 13-yaml中的数据类型 03 14-docker-compose配置文件格式 04 15-docker-compose中的关键字 05 16-prots和volumes关键字的使用 06 17-volumes_from的使用 07 18-extends的使用 08 19-networks的使用 09 20-docker…...

【计算机视觉】OpenCV实战项目:Face-Mask-Detection 项目深度解析:基于深度学习的口罩检测系统

Face-Mask-Detection 项目深度解析&#xff1a;基于深度学习的口罩检测系统 一、项目概述项目特点 二、项目运行方式与执行步骤&#xff08;一&#xff09;环境准备&#xff08;二&#xff09;项目结构&#xff08;三&#xff09;执行步骤 三、重要逻辑代码解析&#xff08;一&…...

鸿蒙OSUniApp 实现的语音输入与语音识别功能#三方框架 #Uniapp

UniApp 实现的语音输入与语音识别功能 最近在开发跨平台应用时&#xff0c;客户要求添加语音输入功能以提升用户体验。经过一番调研和实践&#xff0c;我成功在UniApp项目中实现了语音输入与识别功能&#xff0c;现将过程和方法分享出来&#xff0c;希望对有类似需求的开发者有…...