Мне нужно преобразовать кадры YUV в CVPixelBuffer, которые я получаю от OTVideoFrame Класс
Этот класс предоставляет массив плоскостей в видеокадре, который содержит три элемента для кадра y, u, v, каждый с индексом 0,1,2.
@property (неатомный, сохранить) плоскости NSPointerArray *
и формат из кадр видео
@property (неатомный, сохранить) формат OTVideoFormat *
Содержит такие свойства, как ширина, высота, bytesPerRow и т. Д. Кадра.
Мне нужно добавить фильтр к изображению, которое я получаю в виде OTVideoFrame, я уже пробовал эти ответы:
По этим двум ссылкам есть решения в Objective-C, но я хочу сделать это быстро. Один из ответов во второй ссылке был быстрым, но в нем отсутствует некоторая информация о структуре YUVFrame, на которую ссылается ответ.
Я получаю формат NV12.
Вот что я пытался сделать до сих пор, но не знаю, что делать дальше:
/**
* Calcualte the size of each plane from OTVideoFrame.
*
* @param frame The frame to render.
* @return tuple containing three elements for size of each plane
*/
fileprivate func calculatePlaneSize(forFrame frame: OTVideoFrame)
-> (ySize: Int, uSize: Int, vSize: Int){
guard let frameFormat = frame.format
else {
return (0, 0 ,0)
}
let baseSize = Int(frameFormat.imageWidth * frameFormat.imageHeight) * MemoryLayout<GLubyte>.size
return (baseSize, baseSize / 4, baseSize / 4)
}
/**
* Renders a frame to the video renderer.
*
* @param frame The frame to render.
*/
func renderVideoFrame(_ frame: OTVideoFrame) {
let planeSize = calculatePlaneSize(forFrame: frame)
let yPlane = UnsafeMutablePointer<GLubyte>.allocate(capacity: planeSize.ySize)
let uPlane = UnsafeMutablePointer<GLubyte>.allocate(capacity: planeSize.uSize)
let vPlane = UnsafeMutablePointer<GLubyte>.allocate(capacity: planeSize.vSize)
memcpy(yPlane, frame.planes?.pointer(at: 0), planeSize.ySize)
memcpy(uPlane, frame.planes?.pointer(at: 1), planeSize.uSize)
memcpy(vPlane, frame.planes?.pointer(at: 2), planeSize.vSize)
let yStride = frame.format!.bytesPerRow.object(at: 0) as! Int
// multiply chroma strides by 2 as bytesPerRow represents 2x2 subsample
let uStride = frame.format!.bytesPerRow.object(at: 1) as! Int
let vStride = frame.format!.bytesPerRow.object(at: 2) as! Int
let width = frame.format!.imageWidth
let height = frame.format!.imageHeight
var pixelBuffer: CVPixelBuffer? = nil
var err: CVReturn;
err = CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, nil, &pixelBuffer)
if (err != 0) {
NSLog("Error at CVPixelBufferCreate %d", err)
fatalError()
}
}
Руководствуясь этими двумя ссылками, я пытался создать буфер пикселей, но каждый раз на этом этапе я останавливался, потому что преобразование кода Objective-C после этого не похоже на то, что мы имеем в Swift 3.