ffmpeg視頻拼接合成/多YUV拼接合成一個YUV

       最近在預研融屏/多畫面顯示,接觸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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章