diff options
Diffstat (limited to 'media/video/capture/win/video_capture_device_win.cc')
-rw-r--r-- | media/video/capture/win/video_capture_device_win.cc | 153 |
1 files changed, 41 insertions, 112 deletions
diff --git a/media/video/capture/win/video_capture_device_win.cc b/media/video/capture/win/video_capture_device_win.cc index 5a587b5..721fb25 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) { |