M
muaddib1981
Требуется перевести буфер из одного формата в другой по определенной формуле с плавающей точкой, а именно из формата yuyv в формат rgb24 (если это что-то кому то скажет).
Хотел сократить расчеты записав все значения в массив и просто беря оттуда нужные значения.
Но оказывается что каждый раз считать получается быстрее, вопрос почему?
Компилятор gcc.
Привожу тестовый код программы, непосредственный расчет ведется со скоростью 18 циклов/сек, если брать рассчитанные значения из массива - 6 циклов/сек.
Исходный буфер pbuffer заполняю случайными значения от 0 до 255. Если буфер заполнять константами, то скорость большая, но думаю это из-за оптимизации.
Хотел сократить расчеты записав все значения в массив и просто беря оттуда нужные значения.
Но оказывается что каждый раз считать получается быстрее, вопрос почему?
Компилятор gcc.
Привожу тестовый код программы, непосредственный расчет ведется со скоростью 18 циклов/сек, если брать рассчитанные значения из массива - 6 циклов/сек.
Исходный буфер pbuffer заполняю случайными значения от 0 до 255. Если буфер заполнять константами, то скорость большая, но думаю это из-за оптимизации.
C++:
#include <iostream>
#include <time.h>
#include <cstdlib>
using namespace std;
#define rgb_ptr unsigned char*
static const int BPP_YUY2 = 2;
static const int BPP_YUY2_PIXEL = 4;
static const int BPP_RGB24 = 3;
unsigned char tableR[256][256][256];
unsigned char tableG[256][256][256];
unsigned char tableB[256][256][256];
inline char clip(int x){
if (x>255)
return 255;
if (x<0)
return 0;
return x;
}
void yuv2rgb(unsigned char y, unsigned char u, unsigned char v, unsigned char *r, unsigned char *g, unsigned char *b)
{
float C = y - 16;
float D = u - 128;
float E = v - 128;
*r = clip(C + ( 1.402 * E ));
*g = clip(C - ( 0.344136 * D + 0.714136 * E ));
*b = clip(C + ( 1.772 * D ));
}
void fillTables(void)
{
int i,j,k;
for (i=0;i<256;i++)
{
for (j=0;j<256;j++)
for (k=0;k<256;k++)
yuv2rgb(i,j,k,&tableR[i][j][k],&tableG[i][j][k],&tableB[i][j][k]);
}
}
void getTables(unsigned char y, unsigned char u, unsigned char v, unsigned char *r, unsigned char *g, unsigned char *b)
{
*r = tableR[y][u][v];
*g = tableG[y][u][v];
*b = tableB[y][u][v];
}
void yuyv_to_rgb(rgb_ptr buffer_yuyv, rgb_ptr buffer_rgb, int width, int height)
{
rgb_ptr pixel_16; // for YUYV
rgb_ptr pixel_24;// for RGB
int y0, u0, v0, y1;
unsigned char r, g, b;
unsigned char r1,g1,b1;
if ( buffer_yuyv == NULL || buffer_rgb == NULL)
return;
pixel_16 = buffer_yuyv;//width * height * 2
pixel_24 = buffer_rgb;//width * height * 3
int i = 0, j = 0;
// while ((i + 2) < height * width * 2)
for (i=0;i < (height * width * 2 -2);i=i+BPP_YUY2_PIXEL)
{
y0 = pixel_16[i];
u0 = pixel_16[i+1];
y1 = pixel_16[i+2];
v0 = pixel_16[i+3];
//yuv2rgb(y0, u0, v0, &r, &g, &b);
getTables(y0, u0, v0, &r, &g, &b); // 1st pixel
pixel_24[j] = r;
pixel_24[j + 1] = g;
pixel_24[j + 2] = b;
//yuv2rgb(y1, u0, v0, &r1, &g1, &b1);
getTables(y1, u0, v0, &r1, &g1, &b1);// 2nd pixel
pixel_24[j+BPP_RGB24] = r1;
pixel_24[j + 1 + BPP_RGB24] = g1;
pixel_24[j + 2 + BPP_RGB24] = b1;
j+=BPP_RGB24;
j+=BPP_RGB24;
//i += BPP_YUY2_PIXEL;
}
}
int main()
{
timespec t1;
timespec t2;
double t;
const int ncycles=100;
unsigned char *pdata = new unsigned char[1024*768*2]; //yuv
unsigned char *data = new unsigned char[1024*768*3]; //rgb24
int i;
srand(time(NULL));
fillTables();
for (i=0;i<1024*768*2;i++)
pdata[i] = rand() % 255;
//for (i=0;i<1024*768*2;i++)
// pdata[i] = i%255;
clock_gettime(1,&t1);
for (i=0;i<ncycles;i++)
{
yuyv_to_rgb(pdata,data,1024,768);
cout<<"#"<<i<<" ";
cout.flush();
}
clock_gettime(1,&t2);
t= (t2.tv_sec-t1.tv_sec)+(t2.tv_nsec-t1.tv_nsec)/1000000000.0; //складываем секунды и наносекунды
cout<<"\nTime: "<<t<< "secs\n";
cout<<"Cycles per sec: "<<ncycles/t<<"\n";
delete pdata;
delete data;
return 0;
}