summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authordmichael <dmichael@chromium.org>2014-10-30 13:52:28 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-30 20:52:53 +0000
commitceeb175aea0b422c14c2611bfb12a850a80cd36a (patch)
tree36a0db1a9515b36f9a8f0664cf1ce34e0f622710 /media
parentac77ecc781ff1860e3344b99d6f5a8e9d672dd73 (diff)
downloadchromium_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')
-rw-r--r--media/video/capture/win/video_capture_device_factory_win.cc117
-rw-r--r--media/video/capture/win/video_capture_device_mf_win.cc5
-rw-r--r--media/video/capture/win/video_capture_device_mf_win.h3
-rw-r--r--media/video/capture/win/video_capture_device_win.cc31
-rw-r--r--media/video/capture/win/video_capture_device_win.h4
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();