2013-03-20 79 views
4

我正在使用AV Foundation來處理來自攝像機(iPhone 4s,iOS 6.1.2)的幀。我正在根據AV Foundation編程指南設置AVCaptureSession,AVCaptureDeviceInput,AVCaptureVideoDataOutput。一切都按預期工作,我可以在captureOutput:didOutputSampleBuffer:fromConnection:代表中接收幀。AV Foundation:AVCaptureVideoPreviewLayer和幀持續時間

我也有這樣設置的預覽層:

AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession]; 
[videoPreviewLayer setFrame:self.view.bounds]; 
videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
[self.view.layer insertSublayer:videoPreviewLayer atIndex:0]; 

事情是,我不需要每秒30幀的幀我處理,我不能夠處理他們這麼快呢。所以我使用此代碼來限制幀持續時間:

// videoOutput is AVCaptureVideoDataOutput set earlier 
AVCaptureConnection *conn = [videoOutput connectionWithMediaType:AVMediaTypeVideo]; 
[conn setVideoMinFrameDuration:CMTimeMake(1, 10)]; 
[conn setVideoMaxFrameDuration:CMTimeMake(1, 2)]; 

這工作得很好,並限制由captureOutput代表收到的幀。

但是,這也限制了預覽圖層上的每秒幀數,預覽視頻變得無法響應。

我從文檔中瞭解到,幀持續時間是在連接上獨立設置的,預覽層的確有不同的AVCaptureConnection。在[videoPreviewLayer connection]上檢查混合/最大幀持續時間顯示它確實設置爲默認值(1/30和1/24),並且不同於連接AVCaptureVideoDataOutput時設置的持續時間。

那麼,是否有可能僅限於幀捕捉輸出限制幀持續時間,並且仍然在預覽視頻上看到1/24-1/30幀持續時間?怎麼樣?

謝謝。

回答

4

雖然您確定有兩個AVCaptureConnection s,但這並不意味着它們可以獨立設置最小和最大幀持續時間。這是因爲他們共享相同的物理硬件

如果連接#1以5幀/秒的速率(例如)以1/5秒的幀持續時間激活捲簾快門,則存在不可能連接#2可以同時激活快門30次/秒,幀持續時間爲1/30秒。

要獲得您想要的效果,需要兩個攝像頭!

接近你想要的東西的唯一方法就是沿着3月22日回答中Kaelin Colclasure概述的方法。

可以選擇在該方法中稍微複雜一點,但是。例如,您可以使用計數器來決定丟棄哪些幀,而不是讓線程休眠。您可以讓該計數器響應實際幀速率(您可以通過captureOutput:didOutputSampleBuffer:fromConnection:委託人的元數據以及圖像數據獲得該幀數,也可以通過手動計算幀來計算)。你甚至可以通過合成框架來合理模仿更長時間的曝光,而不是將它們合併 - 就像App Store中的一些「慢速快門」應用一樣(留下細節 - 例如不同的滾動快門文物 - 沒有真正的在1/5秒掃描的一幀和1/25秒掃描的五幀之間差別很大,然後粘在一起)。

是的,這是一項工作,但您試圖使一臺攝像機的實時行爲像兩個一樣 - 並且這從來都不會輕鬆。

+0

「這並不容易。」誇張的 – aleclarson 2014-05-30 20:34:42

+0

嗨@Wildaker你能幫忙解釋一下幀持續時間以及在這個問題中使用不同值的含義嗎?謝謝! http://stackoverflow.com/questions/34937008/exporting-videos-on-ios-understanding-and-setting-frame-duration-property – Crashalot 2016-01-22 00:36:21

+0

對不起,但沒有試驗,我真的不能說,@Crashalot。這不是我所做的。 – Wildaker 2016-01-23 09:36:11

1

我對我的Cocoa(Mac OS X)應用程序有同樣的問題。以下是我如何解決它:

首先,請確保在單獨的調度隊列上處理捕獲的幀。還要確保你沒有準備處理的任何幀都被丟棄;這是默認設置,但我將下面的標記設置爲只是爲了證明我依賴它。

videoQueue = dispatch_queue_create("com.ohmware.LabCam.videoQueue", DISPATCH_QUEUE_SERIAL); 
    videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    [videoOutput setAlwaysDiscardsLateVideoFrames:YES]; 
    [videoOutput setSampleBufferDelegate:self 
            queue:videoQueue]; 
    [session addOutput:videoOutput]; 

然後,當處理委託中的幀時,您可以簡單地讓線程休眠所需的時間間隔。委託人未醒來處理的幀被悄悄丟棄。我實現了用於計數丟失幀的可選方法,只是作爲完整性檢查;我的應用程序從不記錄使用這種技術丟棄任何幀。

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
    didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection; 
{ 
    OSAtomicAdd64(1, &videoSampleBufferDropCount); 
} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection; 
{ 
    int64_t savedSampleBufferDropCount = videoSampleBufferDropCount; 
    if (savedSampleBufferDropCount && OSAtomicCompareAndSwap64(savedSampleBufferDropCount, 0, &videoSampleBufferDropCount)) { 
     NSLog(@"Dropped %lld video sample buffers!!!", savedSampleBufferDropCount); 
    } 
    // NSLog(@"%s", __func__); 
    @autoreleasepool { 
     CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
     CIImage * cameraImage = [CIImage imageWithCVImageBuffer:imageBuffer]; 
     CIImage * faceImage = [self faceImage:cameraImage]; 
     dispatch_sync(dispatch_get_main_queue(),^{ 
      [_imageView setCIImage:faceImage]; 
     }); 
    } 
    [NSThread sleepForTimeInterval:0.5]; // Only want ~2 frames/sec. 
} 

希望這會有所幫助。

+0

謝謝,但我想我不想這樣做,只是丟幀。當您限制幀持續時間時,AV框架將在低照度條件下增加每幀的曝光量,如果您丟幀,則不會獲得此優勢。此外,每幀的處理時間會有所不同,當您限制最小/最大幀持續時間時,您可以讓框架適應您。我不認爲我想要自己計算間隔。 – danielv 2013-03-22 16:44:41

2

想想這樣: 您可以讓捕捉設備限制幀持續時間,以便您獲得更好的曝光。 好。 你想以更高的幀率預覽。 如果您要以更高的速率進行預覽,那麼捕捉設備(相機)將沒有足夠的時間來曝光相框,以便在捕捉的幀處獲得更好的曝光。 這就像要求在預覽中看到不同的幀比捕獲的幀。

我認爲,如果可能的話,這也會是一種負面的用戶體驗。

+0

你的意思很有道理。但是,如果您閱讀「AV Foundation編程指南」和「AVCaptureConnection類參考」的文檔,您會發現預覽圖層和實際輸出設備具有不同的AVCaptureConnection。最小/最大幀持續時間參數在AVCaptureConnection對象上獨立設置,實際上預覽的連接和捕捉輸出連接具有不同的值。這並不奇怪,蘋果公司有誤導性的文檔和不一致的API,但你可以理解爲什麼這可以完全拋棄一個... – danielv 2013-03-28 13:13:06

+1

我還沒有測試過它,但應該可以有其他的方式:低fps上預覽圖層和更高的捕獲幀。這可能就是你獲得獨立捕獲連接的原因。 – gWiz 2013-03-28 13:26:40

+0

嗨@gWiz你能幫忙解釋一下幀持續時間以及在這個問題中使用不同值的含義嗎?謝謝! http://stackoverflow.com/questions/34937008/exporting-videos-on-ios-understanding-and-setting-frame-duration-property – Crashalot 2016-01-22 00:37:03