2015-09-21 8 views
1

Я хочу как можно быстрее перенести данные фреймбуффа opengl в AVCodec.Каков наилучший способ для заполнения AVFrame.data

Я уже конвертированы RGB в YUV с шейдером и читать его с glReadPixels

мне еще нужно заполнить данные AVFrame вручную. Есть ли лучший способ?

AVFrame *frame; 
// Y 
frame->data[0][y*frame->linesize[0]+x] = data[i*3]; 
// U 
frame->data[1][y*frame->linesize[1]+x] = data[i*3+1]; 
// V 
frame->data[2][y*frame->linesize[2]+x] = data[i*3+2]; 
+0

Я думаю, что должно быть возможно считывать данные в PBO и сопоставлять их с адресным пространством клиента и ссылаться на этот адрес в структуре AVFrame. – derhass

+0

, но формат данных - массив YUV. Мне нужны отдельные массивы –

+0

Вы уже можете упорядочить данные по мере необходимости в шейдерах. Сначала это может показаться немного неинтуитивным, но это окончательно возможно. – derhass

ответ

0

Вы можете использовать sws_scale.

На самом деле вам не нужны шейдеры для преобразования RGB-> YUV. Поверьте мне, это не будет иметь совсем другое представление.

swsContext = sws_getContext(WIDTH, HEIGHT, AV_PIX_FMT_RGBA, WIDTH, HEIGHT, AV_PIX_FMT_YUV, SWS_BICUBIC, 0, 0, 0); 
sws_scale(swsContext, (const uint8_t * const *)sourcePictureRGB.data, sourcePictureRGB.linesize, 0, codecContext->height, destinyPictureYUV.data, destinyPictureYUV.linesize); 

Данные destinyPictureYUV будут готовы перейти к кодеку.

В этом примере, destinyPictureYUV - это AVFrame, который вы хотите заполнить. Попробуйте настроить так:

AVFrame * frame; 
AVPicture destinyPictureYUV; 

avpicture_alloc(&destinyPictureYUV, codecContext->pix_fmt, newCodecContext->width, newCodecContext->height); 

// THIS is what you want probably 
*reinterpret_cast<AVPicture *>(frame) = destinyPictureYUV; 

С помощью этой установки вы можете также заполнить вверх с данными вы уже преобразованы в YUV в ГПУ, если вы хотите ... вы можете выбрать, как вы хотите.

+0

Спасибо за легкое решение. но это повредит работе? –

+0

не на самом деле ... 'sws_scale'is сильно оптимизирован. проверьте последнее обновление, которое я написал ... setup destinyPictureYUV/frame [с актом, они то же самое], а затем попытайтесь заполнить YUV напрямую. сравнить производительность для обоих методов. Я думаю, это не будет так сильно. –

+0

Я считаю, что разница будет заметна в зависимости от размера вашего изображения. Помните, что на GPU у вас много ядер GPU против меньших ядер на процессоре. Однако 1 процессорное ядро ​​быстрее ядра GPU. Вот почему иногда 'sws_scale' может быть быстрее, чем GPU. Для ОЧЕНЬ БОЛЬШИХ изображений, может быть, графический процессор будет делать разницу и быть быстрее .. но это просто ставка, я никогда не делал точного эталона. –