Domanda

Sto lavorando su un sistema che invia un video compresso a un client da grafica 3D che vengono eseguiti nel server non appena vengono resi. Ho già il codice funzionante, ma sento che potrebbe essere molto più veloce (ed è già un collo di bottiglia nel sistema)

Ecco cosa sto facendo:

Prima afferro il framebuffer

glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer ); 
.

Allora capovolgo il fotografferbuffer, perché c'è un bug strano con SWSscale (che sto usando per la conversione dello spazio di colore) che sfoglia l'immagine verticalmente quando converti. Sto lanciando in anticipo, niente di speciale.

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;
}
.

Allora lo converto in 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);
.

Allora ho praticamente chiamare il codificatore X264. Sto già usando il preset di zerolatenzione.

int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, _inputPicture, &pic_out);
.

La mia ipotesi è che ci dovrebbe essere un modo più veloce per farlo. Catturando il telaio e convertendolo in YUV420P. Sarebbe bello convertirlo in YUV420P nella GPU e solo dopo averlo copiato per la memoria del sistema, e spero che ci sia un modo per fare la conversione del colore senza la necessità di capovolgere.

Se non c'è modo migliore, almeno questa domanda può aiutare qualcuno a cercare di farlo, per farlo allo stesso modo che ho fatto.

È stato utile?

Soluzione

In primo luogo, utilizzare Texture Async Leggi utilizzando PBOS.Hhere è Esempio Speeds UpsLa lettura utilizzando 2 pbos che funziona in modo asincrono senza bloccarsi della pipeline come Readpixels fa quando viene utilizzato direttamente. Nella mia app ho ottenuto un aumento dell'80% delle prestazioni quando è passato a PBOS. Inoltre, su alcune GPU GLGGETTEXIMAGE () funziona più velocemente di GLREEDPIXEL () quindi provalo.

Ma se vuoi davvero prendere la codifica del video al livello successivo, puoi farlo via CUDA usando Libreria NVIDIA Codec . Ho recentemente chiesto la stessa domanda in modo da Questa può essere utile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top