【问题标题】:Implementing AVVideoCompositing causes video rotation problems实现 AVVideoCompositing 会导致视频旋转问题
【发布时间】:2020-07-23 17:07:18
【问题描述】:

我使用 Apple 的示例 https://developer.apple.com/library/ios/samplecode/AVCustomEdit/Introduction/Intro.html 并且在视频转换方面遇到了一些问题。 如果源资产具有preferredTransform 而非身份,则输出视频将具有错误旋转的帧。如果AVMutableVideoComposition 在属性customVideoCompositorClass 中没有值并且AVMutableVideoCompositionLayerInstruction 的转换设置为asset.preferredTransform,则可以修复此问题。但由于使用采用AVVideoCompositing 协议的自定义视频合成器,我不能使用标准视频合成指令。 如何在将 CVPixelBuffer 放入 Metal 着色器之前预先转换输入资产轨道?或者有其他方法可以解决吗?

原代码片段:

func buildCompositionObjectsForPlayback(_ forPlayback: Bool, overwriteExistingObjects: Bool) {

    // Proceed only if the composition objects have not already been created.
    if self.composition != nil && !overwriteExistingObjects { return }
    if self.videoComposition != nil && !overwriteExistingObjects { return }

    guard !clips.isEmpty else { return }

    // Use the naturalSize of the first video track.
    let videoTracks = clips[0].tracks(withMediaType: AVMediaType.video)
    let videoSize = videoTracks[0].naturalSize

    let composition = AVMutableComposition()

    composition.naturalSize = videoSize

    /*
     With transitions:
     Place clips into alternating video & audio tracks in composition, overlapped by transitionDuration.
     Set up the video composition to cycle between "pass through A", "transition from A to B", "pass through B".
    */
    let videoComposition = AVMutableVideoComposition()

    if self.transitionType == TransitionType.diagonalWipe.rawValue {
        videoComposition.customVideoCompositorClass = APLDiagonalWipeCompositor.self
    } else {
        videoComposition.customVideoCompositorClass = APLCrossDissolveCompositor.self
    }

    // Every videoComposition needs these properties to be set:
    videoComposition.frameDuration = CMTimeMake(1, 30) // 30 fps.
    videoComposition.renderSize = videoSize

    buildTransitionComposition(composition, andVideoComposition: videoComposition)

    self.composition = composition
    self.videoComposition = videoComposition
}

更新: 我为这样的转换做了解决方法:

private func makeTransformedPixelBuffer(fromBuffer buffer: CVPixelBuffer, withTransform transform: CGAffineTransform) -> CVPixelBuffer? {
    guard let newBuffer = renderContext?.newPixelBuffer() else {
        return nil
    }

    // Correct transformation example I took from https://stackoverflow.com/questions/29967700/coreimage-coordinate-system
    var preferredTransform = transform
    preferredTransform.b *= -1
    preferredTransform.c *= -1

    var transformedImage = CIImage(cvPixelBuffer: buffer).transformed(by: preferredTransform)
    preferredTransform = CGAffineTransform(translationX: -transformedImage.extent.origin.x, y: -transformedImage.extent.origin.y)
    transformedImage = transformedImage.transformed(by: preferredTransform)

    let filterContext = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
    filterContext.render(transformedImage, to: newBuffer)

    return newBuffer
}

但是想知道是否有更多节省内存的方法而无需创建新的像素缓冲区

【问题讨论】:

  • “导致视频旋转问题”是什么意思?
  • 我的意思是,如果使用 AVMutableVideoComposition,AVMutableCompositionTrack 的 preferredTransform 属性将不起作用。我不能使用 AVMutableVideoCompositionLayerInstruction.setTransform(_ transform: CGAffineTransform, at time: CMTime) 因为使用自己的类,采用 AVVideoCompositing
  • 你使用什么类型的着色器?
  • 使用金属着色器
  • 顶点/片段还是计算?

标签: swift avfoundation metal core-image core-video


【解决方案1】:

如何在输入资产轨道成为 CVPixelBuffer 之前对其进行预转换 放入金属着色器?

实现最佳性能的最佳方法是直接在着色器中转换视频帧。您只需要在顶点着色器中添加旋转矩阵。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多