OpenGL ES實(shí)踐教程(四)VR全景視頻播放

教程

OpenGL ES實(shí)踐教程1-Demo01-AVPlayer
OpenGL ES實(shí)踐教程2-Demo02-攝像頭采集數(shù)據(jù)和渲染
OpenGL ES實(shí)踐教程3-Demo03-Mirror
其他教程請(qǐng)移步OpenGL ES文集,這一篇介紹以下知識(shí)點(diǎn):

  • AVFoundation——加載視頻;
  • CoreVideo——配置紋理;
  • OpenGL ES——渲染視頻;
  • 3D數(shù)學(xué)——球體以及3維變換;

核心思路

通過AVFoundation加載視頻源,讀取到每一幀的CMSampleBuffer之后,用CoreVideo創(chuàng)建OpenGL ES紋理緩存并上傳GPU;OpenGL ES按照球體的模型來渲染視頻;用移動(dòng)攝像機(jī)朝向或者旋轉(zhuǎn)球體的方式來響應(yīng)手指的移動(dòng)達(dá)到移動(dòng)鏡頭的效果。

效果展示

具體細(xì)節(jié)

1、配置OpenGL ES;

  • loadShaders加載著色器和compileShader編譯著色器的內(nèi)容前面的教程已經(jīng)介紹過都次,不再贅述;
  • setupBuffers配置緩存信息,并且創(chuàng)建頂點(diǎn)數(shù)據(jù)緩存,把球體的頂點(diǎn)和紋理數(shù)據(jù)先上傳GPU;

因?yàn)槟P偷捻旤c(diǎn)數(shù)據(jù)不會(huì)變化,故而可以預(yù)先上傳,使用時(shí)只需通過glBindBuffer即可使用頂點(diǎn)數(shù)據(jù);
如果想每幀都上傳頂點(diǎn)數(shù)據(jù)亦可以。(不推薦)

  • glUniform常量賦值在編譯鏈接完成頂點(diǎn)著色器后,可以設(shè)置著色器里面用到常量;

2、加載視頻;

  • loadAsset創(chuàng)建視頻源,并用loadValuesAsynchronouslyForKeys加載軌道信息;
  • createAssetReader創(chuàng)建Reader,并設(shè)置讀取的格式與軌道目標(biāo);
  • processAsset開始Reader,并啟動(dòng)CADisplayLink開始讀取視頻幀;

通過mReaderVideoTrackOutput的copyNextSampleBuffer可以獲取到下一幀的視頻信息;
通過CMSampleBufferGetImageBuffer可以獲取到CMSampleBuffer里面的像素緩存pixelBuffer,將其傳給GLView用于配置紋理;

    CMSampleBufferRef sampleBuffer = [self.mReaderVideoTrackOutput copyNextSampleBuffer];
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

3、配置紋理;

  • 通過CVBufferGetAttachment獲取pixelBuffer的顏色空間格式,決定使用的顏色轉(zhuǎn)換矩陣,用于下一步的YUV到RGB顏色空間的轉(zhuǎn)換;
  • 通過glActiveTexture啟用紋理,用
    CVOpenGLESTextureCacheCreateTextureFromImage創(chuàng)建紋理,再glBindTexture綁定紋理,設(shè)置好紋理格式;

CVOpenGLESTextureCacheCreateTextureFromImage創(chuàng)建的亮度紋理為frameHeight * frameWidth,格式為GL_LUMINANCE
CVOpenGLESTextureCacheCreateTextureFromImage創(chuàng)建的亮度紋理為frameHeight/2 * frameWidth/2,格式為GL_LUMINANCE_ALPHA

思考0:為何要使用CV?是否可以不使用CV直接讀取紋理信息?

4、YUV到RGB顏色空間的轉(zhuǎn)換;

YUV顏色空間由亮度+色度組成,GPU支持的RGB的顏色空間,故而需要進(jìn)行一次轉(zhuǎn)換。
下面是demo用到的顏色轉(zhuǎn)換矩陣:

const GLfloat kColorConversion601FullRange[] = {
    1.0,    1.0,    1.0,
    0.0,    -0.343, 1.765,
    1.4,    -0.711, 0.0,
};

注意:顏色轉(zhuǎn)換和頂點(diǎn)變換都是通過矩陣來計(jì)算。

5、球體渲染

簡單介紹下全景視頻的原理:
通過多個(gè)攝像機(jī)錄制多方向的視頻,通過投影計(jì)算,存儲(chǔ)到一個(gè)視頻中;
將視頻渲染到球面上,通過攝像機(jī)的位置與朝向,計(jì)算每次能顯示的內(nèi)容并繪制到屏幕。如下圖:


這就涉及到兩個(gè)問題:

  • 將全景的視頻信息存儲(chǔ)在二維的視頻里面;
  • 將二維的視頻還原成全景的視頻信息。
    (攝像機(jī)的位置和朝向計(jì)算看下面)

思考1:全景視頻顯示效果與普通視頻有何區(qū)別?為什么?

球面到2D視頻的展開


假設(shè)地球被圍在一中空的圓柱里,其基準(zhǔn)緯線與圓柱相切(赤道)接觸,然后再假想地球中心有一盞燈,把球面上的圖形投影到圓柱體上,再把圓柱體展開,得到投影。

越靠近畫面的TOP和BOTTOM,圖像的扭曲效果就越嚴(yán)重。上圖還看不太出來,看看下圖。


思考2:是否存在沒有扭曲效果的全景顯示?

2D視頻到球面的顯示
之前的教程有介紹過,點(diǎn)這里
下圖是一張展開了的地球圖像


下圖是按照球體的頂點(diǎn)數(shù)據(jù)進(jìn)行渲染

6、視角變化

球的圓心在原點(diǎn),攝像機(jī)的所在也是原點(diǎn),如下圖。



球坐標(biāo)系(r,θ,φ)與直角坐標(biāo)系(x,y,z)的轉(zhuǎn)換關(guān)系:
x=rsinθcosφ
y=rsinθsinφ
z=rcosθ


思考

思考0:視頻的紋理創(chuàng)建、銷毀非常頻繁,并且紋理普遍較大,CV對(duì)紋理的創(chuàng)建和緩存有針對(duì)的優(yōu)化,故而在處理視頻幀的時(shí)候推薦通過CV來處理紋理(圖像不行)。
如果不是用CV創(chuàng)建紋理,可以通過CVPixelBufferGetBaseAddress,拿到pixelBuffer的像素指針p;p的起始是亮度紋理,p加上亮度紋理的偏移量(frameWidth * frameHeight)之后是色度紋理。

思考1:全景視頻帶有明顯的扭曲效果。因?yàn)槭前?D平面的紋理渲染到球面上,故而帶有扭曲效果。

思考2:存在。天空盒可以做到。天空盒

擴(kuò)展

1、投影方式

Equisolid投影
Mercator投影

2、錄制難點(diǎn)

同步、角度、分屏(雙倍設(shè)備)

和VR的區(qū)別。全景+雙屏。

總結(jié)

demo的起因是群里和徐杰聊天的時(shí)候說到最近看到一個(gè)全景視頻直播,想起以前自己曾想過做一個(gè)全景圖像,結(jié)果因?yàn)椴欢瓹V和AVFoundation、沒有球體的頂點(diǎn)數(shù)據(jù)而放棄。
剛好他有一個(gè)視頻源,就要過來再試試。
結(jié)果這次的demo只花一天的時(shí)間就做完了,第二天的時(shí)間都是微調(diào)手指觸摸的體驗(yàn)。
實(shí)現(xiàn)過程中遇到一些坑,但是在分析完數(shù)據(jù)之后也馬上解決,一次很好的實(shí)踐體驗(yàn)。
篇幅有限,代碼在這里,歡迎star、fork。疑問請(qǐng)留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,786評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,964評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,354評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,554評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,106評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,918評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,093評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,342評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評(píng)論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,839評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,107評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容