Сжатие видео и декодирование | Выбираем программу
Лучший выбор
![]() |
![]() |
![]() |
Если вам надо выбрать лучшее качество видео на выходе между вариантами с использованием аппаратного обеспечения с програмным, то надо обратиться к решениям AMD и Intel (Quality setting) в Cyberlink MediaEspresso, решению от Intel в Arcsoft MediaConverter и решению от nVidia в Badaboom.
Худший выбор
![]() |
![]() |
![]() |
Худший (или может быть наименее оптимизированный) выбор – это решение Intel в Badaboom, оборудование AMD в MediaConverter и nVidia CUDA в MediaEspresso. Различие между худшим и лучшим вариантом в MediaEspresso и MediaConverter достаточно велико и заметно. В Badaboom различие между CUDA и Quick Sync незначительны.
Честно говоря, выбор порой зависит от того, сколько часов мы просмотрели. Когда видео "плохое", это всего лишь означает, что одна сцена в клипе выглядит хуже, чем у конкурирующих конфигураций.
Сжатие видео и декодирование | Как же всё сложно
Мы много часов провели в беседах с экспертами, включая сотрудников из CyberLink, Arcsoft, Elemental, nVidia, AMD, Microsoft и Intel, о проблематике тестирования качества транскодирования. В результате этих обсуждений возникла потребность прояснить ситуацию. Прочитав эту статью, вы можете сделать вывод, что "видео у AMD и Arcsoft несколько туманные", а "nVidia и MediaEspresso вместе выглядят очень чётко". Но это – лишь малая часть истории, она не даёт представления о полной картине.
Мы ставили перед собой задачу разобраться в том, можно ли с уверенностью сказать, кто из nVidia CUDA, AMD APP и Intel Quick Sync даёт наилучшее качество при транскодировании видео. Оказалось, что у этого простого вопроса может не быть чёткого ответа.
Почему? Давайте начнем с ПО. Во-первых, у всех трёх приложений, которые мы использовали для этой статьи, различные установки для кодирования видео на iPad (и для многих других профилей работы). Например, величина битрейт по умолчанию в MediaEspresso – 3 Мбит/с. MediaConverter использует 4 Мбит/с. В Badaboom – 2.5 Мбит/с. Но даже, если все эти установки мы сделаем одинаковыми и равными 3 Мбит/с, а также приравняем и все другие параметры, то сравнение всё равно не будет правильным. Чтобы установить одинаковый битрейт в MediaConverter, мы должны создать обычный профиль H.264 MP4 и вручную выбрать битрейт вместе с другими параметрами. Это действие меняет весь процесс. Когда вы выбираете профиль, есть параметры, которые не задействованы в пользовательском интерфейсе, но влияют на результат. Поскольку MediaConverter больше не использует профиль iPad, это сразу становится недостатком.
H.264 | Badaboom | MediaConverter | MediaEspresso (AMD & nVidia) | MediaEspresso (Intel) |
Программное декодиров. (только процессор) | MediaSDK | Проприет. | Проприет. | MediaSDK |
Программное кодиров. (только процессор) | MediaSDK | Проприет. | Проприет. | MediaSDK |
Аппаратное декодиров./GPGPU | MediaSDK (Intel), проприет. (CUDA) | APP Reference Library (AMD), CUDA Reference Library (nVidia), MediaSDK (Intel) | APP Reference Library (AMD), CUDA Reference Library (nVidia) | MediaSDK |
Аппаратное декод. | MediaSDK | Проприетарное с DXVA | Проприетарное с DXVA | MediaSDK |
Во вторых, надо поговорить о кодировщиках и декодировщиках. Практически невозможно выбрать один наилучший декодировщик при таких несопоставимых результатах. Например, если вы используете HD Graphics 2000 или 3000 в MediaEspresso, Badaboom или MediaConverter, вы всегда используете кодировщик и декодировщик из библиотеки Intel MediaSDK. Cyberlink использует только свои проприетарные кодировщик и декодировщик на оборудовании AMD и nVidia. Badaboom вообще не поддерживает кодирование на базе АРР, а CUDA-кодировщик был разработан компанией самостоятельно. А вот Arcsoft и Cyberlink используют референсную библиотеку nVidia, чтобы транскодировать на nVidia GPU. Если вы смотрели наши ролики, то знаете, что использование одной и той же библиотеки не гарантирует одинаковый результат.
Даже если игнорировать проблемы выделения конкретного кодировщика, сравнение различного оборудования в одном и том же приложений может привести к большому количеству проблем. Для кодирования, управление скоростью, выбор моды (Inter/Intra, 4x4, 8x8, 16x16 блоков), опция кодирования (B frame) – всё это влияет на качество видео. Один из программистов как-то отметил, что параметры кодирования, используемые в разных библиотеках, могут не быть одинаковыми. Например, может быть так, что MediaEspresso использует макроблок 4х4 в АРР и 8х8 – в CUDA.
И всё-таки: отчего же получается плохое видео? Один из производителей ПО рассказал нам, что он использует Elecard StreamEye Studio, чтобы анализировать транскодированное видео. Но что проиcходит, когда под вопрос встают входные материалы? Когда вы транскодируете видео, сначала надо пройти декодирование, а затем – кодирование. После этого, каждое активное действие с транскодированием видео заставляет его пройти через другой декодер и определенный рендеринг. Это означает, что вы смотрите на свои данные через четыре линзы. Если вдруг возникает ошибка, откуда она берется? Научный подход советует нам изолировать как можно больше переменных. Это означает, что мы не должны менять разрешение при транскодировании, не должны менять скорость передачи кадров или профилей CABAC. Только при тестировании параметров один за одним удастся изолировать реально действующие факторы. В любой ситуации нельзя забывать, что мы просматриваем видео через несколько "линз", даже когда мы используем нечто столь же хорошее как StreamEye Studio. В этом случае вы используете декодер Elecard и специфический рендеринг, чтобы получить кадры для анализа.
Ни одна компания не дала нам доступ к своему кодировщику, так, чтобы мы могли извлечь кадры из буфера, поэтому мы не смогли оценить изображения, не изменённые плеером (то есть после декодирования и рендеринга).
На уровне кодека обычно используется анализ PSNR (пиковое отношение сигнал/шум), но также, в случае работы со звуком, этот анализ не точный. Этот метод конечно хорош, но имеет очень мало промышленных стандартов. Различные инструменты вычисляют PSNR по-разному. Один из разработчиков рассказал нам, что компания Textronix однажды продала устройство за 50 тысяч долларов для анализа изображений, но при этом вы могли использовать только референсные изображения компании. Какой же вывод можно из этого сделать? Эксперты AMD рассказали нам, что инженеры компании используют измерения PSNR, только чтобы убедиться, что используется одинаковый протокол и точки отсчёта.
Кое-кто говорил, что анализ H.264 проще, чем MPEG-2. Естественно, стандарт H.264 имеет более жёсткие требования декодирования, в нём допускается меньше погрешностей (по факту всё происходит с точностью до бита). Ещё один из методов – проанализировать поток данных (bitstream), чтобы понять совместимость результата, но это не скажет вам ничего о качестве видео – хорошее оно или плохое. Несовместимый поток может выглядеть хорошо, а совместимый – плохо. Это может происходит в таких видео, где есть ошибки треккинга.
Ситуация усложняется ещё и тем, что хорошие декодеры (программные или аппаратные) могут быть плохи для кодирования. Это означает, что видео, где вы можете видеть какие-то визуальные артефакты могут появиться в VLC и не появиться в PowerDVD или WMP12. Нет универсального кодека, который мог бы быть лучшим во всём, поэтому всегда будут ошибки в изображении, в зависимости от транскодирования и работы декодирования/рендеринга для воспроизведения картинки. Поэтому даже если нашли проблему в кодировании и декодировании, как вы отличите плохое видео от хорошего видео? Аппаратное декодирование типа UVD или PureVideo корректирует ошибки на уровне промежуточного ПО в процессе работы (как память с ЕСС), поэтому даже если вы программист, пишущий ПО для кодирования, вам сложно будет понять, где возникают ошибки.
Естественно, вы можете отличить видео 360p от 1080p. Но сможете ли вы отличить плохую работу транскодирования на разрешении 480р от хорошей? Если у вас немного параметров для оценки качеств видео, то эта задача становится сложной. А что это значит для вашей семьи – мамы, дедушки или младшего брата? Как они могут понять, что полученное из простого для пользования транскодирования видео, это то, что они хотели увидеть?
По мнению экспертов, это основной вопрос всей видео-индустрии. Если у вас нет времени на подробное объяснение всех тонкостей ответа на него, то короткий ответ – вы можете сделать вывод, когда увидите очевидную ошибку. "Вы можете узнать ответ только когда посмотрите". Именно это и произошло с CUDA-кодированием в нашем обзоре платформы Brazos. Здесь не надо смотреть весь ролик, чтобы понять, что ситуация достаточно плоха.
Все это, конечно, можно отнести к мелким придиркам и обвинить автора в том, что он приводит примеры для увлекательного рассказа своей истории. Но если вы транскодировали большие объёмы видео, то знаете, что индустрия очень тщательно изучает все кодеки. На подробное изучение кодировщиков и декодировщиков тратятся тысячи долларов.
![]() |
![]() |
![]() |
В наших тестах мы обнаружили, что 3-5% транскодированного видео имеют очевидные ошибки. В кадрах, показанных чуть выше, ясно видны артефакты, которые можно описать как срыв изображения в WMP12. В этом можно обвинять процесс рендеринга, но это не всегда правильно. Для этого конкретного видео – это ошибка программного декодирования, поскольку артефакты появляются только при проигрывании в WMP12 с HD Graphics 3000.
![]() |
Аналогичная ошибка появляется и в видеотрейлере Up!, что свидетельствует о плохой работе транскодирования. Этот артефакт появляется во всех видео-плейерах, независимо от конфигурации оборудования.
Сжатие видео и декодирование | Внутри чёрного ящика
Итак, мы установили, что анализ качества видео – дело непростое, пока вы не рассматриваете конкретные ошибки. Но каким образом nVidia и AMD работают с транскодированием с использованием GPU? Более конкретно: как они берут последовательный процесс и превращают его в параллельный?
Многопоточное кодирование – процесс динамический. Когда программное кодирование оптимизировано для многоядерного процессора, каждый поток стремится кодировать конкретный кадр. Однако, весь процесс многопоточной работы контролирует операционная система. Это означает, что программист не может управлять тем, какой из потоков закончит свою работу первым и выделять ресурсы процессора в соответствии с этим. Например, первое ядро может завершить кодирование кадра 80, хотя второе и третье ядро ещё не завершили кодирование кадров 78 и 79. Поскольку для кадра 81 нет специального буфера, битрейт для следующих кадров меняется. Это необходимо делать, чтобы оптимизировать работу в нескольких потоках, иначе они будут ждать один другого и всё это будет очень похоже на работу одного ядра с одним потоком вычислений. Именно поэтому кадр попытка №1 транскодирования кадра 81 отличается от попытки №2.
Это один из путей программирования для многопоточного кодирования. Программисты используют и другие стратегии. Например, вы можете разделить вашу работу на срезы и иметь n срезов на кадр. Вы можете также приписать определённые части конвейера декодирования каждому потоку (например, поиск движений, кодирование макроблоков, кодирование энтропии, управление скоростью). У каждой стратегии есть свои преимущества и свои недостатки. Для адекватного масштабирования, особенно с системами, где есть много процессорных ядер, вы должны делить работу на кадры, поскольку для завершения работы каждой порции конвейера кодирования требуется разное время. В этом процессе можно выделить общую часть для всех кодировщиков – управление потоком данных, но она может быть связана с такими конкретными операциями, как поиск движений и их оценка.
Не только это отличает один кодировщик от другого. Этапы в конвейере кодировки могут не отличаться последовательностью, но весь процесс может. Такие операции, как поиск движений могут существенно различаться у разных кодировщиков. Можно говорить о стартовой точке, основанной на предыдущем кадре или на соседних макроблоках. Вот что говорит Майк Шмит, старший менеджер по работе с цифровым видео компании AMD: "Если вы обрабатываете много кадров (или макроблоков) одновременно, у вас нет возможности использовать predictor. Зная об этом, программисты могут форсировать работу последовательного пути без predictor, чтобы получить одинаковый результат. Этого не должно происходить в реальном коде, поскольку это более медленный вариант работы".
![]() |
![]() |
Все эти стратегии программирования привносят в транскодирование некий произвольный элемент, который может влиять на сравнение кодировщиков, особенно, если они работают на процессоре. Поэтому, даже если вы транскодируете данные с одним программным кодировщиком, вы можете получить видео разного качества.
![]() |
MediaConverter – единственное ПО из трёх, которое позволяет вам выбрать, сколько ядер вы хотите использовать для транскодирования. Если вы работаете на одном ядре, то будете каждый раз получать такой же файл. Это разумно, поскольку всё происходит последовательно. Кадр 81 зависит от кадра 80 находящегося в буфере.
Какое всё это имеет отношение к графическим процессорам? Очень большое. Мы как-то случайно провели тестирование дважды. Размер файла после GPGPU и аппаратного кодирования были одними и теми же, независимо от того, сколько раз мы его обрабатывали. Например, когда производится кодирование на базе Quick Sync и декодирование с помощью MediaConverter, Badaboom или MediaEspresso, мы каждый раз получим одинаковый размер файла. Почему же параллельный процесс ведёт себя, как последовательный?
Естественно, всегда есть вещи, которые выполняются последовательно, как сборка кодированных кадров. Но одинаковый размер файлов означает, что кадр №80 всегда кодируется одинаково. Это происходит и при однопоточном транскодировании. Что же там происходит?
Большинство экспертов, которых мы опрашивали, сказали, что хотя они контролируют поток данных, они не знают, что происходит между отсылкой кадра в референсную библиотеку и его возвратом оттуда, уже кодированным.
Очень трудно было найти ответы на эти вопросы, пока мы не обратились к Майку Шмиту, который руководит группой, занимающейся исследованиями в сфере видео-кодеков. Вот что он сказал: "Хотя всё, что связано с GPU, это параллелизм, процесс аналогичен одному ядру с инструкциями SSE… это 16-битные инструкции. По сути дела, один способ (не единственный способ) программировать шейдеры на GPU – программировать их, как будто внутри SSE есть тысяча инструкций SIMD. Таким образом детерминизм сохраняется и нет элемента случайности. В итоге всё зависит от программиста и от того, как он решает проблему".