2

iOS で ReplayKit2 を処理していますが、何らかの理由で CMSampleBuffer を縦向きから横向きに回転する必要があるため、結果が正しくないことがわかりました。

何が恋しいですか?

これはオリジナルのサンプルバッファーですここに画像の説明を入力

これは実際の出力バッファですここに画像の説明を入力

幅と高さは sampleBuffer の寸法です

func rotation(sampleBuffer: CMSampleBuffer, width: Int, height: Int) -> CMSampleBuffer {

        //create pixelbuffer from the delegate method samplebuffer
        let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!

        CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))

        //create CI image from the buffer
        let image = CIImage(cvImageBuffer: pixelBuffer)

        let extent = CGRect(x: 0, y: 0, width: width, height: height)

        var tx = CGAffineTransform(translationX: extent.midX, y: extent.midY)

        tx = tx.rotated(by: CGFloat(Double.pi / 2))

        tx = tx.translatedBy(x: -extent.midX, y: -extent.midY)

        var transformImage = CIFilter(
            name: "CIAffineTransform",
            withInputParameters: [
                kCIInputImageKey: image,
                kCIInputTransformKey: NSValue.init(cgAffineTransform: tx)])!.outputImage!

        //create empty pixelbuffer
        var newPixelBuffer : CVPixelBuffer? = nil

        CVPixelBufferCreate(kCFAllocatorDefault,
                            width,
                            height,
                            kCVPixelFormatType_32BGRA,
                            nil,
                            &newPixelBuffer)
        //render the context to the new pixelbuffer, context is a global
        //CIContext variable. creating a new one each frame is too CPU intensive
        self.ciContext.render(transformImage, to: newPixelBuffer!)

        //finally, write this to the pixelbufferadaptor

        CVPixelBufferUnlockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue: 0))

        var videoInfo: CMVideoFormatDescription?

        CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, newPixelBuffer!, &videoInfo)

        var sampleTimingInfo = CMSampleTimingInfo(duration: CMSampleBufferGetDuration(sampleBuffer), presentationTimeStamp: CMSampleBufferGetPresentationTimeStamp(sampleBuffer), decodeTimeStamp: CMSampleBufferGetDecodeTimeStamp(sampleBuffer))

        var newSampleBuffer: CMSampleBuffer?

        CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, newPixelBuffer!, true, nil, nil, videoInfo!, &sampleTimingInfo, &newSampleBuffer)

        return newSampleBuffer!

    }
4

2 に答える 2

2

iOS 11 で非常に便利な方法を見つけました!

/* Returns a new image representing the original image transformeded for the given CGImagePropertyOrientation */
    @available(iOS 11.0, *)
    open func oriented(_ orientation: CGImagePropertyOrientation) -> CIImage
于 2017-10-30T11:49:00.050 に答える
2

役に立つかも

func rotate(_ sampleBuffer: CMSampleBuffer) -> CVPixelBuffer? {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return nil
        }
        var newPixelBuffer: CVPixelBuffer?
        let error = CVPixelBufferCreate(kCFAllocatorDefault,
                                        CVPixelBufferGetHeight(pixelBuffer),
                                        CVPixelBufferGetWidth(pixelBuffer),
                                        kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
                                        nil,
                                        &newPixelBuffer)
        guard error == kCVReturnSuccess else {
            return nil
        }
        let ciImage = CIImage(cvPixelBuffer: pixelBuffer).oriented(.right)
        let context = CIContext(options: nil)
        context.render(ciImage, to: newPixelBuffer!)
        return newPixelBuffer
    }
于 2020-11-12T17:27:28.770 に答える