Index: media/video/capture/win/video_capture_device_win.cc |
diff --git a/media/video/capture/win/video_capture_device_win.cc b/media/video/capture/win/video_capture_device_win.cc |
index 5a587b54fc7ae1d683387d4eb3cc147e90891f23..721fb259cac3542525a0a7a44cd85076625a24c6 100644 |
--- a/media/video/capture/win/video_capture_device_win.cc |
+++ b/media/video/capture/win/video_capture_device_win.cc |
@@ -10,6 +10,8 @@ |
#include "base/string_util.h" |
#include "base/sys_string_conversions.h" |
#include "base/win/scoped_variant.h" |
+#include "base/win/windows_version.h" |
+#include "media/video/capture/win/video_capture_device_mf_win.h" |
using base::win::ScopedComPtr; |
using base::win::ScopedVariant; |
@@ -142,42 +144,39 @@ void DeleteMediaType(AM_MEDIA_TYPE* mt) { |
} |
} |
-// Help structure used for comparing video capture capabilities. |
-struct ResolutionDiff { |
- int capability_index; |
- int diff_height; |
- int diff_width; |
- int diff_frame_rate; |
- media::VideoCaptureCapability::Format color; |
-}; |
- |
-bool CompareHeight(const ResolutionDiff& item1, const ResolutionDiff& item2) { |
- return abs(item1.diff_height) < abs(item2.diff_height); |
-} |
- |
-bool CompareWidth(const ResolutionDiff& item1, const ResolutionDiff& item2) { |
- return abs(item1.diff_width) < abs(item2.diff_width); |
-} |
+} // namespace |
-bool CompareFrameRate(const ResolutionDiff& item1, |
- const ResolutionDiff& item2) { |
- return abs(item1.diff_frame_rate) < abs(item2.diff_frame_rate); |
-} |
+namespace media { |
-bool CompareColor(const ResolutionDiff& item1, const ResolutionDiff& item2) { |
- return (item1.color < item2.color); |
+// static |
+void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
+ VideoCaptureDeviceMFWin::GetDeviceNames(device_names); |
+ } else { |
+ VideoCaptureDeviceWin::GetDeviceNames(device_names); |
+ } |
} |
-} // namespace |
- |
-namespace media { |
+// static |
+VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { |
+ VideoCaptureDevice* ret = NULL; |
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
+ scoped_ptr<VideoCaptureDeviceMFWin> device( |
+ new VideoCaptureDeviceMFWin(device_name)); |
+ if (device->Init()) |
+ ret = device.release(); |
+ } else { |
+ scoped_ptr<VideoCaptureDeviceWin> device( |
+ new VideoCaptureDeviceWin(device_name)); |
+ if (device->Init()) |
+ ret = device.release(); |
+ } |
-// Name of a fake DirectShow filter that exist on computers with |
-// GTalk installed. |
-static const char kGoogleCameraAdapter[] = "google camera adapter"; |
+ return ret; |
+} |
-// Gets the names of all video capture devices connected to this computer. |
-void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
+// static |
+void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) { |
DCHECK(device_names); |
ScopedComPtr<ICreateDevEnum> dev_enum; |
@@ -196,6 +195,10 @@ void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
device_names->clear(); |
+ // Name of a fake DirectShow filter that exist on computers with |
+ // GTalk installed. |
+ static const char kGoogleCameraAdapter[] = "google camera adapter"; |
+ |
// Enumerate all video capture devices. |
ScopedComPtr<IMoniker> moniker; |
int index = 0; |
@@ -241,15 +244,6 @@ void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
} |
} |
-VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { |
- VideoCaptureDeviceWin* self = new VideoCaptureDeviceWin(device_name); |
- if (self && self->Init()) |
- return self; |
- |
- delete self; |
- return NULL; |
-} |
- |
VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) |
: device_name_(device_name), |
state_(kIdle), |
@@ -338,10 +332,11 @@ void VideoCaptureDeviceWin::Allocate( |
return; |
observer_ = observer; |
+ |
// Get the camera capability that best match the requested resolution. |
- const int capability_index = GetBestMatchedCapability(width, height, |
- frame_rate); |
- VideoCaptureCapability capability = capabilities_[capability_index]; |
+ const VideoCaptureCapabilityWin& found_capability = |
+ capabilities_.GetBestMatchedCapability(width, height, frame_rate); |
+ VideoCaptureCapability capability = found_capability; |
// Reduce the frame rate if the requested frame rate is lower |
// than the capability. |
@@ -359,7 +354,7 @@ void VideoCaptureDeviceWin::Allocate( |
} |
// Get the windows capability from the capture device. |
- hr = stream_config->GetStreamCaps(capability_index, &pmt, |
+ hr = stream_config->GetStreamCaps(found_capability.stream_index, &pmt, |
reinterpret_cast<BYTE*>(&caps)); |
if (SUCCEEDED(hr)) { |
if (pmt->formattype == FORMAT_VideoInfo) { |
@@ -526,7 +521,7 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
if (media_type->majortype == MEDIATYPE_Video && |
media_type->formattype == FORMAT_VideoInfo) { |
- VideoCaptureCapability capability; |
+ VideoCaptureCapabilityWin capability(i); |
REFERENCE_TIME time_per_frame = 0; |
VIDEOINFOHEADER* h = |
@@ -586,79 +581,13 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
DVLOG(2) << "Device support unknown media type " << guid_str; |
continue; |
} |
- capabilities_[i] = capability; |
+ capabilities_.Add(capability); |
} |
DeleteMediaType(media_type); |
media_type = NULL; |
} |
- return capabilities_.size() > 0; |
-} |
- |
-// Loops through the list of capabilities and returns an index of the best |
-// matching capability. |
-// The algorithm prioritize height, width, frame rate and color format in that |
-// order. |
-int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width, |
- int requested_height, |
- int requested_frame_rate) { |
- DCHECK(CalledOnValidThread()); |
- std::list<ResolutionDiff> diff_list; |
- |
- // Loop through the candidates to create a list of differentials between the |
- // requested resolution and the camera capability. |
- for (CapabilityMap::iterator iterator = capabilities_.begin(); |
- iterator != capabilities_.end(); |
- ++iterator) { |
- VideoCaptureCapability capability = iterator->second; |
- |
- ResolutionDiff diff; |
- diff.capability_index = iterator->first; |
- diff.diff_width = capability.width - requested_width; |
- diff.diff_height = capability.height - requested_height; |
- diff.diff_frame_rate = capability.frame_rate - requested_frame_rate; |
- diff.color = capability.color; |
- diff_list.push_back(diff); |
- } |
- |
- // Sort the best height candidates. |
- diff_list.sort(&CompareHeight); |
- int best_diff = diff_list.front().diff_height; |
- for (std::list<ResolutionDiff>::iterator it = diff_list.begin(); |
- it != diff_list.end(); ++it) { |
- if (it->diff_height != best_diff) { |
- // Remove all candidates but the best. |
- diff_list.erase(it, diff_list.end()); |
- break; |
- } |
- } |
- |
- // Sort the best width candidates. |
- diff_list.sort(&CompareWidth); |
- best_diff = diff_list.front().diff_width; |
- for (std::list<ResolutionDiff>::iterator it = diff_list.begin(); |
- it != diff_list.end(); ++it) { |
- if (it->diff_width != best_diff) { |
- // Remove all candidates but the best. |
- diff_list.erase(it, diff_list.end()); |
- break; |
- } |
- } |
- |
- // Sort the best frame rate candidates. |
- diff_list.sort(&CompareFrameRate); |
- best_diff = diff_list.front().diff_frame_rate; |
- for (std::list<ResolutionDiff>::iterator it = diff_list.begin(); |
- it != diff_list.end(); ++it) { |
- if (it->diff_frame_rate != best_diff) { |
- diff_list.erase(it, diff_list.end()); |
- break; |
- } |
- } |
- |
- // Decide the best color format. |
- diff_list.sort(&CompareColor); |
- return diff_list.front().capability_index; |
+ return !capabilities_.empty(); |
} |
void VideoCaptureDeviceWin::SetErrorState(const char* reason) { |