Bug 929431 - Don't reinitialize DirectShow if it's not actually needed. r=jesup a=sylvestre
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Wed, 13 Aug 2014 19:51:39 +0200
changeset 217577 4d0bbb50982d98cfc39f184ecacc6c9a8f8310b7
parent 217576 8e039cfde354c9f967366627e1c856bf96f456fd
child 217578 c0e95adfb454e1253601dd18e29c30b51ddad4a4
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, sylvestre
bugs929431
milestone33.0a2
Bug 929431 - Don't reinitialize DirectShow if it's not actually needed. r=jesup a=sylvestre
media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc
media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h
--- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc
@@ -127,17 +127,17 @@ int32_t VideoCaptureDS::Init(const int32
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                      "Failed to add the send filter to the graph.");
         return -1;
     }
     _inputSendPin = GetInputPin(_sinkFilter);
 
     // Temporary connect here.
     // This is done so that no one else can use the capture device.
-    if (SetCameraOutput(_requestedCapability) != 0)
+    if (SetCameraOutputIfNeeded(_requestedCapability) != 0)
     {
         return -1;
     }
     hr = _mediaControl->Pause();
     if (FAILED(hr))
     {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                      "Failed to Pause the Capture device. Is it already occupied? %d.",
@@ -149,25 +149,21 @@ int32_t VideoCaptureDS::Init(const int32
     return 0;
 }
 
 int32_t VideoCaptureDS::StartCapture(
                                       const VideoCaptureCapability& capability)
 {
     CriticalSectionScoped cs(&_apiCs);
 
-    if (capability != _requestedCapability)
+    if (SetCameraOutputIfNeeded(capability) != 0)
     {
-        DisconnectGraph();
+        return -1;
+    }
 
-        if (SetCameraOutput(capability) != 0)
-        {
-            return -1;
-        }
-    }
     HRESULT hr = _mediaControl->Run();
     if (FAILED(hr))
     {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                      "Failed to start the Capture device.");
         return -1;
     }
     return 0;
@@ -181,65 +177,82 @@ int32_t VideoCaptureDS::StopCapture()
     if (FAILED(hr))
     {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                      "Failed to stop the capture graph. %d", hr);
         return -1;
     }
     return 0;
 }
+
 bool VideoCaptureDS::CaptureStarted()
 {
     OAFilterState state = 0;
     HRESULT hr = _mediaControl->GetState(1000, &state);
     if (hr != S_OK && hr != VFW_S_CANT_CUE)
     {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                      "Failed to get the CaptureStarted status");
     }
     WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                  "CaptureStarted %d", state);
     return state == State_Running;
 
 }
+
 int32_t VideoCaptureDS::CaptureSettings(
                                              VideoCaptureCapability& settings)
 {
     settings = _requestedCapability;
     return 0;
 }
 
-int32_t VideoCaptureDS::SetCameraOutput(
-                             const VideoCaptureCapability& requestedCapability)
+int32_t VideoCaptureDS::SetCameraOutputIfNeeded(
+    const VideoCaptureCapability& requestedCapability)
 {
-
     // Get the best matching capability
     VideoCaptureCapability capability;
     int32_t capabilityIndex;
 
-    // Store the new requested size
-    _requestedCapability = requestedCapability;
     // Match the requested capability with the supported.
     if ((capabilityIndex = _dsInfo.GetBestMatchedCapability(_deviceUniqueId,
                                                             _requestedCapability,
                                                             capability)) < 0)
     {
         return -1;
     }
+
+    if (capability != _activeCapability) {
+        DisconnectGraph();
+        // Store the new mode the camera actually selected
+        _activeCapability = capability;
+    } else {
+        // Camera selected the same mode, nothing to do
+        return 0;
+    }
+
     //Reduce the frame rate if possible.
     if (capability.maxFPS > requestedCapability.maxFPS)
     {
         capability.maxFPS = requestedCapability.maxFPS;
     } else if (capability.maxFPS <= 0)
     {
         capability.maxFPS = 30;
     }
+
     // Store the new expected capture delay
     _captureDelay = capability.expectedCaptureDelay;
 
+    return SetCameraOutput(capability, capabilityIndex);
+}
+
+int32_t VideoCaptureDS::SetCameraOutput(
+                                        const VideoCaptureCapability& capability,
+                                        int32_t capabilityIndex)
+{
     // Convert it to the windows capability index since they are not nexessary
     // the same
     VideoCaptureCapabilityWindows windowsCapability;
     if (_dsInfo.GetWindowsCapability(capabilityIndex, windowsCapability) != 0)
     {
         return -1;
     }
 
--- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h
@@ -48,23 +48,27 @@ public:
 
     virtual bool CaptureStarted();
     virtual int32_t CaptureSettings(VideoCaptureCapability& settings);
 
 protected:
     virtual ~VideoCaptureDS();
 
     // Help functions
-
+    int32_t
+        SetCameraOutputIfNeeded(const VideoCaptureCapability& requestedCapability);
     int32_t
-        SetCameraOutput(const VideoCaptureCapability& requestedCapability);
+        SetCameraOutput(const VideoCaptureCapability& requestedCapability,
+                        int32_t capabilityIndex);
+
     int32_t DisconnectGraph();
     HRESULT VideoCaptureDS::ConnectDVCamera();
 
     DeviceInfoDS _dsInfo;
+    VideoCaptureCapability _activeCapability;
 
     IBaseFilter* _captureFilter;
     IGraphBuilder* _graphBuilder;
     IMediaControl* _mediaControl;
     CaptureSinkFilter* _sinkFilter;
     IPin* _inputSendPin;
     IPin* _outputCapturePin;