Декодирование в определенный формат пикселей в ffmpeg с помощью С++

Мне нужно декодировать видео, но мой видеоплеер поддерживает только формат пикселей RGB8. Поэтому я изучаю, как сделать преобразование формата пикселей в графическом процессоре, желательно в процессе декодирования, но если это невозможно, то после него.

Я нашел Как установить формат пикселя декодирования в libavcodec?, в котором объясняется, как декодировать видео на ffmpeg в определенный формат пикселей, если он поддерживается кодеком.

По сути, get_format() — это функция, которая выбирает из списка поддерживаемых кодеком форматов пикселей формат пикселей для декодированного видео. Мои вопросы:

  1. Одинаков ли этот список поддерживаемых выходных форматов кодеков для всех компьютеров? Например, если мой кодек для H264, то он всегда будет выдавать мне один и тот же список на всех компьютерах? (при условии одинаковой версии ffmpeg для всех компьютеров)
  2. Если я выберу любой из этих поддерживаемых форматов пикселей, всегда ли будет происходить преобразование формата пикселей в графическом процессоре?
  3. Если некоторые преобразования формата пикселей не будут происходить в графическом процессоре, то мой вопрос: преобразует ли функция sws_scale() в графическом или центральном процессоре?
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
2 015
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Это зависит. Во-первых, H264 — это просто стандарт кодека. Хотя libx264 или openh264 реализуют этот стандарт, вы можете догадаться, что каждая реализация поддерживает разные форматы. Но давайте предположим (как вы сделали в своем вопросе), что вы используете одну и ту же реализацию на разных машинах, тогда да, могут быть случаи, когда разные машины поддерживают разные форматы. Возьмем, к примеру, H264_AMF. Для использования кодека вам понадобится видеокарта AMD, а поддерживаемые форматы также будут зависеть от вашей видеокарты.
  2. Декодирование обычно происходит на вашем процессоре, если вы явно не укажете аппаратный декодер. См. этот пример аппаратного декодирования: https://github.com/FFmpeg/FFmpeg/blob/release/4.1/doc/examples/hw_decode.c
    При использовании аппаратного декодирования вы сильно полагаетесь на свой компьютер. И каждый аппаратный кодировщик будет выводить свой собственный (собственный) формат кадра, например. NV12 для видеокарты Nvida. Теперь самое сложное. Закодированные кадры останутся в памяти вашего графического процессора, что означает, что вы можете повторно использовать буфер avframe для преобразования пикселей с помощью OpenCL/GL. Но добиться нулевого копирования GPU при работе с разными фреймворками не так просто, и у меня недостаточно знаний, чтобы помочь вам в этом. Итак, что я бы сделал, так это загрузил декодированный кадр из графического процессора через av_hwframe_transfer_data, как в примере. С этого момента не имеет большого значения, использовали ли вы аппаратное или программное декодирование.
  3. Насколько мне известно, sws_scale не использует аппаратное ускорение. Поскольку он не принимает «hwframes». Если вы хотите выполнить преобразование цвета на аппаратном уровне, вы можете взглянуть на OpenCV, вы можете использовать GPUMat там, затем загрузить свой кадр, вызвать cvtColor и загрузить его снова.

Некоторые общие замечания:
Почти любое масштабирование операций с изображениями и т. д. выполняется быстрее на вашем графическом процессоре, но загрузка и выгрузка данных может занять целую вечность. Для одиночных операций часто не стоит использовать ваш GPU.
В вашем случае я бы попытался сначала поработать с декодированием процессора и преобразованием цвета процессора. Просто убедитесь, что вы используете многопоточные и векторизованные алгоритмы, такие как OpenCV или Intel IPP. Если вам все еще не хватает производительности, вы можете подумать об аппаратном ускорении.

Я слышал, что команда Jetson Nano из NVIDIA собирается поддерживать аппаратное декодирование с помощью ffmpeg. Так как это плата ARM с очень мощным графическим процессором (который может декодировать 8 одновременных потоков 1080p), но с очень ограниченным процессором, я даже не хочу пытаться конвертировать цвета процессора, я уверен, что буду использовать его. Преобразование цветов GPU и, возможно, отсутствие копирования памяти. Я пишу сетевой видеорегистратор, поэтому мне нужно иметь максимальную производительность, потому что будет много одновременного декодирования потоков. Я собираюсь поискать информацию о преобразовании цветов графического процессора, большое спасибо!

PPP 26.07.2019 16:05

Другие вопросы по теме