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

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

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

Например: видео 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-> теперь не выровнены, это не так.

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

С Уважением,

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

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>
0

Другие решения

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

1