国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

利用ffmpeg+opencv實(shí)現(xiàn)畫(huà)中畫(huà)

2019-11-09 15:55:20
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

轉(zhuǎn)自:http://blog.csdn.net/dzhuang123/article/details/45054497

需求:把兩路視頻合成一路,即一個(gè)畫(huà)面同時(shí)顯示兩路視頻,其中一路縮小成小視頻疊在大視頻上面,和電視機(jī)的畫(huà)中畫(huà)效果類(lèi)似。

思路:用h264編碼的視頻舉例,文件中存儲(chǔ)的es流是h264,經(jīng)過(guò)解碼成yuv,yuv可以轉(zhuǎn)換成rgb格式。把小視頻的rgb復(fù)制到大視頻需要被覆蓋的位置上。將重新合成的rgb轉(zhuǎn)換成yuv,利用ffmpeg 或 x264重新編碼出新的視頻即可。

方法:編解碼還是利用ffmpeg 。 ffmpeg 解碼兩路視頻,解碼后都是yuv。利用ffmpeg· 的sws_getContext 函數(shù)改變小圖的大小。之后利用OpenCV完成兩個(gè)圖片的合成(opencv這種高大上的庫(kù)被我用成了這樣····實(shí)在汗顏。其實(shí)此處的合并rgb可以自己寫(xiě)算法實(shí)現(xiàn),本質(zhì)是把小圖的rgb復(fù)制到大圖的對(duì)應(yīng)位置上。)合成好后將rbg轉(zhuǎn)成yuv格式,利用x264重新編碼成h264 ,就看到了大視頻左上角有個(gè)小視頻了。

代碼思路:

兩個(gè)線程,各自解碼,主視頻的線程解碼一幀后通知副視頻的線程進(jìn)行解碼并轉(zhuǎn)化圖片大小,副視頻的線程解碼完成后通知主線程合成視頻并編碼。合成視頻的時(shí)候用opencv很簡(jiǎn)單,直接把yuv轉(zhuǎn)化成rgb,之后在主視頻上設(shè)置敏感區(qū),把小視頻疊加上就行。

主副線程解碼套路一樣,ffmpeg的基本使用套路。把yuv轉(zhuǎn)成opencv mat類(lèi)型的rgb套路也一樣,上副視頻解碼線程的代碼進(jìn)行說(shuō)明。

全局變量:

[cpp] view plain copycv::Mat littlergb,bigrgb;//大小視頻的rgb  cv::Mat littleframe,bigframe;//大小視頻的yuv  

副視頻解碼線程內(nèi)的代碼:

[cpp] view plain copywhile(av_read_frame(pInputFormatContext, &InPack) >=0)      {          len = avcodec_decode_video2(pInputCodecContext, &OutFrame, &nComplete, &InPack);//解碼視頻          if (nComplete>0)          {                 if (GetMessage(&msg, NULL, 0, 0))              {                  switch(msg.message)                  {                  case MY_MSG_DECODE:                      sws_scale(m_pSwsContext,OutFrame.data,OutFrame.linesize, 0,OutFrame.height,dst->data,dst->linesize);//轉(zhuǎn)換圖片大小                        memcpy(littleframe.data,dst->data[0], 640*480);  //以下將ffmpeg的yuv數(shù)據(jù)存到opencv的mat類(lèi)型中。即opencv存儲(chǔ)的yuv數(shù)據(jù)                      memcpy(littleframe.data+640*480,dst->data[1], 640*480/4);                        memcpy(littleframe.data+640*480*5/4,dst->data[2], 640*480/4);                       SetEvent(hEncodeEvent);                        break;                  }              }            }          av_free_packet(&InPack);      }  

合并圖片直接用opencv,代碼如下:

[cpp] view plain copycv::cvtColor(littleframe, littlergb,CV_YUV2BGR_I420);   cv::cvtColor(bigframe, bigrgb,CV_YUV2BGR_I420); //以上yuv轉(zhuǎn)rgb  Mat roi(bigrgb,Rect(0,0,640,480));//大圖上設(shè)置敏感區(qū)  littlergb.copyTo(roi);  //把小圖拷貝過(guò)去  Mat outframe;  cv::cvtColor(bigrgb, outframe,CV_BGR2YUV_I420); //rgb到y(tǒng)uv  

這樣就獲得了合并后的圖片的yuv。

之后進(jìn)行編碼即可。編碼出來(lái)的視頻就是畫(huà)中畫(huà)了。

點(diǎn)擊打開(kāi)鏈接  (樓主源碼鏈接失效了)

這個(gè)代碼,缺了dll和lib還有頭文件,空間不夠傳不上····


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 两当县| 武安市| 东平县| 南昌市| 开鲁县| 东方市| 邓州市| 吉林市| 清涧县| 日喀则市| 衡水市| 九龙城区| 贵州省| 德安县| 巍山| 临武县| 吉首市| 静安区| 德阳市| 古浪县| 县级市| 大悟县| 新绛县| 比如县| 通城县| 葫芦岛市| 习水县| 新平| 巫山县| 民丰县| 门头沟区| 滦平县| 自治县| 安塞县| 蒲城县| 峨眉山市| 紫金县| 娱乐| 胶州市| 常德市| 清新县|