3

我正在創建一個用於iOS的C++庫(是的,不幸的是它必須是C++),它使用AVCaptureSession捕獲通過captureOutput回調傳遞的視頻幀。 C++庫是我的可交付產品。我有一個可可觸摸應用程序來測試/演示它。因此,它看起來像這樣:NSRunLoop和GCD隊列

(測試應用程序)< ----->(C++ LIB(AVFoundation回調))

測試程序具有UI控件,並負責幾乎所有的圖形。 C++庫通過OpenGL將幀呈現給UIView。

你跟我嗎?好


好吧,首先,用戶按下一個UIButton,它會打電話到我的圖書館。此通話需要10秒或更長時間才能完成。所以,如果我把電話直接單擊按鈕背後,用戶界面將被阻止,直到庫函數返回:

-(IBAction)hBut:(id)sender{ 
    [myLib foo]; // takes 10+ seconds to return 
} 

這也是白搭。我想接下來的事情就是產生一個線程調用的lib:

-(void)callIntoLib{ 
    [myLib foo]; 
} 

-(IBAction)hBut:(id)sender{ 
    [NSThread detach..:myLib selector:foo object:nil]; 
} 

此不再阻止用戶界面,但現在的視頻幀回調函數永遠不會觸發(AVCaptureSession的captureOutput)。看起來好像主要的NSRunLoop已被阻止。

接下來我想同樣的事情,但與大中央調度:

-(IBAction)hBut:(id)sender{ 
    _myQueue = dispatch_queue_create("com.domain.me", NULL); // member variable 
    dispatch_async(_myQueue, 
    ^{ 
      [myLib foo]; 
    }); 
} 

此具有相同的行爲。也就是說,視頻幀的回調不會觸發。 Lame

爲什麼主要的NSRunLoop在第二和第三種情況下被阻塞?有沒有辦法將隊列與它關聯?

這是否有意義?

回答

0

此示例代碼僅AVCaptureVideoDataOutput -setSampleBufferDelegate用途:隊列:上GCD串行隊列。看來AVCaptureSession必須和RunLoop一起使用。你需要在你的線程上執行你自己的RunLoop,或者試着修改你的C++ lib作爲這個示例代碼。

+1

這個李k現在已經壞了(蘋果的邪惡站長不斷破壞url)。新版本位於:https://developer.apple.com/library/ios/qa/qa1702/_index.html – Adam 2013-08-27 13:51:36

+0

看來即使線程有自己的runloop,'AVCaptureSession'堅持在主runloop上運行(' CFRunLoopGetMain')。我[產生NSThread](https://github.com/dashesy/pyavfcam/blob/develop/src/modules/avf_impl.m)並運行其中的所有內容,但回調只來自主runloop,如果主runloop被阻塞,沒有收到回叫。如果我在主循環中執行所有操作,那麼一切都很好,只是它不喜歡新線程。我正在談論的不是iOS的OSX。 – dashesy 2015-09-23 01:05:03

2

主線程本身運行其runLoop,因此來自攝像頭的事件在第一種情況下被傳送到您的庫。自定義線程不運行runLoop,你應該自己做。

-(void)callIntoLib { 
    [myLib foo]; 
    self.callIntoLibExecuted = YES; 
} 


-(void)threadBody { 
    @autoreleasepool { 
     self.callIntoLibExecuted = NO; 

     [self performSelector:@selector(callIntoLib) 
       onThread:[NSThread currentThread] 
       withObject:nil 
       waitUntilDone:NO]; 

     while (!self.callIntoLibExecuted) 
     { 
      @autoreleasepool { 
       [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
         beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 
      } 
     } 
    } 
} 

-(IBAction)hBut:(id)sender { 
    [NSThread detachNewThreadSelector:@selector(threadBody) 
       toTarget:self withObject:nil]; 
} 
+0

你試過這個嗎?我有一個自定義[線程與自己的runloop](https://github.com/dashesy/pyavfcam/blob/develop/src/modules/avf_impl。米),仍然'AVFoundation'通過主運行循環。如果主運行循環阻塞,它不會來(我談論的不是iOS的OSX)。 – dashesy 2015-09-23 01:08:14

+0

我認爲AVFoundation在iOS上的OSX上的工作方式不同,這個答案是針對iOS問題提供的。如果您將使用AVCaptureVideoDataOutput而不是AVCaptureMovieFileOutput,則您將能夠捕獲您指定的分派隊列中的回調。試試看。也許那時你的主線程在捕捉過程中不會被使用。 – DisableR 2015-09-24 08:11:09