Корректные значения RGB для AVFrame

#ffmpeg #rgb #cairo #libav #libavcodec

#ffmpeg #rgb #каир #libav #libavcodec

Вопрос:

Я должен заполнить ffmpeg AVFrame-> данные из данных пикселя поверхности cairo. У меня есть этот код:

 /* Image info and pixel data */
width  = cairo_image_surface_get_width( surface );
height = cairo_image_surface_get_height( surface );
stride = cairo_image_surface_get_stride( surface );
pix    = cairo_image_surface_get_data( surface );

for( row = 0; row < height; row   )
{
    data = pix   row * stride;
    for( col = 0; col < width; col   )
    {
        img->video_frame->data[0][row * img->video_frame->linesize[0]   col] = data[0];
        img->video_frame->data[1][row * img->video_frame->linesize[1]   col] = data[1];
        //img->video_frame->data[2][row * img->video_frame->linesize[2]   col] = data[2];
        data  = 4;
    }
    img->video_frame->pts  ;
}
 

Но цвета в экспортированном видео неправильные. Исходное сердце красного цвета. Может кто-нибудь указать мне правильное направление? К сожалению, пример encode.c бесполезен, и в Интернете много путаницы в отношении Y, Cr и Cb, которые я действительно не понимаю. Пожалуйста, не стесняйтесь запрашивать более подробную информацию. Большое спасибо.

неправильные значения RGB

Комментарии:

1. Не могли бы вы опубликовать полный пример кода — что-то, что мы можем скомпилировать и выполнить? Возможно, вам придется проявить творческий подход — рассмотрите возможность размещения входного изображения размером 8×8 в виде массива C (инициализированного кодом). Можете ли вы описать расположение данных pix (является ли это основным RGBA строки с width , height и stride )? В какой части используется формат пикселей YCbCr?

2. Большое спасибо за ответ. Я действительно ценю. Код является частью графического интерфейса GTK3, который превращает серию изображений в фильм. Это проект, который я разрабатываю с 2009 года. К сожалению, я не могу предоставить фрагмент кода, но программное обеспечение с открытым исходным кодом. Поверхность cairo — RGB24. Контекст AV создается как AV_PIX_FMT_YUV420P, потому что, если я использую AV_PIX_FMT_RGB24, я получаю сообщение об ошибке во время завершения: «Ширина ввода больше шага». Надеюсь, это поможет, пожалуйста, не стесняйтесь запрашивать дополнительную информацию.

3. Мое текущее понимание YCbCr заключается в том, что он состоит из яркости / красного / синего, где яркость — это яркость, а красный и синий — это значения цветности с информацией о красном / зеленом и синем / зеленом соответственно. Это работает путем объединения черно-белого изображения с двумя каналами цветности

Ответ №1:

Необходимо использовать libswscale для преобразования исходных данных изображения из RGB24 YUV420P в.

Что-то вроде:

 int width  = cairo_image_surface_get_width( surface );
int height = cairo_image_surface_get_height( surface );
int stride = cairo_image_surface_get_stride( surface );
uint8_t *pix = cairo_image_surface_get_data( surface );

uint8_t *data[1] = { pix };
int linesize[1]  = { stride };

struct SwsContext *sws_ctx = sws_getContext(width, height, AV_PIX_FMT_RGB24 ,
                                            width, height, AV_PIX_FMT_YUV420P,
                                            SWS_BILINEAR, NULL, NULL, NULL);

sws_scale(sws_ctx, data, linesize, 0, height, 
          img->video_frame->data, img->video_frame->linesize);

sws_freeContext(sws_ctx);
 

Смотрите пример здесь: scaling_video

Комментарии:

1. Спасибо за ваш ответ. Я также использовал sws_scale, ошибок во время кодирования не было, но видео даже не воспроизводилось, а VLC показывает кучу этих бесполезных сообщений в окне терминала: [h264 @ 0x7f1508c82700] совместно расположенные POCs недоступны [h264 @ 0x7f1508c9f400] mmco: короткий сбой unref [h264 @ 0x7f1508cd8f80] совместно расположенные POCs недоступныпример не помог, поскольку он конвертируется ИЗ YUV420P, но спасибо, я оценил это. Если вы хотите узнать больше, я могу внести изменения на сервер SVN, и вы можете посмотреть, это хороший графический интерфейс и хорошее программное обеспечение, просто, к сожалению, недооцененное.

2. @GiuTor Не могли бы вы сбросить образец изображения cairo в файл где-нибудь и опубликовать формат, ширину и высоту?

3. корректен ли этот код для сброса изображения: /* Информация об изображении и пиксельные данные */ width = cairo_image_surface_get_width(поверхность); height = cairo_image_surface_get_height(поверхность); stride = cairo_image_surface_get_stride(поверхность); pix = cairo_image_surface_get_data(поверхность); FILE * fp = fopen(«cairo_image.raw» , «w»); fwrite (pix, 4 *width, sizeof(pix), fp); fclose(fp);