2011-12-15 60 views
3

我想使用AVFoundation框架從AVCaptureStillImageOutput快速捕獲一系列靜止圖像,就像某些相機的突發模式。我想使用完成處理程序,保存CMSampleBufferRef供以後處理

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection 
               completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 

並將imageSampleBuffer傳遞給NSOperation對象以供以後處理。但我無法找到一種方法來保留NSOperation類中的緩衝區。

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection 
               completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 

    //Add to queue 
    SaveImageDataOperation *saveOperation = [[SaveImageDataOperation alloc] initWithImageBuffer:imageSampleBuffer]; 
    [_saveDataQueue addOperation:saveOperation]; 
    [saveOperation release]; 

    //Continue 
    [self captureCompleted]; 
}]; 

有沒有人知道我在這裏做錯了什麼?有沒有更好的方法來做到這一點?

回答

7

「重要提示:即使在使用垃圾回收的進程中,CMSampleBuffer的客戶端也必須通過調用CFRetain和CFRelease顯式管理保留計數。」

來源:CoreMedia.Framework CMSampleBuffer.h

0

我已經做了很多與CMSampleBuffer工作的對象,最近,我已經瞭解到,大部分在實時操作由OS源媒體緩衝區是從池中分配。如果AVFoundation(或CoreVideo/CoreMedia)耗盡了池中的緩衝區(也就是說CFR在很長的時間內保留一個緩衝區),則進程的實時方面將會受到影響或阻塞,直到您將CF釋放回緩衝區游泳池。

因此,除了操縱CMSampleBuffer上的CFRetain/CFRelease計數,您應該只保留足夠長的緩衝區以解壓CMBlockBuffer/CMFormat並創建一個新的CMSampleBuffer以傳遞到您的NSOperationQueue或dispatch_queue_t供以後處理。

在我的情況下,我想通過網絡從VideoToolbox傳遞壓縮的CMSampleBuffers。我基本上創建了一個CMSampleBuffer的深層副本,我的應用程序可以完全控制內存分配/生存期。從那裏,我將複製的CMSampleBuffer放在一個隊列中供網絡I/O使用。

如果樣本數據被壓縮,深度複製應該相對較快。在我的應用程序中,我使用NSKeyedArchiver從源CMSampleBuffer的相關部分創建NSData對象。對於H.264視頻數據,這意味着CMBlockBuffer內容,SPS/PPS頭字節以及SampleTimingInfo。通過對這些元素進行序列化,我可以在網絡的另一端重建一個CMSampleBuffer,它的行爲與VideoToolbox給我的相同。特別是,AVSampleBufferLayer能夠顯示它們,就好像它們本機來源於機器。

爲您的應用我想提出以下建議:

  1. 把你的源CMSampleBuffer和壓縮的像素數據。如果您可以使用VideoToolbox中的硬件編碼器僅創建I-幀 H.264圖像質量非常高。 VT編碼器 顯然非常適合電池使用時間,可能比JPEG要好很多,除非它們在 系統上也有硬件JPEG編解碼器。
  2. 將壓縮的CMSampleBuffer輸出深度拷貝 VideoToolbox,VT將CF釋放原始CMSampleBuffer返回 到捕獲子系統使用的池。
  3. 保留VT壓縮的CMSampleBuffer的時間足夠長,以便排入深層副本以供日後處理。

由於AVFoundation電影記錄可以做的步驟#1和#2實時不會耗盡緩衝區,你應該能夠深拷貝和排隊上dispatch_queue您的數據,而無需耗盡由所使用的緩衝池視頻捕獲組件和VideoToolbox組件。

相關問題