Fast CinemaDNG

Быстрое решение для обработки CinemaDNG на видеокартах NVIDIA

программное обеспечение Fast CinemaDNG Processor

Быстрое декодирование DNG изображений, сжатых по алгоритму Lossless JPEG

Алгоритм сжатия без потерь широко используется во многих фото- и видеокамерах, снимающих в формате RAW. Это необходимо, прежде всего, для увеличения количества кадров, которые помещаются во встроенной памяти или на флеш-карте камеры. Сжатие без потерь гарантирует возможность абсолютно точного восстановления исходных данных, но коэффициент сжатия сырых данных получается небольшим, обычно в диапазоне 1,5-2 раз. Этот алгоритм сжатия без потерь может работать с исходными данными, у которых разрешение от 2 бит до 16 бит на пиксел. Такое кодирование обычно делается аппаратным образом внутри камеры, причём в реальном времени. Это так у большинства камер.

Сжатие без потерь по алгоритму Lossless JPEG подразумевает следующие шаги

  • Поскольку обычно нужно кодировать сырые данные, то важно помнить, что изображение состоит из байеровских паттернов типа RGGB, как это и положено до работы программы демозаики. Поэтому первым шагом у изображения увеличивают ширину в 2 раза, при этом высота автоматически в 2 раза уменьшается. Это необходимо для обеспечения лучшей корреляции данных при кодировании.
  • Перед кодированием нужно выбрать формулу для предсказания (одну из 7 возможных). Это необходимо для того, чтобы кодировать разницу между истинным значением и предсказанным. Обычно такой шаг приводит к компрессии гистограммы данных, что хорошо сказывается и на последующем сжатии изображения. Для предсказания чаще всего используется вариант номер 6, соответствующий формуле Px = Rb + (Ra - Rc)/2. Это означает, что для предсказания используется значение пиксела сверху плюс половина разности между левым и левым верхним пикселами.
  • Сжатие происходит по алгоритму Хаффмана. При этом используется не дерево, а фиксированная таблица. Если у изображения только одна компонента, то достаточно одной таблицы. Чаще всего компоненты две, так что в этом случае нужны две таблицы Хаффмана.
  • Обычно с самого начала исходное изображение разбивается на тайлы, поэтому нужно отдельно закодировать каждый тайл, а потом в заголовок RAW записать таблицу смещений, по которой можно будет найти начало каждого сжатого тайла.

Декодирование Lossless JPEG

  • Скорость работы декодера Lossless JPEG определяется в основном временем декодирования по Хаффману. Фактически, нужно побитово считывать сжатые данные, определять коды из таблицы Хаффмана и восстанавливать исходные данные.
  • После декодирования вычисляем исходное значение по обратной формуле предсказания, восстанавливаем правильную длину и ширину кадра.
  • Декодируем все тайлы и собираем исходное изображение в формате RAW.

Конфигурация компьютера для тестирования

  • CPU Intel Core i7-6700 (Skylake, 4 ядра, 3.4–4.0 ГГц)
  • GPU NVIDIA GeForce GTX 1080 (Pascal, 20 SMM, 2560 ядер, 1.6–1.7 ГГц)
  • OS Windows 10 (x64)

Сравнение декодеров Lossless JPEG

Для сравнения декодеров для RAW данных, сжатых без потерь, будем использовать следующие библиотеки:

  • Декодер Lossless JPEG из Adobe DNG SDK
  • Декодер LJ92 (библиотека liblj92)
  • Декодер Lossless JPEG из Fast CinemaDNG Processor (библиотека Fastvideo LJ Decoder)

В реальной ситуации все эти программы работают в многопоточном режиме, причём каждый тайл (или каждый кадр) декодируется в отдельном потоке. Для сравнения мы приведём результаты декодирования для однопоточного приложения, при этом будем декодировать одни и те же DNG изображения, на одном и том же процессоре. Декодирование полностью выполняется на CPU, возможности видеокарты для вычислений при этом не задействуются. Тестовые изображения имеют разрешение от 2 МПикс до 16 МПикс, исходные данные 12-битные, две компоненты (одна или две таблицы Хаффмана), один тайл, паттерн демозаики RGGB, сжатие по алгоритму Lossless JPEG.

Производительность однопоточных декодеров Lossless JPEG

  • Adobe DNG SDK (12-16 бит): 30 - 32 МПикс/сек
  • LJ92 (библиотека liblj92, 12/16 бит): 45 - 50 МПикс/сек
  • Fastvideo LJ Decoder (16 бит): 60 - 70 МПикс/сек
  • Fastvideo LJ Decoder (12 бит): 75 - 90 МПикс/сек

Хорошо видно, что производительность Fastvideo LJ Decoder заметно выше, поэтому использование этой библиотеки даёт значительное ускорение при декодировании DNG изображений, сжатых по алгоритму Lossless JPEG. Этот декодер позволяет ускорить загрузку и декодирование сырых данных, что очень важно для плавного вывода серий CinemaDNG изображений при просмотре видео. Эта библиотека написана на языке Си без ассемблера, т.е. может быть использована и на других аппаратных платформах в том же самом виде.

В случае с декодированием 12/14/16-битных DNG мы видим, что декодеры Adobe и LJ92 имею практически ту жу самую производительность для 12-битных и 16-битных данных. Лучший результат для Fastvideo LJ Decoder достигается для 12-битных данных, а для 16-битных полученная производительность выше, чем у декодеров LJ92 и Adobe.

Скорость декодирования DNG для 8-поточных приложений

Ниже приведены бенчмарки для "плохого" и "хорошего" случаев. В самом неудобном варианте картинка имеет разрешение 16 бит и слабое сжатие, во втором случае картинка 12-битная, а сжатие сильное. Эти результаты показывают, какого масштабирования можно достичь при использовании многопоточных приложений для декодирвания DNG на CPU. Хорошо видно, что производительность растёт нелинейным образом.

Тест № 1: Изображение 16 бит, сжатие 10,4 бит на пиксел (без потерь)
  • LJ92 (библиотека liblj92): 266 МПикс/сек
  • Fastvideo LJ Decoder: 407 МПикс/сек
Тест № 2: Изображение 12 бит, сжатие 5,6 бит на пиксел (без потерь)
  • LJ92 (библиотека liblj92): 284 МПикс/сек
  • Fastvideo LJ Decoder: 475 МПикс/сек

Эти результаты говорят о том, что быстрое декодирование DNG возможно делать в реальном времени для разрешения 4К и вплоть до 6К при использовании многопоточных декодеров на многоядерных CPU. Ключевыми факторами являются оптимизация самого процесса декодирования и создание многопоточного приложения для достижения максимальной производительности.

Полученные результаты в ближайшее время мы используем для ускорения декодирования файлов CR2, NEF, ARW и других RAW форматов, которые используют кодирование в джипег без потерь.