I am creating a basic application for recording screen activity using FFMPEG Library calls. My Program flow is as below - Fetch input data from framebuffer (in RGB format) --> Converting to YUV420 format and scaling to desirable resolution -> Encode the frame and Send to Muxer for MPEG2 convesrion.
Input data to my program is raw frambuffer data in RGB Format. I am using FFMPEG's sws_scale api for converting RGB to YUV420 image for encoding. Below is the code for converting the pixel format-
static int get_frame_buffer_data(AVFrame *pict, int frame_index, int width,
int height, enum AVPixelFormat pix_fmt, char *rawFrame)
{
struct SwsContext *sws_ctx = NULL;
int ret = 0;
rfbLog("[%s:%d]before conv_frame alloc:::pix_fmt = %d width = %d height = %d\n",__func__,__LINE__,pix_fmt,width,height);
//picture->data[0] = (uint8_t*)&frameBuffer[0];
picture->data[0] = (uint8_t*)&rawFrame[0];
sws_ctx = sws_getCachedContext(sws_ctx,picture->width, picture->height, picture->format,width, height, pix_fmt,SWS_BICUBIC, NU LL, NULL, NULL);
if (!sws_ctx)
{
rfbLog("[%s:%d]Cannot initialize the conversion context\n",__func__,__LINE__);
av_frame_free(&picture);
sws_freeContext(sws_ctx);
return -1;
}
rfbLog("[%s:%d]before sws_scale::: picture->linesize[0]=%d picture->height=%d pict->linesize = %d\n",__func__,__LINE__,picture ->linesize[0],picture->height,pict->linesize[0]);
ret = sws_scale(sws_ctx, (const uint8_t * const *)picture->data, picture->linesize, 0, picture->height, pict->data, pict->line size);
rfbLog("[%s:%d]after sws_scale::: picture->linesize[0]=%d picture->height=%d pict->linesize = %d returned height = %d\n",__fun c__,__LINE__, picture->linesize[0],picture->height,pict->linesize[0], ret);
if (ret < 0)
{
rfbLog("[%s:%d]could not convert to yuv420\n",__func__,__LINE__);
sws_freeContext(sws_ctx);
av_frame_free(&picture);
return -1;
}
sws_freeContext(sws_ctx);
return 0;
}
I noticed that adding this code is making the application very slow. Profiling data gave me the information that sws_scale is taking very much time for converting the data to YUV420 . It is taking almost around 200 ms, which is making CPU time utilization very high and making my application unresponsive sometime.
Can we optimize this or use any alternative solution for conversion and how can we achieve that?