OpenGLおよびX264を使用したリアルタイム3Dグラフィックの高速エンコード
-
13-12-2019 - |
質問
私は、レンダリングされるとすぐに、サーバーで行われる3Dグラフィックからクライアントに圧縮されたビデオを送信するシステムに取り組んでいます。 私はすでにコードが働いていますが、私はそれがそれほど速くなる可能性があると感じます(そしてそれはすでにシステムのボトルネックです)
これは私がしていることです:
最初にフレームバッファ
をつかむglReadBuffer( GL_FRONT );
glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer );
.
それから私は、変換したときに画像を垂直に反転させるSWSSCALE(ColorSpace変換を使用している)の奇妙なバグがあるため、フレームバッファをやめてください。私は事前にひっくり返っています、何も派手です。
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エンコーダを呼び出すだけです。私はすでに潜在性プリセットを使用しています。
int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, _inputPicture, &pic_out);
.
私の推測はこれを行うためのより速い方法があるべきだということです。フレームをキャプチャし、それをYUV420Pに変換します。 GPUのYUV420Pに変換するのは、システムメモリにコピーした後に初めて、そしてうまくいけば、フリップする必要なしに色変換を行う方法があることがうれしいです。
より良い方法がない場合、少なくともこの質問は、私がしたのと同じ方法でこれをやろうとしている誰かがそれをするのを助けるかもしれません。
解決
最初に、Pbos.hereを使用して読み取るASYNCテクスチャを使用してください例スピードアップReadPixelsのようなパイプラインを失速させずに非同期的に機能する2 PBOを使用することで、PBOに切り替えたときに80%のパフォーマンスが得られました。 さらに、いくつかのGPUS GlgetTexImage()ではGlreadPixels()より速く機能します。そのため、試してみてください。
しかし、あなたが本当にビデオエンコーディングを次のレベルに取りたいのなら、 NVIDIAコーデックライブラリ .i最近、同じ質問をしたので、このは役立ちます。