Pergunta

Eu estou trabalhando em um sistema que envia um vídeo compactado para um cliente de gráficos 3d que são feitas no servidor, assim como eles são processados.Eu já tenho o código de trabalho, mas eu sinto que poderia ser muito mais rápido (e ele já é um gargalo do sistema)

Aqui está o que eu estou fazendo:

Primeiro eu pegar o framebuffer

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

Então eu virar o framebuffer, porque não é um estranho bug com swsScale (que eu estou usando para conversão de espaço de cores) que inverte a imagem verticalmente, quando eu converter.Estou lançando antecipadamente, nada de fantasia.

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

Então eu convertê-lo para 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);

Então eu praticamente só chamar o encoder x264.Eu já estou usando o zerolatency preset.

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

Meu palpite é de que deve haver uma maneira mais rápida para fazer isso.A captura de quadro e convertê-lo para YUV420p.Seria bom para convertê-lo para YUV420p na GPU, e só depois de copiar para a memória do sistema, e espero que existe uma forma de fazer a conversão de cores, sem a necessidade de se inverter.

Se não há maneira melhor, pelo menos esta pergunta pode ajudar alguém tentar fazer isso, fazê-lo da mesma maneira que eu.

Foi útil?

Solução

Primeiro , use assíncrono textura de leitura usando PBOs.Aqui é exemplo Ele acelera a ups a ler usando 2 PBOs que funcionam de forma assíncrona, sem barrar o pipeline como readPixels faz quando usado diretamente.Na minha aplicação eu tenho 80% de aumento de performance quando mudou para PBOs.Além disso , em algumas GPUs glGetTexImage() funciona mais rápido que o glReadPixels() para experimentá-lo.

Mas se você realmente quiser fazer a codificação de vídeo para o próximo nível, você pode fazê-lo através do CUDA utilizando Nvidia Biblioteca De Codec.Eu recentemente fez a mesma pergunta para este pode ser útil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top