Как получить последовательную глубокую копию содержимого MTLTexture? - PullRequest
0 голосов
/ 24 января 2020

MTLTexture deep copy artefacts

Я получаю YUV 420 CMSampleBuffer с экрана в моем системном расширении вещания, однако, когда я пытаюсь получить доступ к нижележащим байтам, я получаю противоречивые результаты : артефакты, которые представляют собой смесь (кажется) прошлых и будущих кадров. Я обращаюсь к байтам, чтобы повернуть портретные кадры на четверть оборота в пейзаж, но проблема сводится к тому, что невозможно правильно скопировать текстуру.

Структура артефактов может сильно измениться. Они могут быть повсюду и, кажется, имеют фундаментальную «форму bru sh», которая представляет собой квадратную плитку, иногда маленькую, иногда большую, что, кажется, зависит от неудачной работы вокруг под рукой. Они могут встречаться как в каналах яркости, так и цветности, что приводит к интересным эффектам. «Зерно» артефактов иногда кажется горизонтальным, что, я полагаю, является вертикальным в исходном кадре.

У меня есть два работающих обходных пути:

  • вращайте буферы, используя Metal
  • вращение буферов с использованием CoreImage (даже «программное обеспечение» CIContext работает)

Причина, по которой я пока не могу отправить эти обходные пути, заключается в том, что система У широковещательных расширений очень низкий предел памяти - 50 МБ, и использование памяти может резко возрасти с этими двумя решениями, и, кажется, есть взаимодействия с другими частями системы (например, AVAssetWriter или демон, который сбрасывает кадры в мое адресное пространство). Я все еще работаю над пониманием использования памяти здесь.

Артефакты кажутся проблемой синхронизации. Однако у меня есть ощущение, что это не столько новый кадр, который записывается в буфер, на который я смотрю, а скорее какой-то устаревший кеш. CPU или GPU? Есть ли у кешей кеш? Плиточный характер артефактов напоминает мне о iOS графических процессорах, но с небольшим количеством соли (не с аппаратным обеспечением).

Это подводит меня к названию вопроса. Если это проблема с кэшированием и Metal / CoreImage имеет согласованное представление о пикселях, возможно, я смогу получить Металл для гриппа sh нужных мне данных, потому что снимок экрана BGRA преобразуется в YUV IOSurface имеет Metal шейдер, написанный на нем.

Итак, я взял входящий CMSampleBuffer CVPixelBuffer IOSurface и создал из него MTLTexture (со всеми видами cacheMode s и storageMode s, еще не пробовали hazardTrackingMode s), а затем скопировали байты с помощью MTLTexture.getBytes(bytesPerRow:from:mipmapLevel:).

Все же проблема сохраняется. Мне бы очень хотелось, чтобы по соображениям памяти работал подход глубокого копирования ЦП.

Чтобы ответить на некоторые вопросы:

  • это не проблема байтов на строку, это наклоняю изображения
  • в случае процессора. Я блокирую базовый адрес CVPixelBuffer
  • Я даже блокирую базовый IOSurface
  • Я пытался сбросить IOSurface s, чья блокировка семени изменяется под блокировкой
  • Я сбрасываю фреймы, когда это необходимо
  • Я попытался установить случайные заборы памяти и мьютексы повсюду (не аппаратный человек)
  • Я еще не разобрал CoreImage пока

Этот вопрос является продолжением одного сообщения, опубликованного на форумах разработчиков Apple

Smaller tile artefact

...