diff options
author | dmichael <dmichael@chromium.org> | 2014-10-30 13:52:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-30 20:52:53 +0000 |
commit | ceeb175aea0b422c14c2611bfb12a850a80cd36a (patch) | |
tree | 36a0db1a9515b36f9a8f0664cf1ce34e0f622710 /media | |
parent | ac77ecc781ff1860e3344b99d6f5a8e9d672dd73 (diff) | |
download | chromium_src-ceeb175aea0b422c14c2611bfb12a850a80cd36a.zip chromium_src-ceeb175aea0b422c14c2611bfb12a850a80cd36a.tar.gz chromium_src-ceeb175aea0b422c14c2611bfb12a850a80cd36a.tar.bz2 |
Revert of Windows video capture: Remove duplicated code from GetDeviceSupportedFormats* (patchset #3 id:200001 of https://codereview.chromium.org/558503003/)
Reason for revert:
See https://code.google.com/p/chromium/issues/detail?id=428958
Original issue's description:
> Windows video capture: Remove duplicated code from GetDeviceSupportedFormats*
>
> The code for GetDeviceSupportedFormatsMediaFoundation and GetDeviceSupportedFormatsDirectShow are already implemented in video_capture_device_mf_win.cc and video_capture_device_win.cc respectively. This CL refactors the implementation so that video_capture_device_factory_win.cc can make use of that code.
>
> Committed: https://crrev.com/b6dae80f8f10b8af1e3026de9f5af4f3128e812a
> Cr-Commit-Position: refs/heads/master@{#301891}
TBR=mcasas@chromium.org,perkj@chromium.org,tommi@chromium.org,magjed@chromium.org
NOTREECHECKS=true
NOTRY=true
Review URL: https://codereview.chromium.org/691143002
Cr-Commit-Position: refs/heads/master@{#302151}
Diffstat (limited to 'media')
5 files changed, 115 insertions, 45 deletions
diff --git a/media/video/capture/win/video_capture_device_factory_win.cc b/media/video/capture/win/video_capture_device_factory_win.cc index 145def8..affad62 100644 --- a/media/video/capture/win/video_capture_device_factory_win.cc +++ b/media/video/capture/win/video_capture_device_factory_win.cc @@ -216,14 +216,27 @@ static void GetDeviceNamesMediaFoundation(Names* device_names) { static void GetDeviceSupportedFormatsDirectShow(const Name& device, VideoCaptureFormats* formats) { DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); + ScopedComPtr<ICreateDevEnum> dev_enum; + HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, + CLSCTX_INPROC); + if (FAILED(hr)) + return; + + ScopedComPtr<IEnumMoniker> enum_moniker; + hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, + enum_moniker.Receive(), 0); + // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera + // exists. Therefore the FAILED macro can't be used. + if (hr != S_OK) + return; + // Walk the capture devices. No need to check for device presence again since // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old // VFW devices are already skipped previously in GetDeviceNames() enumeration. base::win::ScopedComPtr<IBaseFilter> capture_filter; - HRESULT hr = - VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), - CLSID_VideoInputDeviceCategory, - capture_filter.Receive()); + hr = VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), + CLSID_VideoInputDeviceCategory, + capture_filter.Receive()); if (!capture_filter) { DLOG(ERROR) << "Failed to create capture filter: " << logging::SystemErrorCodeToString(hr); @@ -240,15 +253,54 @@ static void GetDeviceSupportedFormatsDirectShow(const Name& device, return; } - CapabilityList capabilities; - if (!VideoCaptureDeviceWin::CreateCapabilityMap( - output_capture_pin, capture_filter, &capabilities)) { - DLOG(ERROR) << "CreateCapabilityMap failed"; + ScopedComPtr<IAMStreamConfig> stream_config; + hr = output_capture_pin.QueryInterface(stream_config.Receive()); + if (FAILED(hr)) { + DLOG(ERROR) << "Failed to get IAMStreamConfig interface from " + "capture device: " << logging::SystemErrorCodeToString(hr); return; } - for (const CapabilityWin& capability : capabilities) - formats->push_back(capability.supported_format); + int count = 0, size = 0; + hr = stream_config->GetNumberOfCapabilities(&count, &size); + if (FAILED(hr)) { + DLOG(ERROR) << "GetNumberOfCapabilities failed: " + << logging::SystemErrorCodeToString(hr); + return; + } + + scoped_ptr<BYTE[]> caps(new BYTE[size]); + for (int i = 0; i < count; ++i) { + VideoCaptureDeviceWin::ScopedMediaType media_type; + hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get()); + // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() + // macros here since they'll trigger incorrectly. + if (hr != S_OK || !media_type.get()) { + DLOG(ERROR) << "GetStreamCaps failed: " + << logging::SystemErrorCodeToString(hr); + return; + } + + if (media_type->majortype == MEDIATYPE_Video && + media_type->formattype == FORMAT_VideoInfo) { + VideoCaptureFormat format; + format.pixel_format = + VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat( + media_type->subtype); + if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) + continue; + VIDEOINFOHEADER* h = + reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); + format.frame_size.SetSize(h->bmiHeader.biWidth, + h->bmiHeader.biHeight); + // Trust the frame rate from the VIDEOINFOHEADER. + format.frame_rate = (h->AvgTimePerFrame > 0) ? + kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) : + 0.0f; + formats->push_back(format); + DVLOG(1) << device.name() << " " << format.ToString(); + } + } } static void GetDeviceSupportedFormatsMediaFoundation( @@ -270,11 +322,45 @@ static void GetDeviceSupportedFormatsMediaFoundation( return; } - CapabilityList capabilities; - VideoCaptureDeviceMFWin::FillCapabilities(reader, &capabilities); + DWORD stream_index = 0; + ScopedComPtr<IMFMediaType> type; + while (SUCCEEDED(reader->GetNativeMediaType( + kFirstVideoStream, stream_index, type.Receive()))) { + UINT32 width, height; + hr = MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &width, &height); + if (FAILED(hr)) { + DLOG(ERROR) << "MFGetAttributeSize failed: " + << logging::SystemErrorCodeToString(hr); + return; + } + VideoCaptureFormat capture_format; + capture_format.frame_size.SetSize(width, height); + + UINT32 numerator, denominator; + hr = MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, &denominator); + if (FAILED(hr)) { + DLOG(ERROR) << "MFGetAttributeSize failed: " + << logging::SystemErrorCodeToString(hr); + return; + } + capture_format.frame_rate = denominator + ? static_cast<float>(numerator) / denominator : 0.0f; + + GUID type_guid; + hr = type->GetGUID(MF_MT_SUBTYPE, &type_guid); + if (FAILED(hr)) { + DLOG(ERROR) << "GetGUID failed: " + << logging::SystemErrorCodeToString(hr); + return; + } + VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, + &capture_format.pixel_format); + type.Release(); + formats->push_back(capture_format); + ++stream_index; - for (const CapabilityWin& capability : capabilities) - formats->push_back(capability.supported_format); + DVLOG(1) << device.name() << " " << capture_format.ToString(); + } } // Returns true iff the current platform supports the Media Foundation API @@ -367,13 +453,10 @@ void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( const Name& device, VideoCaptureFormats* formats) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(formats); if (use_media_foundation_) GetDeviceSupportedFormatsMediaFoundation(device, formats); else GetDeviceSupportedFormatsDirectShow(device, formats); - for (const VideoCaptureFormat& format : *formats) - DVLOG(1) << device.name() << " " << format.ToString(); } } // namespace media diff --git a/media/video/capture/win/video_capture_device_mf_win.cc b/media/video/capture/win/video_capture_device_mf_win.cc index e59f725..a222d1c 100644 --- a/media/video/capture/win/video_capture_device_mf_win.cc +++ b/media/video/capture/win/video_capture_device_mf_win.cc @@ -58,9 +58,8 @@ static bool FillFormat(IMFMediaType* type, VideoCaptureFormat* format) { return true; } -HRESULT VideoCaptureDeviceMFWin::FillCapabilities( - IMFSourceReader* source, - CapabilityList* capabilities) { +HRESULT FillCapabilities(IMFSourceReader* source, + CapabilityList* capabilities) { DWORD stream_index = 0; ScopedComPtr<IMFMediaType> type; HRESULT hr; diff --git a/media/video/capture/win/video_capture_device_mf_win.h b/media/video/capture/win/video_capture_device_mf_win.h index e17896d..fc11d19 100644 --- a/media/video/capture/win/video_capture_device_mf_win.h +++ b/media/video/capture/win/video_capture_device_mf_win.h @@ -19,7 +19,6 @@ #include "base/win/scoped_comptr.h" #include "media/base/media_export.h" #include "media/video/capture/video_capture_device.h" -#include "media/video/capture/win/capability_list_win.h" interface IMFSourceReader; @@ -35,8 +34,6 @@ class MEDIA_EXPORT VideoCaptureDeviceMFWin public VideoCaptureDevice { public: static bool FormatFromGuid(const GUID& guid, VideoPixelFormat* format); - static HRESULT FillCapabilities(IMFSourceReader* source, - CapabilityList* capabilities); explicit VideoCaptureDeviceMFWin(const Name& device_name); virtual ~VideoCaptureDeviceMFWin(); diff --git a/media/video/capture/win/video_capture_device_win.cc b/media/video/capture/win/video_capture_device_win.cc index de21300..83e1bd3 100644 --- a/media/video/capture/win/video_capture_device_win.cc +++ b/media/video/capture/win/video_capture_device_win.cc @@ -306,8 +306,7 @@ bool VideoCaptureDeviceWin::Init() { return false; } - return CreateCapabilityMap( - output_capture_pin_, capture_filter_, &capabilities_); + return CreateCapabilityMap(); } void VideoCaptureDeviceWin::AllocateAndStart( @@ -474,12 +473,11 @@ void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer, buffer, length, capture_format_, 0, base::TimeTicks::Now()); } -bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, - IBaseFilter* capture_filter, - CapabilityList* capabilities) { +bool VideoCaptureDeviceWin::CreateCapabilityMap() { + DCHECK(CalledOnValidThread()); ScopedComPtr<IAMStreamConfig> stream_config; - HRESULT hr = output_capture_pin->QueryInterface(stream_config.Receive()); - if (FAILED(hr) || !stream_config) { + HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); + if (FAILED(hr)) { DPLOG(ERROR) << "Failed to get IAMStreamConfig interface from " "capture device: " << logging::SystemErrorCodeToString(hr); return false; @@ -487,10 +485,9 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, // Get interface used for getting the frame rate. ScopedComPtr<IAMVideoControl> video_control; - hr = capture_filter->QueryInterface(video_control.Receive()); - DLOG_IF(WARNING, FAILED(hr) || !video_control) - << "IAMVideoControl Interface NOT SUPPORTED: " - << logging::SystemErrorCodeToString(hr); + hr = capture_filter_.QueryInterface(video_control.Receive()); + DLOG_IF(WARNING, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED: " + << logging::SystemErrorCodeToString(hr); int count = 0, size = 0; hr = stream_config->GetNumberOfCapabilities(&count, &size); @@ -507,7 +504,7 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, stream_index, media_type.Receive(), caps.get()); // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() // macros here since they'll trigger incorrectly. - if (hr != S_OK || !media_type.get()) { + if (hr != S_OK) { DLOG(ERROR) << "Failed to GetStreamCaps: " << logging::SystemErrorCodeToString(hr); return false; @@ -523,10 +520,6 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); - if (!h) { - DLOG(ERROR) << "VIDEOINFOHEADER is NULL"; - continue; - } format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); // Try to get a better |time_per_frame| from IAMVideoControl. If not, use @@ -538,7 +531,7 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, const SIZE size = {format.frame_size.width(), format.frame_size.height()}; hr = video_control->GetFrameRateList( - output_capture_pin, stream_index, size, &list_size, &max_fps); + output_capture_pin_, stream_index, size, &list_size, &max_fps); // Can't assume the first value will return the max fps. // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates @@ -554,11 +547,11 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap(IPin* output_capture_pin, ? (kSecondsToReferenceTime / static_cast<float>(time_per_frame)) : 0.0; - capabilities->emplace_back(stream_index, format); + capabilities_.emplace_back(stream_index, format); } } - return !capabilities->empty(); + return !capabilities_.empty(); } // Set the power line frequency removal in |capture_filter_| if available. diff --git a/media/video/capture/win/video_capture_device_win.h b/media/video/capture/win/video_capture_device_win.h index cd46d78..a52aba6a 100644 --- a/media/video/capture/win/video_capture_device_win.h +++ b/media/video/capture/win/video_capture_device_win.h @@ -62,9 +62,6 @@ class VideoCaptureDeviceWin REFGUID major_type); static VideoPixelFormat TranslateMediaSubtypeToPixelFormat( const GUID& sub_type); - static bool CreateCapabilityMap(IPin* output_capture_pin, - IBaseFilter* capture_filter, - CapabilityList* capabilities); explicit VideoCaptureDeviceWin(const Name& device_name); virtual ~VideoCaptureDeviceWin(); @@ -88,6 +85,7 @@ class VideoCaptureDeviceWin // Implements SinkFilterObserver. virtual void FrameReceived(const uint8* buffer, int length); + bool CreateCapabilityMap(); void SetAntiFlickerInCaptureFilter(); HRESULT InstantiateWDMFiltersAndPins(); HRESULT AddWDMCrossbarFilterToGraphAndConnect(); |