Я пытаюсь изменить тестовый шаблон стримера ffmpeg, Проблемы с синхронизацией libavformat / ffmpeg с x264 и RTP , в знакомый формат RGB. Моя более широкая цель — вычислять кадры потокового видео на лету.
Поэтому я заменил его AV_PIX_FMT_MONOWHITE
с AV_PIX_FMT_RGB24
«RGB 8: 8: 8, 24bpp, RGBRGB …» в соответствии с http://libav.org/doxygen/master/pixfmt_8h.html .
Заполнить его массив пикселей под названием data
Я перепробовал много вариантов
for (int y=0; y<HEIGHT; ++y) {
for (int x=0; x<WIDTH; ++x) {
uint8_t* rgb = data + ((y*WIDTH + x) *3);
const double i = x/double(WIDTH);
// const double j = y/double(HEIGHT);
rgb[0] = 255*i;
rgb[1] = 0;
rgb[2] = 255*(1-i);
}
}
В HEIGHT
ИксWIDTH
= 80×60, эта версия дает
, когда я ожидаю один сине-красный горизонтальный градиент.
640×480 дает тот же шаблон с 4 столбцами, но с гораздо большим количеством горизонтальных полос.
640×640, 160×160 и т. Д., Выход три столбцы, цианистый / пурпурный / желтоватый, с таким же типом горизонтальной полосатости.
Вертикальные градиенты ведут себя еще более странно.
Внешний вид не был затронут AV_PIX_FMT_RGBA
попытка (4 не 3 байта на пиксель, альфа = 255). Также не зависит от порта от C до C ++.
Аргумент srcStrides
перешел к sws_scale()
массив длины 1, содержащий один int HEIGHT
,
Доступ к каждому пикселю AVFrame задает тот же вопрос менее подробно, пока без ответа.
Стример издает одно предупреждение, которое, я сомневаюсь, влияет на внешний вид:
[rtp @ 0x269c0a0] Encoder did not produce proper pts, making some up.
Так. Как установить значение RGB пикселя в кадре для отправки в sws_scale () (а затем в x264_encoder_encode () и av_interleaved_write_frame ())?
использование avpicture_fill()
как описано в Кодирование скриншота в видео с использованием FFMPEG .
Вместо прохождения data
прямо к sws_scale()
, сделай это:
AVFrame* pic = avcodec_alloc_frame();
avpicture_fill((AVPicture *)pic, data, AV_PIX_FMT_RGB24, WIDTH, HEIGHT);
а затем заменить 2-й и 3-й аргументы sws_scale()
с
pic->data, pic->linesize,
Тогда указанные выше градиенты работают правильно при многих разрешениях.
Аргумент srcStrides, переданный в sws_scale (), является массивом длины 1, содержащим один int HEIGHT.
Страйд (АКА linesize) — расстояние в байтах между двумя строками. По разным причинам, связанным главным образом с оптимизацией, она часто больше, чем просто ширина в байтах, поэтому в конце каждой строки есть отступы.
В вашем случае, без каких-либо отступов, шаг должен быть шириной * 3.