GPUImage詳細(xì)解析(二)

解析

GPUImage詳細(xì)解析(一)
上一篇介紹的是GPUImageFramebufferGPUImageFilter愁铺。
簡(jiǎn)單回顧一下:

  • GPUImageFilter就是用來(lái)接收源圖像,通過(guò)自定義的頂點(diǎn)铅鲤、片元著色器來(lái)渲染新的圖像司蔬,并在繪制完成后通知響應(yīng)鏈的下一個(gè)對(duì)象。
  • GPUImageFramebuffer就是用來(lái)管理紋理緩存的格式與讀寫(xiě)幀緩存的buffer。

這一篇介紹的是GPUImageVideoCameraGPUImageView帆啃。

GPUImageVideoCamera

GPUImageVideoCamera是GPUImageOutput的子類(lèi),提供來(lái)自攝像頭的圖像數(shù)據(jù)作為源數(shù)據(jù)窍帝,一般是響應(yīng)鏈的源頭努潘。

1、視頻圖像采集 :AVCaptureSession

GPUImage使用AVFoundation框架來(lái)獲取視頻坤学。
AVCaptureSession類(lèi)從AV輸入設(shè)備的采集數(shù)據(jù)到制定的輸出疯坤。
為了實(shí)現(xiàn)實(shí)時(shí)的圖像捕獲,要實(shí)現(xiàn)AVCaptureSession類(lèi)深浮,添加合適的輸入(AVCaptureDeviceInput)和輸出(比如 AVCaptureMovieFileOutput)
調(diào)用startRunning開(kāi)始輸入到輸出的數(shù)據(jù)流压怠,調(diào)用stopRunning停止數(shù)據(jù)流。
需要注意的是startRunning函數(shù)會(huì)花費(fèi)一定的時(shí)間飞苇,所以不能在主線(xiàn)程(UI線(xiàn)程)調(diào)用菌瘫,防止卡頓。
sessionPreset 屬性可以自定義一些設(shè)置布卡。
特殊的選項(xiàng)比如說(shuō)高幀率雨让,可以通過(guò) AVCaptureDevice來(lái)設(shè)置。
AVCaptureSession使用的簡(jiǎn)單示例:

_captureSession = [[AVCaptureSession alloc] init];
    [_captureSession beginConfiguration];
// 中間可以實(shí)現(xiàn)關(guān)于session屬性的設(shè)置
    [_captureSession commitConfiguration];
  • AVCaptureVideoDataOutput
    AVCaptureVideoDataOutputAVCaptureOutput的子類(lèi)羽利,用來(lái)處理從攝像頭采集的未壓縮或者壓縮過(guò)的圖像幀宫患。
    通過(guò)captureOutput:didOutputSampleBuffer:fromConnection: delegate,可以訪(fǎng)問(wèn)圖像幀。
    通過(guò)下面這個(gè)方法娃闲,可以設(shè)置delegate虚汛。
- (void)setSampleBufferDelegate:
(id<AVCaptureVideoDataOutputSampleBufferDelegate>)sampleBufferDelegate 
queue:(dispatch_queue_t)sampleBufferCallbackQueue;

需要注意的是,當(dāng)一個(gè)新的視頻圖像幀被采集后皇帮,它會(huì)被傳送到output卷哩,調(diào)用這里設(shè)置的delegate。所有的delegate函數(shù)會(huì)在這個(gè)queue中調(diào)用属拾。如果隊(duì)列被阻塞将谊,新的圖像幀到達(dá)后會(huì)被自動(dòng)丟棄(默認(rèn)alwaysDiscardsLateVideoFrames = YES)。這允許app處理當(dāng)前的圖像幀渐白,不需要去管理不斷增加的內(nèi)存尊浓,因?yàn)樘幚硭俣雀簧喜杉乃俣龋却幚淼膱D像幀會(huì)占用內(nèi)存纯衍,并且不斷增大栋齿。
必須使用同步隊(duì)列處理圖像幀,保證幀的序列是順序的襟诸。

  • frameRenderingSemaphore 幀渲染的信號(hào)量
    下面有一個(gè)這樣的調(diào)用瓦堵,用于等待處理完一幀后,再接著處理下一幀歌亲。
        if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0)
        {
            return;
        }
        runAsynchronouslyOnVideoProcessingQueue(^{
              dispatch_semaphore_signal(frameRenderingSemaphore);
        });
  • rotateCamera
    前后攝像頭翻轉(zhuǎn):更改videoInput的設(shè)置菇用。

2、顏色空間:YUV

YUV是被歐洲電視系統(tǒng)所采用的一種顏色編碼方法陷揪。
采用YUV色彩空間的重要性是它的亮度信號(hào)Y色度信號(hào)U惋鸥、V是分離的。如果只有Y信號(hào)分量而沒(méi)有U鹅龄、V分量揩慕,那么這樣表示的圖像就是黑白灰度圖像。彩色電視采用YUV空間正是為了用亮度信號(hào)Y解決彩色電視機(jī)與黑白電視機(jī)的兼容問(wèn)題扮休,使黑白電視機(jī)也能接收彩色電視信號(hào)迎卤。

YCbCr或Y'CbCr有的時(shí)候會(huì)被寫(xiě)作:YCBCR或是Y'CBCR,是色彩空間的一種玷坠,通常會(huì)用于影片中的影像連續(xù)處理蜗搔,或是數(shù)字?jǐn)z影系統(tǒng)中。Y'為顏色的亮度(luma)成分八堡、而CB和CR則為藍(lán)色和紅色的濃度偏移量成份樟凄。
YUV主要用于優(yōu)化彩色視頻信號(hào)的傳輸,使其向后相容老式黑白電視兄渺。與RGB視頻信號(hào)傳輸相比缝龄,它最大的優(yōu)點(diǎn)在于只需占用極少的頻寬(RGB要求三個(gè)獨(dú)立的視頻信號(hào)同時(shí)傳輸)。

CbCr 則是在世界數(shù)字組織視頻標(biāo)準(zhǔn)研制過(guò)程中作為ITU - R BT.601 建議的一部分,其實(shí)是YUV經(jīng)過(guò)縮放和偏移的翻版叔壤。其中Y與YUV 中的Y含義一致,Cb,Cr 同樣都指色彩瞎饲,只是在表示方法上不同而已。在YUV 家族中炼绘,YCbCr 是在計(jì)算機(jī)系統(tǒng)中應(yīng)用最多的成員嗅战,其應(yīng)用領(lǐng)域很廣泛,JPEG俺亮、MPEG均采用此格式驮捍。一般人們所講的YUV大多是指YCbCr。YCbCr 有許多取樣格式脚曾,如4∶4∶4,4∶2∶2,4∶1∶1 和4∶2∶0东且。
百度百科的介紹
YUV數(shù)據(jù)格式-圖文詳解
GPUImage中的YUV
GLProgram *yuvConversionProgram; 將YUV顏色空間轉(zhuǎn)換成RGB顏色空間的GLSL。
CVPixelBufferGetPlaneCount()返回緩沖區(qū)的平面數(shù)本讥。
通過(guò)CVOpenGLESTextureCacheCreateTextureFromImage()創(chuàng)建兩個(gè)紋理luminanceTextureRef(亮度紋理)和chrominanceTextureRef(色度紋理)苇倡。
convertYUVToRGBOutput()把YUV顏色空間的紋理轉(zhuǎn)換成RGB顏色空間的紋理
頂點(diǎn)著色器-通用kGPUImageVertexShaderString
片元著色器:
1、kGPUImageYUVFullRangeConversionForLAFragmentShaderString
2囤踩、kGPUImageYUVVideoRangeConversionForLAFragmentShaderString
區(qū)別在不同的格式
video-range (luma=[16,235] chroma=[16,240])
full-range (luma=[0,255] chroma=[1,255])

3、紋理繪制

glActiveTextue 并不是激活紋理單元晓褪,而是選擇當(dāng)前活躍的紋理單元堵漱。每一個(gè)紋理單元都有GL_TEXTURE_1D, 2D, 3D 和 CUBE_MAP。

    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &_texture);
    glBindTexture(GL_TEXTURE_2D, _texture);

SO的詳細(xì)介紹

GPUImageView

GPUImageView是響應(yīng)鏈的終點(diǎn)涣仿,一般用于顯示GPUImage的圖像勤庐。

1、填充模式

GPUImageFillModeType fillMode圖像的填充模式好港。
sizeInPixels 像素區(qū)域大小愉镰。
recalculateViewGeometry() 重新計(jì)算圖像頂點(diǎn)位置數(shù)據(jù)。
AVMakeRectWithAspectRatioInsideRect() 在保證寬高比不變的前提下钧汹,得到一個(gè)盡可能大的矩形丈探。
如果是kGPUImageFillModeStretch
圖像拉伸,直接使寬高等于1.0即可拔莱,原圖像會(huì)直接鋪滿(mǎn)整個(gè)屏幕碗降。

如果是kGPUImageFillModePreserveAspectRatio
保持原寬高比,并且圖像不超過(guò)屏幕塘秦。那么以當(dāng)前屏幕大小為準(zhǔn)讼渊。
widthScaling = insetRect.size.width / currentViewSize.width;

如果是kGPUImageFillModePreserveAspectRatioAndFill
保持原寬高比,并且圖像要鋪滿(mǎn)整個(gè)屏幕尊剔。那么圖像大小為準(zhǔn)爪幻。
widthScaling = currentViewSize.height / insetRect.size.height;

imageVertices存放著頂點(diǎn)數(shù)據(jù),上面的修改都會(huì)存放在這個(gè)數(shù)組。

2挨稿、OpenGL ES繪制

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;源圖像已經(jīng)準(zhǔn)備好仇轻,開(kāi)始繪制。
setDisplayFramebuffer()會(huì)綁定GPUImageView的幀緩存叶组,同時(shí)調(diào)試視口大小為view的大小拯田。
glActiveTexture上面已經(jīng)介紹過(guò),是選擇一個(gè)紋理單元甩十。先選擇紋理單元4船庇,然后把源圖像數(shù)據(jù)綁定到GL_TEXTURE_2D的位置上。最后告訴片元著色器侣监,紋理單元是4鸭轮。

        glActiveTexture(GL_TEXTURE4);
        glBindTexture(GL_TEXTURE_2D, [inputFramebufferForDisplay texture]);
        glUniform1i(displayInputTextureUniform, 4);

這兩行是分別綁定頂點(diǎn)坐標(biāo)數(shù)據(jù)和紋理坐標(biāo)數(shù)據(jù)。

        glVertexAttribPointer(displayPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices);
        glVertexAttribPointer(displayTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [GPUImageView textureCoordinatesForRotation:inputRotation]);

這兩行是設(shè)定輸入的源圖像數(shù)據(jù)緩存橄霉,并且對(duì)緩存加鎖窃爷。

    inputFramebufferForDisplay = newInputFramebuffer;
    [inputFramebufferForDisplay lock];

在準(zhǔn)備好著色器、紋理data姓蜂、頂點(diǎn)位置坐標(biāo)和紋理坐標(biāo)后按厘,就可以調(diào)用
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);繪制圖像。

demo

這里有一個(gè)簡(jiǎn)單的示例钱慢,介紹如何用GPUImageVideoCamera采集圖像并且用GPUImageView顯示出來(lái)逮京。
十分簡(jiǎn)單,核心代碼不過(guò)十行束莫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末懒棉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子览绿,更是在濱河造成了極大的恐慌策严,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饿敲,死亡現(xiàn)場(chǎng)離奇詭異妻导,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)怀各,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)栗竖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人渠啤,你說(shuō)我怎么就攤上這事狐肢。” “怎么了沥曹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵份名,是天一觀(guān)的道長(zhǎng)碟联。 經(jīng)常有香客問(wèn)我,道長(zhǎng)僵腺,這世上最難降的妖魔是什么鲤孵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辰如,結(jié)果婚禮上普监,老公的妹妹穿的比我還像新娘。我一直安慰自己琉兜,他們只是感情好凯正,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著豌蟋,像睡著了一般廊散。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梧疲,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天允睹,我揣著相機(jī)與錄音,去河邊找鬼幌氮。 笑死缭受,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的该互。 我是一名探鬼主播贯涎,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼慢洋!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起陆盘,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤普筹,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后隘马,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體太防,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年酸员,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜒车。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幔嗦,死狀恐怖酿愧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邀泉,我是刑警寧澤嬉挡,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布钝鸽,位于F島的核電站,受9級(jí)特大地震影響庞钢,放射性物質(zhì)發(fā)生泄漏拔恰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一基括、第九天 我趴在偏房一處隱蔽的房頂上張望颜懊。 院中可真熱鬧,春花似錦风皿、人聲如沸河爹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)昌抠。三九已至,卻和暖如春鲁僚,著一層夾襖步出監(jiān)牢的瞬間炊苫,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工冰沙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侨艾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓拓挥,卻偏偏與公主長(zhǎng)得像唠梨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侥啤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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