Реализация AVVideoCompositing вызывает проблемы с вращением видео - PullRequest
1 голос
/ 11 апреля 2020

Я использую пример Apple https://developer.apple.com/library/ios/samplecode/AVCustomEdit/Introduction/Intro.html и имею некоторые проблемы с преобразованием видео. Если исходные ресурсы имеют preferredTransform, отличное от удостоверения, выходное видео будет иметь неправильно повернутые кадры. Эта проблема может быть исправлена, если AVMutableVideoComposition не имеет значения в свойстве customVideoCompositorClass и когда преобразование AVMutableVideoCompositionLayerInstruction установлено с помощью asset.preferredTransform. Но из-за использования собственного видеокомпозитора, использующего протокол AVVideoCompositing, я не могу использовать стандартные инструкции по компоновке видео. Как я могу предварительно преобразовать треки входных ресурсов до того, как CVPixelBuffer будет помещен в металлические шейдеры? Или есть какой-то другой способ исправить это?

Фрагмент исходного кода:

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
}

Но интересно, есть ли более эффективный способ памяти без создания новых пиксельных буферов

1 Ответ

1 голос
/ 11 апреля 2020

Как можно предварительно преобразовать дорожки входных ресурсов до того, как CVPixelBuffer будет помещен в металлические шейдеры?

Лучший способ добиться максимальной производительности - преобразовать видеокадр непосредственно в шейдер. Вам просто нужно добавить матрицу вращения в ваш вершинный шейдер.

...