2010-11-21 41 views

回答

19

從iOS 4.0開始,您可以使用AVCaptureDeviceInput將攝像頭作爲設備輸入,並將其連接到AVCaptureVideoDataOutput,並將其設置爲代表。通過爲攝像機設置一個32bpp的BGRA格式,代表對象將以完美的格式接收來自攝像機的每幀,並立即傳送到glTexImage2D(或glTexSubImage2D,如果設備不支持非冪次冪紋理; I認爲MBX設備屬於這一類)。

有一堆幀大小和幀速率選項;猜測你必須調整這些取決於你想要使用GPU的其他因素。我發現一個完全無關緊要的場景,只有帶有紋理的四邊形才能顯示最新的幀,僅在新幀到達iPhone 4時重新繪製,才能夠顯示該設備的最大720p 24fps的素材,而沒有任何明顯的延遲。我沒有做過比這更徹底的基準測試,所以希望別人能提供建議。

原則上,根據API,幀可以返回一些在掃描線之間的內存填充,這意味着在發佈到GL之前需要對內容進行一些混洗,因此您需要爲此實現代碼路徑。在實踐中,純粹從經驗角度來講,似乎iOS的當前版本從來沒有以這種形式返回圖像,所以它不是真正的性能問題。

編輯:它現在非常接近三年後。在此期間,蘋果公司發佈了iOS 5,6和7.其中5款產品分別推出了CVOpenGLESTextureCVOpenGLESTextureCache,這些都是將視頻從捕獲設備傳輸到OpenGL的智能方式。 Apple提供樣本代碼here,其中特別感興趣的部分在RippleViewController.m,特別是其setupAVCapturecaptureOutput:didOutputSampleBuffer:fromConnection: - 見行196-329。可悲的條款和條件阻止代碼的重複,這裏不附加整個項目,但一步一步的設置是:

  1. 創建CVOpenGLESTextureCacheCreateAVCaptureSession;
  2. 爲視頻抓取合適的AVCaptureDevice;
  3. 用該捕獲設備創建一個AVCaptureDeviceInput;
  4. 附加一個AVCaptureVideoDataOutput並告訴它將您稱爲樣本緩衝區委託。

在接收每個樣品緩衝液:

  1. 從它那裏得到的CVImageBufferRef;
  2. 使用CVOpenGLESTextureCacheCreateTextureFromImage從CV圖像緩衝區獲得Y和UV CVOpenGLESTextureRef;
  3. 從CV OpenGLES紋理引用中獲取紋理目標和名稱以綁定它們;
  4. 在着色器中結合了亮度和色度。
+0

感謝您的回答。我會去挖。 – Eonil 2010-11-22 07:35:43

+1

把整件事情聯繫起來只有200條線;抱歉沒有發佈代碼 - 我只在工作時解決了問題,因此我被禁止發佈我的內容。但它確實很平凡,我花了很多時間去弄清楚文檔中哪些是合適的類,而不是編碼。 – Tommy 2010-11-22 10:30:29

+0

@Eonil如果您喜歡他的回答,請將其標記爲已接受的答案。 – pr1001 2011-02-26 13:11:10

0

使用RosyWriter爲更好的示例如何做OpenGL視頻渲染。性能非常好,特別是如果您降低幀速率(在1080P/30時大約10%,在1080P/15時大於5%)。