Как наложить представления на каждый захваченный кадр внутри CVImageBuffer, в реальном времени, а не после обработки - PullRequest
0 голосов
/ 24 мая 2018

Мне удалось настроить базовый AVCaptureSession, который записывает видео и сохраняет его на устройстве с помощью AVCaptureFileOutputRecordingDelegate.Я искал документы, чтобы понять, как мы можем добавить наложения статистики поверх записываемого видео.

т.е.

enter image description here

Как вы можете видеть на изображении выше.У меня есть несколько оверлеев поверх слоя предварительного просмотра видео.Теперь, когда я сохраняю свой выходной видеосигнал, я хотел бы также наложить эти виды на видео.

Что я пробовал до сих пор?

  • Честно говоря, я просто прыгаю вокругв Интернете, чтобы найти авторитетный блог, объясняющий, как можно это сделать.Но не удалось найти его.
  • Я читал несколько мест, где можно отображать наложения текстового слоя, как описано в после поста , создав CALayer и добавив его в качестве подслоя.
  • Но что если я захочу сделать MapView поверх записываемого видео?Также я не ищу снимок экрана.Некоторое содержимое на экране не будет частью окончательной записи, поэтому я хочу иметь возможность просмотра вишневого пика, который будет составлен.

Что я ищу?

  1. Направление.
  2. Нет прямого решения
  3. Ссылка на документацию и имена классов, о которых я должен прочитать больше.

Прогресс пока:

Мне удалось понять, что мне нужно взять CVImageBuffer из CMSampleBuffer и нарисовать текст поверх него.Мне все еще неясно, возможно ли как-то наложить MapView поверх записываемого видео.

1 Ответ

0 голосов
/ 28 мая 2018

Лучший способ помочь вам в достижении вашей цели - это использование Metal фреймворка.Использование камеры Metal хорошо для минимизации влияния на ограниченные вычислительные ресурсы устройства.Если вы пытаетесь добиться минимального доступа к датчику камеры, использование AVCaptureSession было бы действительно хорошим началом.

Вам нужно получить данные каждого кадра из CMSampleBuffer (вы правы), а затем преобразовать кадр в MTLTexture.AVCaptureSession будет непрерывно отправлять нам кадры с камеры устройства посредством обратного вызова делегата.

Все доступные наложения также должны быть преобразованы в MTLTextures.Затем вы можете объединить все MTLTextures слои с помощью операции over.

Итак, здесь вы найдете всю необходимую информацию в четырехкомпонентной металлической камере серия .

А вот ссылка на блог : О композитинге в металле .

Также мне бы хотелосьчтобы опубликовать фрагмент кода (работа с AVCaptureSession in Metal):

import Metal

guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
    // Handle an error here.
}

// Texture cache for converting frame images to textures
var textureCache: CVMetalTextureCache?

// `MTLDevice` for initializing texture cache
var metalDevice = MTLCreateSystemDefaultDevice()

guard
    let metalDevice = metalDevice
    where CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, metalDevice, nil, &textureCache) == kCVReturnSuccess
else {
    // Handle an error (failed to create texture cache)
}

let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)

var imageTexture: CVMetalTexture?
let result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache.takeUnretainedValue(), imageBuffer, nil, pixelFormat, width, height, planeIndex, &imageTexture)

// `MTLTexture` is in the `texture` variable now.
guard
    let unwrappedImageTexture = imageTexture,
    let texture = CVMetalTextureGetTexture(unwrappedImageTexture),
    result == kCVReturnSuccess
else {
    throw MetalCameraSessionError.failedToCreateTextureFromImage
}

И здесь вы можете найти окончательный проект на GitHub: MetalRenderCamera

...