Как заставить avcodec использовать невыровненные плоскости данных кадра?

Я долго искал возможность заставить avcodec использовать невыровненную память для своих данных AVFrame.

В зависимости от формата пикселя горизонтальные плоскости данных AVFrame-> могут быть дополнены дополнительными данными для выравнивания в памяти для повышения производительности.

например: видео 1920 * 1080 с 4 байтами на пиксель будет иметь 1920 * 4 = 7680 байтов на плоскость.

С avcodec, если вы декодируете это видео, оно создаст 7808 байт на плоскость.

Это добавляет 7808 - 7680 = 128 байт дополнительного заполнения.

Для моих целей я хотел бы заставить avcodec использовать невыровненные данные, чтобы я мог копировать весь непрерывный фрагмент данных кадра вместо того, чтобы копировать и форматировать более мелкие фрагменты по одному в непрерывный фрагмент.

В заголовках обнаружен следующий флаг:

/* encoding support
   These flags can be passed in AVCodecContext.flags before initialization.
   Note: Not everything is supported yet.
*/

/**
 * Allow decoders to produce frames with data planes that are not aligned
 * to CPU requirements (e.g. due to cropping).
 */
#define CODEC_FLAG_UNALIGNED 0x0001

Если установить для этого AVCodecContext.flags значение CODEC_FLAG_UNALIGNED, предполагается, что данные AVFrame-> теперь не выровнены, это не так.

Я не уверен, что смотрю в нужное место или правильно использую этот флаг.

С уважением,

Любопытный Джордж


person user3244284    schedule 28.01.2014    source источник
comment
у кодеков есть много причин выбирать шаг длиннее ширины, ограничения ЦП являются лишь одной из его частей.   -  person Alex Cohn    schedule 28.01.2014
comment
Примечание. Пока не все поддерживается. Вы уверены, что флаг поддерживается?   -  person Philip Pittle    schedule 29.01.2014


Ответы (2)


Важная вещь с ffmpeg — всегда проверять, что все действительно заботится об определенной опции. Не похоже, что многие кодеки на самом деле используют этот флаг:

~/sources/ffmpeg-2.1.1> find libavcodec/ -name \*.c | xargs grep CODEC_FLAG_UNALIGNED
libavcodec/hevc_ps.c:        !(s->avctx->flags & CODEC_FLAG_UNALIGNED)) {
libavcodec/h264_ps.c:                !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) {
~/sources/ffmpeg-2.1.1>
person George Y.    schedule 29.01.2014
comment
Вы правы, этот флаг используется очень редко, что отвечает на вопрос, что я неправильно использую этот флаг для своей цели. Единственный вопрос сейчас в том, какой ФЛАГ/Опция/Настройка это - person user3244284; 29.01.2014
comment
Вы можете спросить в списке рассылки ffmpeg, но я думаю, что такого флага нет. Обратите внимание, что даже исходное описание позволяет, но не требует, чтобы декодер создавал невыровненные кадры. - person George Y.; 29.01.2014

После декодирования вы можете использовать swrescale для форматирования пикселей в предоставленный вами буфер памяти. Просто установите одинаковое разрешение ввода и вывода, выделите кусок памяти и установите шаг строки равным ширине кадра.

person szatmary    schedule 28.01.2014
comment
Действительно, это один из обходных путей, к сожалению, в моем случае с видео в формате Full HD это swsrescale добавляет 3-4 миллисекунды накладных расходов, что прискорбно, я пытаюсь пропустить это - person user3244284; 29.01.2014
comment
Декодеры просто не делают то, что вы просите. Вы не можете получить что-то просто так. Он записывает в выровненную память, потому что доступ к выровненной памяти самый быстрый. поэтому, даже если бы это сделал декодер, эти 3 мс просто были бы потрачены в декодере, а не в swscale. - person szatmary; 29.01.2014