跳到主要內容
Flow

模組

模組模型、Module API,以及各模組的實作。總覽見 architecture.md。

模組模型

所有實作(解碼器、runtime、輸出)皆為第一方模組:原始碼位於 Modules/,靜態連結進 App,由 composition root 組裝。不支援外部模組(無 bundle、manifest、下載或安裝)。

// Packages/Composition/Sources/FlowComposition/Modules.swift:唯一知道用了哪些實作的地方
import FlowAVAudio
import FlowFFmpeg
import FlowFile
import FlowMetal4
public import FlowModuleHost
import FlowVideoToolbox

@_spi(Benchmark) public enum FlowModules {
    public static let essential: [ModuleEntry] = [
        .essential(FileModule.self),
        .essential(FFmpegModule.self),       // 替換:改這行與對應 import(另加一行 package 依賴)
        .essential(VideoToolboxModule.self),
        .essential(AVAudioModule.self),
        .essential(Metal4Module.self),
    ]
}
  • FlowPlayer:FlowComposition 以 FlowPlayer 組裝 ComponentRegistry、PlayerController、ModuleHost、PlayerSession,四者皆不對外公開。App 只用 init()(啟用 FlowModules.essential)、api(PlayerAPI)、makeVideoView()、attach(_:)(進行中開始的 load 會等它完成)、shutdown(),公開 API 不含 Kernel 型別;指定模組與 EngineConfiguration 的 init 及 FlowModules 只以 @_spi(Benchmark) 開放;影片 view 由 PresenterFactory.makeSurface() 提供,App 與 composition root 都不需知道 presenter 型別。Benchmarks 經同一個 FlowPlayer 組裝,量到的就是發行的。
  • 替換:同一介面的實作可互換,改模組名稱與 import 即可;依賴某 runtime 的模組需隨該 runtime 一起替換。
  • 偏好順序:清單順序即同級實作的偏好順序(見解碼策略)。
  • 必要性:.essential 不可停用,啟用失敗時 FlowPlayer 初始化失敗;.optional 啟用失敗只記 log,ModuleHost.setEnabled 可停用與重新啟用。FlowPlayer 不開放 ModuleHost,App 無法停用模組;出貨的模組皆為 .essential。
  • in-process:模組不使用 ExtensionKit/XPC;完整 SwiftUI、直接呼叫框架 API、熱路徑零開銷。
  • Library validation:主程式不載入外部程式碼,Hardened Runtime 下無需 disable-library-validation。

不提供 Script(JavaScript):帶來額外 runtime 與維護負擔。

Module API

定義於 FlowModuleAPI;模組另可依賴 FlowMedia(媒體值型別)與 FlowDiagnostics(Logger、signpost、計數器)。

public protocol FlowModule: AnyObject, SendableMetatype {
    /// 穩定識別碼;預設為完整型別名稱
    static var id: String { get }
    init()
    /// 只在這裡註冊;停用時由 FlowModuleHost 撤銷所有註冊
    @MainActor func activate(_ context: any ModuleContext) throws
    @MainActor func deactivate()
}

@MainActor
public protocol ModuleContext {
    var media: any MediaRegistry { get }        // MediaSourceFactory、DemuxerFactory
    var decoders: any DecoderRegistry { get }   // VideoDecoderFactory、AudioDecoderFactory
    var outputs: any OutputRegistry { get }     // AudioOutputFactory、PresenterFactory
    var runtimes: any RuntimeRegistry { get }   // DisplayRuntime 等 NodeRuntime
    var player: any PlayerAPI { get }           // Command/Property/Event(見 player-api.md)
}
  • 能力可任意組合:一個模組可同時註冊多種實作並呼叫 API(如 FlowMetal4 註冊 runtime 與 presenter)。
  • 版本:與 App 一起建置,FlowModuleAPI 不需維持 ABI 穩定,可隨需求重構。
  • 停用:撤銷所有註冊即生效;播放中的媒體沿用已建立的元件,下次載入時 FlowEngine 改選其他實作。重新啟用後恢復原本的偏好順序。

模組一覽

模組註冊說明
FlowFileFileSourceFactory(file)本機檔案 MediaSource
FlowFFmpegFFmpegDemuxerFactory、FFmpegAudioDecoderFactory見 FFmpeg
FlowVideoToolboxVTVideoDecoderFactory(.hardware)硬解(格式見 codecs.md),IOSurface-backed 輸出,FrameReorder 依 PTS 重排;啟用時背景預熱
FlowAVAudioAVAudioOutputFactory見 audio.md
FlowMetal4Metal4DisplayRuntime、MetalLayerPresenterFactory見 Metal 4

FFmpeg

  • FFmpegDemuxerFactory:自訂 AVIO 經 MediaSource 讀取,packet 零拷貝;開檔不呼叫 avformat_find_stream_info。edit list 與 AV_PKT_DATA_SKIP_SAMPLES 對應到 Packet.isDiscardable、Packet.trim。格式見 codecs.md。
  • 色度格式(見核心協定):H.264/HEVC 取自 avcC 的 SPS 與 hvcC 的 chroma_format_idc;libavformat 有 pixel format 時改用其描述:RGB、調色盤、Bayer、XYZ、硬體格式為 nil,扣除 alpha 只剩一個分量為單色,其餘依 log2_chroma_w/log2_chroma_h。
  • FFmpegAudioDecoderFactory:libavcodec 解碼,libswresample 重取樣到輸出格式;只讀 Packet 的契約欄位,任何 demuxer 的 packet 都照樣修剪。格式見 codecs.md。
  • package 依賴只有 FFmpeg 的 XCFramework 與契約(FlowModuleAPI、FlowMedia、FlowDiagnostics);C 型別不越過模組邊界。
  • 新增其他解碼器=新增模組實作 VideoDecoderFactory 或 AudioDecoderFactory,選擇與 fallback 由 FlowEngine 處理。

Metal 4

  • Runtime:Metal4DisplayRuntime 實作 DisplayRuntime,接受本模組的 presenter(見 DisplayRuntime)。
  • Presenter:MetalLayerPresenter(MetalVideoView 由 makeSurface() 提供);OffscreenPresenter 以 @_spi(Benchmark) 開放,僅供 Benchmarks 自行註冊(見 benchmark.md)。
  • Shader ABI:Shaders/Include/Flow/(FlowShader.h:紋理/buffer 索引、function constant 與 DisplayUniforms;Color.h:轉換函式),供內建 shader 使用,建置期由 MetalLibraryPlugin 把 FlowMetal4 自身的 Shaders/ 編譯為 metallib。破壞性變更遞增 FLOW_SHADER_ABI_MAJOR。