CoreImage и Metal Interusage

Я получаю данные в формате jpeg через одноранговое устройство iOS. Обрабатываю и отображаю с помощью CoreImage и Metal + MTKView следующим образом. Я получаю данные в формате jpeg и конвертирую их в CIImage. Затем я применяю соответствующее преобразование к CIImage и визуализирую его в CVPixelBuffer. Затем я отображаю этот CVPixelBuffer в MTKView через сквозные шейдеры (обработка металлов и MTKView не используют ciContext, который используется частью кода CIImage). Затем я конвертирую буфер пикселей в YUV, выполняю некоторую обработку изображений и также отображаю эти данные в MTKView. Проблема в том, что иногда он становится слишком медленным и медленным. Есть ли в приведенном ниже коде узкие места, вызванные использованием CoreImage и Metal? Как сделать этот конвейер лучше?

   private func handleImageData(_ data:Data) {

    DispatchQueue.main.async {
        if let image = CIImage(data: data) {
            self.displayImage(image)
        }
     }

    }


   private func displayImage(_ image:CIImage) {
       let transformFilter = CIFilter(name: "CIAffineTransform")!
       transformFilter.setValue(image, forKey: "inputImage")
       transformFilter.setValue(NSValue(cgAffineTransform: self.framesTransform), forKey: "inputTransform")
       let sourceImage = transformFilter.value(forKey: "outputImage") as! CIImage

     //Render CIImage to pixel buffer


     var pixelBuffer:CVPixelBuffer? = nil

     CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, self.ciPixelBufferPool!, &pixelBuffer)

    if let pixBuf = pixelBuffer {
        self.ciContext.render(sourceImage, to: pixBuf)

        self.displayPixelBufferOnMTKView(pixBuf)

       //Convert the pixel buffer to YUV as some filters operate only on YUV
        if let yuvPixelBuffer = self.rgb2yuvFrameRenderer?.copyRenderedPixelBuffer(pixBuf) {

           self.processYUVPixelBuffer(yuvPixelBuffer)

        }

    }
}

Вот код шейдера Metal:

 // Compute kernel
 kernel void kernelRGBtoYUV(texture2d<half, access::read> inputTexture [[ texture(0) ]],
                       texture2d<half, access::write> textureY [[ texture(1) ]],
                       texture2d<half, access::write> textureCbCr [[ texture(2) ]],
                       constant ColorConversion &colorConv [[ buffer(0) ]],
                       uint2 gid [[thread_position_in_grid]])
 {
    // Make sure we don't read or write outside of the texture
     if ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {
       return;
     }

   float3 inputColor = float3(inputTexture.read(gid).rgb);

   float3 yuv = colorConv.matrix*inputColor + colorConv.offset;

   half4 uv = half4(yuv.gbrr);

   textureY.write(half(yuv.x), gid);

   if (gid.x % 2 == 0 && gid.y % 2 == 0) {
      textureCbCr.write(uv, uint2(gid.x / 2, gid.y / 2));
   }

 }

person Deepak Sharma    schedule 06.08.2019    source источник
comment
Зачем вам нужны CVPixelBuffers? Например, вы можете визуализировать CIImage прямо в виде (view.currentDrawable.texture).   -  person Frank Schlegel    schedule 06.08.2019
comment
Проблема в том, что мне нужен CVPixelBuffer, чтобы преобразовать его в YUV420, обработать данные YUV и отобразить их в другом MTKView. Мой вопрос: действительно ли это снижает производительность, как я?   -  person Deepak Sharma    schedule 06.08.2019
comment
Не могли бы вы уточнить, как вы конвертируете данные в YUV420?   -  person Frank Schlegel    schedule 06.08.2019
comment
Я использую шейдер Metal Compute для преобразования rgb в yuv420.   -  person Deepak Sharma    schedule 07.08.2019
comment
Вы можете выполнить преобразование в пользовательском CIColorKernel, тогда вам не нужно будет выполнять рендеринг в CVPixelBuffer между ними.   -  person Frank Schlegel    schedule 07.08.2019
comment
Я не знаю, можно ли легко преобразовать вычислительный шейдер Metal в CIColorKernel. Есть указатели?   -  person Deepak Sharma    schedule 07.08.2019
comment
К сожалению, документации Apple очень немного. Этот пост, вероятно, является хорошей отправной точкой: medium.com/@shu223 / core-image-filters-with-metal-71afd6377f4. Если вы опубликуете свой шейдерный код, я могу помочь вам с преобразованием.   -  person Frank Schlegel    schedule 08.08.2019
comment
Я обновил вопрос кодом шейдера Metal.   -  person Deepak Sharma    schedule 08.08.2019
comment
Хм ... к сожалению, Core Image не поддерживает создание двух выходных данных одновременно, поэтому этот двухплоскостной подход не сработает. Я так понимаю, это формат буфера пикселей, который вы получите при захвате камерой. Вам действительно нужен этот конкретный формат или вам просто нужно работать в цветовом пространстве YUV?   -  person Frank Schlegel    schedule 08.08.2019
comment
Да, я получаю это с камеры. Я конвертирую его в RGB, сжимаю как jpeg и отправляю на одноранговое устройство по сети. Другое устройство затем преобразует его в YUV. Если бы существовал способ сжатия и отправки данных YUV420 на другое устройство, это было бы лучше всего. Но как?   -  person Deepak Sharma    schedule 08.08.2019
comment
К сожалению, я слишком мало знаю о сжатии. Для чего вам нужны буферы YUV? Может быть, есть способ добиться того же на основе данных RGB.   -  person Frank Schlegel    schedule 08.08.2019
comment
Некоторые из моих фильтров напрямую работают с YUV. Но тогда мне нужно было бы их переписать для RGB. Плюс больше строк в потоке управления.   -  person Deepak Sharma    schedule 08.08.2019
comment
И да, мне нужны данные в градациях серого, которые являются Y-компонентом. Эта текстура Y обрабатывается напрямую кодом, отличным от Metal / OpenGL / CoreImage. Я использую vImage API, который использует Accelerate Framework.   -  person Deepak Sharma    schedule 08.08.2019
comment
Хм, сложно. С этими ограничениями я не вижу большого потенциала для оптимизации. Может быть, вы можете как-то сжать (zip?) Необработанные данные пиксельного буфера YUV отправителя и передать их вместо этого.   -  person Frank Schlegel    schedule 08.08.2019
comment
Не могли бы вы взглянуть на этот вопрос - https://stackoverflow.com/questions/57834241/ciimage-display-mtkview-vs-glkview-performance   -  person Deepak Sharma    schedule 07.09.2019