Форум программистов, компьютерный форум, киберфорум
Программирование графики
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 22.02.2018
Сообщений: 25
1

Перевод изображения из AVFrame в массив RGBQUAD

02.05.2018, 13:02. Показов 3005. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Пишу программу для вывода видео на FFMpeg и столкнулся с следующей проблемой. При декодировании кадров видео я получаю кадры неопределённого формата в виде структур AVFrame. Поскольку вывод планируется в заранее созданное графическое окно, я хочу преобразовать каждый из этих кадров в массив RGBQUAD и вывести через DIBSection. Но как это сделать, используя стандартный набор библиотек FFMpeg?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AVPacket packet = {};
    
av_read_frame(pFormatCtx, &packet);
int frame_decoded = 0;
 
if (packet.stream_index == videoStreamIndex)
{
    AVFrame *frame = av_frame_alloc();
    AVPacket avpkt = {};
    av_init_packet(&avpkt);
    const AVPacket *p_avpkt = &avpkt;
    
    int gotPicture = 0;
    int videoFrameBytes = avcodec_decode_video2(pVideoCodecCtx, frame, &gotPicture, p_avpkt);
}
Вот так выглядит получение кадра. Разрешение видео и размеры окна для вывода нам на данный момент уже известны.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.05.2018, 13:02
Ответы с готовыми решениями:

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

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

Чтение RGBQUAD
Собственно такой функцией записал цвета с экрана в RGBQUAD Как к нему обращаться? И можно ли...

Подготовка AVFrame к записи
Доброго времени суток! Пишу видеоплеер на основе ffmpeg. Для вывода использую WinAPI, поэтому...

5
2707 / 862 / 325
Регистрация: 10.02.2018
Сообщений: 2,042
02.05.2018, 16:47 2
Формат данных, которые получаются после декодирования зависит от кодека. Разные кодеки заточены под работу с разными форматами пикселя. Для mpeg-ов это обычно планарные YUV (AV_PIX_FMT_YUV420P или AV_PIX_FMT_YUV422P). В общем случае для определения формата нужно смотреть значение AVCodecContext::pix_fmt или AVFrame::format.

То, что вы называете RGBQUAD в спецификации ffmpeg именуется не планарным RGB, возможно AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA или что-то подобное.

Вам нужно произвести конвертацию картинки из одного формата в другой. Для этих целей в ffmpeg есть функция sws_scale. Она занимается сразу двумя вещами: переводом формата пикселя и масштабированием. Если требуется только что-то одно, то всё равно нужно использовать её. Поищите примеры использования данной функции.
1
0 / 0 / 0
Регистрация: 22.02.2018
Сообщений: 25
02.05.2018, 18:20  [ТС] 3
Спасибо за интформацию про функцию sws_scale. Но всё равно встаёт вопрос: как выводить конвертированное изображение в графическое окно, если функция sws_scale сохраняет обработанное изображение в структуру AVFrame, а как получить из неё массив RGBQUAD - непонятно.
0
2707 / 862 / 325
Регистрация: 10.02.2018
Сообщений: 2,042
02.05.2018, 19:20 4
Лучший ответ Сообщение было отмечено Mad_Programmer как решение

Решение

Цитата Сообщение от Mad_Programmer Посмотреть сообщение
как получить из неё массив RGBQUAD - непонятно
А я не очень понимаю, что не понятно вам...
Если речь идёт о выводе средствами WinApi, то структура DIB секции аналогична структуре битов непланарной RGB картинки в ffmeg. Возможно, что единственное отличие будет в количестве байт для выравнивания строк.
Берёте буфер картинки из AVFrame и используете его как биты для отрисовки в функции SetDIBitsToDevice, например.
AVFrame::data[0] - буфер картинки, указатель на первый пиксель первой строки.
AVFrame::linesize[0] - размер строки в байтах с учётом выравнивания.
Кликните здесь для просмотра всего текста
Код
                              Width (pixels)
        |<--------------------------------------------------->|
        |                                                     |
        |    pixel 1        pixel 2                pixel W    |  align  |
        |<------------->|<------------->|     |<------------->|<------->|
        |               |               |     |               |         |
        +---+---+---+---+---+---+---+---+     +---+---+---+---+---------+-------
line 1  | R | G | B | A | R | G | B | A | ... | R | G | B | A |   ///   |      |
        +---+---+---+---+---+---+---+---+     +---+---+---+---+---------+      |
line 2  | R | G | B | A | R | G | B | A | ... | R | G | B | A |   ///   |      |
        +---+---+---+---+---+---+---+---+     +---+---+---+---+---------+      | Height (lines)
 ...                                                                           |
        +---+---+---+---+---+---+---+---+     +---+---+---+---+---------+      |
line H  | R | G | B | A | R | G | B | A | ... | R | G | B | A |   ///   |      |
        +---+---+---+---+---+---+---+---+     +---+---+---+---+---------+-------
        |                                                               |
        |                                                               |
        |                        linesize (bytes)                       |
        |<------------------------------------------------------------->|

PS
Про код из первого сообщения. Если это реальный код вашей программы, то он работать не будет. В функцию декомпресии должен подаваться реальный пакет с прочитанными данными (packet), а не пустой свежесозданный (p_avpkt).
0
0 / 0 / 0
Регистрация: 22.02.2018
Сообщений: 25
02.05.2018, 19:41  [ТС] 5
Цитата Сообщение от Ygg Посмотреть сообщение
Про код из первого сообщения. Если это реальный код вашей программы, то он работать не будет. В функцию декомпресии должен подаваться реальный пакет с прочитанными данными (packet), а не пустой свежесозданный (p_avpkt).
Спасибо за замечание, а то я не мог понять что у меня с кадром не так и почему sws_scale говорит, что неправильно заданы указатели на исходное изображение.
0
0 / 0 / 0
Регистрация: 22.02.2018
Сообщений: 25
05.05.2018, 21:13  [ТС] 6
Ну вот, получился такой код:
C++
1
2
3
4
5
6
7
8
AVFrame *pFrameRGB = av_frame_alloc();
int pictureSize = avpicture_get_size(PIX_FMT_RGBA, 1280, 720);
uint8_t *buffer = (uint8_t *)av_malloc(pictureSize * sizeof (uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGBA, 1280, 720);
SwsContext *pImgConvertCtx = sws_getContext(width, height, pVideoCodecCtx->pix_fmt, width, height, PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(pImgConvertCtx, frame->data, frame->linesize, 0, 720, pFrameRGB->data, pFrameRGB->linesize);
av_free(buffer);
int res3 = SetDIBitsToDevice(canvas, 0, 0, 1280, 720, 0, 720, 0, 720, (const void *)pFrameRGB->data[0], &info, DIB_RGB_COLORS);
Здесь: canvas - HDC, для которого выбрана DIB секция dib, info - BITMAPINFO с информацией о DIB секции.
0
05.05.2018, 21:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.05.2018, 21:13
Помогаю со студенческими работами здесь

Ffmpeg сохранить AVFrame в .bmp или .jpg
Контекст конвертирования создаю так: imgconvertCtx = sws_getCachedContext( imgconvertCtx, codecCtx...

Перевод изображения в монохромное
Добрый день. Имеется следующая задача: необходимо из одного пикчербокса (вебкамера) перенести...

Перевод изображения в текст
Привет всем! Помогите пожалуйста закодировать картинку в текст с возможностью раскодирования.

Перевод изображения в спектр
Написать программу для вычисления Преобразования Фурье для входного изображения. Вывести на экран...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru