Про HEVC/HEIC

(скопирую из фейсбука, чуть расширив, может и пригодится кому)

Довелось тут залезть в потроха формату HEIC/HEIF, не могу не высказать к нему свое отношение, хоть никто вроде и не спрашивал.

Summary: хороший формат, с потенциалом.

Что там хорошего:

  • есть 8 и 10 бит (может быть и больше, но в дикой природе никто не видел)
  • Сжатие H.265 гораздо лучше (старого) JPEG при том же/сравнимом качестве.
  • Контейнер (MP4/ISO BMFF) тоже удобный, удобно разбирать, можно что хочешь положить (стандартно кладут EXIF и XMP, но нет причин не класть туда вообще что угодно). Уж всяко лучше "контейнеров" JPEG и (тем более) PNG.
  • Можно разместить что уже угодно: отдельную картинку, сборную картинку (grid), последовательность, "анимированный гиф", превьюшки любых размеров, многослойную (оверлей) картинку.
  • На практике (Apple Canon) картинки больших размеров порезаны на тайлы (grid), что позволяет параллельное декодирование. У Canon порезано крупновато, у Apple (IMHO) мелковато, но на современных многоядерных компьютерах и телефонах - это позволяет декодировать во все ядра (в отличие от тех же JPEG и PNG, да и от TIFF: параллельных распаковщиков тайловых TIFF практически же и нет, хотя казалось бы).
  • Кодировать, естественно, тоже можно параллельно.
  • Кодировать-декодировать можно и аппаратно, благо H.265 кодек влепили уже много где. Это не очень нужно для фото (45-мегапиксельный файл от EOS R5 распаковывается на 16 ядрах за ~200 миллисекунд, считая YCC-RGB конверсию), но если вы лепите какую-то потоковую обработку тысяч файлов, или же кодирование....

Что там плохого:

  • Cложная и очень большая спецификация
  • Нет (ну или я не нашел) указания на приоритет метаданных:
    К примеру, если в irot-box (часть формата) указан один поворот, а в EXIF - другой, то у какого будет приоритет? Ну вроде бы у irot. А если какой-то "редактор" решил, что вот lossless rotation будем делать заданием тега в EXIF и сам так работает....? Этот трюк работал в JPEG (потому что EXIF - часть спецификации JPEG по сути) и я уже предвижу как он откочует в HEIC.
  • Есть некоторая недоделка в части цвета, а именно
    • Цвет задается
      • или тройкой полей, задающих конверсию YCC-RGB, RGB Color Primaries для получившегося RGB и тоновой кривой (это именно единичные поля, задающие "номер строчки в стандартной таблице")
      • или вложенным ICC профилем (причем есть два типа записей для профиля, но неясно в чем отличие)
    • Если цвет задан таблицами - нет профиля и наоборот.
    • Соответственно, если вы цепляете профиль, то конверсия YCC-RGB идет со стандартными коэффициентами (номер два), а задать свою нельзя.  JPEG в этом месте был гибче, хотя никто YCC-RGB коэффициенты на практике нестандартные не использовал.
    Понятно почему так сделано: аппаратные кодеки (скорее всего) имеют внутри готовые таблицы коэффициентов, но вот странность есть.

Для разработчика:

  • Если вам нужно поддержать "еще один формат" как-то, берите libheif и все будет.
  • Но libheif очень медленная, особенно для тайловых изображений (а это основной массив HEIF/HEIC файлов на сегодня)
    • Конверсия цвета из, к примеру, 10-bit YCC (planar) в 8-bit RGB interleaved - будет делаться в три стадии (в 16-бит RGB planar, потом в 8 бит planar, потом в interleaved).
    • Для тайловых изображений полностью избавиться от конверсии не получится, тайлы склеиваются внутри в формате RGB-planar.
    • Декодирование тайлов делается последовательно, хотя backend (libde265) умеет параллельно.
  • Поэтому, если интересует результат (в смысле скорости), писать по хорошему придется самому:
    • Параллельное декодирование
    • YCC-RGB-конверсию
    • совокупление какого-то разбора ISO BMFF с декодером.
  • Если вы вдруг хотите прославиться на ниве опенсорца - истину говорю вам, готового приличного решения для HEIC/HEIF нет, можно вот прямо начинать делать (я - не буду :).
    В принципе, можно и libheif довести до ума, не знаю примут ли такой патч в апстрим.

Comments

Но MP4 контейнер же битовый, с Variable length integers, и прочими оптимизациями под БИТОВЫЙ поток и аппаратное декодирование, это же ад на процессорах разбирать! Или они от этого тут отказались?

Ну погоди, там перед боксами полноценные 4-байтовые размеры (ну или 64 битные могут быть, на практике не видал).
И в большинстве боксов - нормальные 1-2-4-байтовые же поля.

Ужасы которые ты пишешь - они собственно могут быть в тех кусках, которые суют потом в H.265 декодер (вот в hvcC есть такое), ну так это декодерово дело как их там фигачить, руками это щупать не приходится.

Ну вот я не знаю, как они сделали. Я делал сериализатор/десериализатор в MPEG4 для VRML (да, VRML был частью стандарта MPEG4!) лет 15 назад и там был контейнер именно битовый…
Но вообще у MPEG4 жтих контейнров штуки 4 же — transport stream, packet stream, ещё что-то, и все разные…

MP4 - это MPEG4 Part 14.

Я не помню за давностью лет какой у нас Part был.

Короче, в MP4 (это подмножество MPEG4, одна часть стандарта) заголовок бокса 8 байт строго, содержимое бокса бывает всякое, но variable bits я видел только у собственно контентной части, заголовка H.265-кадра.
Нормальному человеку в это место лезть не надо, нужны метаданные (ID картинок, цветовые данные) - они человеческие.

.. и более бит? HDR-вывод?

HDR если показ.
Ну и типа можно отредактировать разок (другой) без постеризации.

Не спрашивали, но было интересно. Сам пытался как-то перегонять в него джейпеги из Лайтрума, предназначенные для помещения в Apple Photos с последующим разглядыванием фоток родственниками на их планшетах. И, блин, я потерпел фиаско. Делал это тремя способами и все они костыльные. Почему, блин, он до сих пор не в Лайтруме и Фотошопе? Через маковский Preview (там какая-то зелень лезла сверху), через бинарник (и даже вроде Икскод для этого ставил), через Darkroom (дурацкая идея гнать фотки на мобильное устройство, там их сохранять, а потом куда-то через облако вытаскивать). И, кажется, я столкнулся с проблемой, что стороны картинки должны быть кратными двум, то есть, типа 1681х1050 быть не может. Это правда?

Ради интереса сравнивал тут же с webp. HEIF визуально и по размеру файла победил. Обыдно, что ни один браузеры его не спешат поддердивать.

Есть ли какие-то уже человеческие средства для конвертирования чтобы вжух и готово?

Что-то я вроде ответил уже, а ответ куда-то того, может кнопку не ту нажал.

Человеческих средств не видел - но мне и не надо было.
Сам формат внутри - размер кратен 16ти, но есть (внутри в метаданных) кроп и он вроде ничему не обязан быть кратен.