首页 > 解决方案 > 如何在 iOS 中轻松渲染视频帧,如 AVSampleBufferDisplayLayer

问题描述

我正在尝试制作一个流式传输 RTP h264 视频的自定义视频渲染。

我第一次尝试使用 AVSampleBufferDisplayLayer,结果非常好。非常易于使用,因为我只需要将流式 h264 视频转换为 CMSampleBuffer 并将数据排队到 DisplayLayer。DisplayLayer 为我做了一切,例如适当的播放速度、调整大小等。但是,最大的问题是我需要对视频进行一些合成和裁剪,而 AVSampleBufferDisplayLayer 不支持任何这些操作。

所以我尝试使用 Video Toolbox 将帧解码为原始缓冲区,以便我可以使用 Apple 提供的 CoreImage 或 Accelerate 框架轻松编辑它们。我可以获得解码帧(CVPixelBuffer/CVImageBuffer),但正确显示它们对我来说真的很困难。

func someFunctionOnView() {
  var outputCallback = VTDecompressionOutputCallbackRecord()
  outputCallback.decompressionOutputCallback = decompressionSessionDecodeFrameCallback
  outputCallback.decompressionOutputRefCon = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
                
  let status = VTDecompressionSessionCreate(allocator: kCFAllocatorDefault,
                                            formatDescription: desc,    
                                            decoderSpecification: decoderParameters,
                                            imageBufferAttributes: destinationPixelBufferAttributes,outputCallback: &outputCallback,
                                             decompressionSessionOut: &videoSessionM)
}

private func decompressionSessionDecodeFrameCallback(
  _ decompressionOutputRefCon: UnsafeMutableRawPointer?, 
  _ sourceFrameRefCon: UnsafeMutableRawPointer?, _ status: OSStatus, 
  _ infoFlags: VTDecodeInfoFlags, 
  _ imageBuffer: CVImageBuffer?, _ presentationTimeStamp: CMTime, 
  _ presentationDuration: CMTime) -> Void {
    
    let streamManager: ViewController = unsafeBitCast(decompressionOutputRefCon, to: ViewController.self)
    if status == noErr {
     
        if let img = imageBuffer {
            let pixelBuffer: CVPixelBuffer = img
      
            // Do some operations such as cropping or compositing etc.
            let output = resizePixelBuffer(pixelBuffer, cropX: 0, cropY: 0, 
              cropWidth: 300, cropHeight: 200, scaleWidth: 100, scaleHeight: 100)
       
            // NEED HELP
            // Render the frames in a timely manner onto a view or layer
        }
        
    }
}

我可以就某些问题获得一些帮助或建议吗?

  1. 如何及时展示相框的资料和帮助?目前,帧播放速度过快或过慢。是否有开源程序或书籍可以让我了解视频渲染器的工作原理?
  2. Swift 上是否有任何众所周知的库已经提供了我想要的功能?或者 Apple 是否提供任何能够正确显示 CVPixelBuffer/CVImageBuffer 的框架。
  3. 对视频进行操作的更简单方法。苹果提供的 AVFoundation 似乎没有任何处理 h264 流的功能。有什么我想念的吗?
  4. 如何将 CMTime 转换为 CFTimeInterval 或其他时间,以便我可以使用 MTLCommandBuffer present(_:atTime:)预设图像

标签: iosswiftvideovideo-processingrenderer

解决方案


推荐阅读