2016-09-25 24 views
3

一般的に行われているように、あなたが(PNGファイルの長いシーケンスを必要とせずに長いアニメーションのためのムービーファイルを使用できるように、私はMPEG映画の背景を透明にすることのためにクロマキーフィルタを書かれていますいくつかのタイプのiOSアニメーション用)。iOSの10休憩カスタムCIFilter

私は、AVPlayer,AVVideoComposition、およびカスタムCIFilterを使用して、ビデオを背景イメージにレンダリングしています。背景画像は、ユーザーがアプリと対話することによって動的に変更することができます。

これは、iOS 10が出てから壊れてしまうまでうまくいきました。

今何が起こるすると、そのビデオの再生ですが、何のクロマキーが発生していないとXcodeが繰り返し次のエラーを吐く:

need a swizzler so that YCC420v can be written. 

はここCIFilterが生成すべきかの画像です:

result with custom CIFilter working (pre iOS 10)

、代わりにこれは(iOSの10以降)を生成するものである:

result with broken CIFilter (post iOS 10)

はここEAGLContextを作成し、カスタムCIFilterを適用する私のコードのセクションです:

private class ChromaKeyFilter : CIFilter { 
private var kernel: CIColorKernel! 
var inputImage: CIImage? 
var activeColor = CIColor(red: 0.0, green: 1.0, blue: 0.0) 
var threshold: Float = 0.05 

override init() { 
    super.init() 
    kernel = createKernel() 
} 

required init(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder)! 
    kernel = createKernel() 
} 

override var outputImage: CIImage? { 
    if let inputImage = inputImage { 
     let dod = inputImage.extent 
     let args = [inputImage as AnyObject, activeColor as AnyObject, threshold as AnyObject] 
     return kernel.applyWithExtent(dod, arguments: args) 
    } 
    return nil 
} 

private func createKernel() -> CIColorKernel { 
    let kernelString = 
     "kernel vec4 chromaKey(__sample s, __color c, float threshold) { \n" + 
      //below kernel was adapted from the GPUImage custom chromakeyfilter: 
      //https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageChromaKeyFilter.m#L30 
      " float maskY = 0.2989 * c.r + 0.5866 * c.g + 0.1145 * c.b;\n" + 
      " float maskCr = 0.7132 * (c.r - maskY);\n" + 
      " float maskCb = 0.5647 * (c.b - maskY);\n" + 
      " float Y = 0.2989 * s.rgb.r + 0.5866 * s.rgb.g + 0.1145 * s.rgb.b;\n" + 
      " float Cr = 0.7132 * (s.rgb.r - Y);\n" + 
      " float Cb = 0.5647 * (s.rgba.b - Y);\n" + 
      " float blendValue = smoothstep(threshold, threshold + 0.5, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));\n" + 
      " return blendValue * vec4(s.rgb, 1.0); \n" + 
    "}" 
    let kernel = CIColorKernel(string: kernelString) 
    return kernel! 
} 

}

誰:

let myEAGLContext = EAGLContext.init(API: EAGLRenderingAPI.OpenGLES2) 
    //let cicontext = CIContext.init(EAGLContext: myEAGLContext, options: [kCIContextWorkingColorSpace: NSNull()]) 
    let cicontext = CIContext.init(EAGLContext: myEAGLContext) 

    let filter = ChromaKeyFilter() 
    filter.activeColor = CIColor.init(red: 0, green:1.0, blue: 0.0) 
    filter.threshold = self.threshold 

    //most of below comes from the "WWDC15 What's New In Core Image" slides 
    let vidComp = AVVideoComposition(asset: videoAsset!, 
            applyingCIFiltersWithHandler: 
     { 
      request in 
      let input = request.sourceImage.imageByClampingToExtent() 

      filter.inputImage = input 

      let output = filter.outputImage!.imageByClampingToExtent() 
      request.finishWithImage(output, context: cicontext) 
      self.reloadInputViews() 

    }) 

    let playerItem = AVPlayerItem(asset: videoAsset!) 
    playerItem.videoComposition = vidComp 
    self.player = AVPlayer(playerItem: playerItem) 
    self.playerInitialized = true 
    let layer = AVPlayerLayer(player: player) 

    self.subviews.forEach { subview in 
     subview.removeFromSuperview() 
    } 

    layer.frame = CGRect(x: 0.0, y: 0.0, width: self.frame.size.width, height: self.frame.size.height) 
    self.layer.addSublayer(layer) 

そしてここでは、カスタムCIFilterのコードですなぜこれだけが壊れているのか、いくつかのアイデアがありますか?興味深いことに、電話でのみ壊れています。 iOS 10が出てからずっと遅くても、シミュレータではまだ動作します。

+0

可能なパラレル:http://stackoverflow.com/questions/33097976/whats-the-needあなたBGRAへAVPlayerLayerpixelBufferAttributesはアルファの欠如を修正し、記録されたエラーを消音設定

-a-swizzler-so-that-rgb8-can-be-that-c​​ore-image-give – matt

答えて

3

iOS10(デバイス)パイプラインの一部(プレーヤーの層?)がYUVに切り替わったようです。ここ

layer.pixelBufferAttributes = [kCVPixelBufferPixelFormatTypeKey as String: NSNumber(value: kCVPixelFormatType_32BGRA)] 
+0

ありがとう!それは私のためのわずかな変更で動作します: layer.pixelBufferAttributes = [kCVPixelBufferPixelFormatTypeKey as String:NSNumber(unsignedInt:kCVPixelFormatType_32BGRA)] –

+0

あなたは何をしなければなりませんでしたか? –

+0

おっと、私の悪い - 私はあなたがスイフトを使用していると思っていました3 –