我正在处理一个系统,该系统会在服务器端渲染3D图形,并将压缩后的视频发送给客户端。我已经编写了可行的代码,但是我感觉它可以更快(因为它已经成为系统的瓶颈)。
以下是我的操作步骤:
首先,我获取帧缓冲区。
我的猜测是,应该有一种更快的方法来做这件事。捕获帧并将其转换为YUV420p。最好在GPU中将其转换为YUV420p,然后再将其复制到系统内存中,希望有一种不需要翻转即可进行颜色转换的方法。
如果没有更好的方法,至少这个问题可以帮助那些试图以我所做的方式进行操作的人。
以下是我的操作步骤:
首先,我获取帧缓冲区。
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer );
然后我翻转帧缓冲,因为在使用 swsScale 进行色彩空间转换时遇到了一个奇怪的 bug,它会在转换图像时垂直翻转。我提前进行翻转,没有任何花哨的操作。
void VerticalFlip(int width, int height, byte* pixelData, int bitsPerPixel)
{
byte* temp = new byte[width*bitsPerPixel];
height--; //remember height array ends at height-1
for (int y = 0; y < (height+1)/2; y++)
{
memcpy(temp,&pixelData[y*width*bitsPerPixel],width*bitsPerPixel);
memcpy(&pixelData[y*width*bitsPerPixel],&pixelData[(height-y)*width*bitsPerPixel],width*bitsPerPixel);
memcpy(&pixelData[(height-y)*width*bitsPerPixel],temp,width*bitsPerPixel);
}
delete[] temp;
}
然后我将其转换为YUV420p格式。
convertCtx = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
uint8_t *src[3]= {buffer, NULL, NULL};
sws_scale(convertCtx, src, &srcstride, 0, height, pic_in.img.plane, pic_in.img.i_stride);
然后我基本上只是调用了x264编码器。我已经使用了zerolatency预设。
int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, _inputPicture, &pic_out);
我的猜测是,应该有一种更快的方法来做这件事。捕获帧并将其转换为YUV420p。最好在GPU中将其转换为YUV420p,然后再将其复制到系统内存中,希望有一种不需要翻转即可进行颜色转换的方法。
如果没有更好的方法,至少这个问题可以帮助那些试图以我所做的方式进行操作的人。