Repository navigation
Conversation
Plugins can now expose their own camera sources to the built-in video presenter (booth) without registering a system-level DirectShow device. - SDK: IPluginCameraProvider / IPluginCameraFrameSink / PluginCameraDescriptor, service IProviderCameraService; CurrentApiVersion 1.13.0 -> 1.14.0 - Host: CameraProviderRegistry, provider cameras merged into the booth camera list, non-DirectShow render path (WPF Image sharing the VideoCaptureElement LayoutTransform/RenderTransform instances), capture via latest frame reusing the existing insert-to-canvas pipeline, lifecycle cleanup on plugin unload - Docs: docs/camera-provider.md, plugin_sdk rules, SDK README Verified: host builds (x64 Release, 0 errors); 27 host-integration assertions pass; GUI smoke test renders provider frames in the video presenter and captures a photo. Existing DirectShow cameras and plugins are unaffected.
Member
|
请确认无误后可合并 |
Collaborator
|
谁确认喵喵,要我跟进嘛 @CJKmkp |
Member
|
你来吧 |
Collaborator
|
玩下周跟进 你们都别动 |
- 展台特殊模式 + 漫游时跳过“多指书写”手势拦截,让 WPF/WinRT 双指捏合 进入 VideoPresenterSpecialMode_ManipulationDelta / ApplyWinRTVideoPresenterGesture, 而不是被漫游/墨迹手势吃掉,表现为“墨迹能缩放、摄像头画面只平移” - WinRT 路径把展台特殊模式分支提到漫游分支之前 - 非多指书写时信任 WPF 报的 manipulator 数;有缩放增量时也允许缩放, 避免触点记账偏少把捏合误判成单指
漫游双指手势走的是 TransformBoardRoamingContent:它对板书墨迹/图片应用完整 矩阵,但对视频展台预览只同步 translationDelta(旧假设“展台不支持缩放”), 所以漫游里墨迹能缩放、实时画面和相册照片不动。 - 双指手势把 previousMidpoint 作为锚点传给 TransformBoardRoamingContent - 展台预览按同样的 scale 等比缩放,并保持“缩放锚点 + 平移”的变换一致 - ApplyBoothPreviewTransform 同时更新实时画面与冻结照片的 Scale,相册页同样生效 - 不再依赖 Board 的双指缩放开关:漫游使用自己的 IsEnableTwoFingerZoomRoaming - 回退上一版试探性的“漫游时跳过多指书写拦截”改动,避免抢漫游手势
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
本 PR 完全使用 Vibe Coding 编写。功能已测试过,可以正常使用(如下图)。PR 目的是便于插件注册视频展台摄像头源。
同时本 pr 也尝试解决了漫游无法缩放视频展台画面的问题,等待在校实际测试。
以下为 aigc,已人工删减。
动机(真实用例)
宿主「视频展台」的摄像头下拉框只有一条数据来源:DirectShow
FilterCategory.VideoInputDevice枚举(MW_VideoPresenter.cs+DirectShowCameraService.cs)。插件无法向这个列表注入任何非 DirectShow 来源。
我们的真实设备是驿欧无线视频展台:它只输出 WiFi RTSP 流(
rtsp://<设备IP>:554/stream0),本身不是 USB/DirectShow 摄像头。目前唯一能让它出现在宿主下拉框里的办法是在系统里注册一个
虚拟 DirectShow 摄像头(原生 C++ COM 滤波器 + HKCU 注册表 + VMR9 renderless 分配器协商)。
这条路径的代价:
DevicePath冲突/串台风险;更正规的做法是宿主直接提供 plugin camera provider 能力:插件把自己采集的帧交给宿主,
由宿主负责预览、拍照与分辨率。本 PR 实现该能力,且不改变现有 DirectShow 路径的行为。
改动摘要
展开
1. SDK(
InkCanvas.PluginSdk/)ICameraProviderService+ 相关类型(ICameraProviderService.cs,233 行):ICameraProviderService:RegisterProvider/UnregisterProvider/NotifyCamerasChanged;IPluginCameraProvider(插件实现):ProviderId、GetCameras()、StartCamera(cameraId, sink)、StopCamera(cameraId)、SetCameraFormat(w,h,fps);IPluginCameraFrameSink(宿主实现):IsActive、Submit(byte[] bgr24, w, h, stride, ts);PluginCameraDescriptor(Id / DisplayName / Capabilities / SupportsPropertyControl)、PluginCameraCapability(W/H/FPS)。HostApiRequirement.CurrentApiVersion1.13.0 → 1.14.0(按文件注释的维护规则:新增对外接口必须抬次版本号)。README.md增加 camera provider 章节;rules/plugin_sdk.md更新服务表 + 新增使用章节。2. 宿主(
Ink Canvas/)Helpers/CameraProviderRegistry.cs(新增 556 行)IPluginCameraFrameSink实现。双缓冲“最近一帧”(避免逐帧分配大数组)、活动推流生命周期、CamerasChanged/FrameSubmitted事件、RenderLatestFrame/GetLatestFrameBitmapSourcePlugins/Services/CameraProviderService.cs(新增 59 行)App.xaml.csICameraProviderServiceHelpers/ICameraService.csCameraInfo增加IsProviderCamera/ProviderId/ProviderCameraIdHelpers/DirectShowCameraService.cs(+329)RefreshCameraListAsync把 provider 摄像头合并进AvailableCameras;②EnumerateResolutionsAsync用插件声明的能力填充NativeResolutions/AllResolutionFpsCombos(在调用线程内联填充,避免与 UI 遍历竞争);③StartPreviewAsync为 provider 摄像头走推流分支(转发FrameReceived、GetCurrentFrameAsBitmap*);④ProbeCameraPropertiesAsync对 provider 摄像头短路(属性滑块置灰)MainWindow.xamlVideoPresenterSpecialModeContainer内新增VideoPresenterProviderImage(WPFImage)MainWindow_cs/MW_VideoPresenter.cs(+493)WriteableBitmap→ Image;与VideoCaptureElement共享 LayoutTransform/RenderTransform 实例(缩放/旋转/镜像/批注一致);拍照取最近帧后走现有旋转/镜像/矫正/插画布管线;生命周期(切换摄像头/分辨率、照片页、退出展台、卸载插件);CamerasChanged时刷新下拉框Plugins/PluginManager.csProviderId兜底清理 providerdocs/camera-provider.md(新增 257 行)3. 关键实现点
ICameraService.AvailableCameras,所有现有列表/索引/持久化/预选逻辑(
videoPresenterLastCameraName等)零改动即可工作。VideoPresenterProviderImage的LayoutTransform/RenderTransform在代码里指向
VideoCaptureElement的同一批实例,因此镜像(VideoPresenterFullCanvasMirror)、旋转(
VideoPresenterFullCanvasRotation)、缩放/平移(ApplyBoothPreviewTransform)、墨迹批注、照片页变换全部自动一致,无需复制逻辑。
CameraProviderRegistry.GetLatestFrameBitmapSource(),之后完全复用现有 path 2(旋转/镜像/纸框矫正/插照片栏)。
Submit;宿主在锁内拷贝到双缓冲,UI 线程合并渲染通知并用WriteableBitmap.WritePixels更新,插件缓冲区可立即复用。DirectShowCameraService的所有 DirectShow 分支保留原逻辑,只在入口处根据
CameraInfo.IsProviderCamera分流;PluginManager的清理对不注册 provider 的插件是空操作。