Применение эффекта к превью камеры iPhone «Видео»
-
28-10-2019 - |
Вопрос
Моя цель - написать собственный контроллер вида камеры, который:
- Можно делать фотографии во всех четырех ориентациях интерфейса как с помощью задней, так и, если возможно, передней камеры.
- Правильно поворачивает и масштабирует предварительный просмотр «видео», а также фотографию с полным разрешением.
- Позволяет применить (простой) эффект ОБЕИМ к предварительному просмотру "видео" и фотографии с полным разрешением.
Реализация (в iOS 4.2 / Xcode 3.2.5):
Из-за требования (3) мне пришлось перейти к AVFoundation.
Я начал с технических вопросов и ответов QA1702 и сделал эти изменения:
- Изменил sessionPreset на AVCaptureSessionPresetPhoto.
- Добавлен AVCaptureStillImageOutput в качестве дополнительного вывода перед началом сеанса.
Проблема, с которой я столкнулся, связана с производительностью обработки изображения предварительного просмотра (кадра предварительного просмотра "видео").
Сначала я получаю результат UIImage для imageFromSampleBuffer:
в буфере выборки из captureOutput:didOutputSampleBuffer:fromConnection:
. Затем я масштабирую и поворачиваю его для экрана с помощью CGGraphicsContext.
На данный момент частота кадров уже ниже 15 кадров в секунду, указанных в видеовыходах сеанса, и когда я добавляю эффект, она падает ниже или около 10. Приложение быстро вылетает из-за нехватки памяти. .
Мне удалось снизить частоту кадров до 9 кадров в секунду на iPhone 4 и до 8 кадров в секунду на iPod Touch (4-го поколения).
Я также добавил код для «очистки» очереди отправки, но я не уверен, насколько это действительно помогает. Обычно каждые 8-10 кадров устанавливается флаг, который сигнализирует, что captureOutput:didOutputSampleBuffer:fromConnection:
нужно немедленно вернуться, а не обрабатывать кадр. Флаг сбрасывается после завершения операции синхронизации в выходной очереди отправки.
На данный момент я даже не возражаю против низкой частоты кадров, но, очевидно, мы не можем поставлять сбои из-за нехватки памяти. Кто-нибудь знает, как предпринять действия, чтобы предотвратить условия нехватки памяти в этом случае (и / или лучший способ «очистить» очередь отправки)?
Решение
Чтобы предотвратить проблемы с памятью, просто создайте пул автозапуска в captureOutput:didOutputSampleBuffer:fromConnection:
.
В этом есть смысл, поскольку imageFromSampleBuffer:
возвращает автоматически выпущенный объект UIImage. Кроме того, он сразу же освобождает любые автоматически выпущенные объекты, созданные кодом обработки изображений.
Мое тестирование показало, что это будет работать без предупреждений о памяти на iPhone 4 или iPod Touch (4-го поколения), даже если запрашиваемый FPS очень высокий (например, 60), а обработка изображения очень медленная (например, 0,5+ секунды).
СТАРОЕ РЕШЕНИЕ:
Как отметил Брэд, Apple рекомендует выполнять обработку изображений в фоновом потоке, чтобы не мешать быстродействию пользовательского интерфейса. Я не заметил большой задержки в этом случае, но передовой опыт - это передовой опыт, поэтому используйте вышеупомянутое решение с пулом автозапуска вместо запуска его в основной очереди отправки / основном потоке.
Чтобы предотвратить проблемы с памятью, просто используйте основную очередь отправки вместо создания новой.
Это также означает, что вам не нужно переключаться на основной поток в captureOutput:didOutputSampleBuffer:fromConnection:
, когда вы хотите обновить пользовательский интерфейс.
В коде setupCaptureSession
измените FROM:
Кому:
родовое словоДругие советы
Принципиально лучшим подходом было бы использование OpenGL, чтобы справиться с такой тяжелой работой, связанной с изображениями, для вас (как я вижу, вы пытаетесь в ваша последняя попытка ). Однако даже в этом случае у вас могут возникнуть проблемы с созданием кадров для обработки.
Хотя кажется странным, что вы столкнетесь с накоплением памяти при обработке кадров (по моему опыту, вы просто перестаете получать их, если не можете обрабатывать их достаточно быстро), очереди Grand Central Dispatch могут забиваться, если они ждут ввода / вывода.
Возможно, семафор отправки позволит вам регулировать добавление новых элементов в очереди обработки. Чтобы узнать больше об этом, я настоятельно рекомендую Майка Эша " GCD Practicum », в которой он рассматривает оптимизацию операции обработки эскизов с привязкой к вводу-выводу с использованием семафоров отправки.