Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / media / video / capture / mac / video_capture_device_qtkit_mac.mm
index 7f4a853..09622e4 100644 (file)
     QTCaptureDecompressedVideoOutput *captureDecompressedOutput =
         [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease];
     [captureDecompressedOutput setDelegate:self];
+    [captureDecompressedOutput setAutomaticallyDropsLateVideoFrames:YES];
     if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) {
       [self sendErrorString:[NSString
           stringWithFormat:@"Could not connect video capture output (%@): %@",
   } else {
     // Remove the previously set capture device.
     if (!captureDeviceInput_) {
-      [self sendErrorString:[NSString
+      // Being here means stopping a device that never started OK in the first
+      // place, log it.
+      [self sendLogString:[NSString
           stringWithUTF8String:"No video capture device set, on removal."]];
       return YES;
     }
-    if ([[captureSession_ inputs] count] > 0) {
-      // The device is still running.
-      [self stopCapture];
-    }
-    if ([[captureSession_ outputs] count] > 0) {
-      // Only one output is set for |captureSession_|.
-      DCHECK_EQ([[captureSession_ outputs] count], 1u);
-      id output = [[captureSession_ outputs] objectAtIndex:0];
-      [output setDelegate:nil];
-
-      // TODO(shess): QTKit achieves thread safety by posting messages to the
-      // main thread.  As part of -addOutput:, it posts a message to the main
-      // thread which in turn posts a notification which will run in a future
-      // spin after the original method returns.  -removeOutput: can post a
-      // main-thread message in between while holding a lock which the
-      // notification handler  will need.  Posting either -addOutput: or
-      // -removeOutput: to the main thread should fix it, remove is likely
-      // safer. http://crbug.com/152757
-      [captureSession_ performSelectorOnMainThread:@selector(removeOutput:)
-                                        withObject:output
-                                     waitUntilDone:YES];
-    }
+    // Tear down input and output, stop the capture and deregister observers.
+    [self stopCapture];
     [captureSession_ release];
     captureSession_ = nil;
     [captureDeviceInput_ release];
 }
 
 - (void)stopCapture {
-  if ([[captureSession_ inputs] count] == 1) {
+  // QTKit achieves thread safety and asynchronous execution by posting messages
+  // to the main thread, e.g. -addOutput:. Both -removeOutput: and -removeInput:
+  // post a message to the main thread while holding a lock that the
+  // notification handler might need. To avoid a deadlock, we perform those
+  // tasks in the main thread. See bugs http://crbug.com/152757 and
+  // http://crbug.com/399792.
+  [self performSelectorOnMainThread:@selector(stopCaptureOnUIThread:)
+                         withObject:nil
+                      waitUntilDone:YES];
+  [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)stopCaptureOnUIThread:(id)dummy {
+  if ([[captureSession_ inputs] count] > 0) {
+    DCHECK_EQ([[captureSession_ inputs] count], 1u);
     [captureSession_ removeInput:captureDeviceInput_];
     [captureSession_ stopRunning];
   }
-
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
+  if ([[captureSession_ outputs] count] > 0) {
+    DCHECK_EQ([[captureSession_ outputs] count], 1u);
+    id output = [[captureSession_ outputs] objectAtIndex:0];
+    [output setDelegate:nil];
+    [captureSession_ removeOutput:output];
+  }
 }
 
 // |captureOutput| is called by the capture device to deliver a new frame.
   [lock_ unlock];
 }
 
+- (void)sendLogString:(NSString*)message {
+  DVLOG(1) << [message UTF8String];
+  [lock_ lock];
+  if (frameReceiver_)
+    frameReceiver_->LogMessage([message UTF8String]);
+  [lock_ unlock];
+}
+
 @end