You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解码ProresRAW为原生拜耳表示时出现AVFoundation -11821错误如何解决?

ProRes RAW解码失败原因与解决方案

你遇到的错误码-11821(无法解码)底层对应-12137,本质是AVAssetReader的输出配置不符合ProRes RAW的解码要求。

常见失败原因

  • 输出配置错误:你当前使用的outputSettings没有指定输出原生拜耳CFA数据,AVFoundation会默认尝试将ProRes RAW解码为渲染后的彩色帧,而ProRes RAW解码器不支持通过普通AVAssetReader路径输出渲染后帧,直接触发解码错误。
  • 资源未完成加载:直接同步调用movieAsset.tracks时可能AVAsset还未完成元数据加载,读取到的轨道信息不完整,导致解码链路初始化失败。
  • 运行环境不支持:ProRes RAW原生拜耳输出仅支持macOS 10.15及以上版本,且需要设备带有ProRes硬件解码能力(M系列芯片Mac、带硬件解码模块的Intel Mac),iOS/iPadOS暂不支持原生拜耳数据输出。

代码调整方案

首先修改outputSettings配置,仅指定输出拜耳像素格式,不要加其他转换类参数:

// 请根据你的ProRes RAW实际拜耳排列选择对应格式,可选值包括kCVPixelFormatType_14Bayer_RGGB、kCVPixelFormatType_14Bayer_BGGR等
let outputSettings = [
    kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_14Bayer_RGGB
] as [String : Any]

然后调整AVAsset初始化逻辑,等待资源加载完成再初始化读取器:

class Decoder {
    private let assetReader: AVAssetReader?
    private let output: AVAssetReaderTrackOutput

    init(fileURL: URL) async throws {
        VTRegisterProfessionalVideoWorkflowVideoDecoders()
        
        // 配置asset,开启精确时序,等待轨道加载完成
        let movieAsset = AVURLAsset(url: fileURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
        let tracks = try await movieAsset.load(.tracks).filter { $0.mediaType == .video }
        
        guard let firstTrack = tracks.first else {
            print("No video tracks found")
            throw NSError(domain: "DecoderError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无可用视频轨道"])
        }
        
        let out = AVAssetReaderTrackOutput(track: firstTrack, outputSettings: outputSettings)
        out.alwaysCopiesSampleData = false // 无需额外拷贝,降低内存开销
        
        let assetReader = try AVAssetReader(asset: movieAsset)
        guard assetReader.canAdd(out) else {
            throw NSError(domain: "DecoderError", code: -2, userInfo: [NSLocalizedDescriptionKey: "不支持的输出配置"])
        }
        assetReader.add(out)
        
        self.assetReader = assetReader
        self.output = out
    }

    func run(){
        guard let assetReader = assetReader, assetReader.startReading() else {
            print("Failed to start asset reader: \(assetReader?.error ?? NSError())")
            return
        }

        while assetReader.status == .reading {
            guard let sampleBuffer = output.copyNextSampleBuffer() else {
                if let error = assetReader.error {
                    print("Decode error: \(error)")
                }
                break
            }
            print("Decoding success!")
            // 此处处理拿到的原生拜耳SampleBuffer即可
            CMSampleBufferInvalidate(sampleBuffer)
        }
        
        if assetReader.status == .completed {
            print("全部帧解码完成")
        }
    }
}

额外说明

解码得到的SampleBuffer中附带了ProRes RAW的所有元数据(黑电平、白电平、色彩矩阵、拜耳排列等),可以通过CMGetAttachment接口从SampleBuffer中读取,无需硬编码参数。

内容的提问来源于stack exchange,提问作者JaSHin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:45:07