最近在预研融屏/多画面显示,接触ffmpeg比较多,首先想到的是将多YUV合成一个YUV,然后再渲染显示,立马动手起来。
首先,先从简单的来,选取两个YUV,分辨率分别为480*272、352*288,然后合成目标702*288的YUV,这样是考虑多画面时有不一致的分辨率,把它们弄成统一的分辨率再合成,YUV的格式都是YUV420P采样格式,统一分辨率是352*288。
第二,裁减YUV,利用到ffmpeg的sws_scale函数去裁减,先初始化SwsContext
/*
in_w --- 源分辨率的宽, in_h ---- 源分辨率的高
frame_msg->width/height --- 需要裁减成的分辨率
SWS_BICUBLIN --- 裁减时使用的算法
*/
code_msg->pSwsCtx = sws_getContext(in_w, in_h, AV_PIX_FMT_YUV420P,
frame_msg->width, frame_msg->height, AV_PIX_FMT_YUV420P,
SWS_BICUBLIN, NULL, NULL, NULL);
然后进行裁减
/*
code_msg->pFrame->data --- 源YUV
code_msg->pCodecCtx->height --- 源YUV的高
code_msg->pSwsframe->data --- 裁减后的YUV
*/
ret = sws_scale(code_msg->pSwsCtx, code_msg->pFrame->data, code_msg->pFrame->linesize, 0,
code_msg->pCodecCtx->height, code_msg->pSwsframe->data, code_msg->pSwsframe->linesize)
详细使用请参考: https://blog.csdn.net/weixin_33859844/article/details/90305179
第三,合成YUV,首先申请一个AVFrame来存储目标YUV,然后将两个YUV拷贝进这个目标容器就行了,拷贝时注意U、V分量,在Y420采样中,在水平和垂直清晰方面,Cb和Cr都是Y的一半,所以U、V分量在拷贝时各自拷贝一半即可。我是将两个YUV左右显示的。
/*
RENDER_HEIGHT --- 目标YUV的高
RENDER_WIDTH --- 目标YUV的宽
code_msg_01.pSwsframe --- 裁减后的YUV
code_msg_02.pFrame --- 第二个YUV
pDstFrame->data --- 目标YUV
*/
while(nYIndexdata[0] + nYIndex*RENDER_WIDTH, code_msg_01.pSwsframe->data[0]+nYIndex*RENDER_WIDTH/2, RENDER_WIDTH/2);
memcpy(pDstFrame->data[0] + nYIndex*RENDER_WIDTH+ RENDER_WIDTH/2, code_msg_02.pFrame->data[0]+nYIndex*RENDER_WIDTH/2, RENDER_WIDTH/2);
nYIndex++;
//Y420采样,在水平和垂直清晰方面,Cb和Cr都是Y的一半,所以U、V分量在拷贝时各自拷贝一半即可
if(nUVIndexdata[1] + nUVIndex*RENDER_WIDTH/2, code_msg_01.pSwsframe->data[1]+nUVIndex*code_msg_01.pSwsframe->width/2,code_msg_01.pSwsframe->width/2);
memcpy(pDstFrame->data[1] + nUVIndex*RENDER_WIDTH/2+ RENDER_WIDTH/4, code_msg_02.pFrame->data[1]+nUVIndex*RENDER_WIDTH/4, RENDER_WIDTH/4);
//U
memcpy(pDstFrame->data[2] + nUVIndex*RENDER_WIDTH/2, code_msg_01.pSwsframe->data[2]+nUVIndex*code_msg_01.pSwsframe->width/2, code_msg_01.pSwsframe->width/2);
memcpy(pDstFrame->data[2] + nUVIndex*RENDER_WIDTH/2+ RENDER_WIDTH/4, code_msg_02.pFrame->data[2]+nUVIndex*RENDER_WIDTH/4, RENDER_WIDTH/4);
nUVIndex++;
}
}
最后,效果图如下:
测试使用的代码请参考: //download.csdn.net/download/karongsmile/12242104