最近在預研融屏/多畫面顯示,接觸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(nYIndex<RENDER_HEIGHT)
{
memcpy(pDstFrame->data[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(nUVIndex<RENDER_HEIGHT/2)
{
memcpy(pDstFrame->data[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