Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / media / video / capture / win / video_capture_device_win.cc
index d2907db..c0bd9d2 100644 (file)
@@ -13,6 +13,7 @@
 #include "base/win/metro.h"
 #include "base/win/scoped_co_mem.h"
 #include "base/win/scoped_variant.h"
+#include "base/win/windows_version.h"
 #include "media/base/media_switches.h"
 #include "media/video/capture/win/video_capture_device_mf_win.h"
 
@@ -154,10 +155,14 @@ void DeleteMediaType(AM_MEDIA_TYPE* mt) {
 // static
 void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
-  // Use Media Foundation for Metro processes (after and including Win8)
-  // and DirectShow for any other platforms.
-  if (base::win::IsMetroProcess() &&
-      !cmd_line->HasSwitch(switches::kForceDirectShowVideoCapture)) {
+  // Use Media Foundation for Metro processes (after and including Win8) and
+  // DirectShow for any other versions, unless forced via flag. Media Foundation
+  // can also be forced if appropriate flag is set and we are in Windows 7 or
+  // 8 in non-Metro mode.
+  if ((base::win::IsMetroProcess() &&
+      !cmd_line->HasSwitch(switches::kForceDirectShowVideoCapture)) ||
+      (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
+      cmd_line->HasSwitch(switches::kForceMediaFoundationVideoCapture))) {
     VideoCaptureDeviceMFWin::GetDeviceNames(device_names);
   } else {
     VideoCaptureDeviceWin::GetDeviceNames(device_names);
@@ -166,8 +171,20 @@ void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
 
 // static
 void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device,
-    VideoCaptureCapabilities* formats) {
-  NOTIMPLEMENTED();
+    VideoCaptureFormats* formats) {
+  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+  // Use Media Foundation for Metro processes (after and including Win8) and
+  // DirectShow for any other versions, unless forced via flag. Media Foundation
+  // can also be forced if appropriate flag is set and we are in Windows 7 or
+  // 8 in non-Metro mode.
+  if ((base::win::IsMetroProcess() &&
+      !cmd_line->HasSwitch(switches::kForceDirectShowVideoCapture)) ||
+      (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
+      cmd_line->HasSwitch(switches::kForceMediaFoundationVideoCapture))) {
+    VideoCaptureDeviceMFWin::GetDeviceSupportedFormats(device, formats);
+  } else {
+    VideoCaptureDeviceWin::GetDeviceSupportedFormats(device, formats);
+  }
 }
 
 // static
@@ -263,6 +280,12 @@ void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
   }
 }
 
+// static
+void VideoCaptureDeviceWin::GetDeviceSupportedFormats(const Name& device,
+    VideoCaptureFormats* formats) {
+  NOTIMPLEMENTED();
+}
+
 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
     : device_name_(device_name),
       state_(kIdle) {
@@ -341,7 +364,7 @@ bool VideoCaptureDeviceWin::Init() {
 }
 
 void VideoCaptureDeviceWin::AllocateAndStart(
-    const VideoCaptureCapability& capture_format,
+    const VideoCaptureParams& params,
     scoped_ptr<VideoCaptureDevice::Client> client) {
   DCHECK(CalledOnValidThread());
   if (state_ != kIdle)
@@ -351,15 +374,16 @@ void VideoCaptureDeviceWin::AllocateAndStart(
 
   // Get the camera capability that best match the requested resolution.
   const VideoCaptureCapabilityWin& found_capability =
-      capabilities_.GetBestMatchedCapability(capture_format.width,
-                                             capture_format.height,
-                                             capture_format.frame_rate);
-  VideoCaptureCapability capability = found_capability;
+      capabilities_.GetBestMatchedFormat(
+          params.requested_format.frame_size.width(),
+          params.requested_format.frame_size.height(),
+          params.requested_format.frame_rate);
+  VideoCaptureFormat format = found_capability.supported_format;
 
   // Reduce the frame rate if the requested frame rate is lower
   // than the capability.
-  if (capability.frame_rate > capture_format.frame_rate)
-    capability.frame_rate = capture_format.frame_rate;
+  if (format.frame_rate > params.requested_format.frame_rate)
+    format.frame_rate = params.requested_format.frame_rate;
 
   AM_MEDIA_TYPE* pmt = NULL;
   VIDEO_STREAM_CONFIG_CAPS caps;
@@ -377,20 +401,19 @@ void VideoCaptureDeviceWin::AllocateAndStart(
   if (SUCCEEDED(hr)) {
     if (pmt->formattype == FORMAT_VideoInfo) {
       VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);
-      if (capability.frame_rate > 0)
-        h->AvgTimePerFrame = kSecondsToReferenceTime / capability.frame_rate;
+      if (format.frame_rate > 0)
+        h->AvgTimePerFrame = kSecondsToReferenceTime / format.frame_rate;
     }
-    // Set the sink filter to request this capability.
-    sink_filter_->SetRequestedMediaCapability(capability);
-    // Order the capture device to use this capability.
+    // Set the sink filter to request this format.
+    sink_filter_->SetRequestedMediaFormat(format);
+    // Order the capture device to use this format.
     hr = stream_config->SetFormat(pmt);
   }
 
   if (FAILED(hr))
     SetErrorState("Failed to set capture device output format");
 
-  if (capability.color == PIXEL_FORMAT_MJPEG &&
-      !mjpg_filter_.get()) {
+  if (format.pixel_format == PIXEL_FORMAT_MJPEG && !mjpg_filter_.get()) {
     // Create MJPG filter if we need it.
     hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC);
 
@@ -408,8 +431,7 @@ void VideoCaptureDeviceWin::AllocateAndStart(
     }
   }
 
-  if (capability.color == PIXEL_FORMAT_MJPEG &&
-      mjpg_filter_.get()) {
+  if (format.pixel_format == PIXEL_FORMAT_MJPEG && mjpg_filter_.get()) {
     // Connect the camera to the MJPEG decoder.
     hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_,
                                        NULL);
@@ -433,11 +455,9 @@ void VideoCaptureDeviceWin::AllocateAndStart(
     return;
   }
 
-  // Get the capability back from the sink filter after the filter have been
+  // Get the format back from the sink filter after the filter have been
   // connected.
-  const VideoCaptureCapability& used_capability
-      = sink_filter_->ResultingCapability();
-  client_->OnFrameInfo(used_capability);
+  capture_format_ = sink_filter_->ResultingFormat();
 
   // Start capturing.
   hr = media_control_->Run();
@@ -480,8 +500,8 @@ void VideoCaptureDeviceWin::StopAndDeAllocate() {
 // Implements SinkFilterObserver::SinkFilterObserver.
 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer,
                                           int length) {
-  client_->OnIncomingCapturedFrame(buffer, length, base::Time::Now(),
-                                   0, false, false);
+  client_->OnIncomingCapturedFrame(
+      buffer, length, base::TimeTicks::Now(), 0, capture_format_);
 }
 
 bool VideoCaptureDeviceWin::CreateCapabilityMap() {
@@ -524,8 +544,8 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
       VideoCaptureCapabilityWin capability(i);
       VIDEOINFOHEADER* h =
           reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
-      capability.width = h->bmiHeader.biWidth;
-      capability.height = h->bmiHeader.biHeight;
+      capability.supported_format.frame_size.SetSize(h->bmiHeader.biWidth,
+                                                     h->bmiHeader.biHeight);
 
       // Try to get a better |time_per_frame| from IAMVideoControl.  If not, use
       // the value from VIDEOINFOHEADER.
@@ -533,7 +553,8 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
       if (video_control) {
         ScopedCoMem<LONGLONG> max_fps;
         LONG list_size = 0;
-        SIZE size = { capability.width, capability.height };
+        SIZE size = {capability.supported_format.frame_size.width(),
+                     capability.supported_format.frame_size.height()};
 
         // GetFrameRateList doesn't return max frame rate always
         // eg: Logitech Notebook. This may be due to a bug in that API
@@ -551,30 +572,32 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
         }
       }
 
-      capability.frame_rate = (time_per_frame > 0) ?
-          static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0;
+      capability.supported_format.frame_rate =
+          (time_per_frame > 0)
+              ? static_cast<int>(kSecondsToReferenceTime / time_per_frame)
+              : 0;
 
       // DirectShow works at the moment only on integer frame_rate but the
       // best capability matching class works on rational frame rates.
-      capability.frame_rate_numerator = capability.frame_rate;
+      capability.frame_rate_numerator = capability.supported_format.frame_rate;
       capability.frame_rate_denominator = 1;
 
       // We can't switch MEDIATYPE :~(.
       if (media_type->subtype == kMediaSubTypeI420) {
-        capability.color = PIXEL_FORMAT_I420;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_I420;
       } else if (media_type->subtype == MEDIASUBTYPE_IYUV) {
         // This is identical to PIXEL_FORMAT_I420.
-        capability.color = PIXEL_FORMAT_I420;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_I420;
       } else if (media_type->subtype == MEDIASUBTYPE_RGB24) {
-        capability.color = PIXEL_FORMAT_RGB24;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_RGB24;
       } else if (media_type->subtype == MEDIASUBTYPE_YUY2) {
-        capability.color = PIXEL_FORMAT_YUY2;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_YUY2;
       } else if (media_type->subtype == MEDIASUBTYPE_MJPG) {
-        capability.color = PIXEL_FORMAT_MJPEG;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_MJPEG;
       } else if (media_type->subtype == MEDIASUBTYPE_UYVY) {
-        capability.color = PIXEL_FORMAT_UYVY;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_UYVY;
       } else if (media_type->subtype == MEDIASUBTYPE_ARGB32) {
-        capability.color = PIXEL_FORMAT_ARGB;
+        capability.supported_format.pixel_format = PIXEL_FORMAT_ARGB;
       } else {
         WCHAR guid_str[128];
         StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str));
@@ -590,10 +613,10 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
   return !capabilities_.empty();
 }
 
-void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
+void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
   DCHECK(CalledOnValidThread());
   DVLOG(1) << reason;
   state_ = kError;
-  client_->OnError();
+  client_->OnError(reason);
 }
 }  // namespace media