Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: media/video/capture/win/video_capture_device_win.cc

Issue 276383002: VideoCaptureDeviceWin: Extract class-static method into a Factory (both MF/DS) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased factory win. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 76c4c60ebe97b4226e94ee1e1d5e6fa57bcbb514..24d916aaa77f748be33339cfb6ca2b22377deaaa 100644
--- a/media/video/capture/win/video_capture_device_win.cc
+++ b/media/video/capture/win/video_capture_device_win.cc
@@ -10,14 +10,9 @@
#include <algorithm>
#include <list>
-#include "base/command_line.h"
-#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
-#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"
using base::win::ScopedCoMem;
@@ -25,11 +20,12 @@ using base::win::ScopedComPtr;
using base::win::ScopedVariant;
namespace media {
-namespace {
// Finds and creates a DirectShow Video Capture filter matching the device_name.
-HRESULT GetDeviceFilter(const VideoCaptureDevice::Name& device_name,
- IBaseFilter** filter) {
+// static
+HRESULT VideoCaptureDeviceWin::GetDeviceFilter(
+ const VideoCaptureDevice::Name& device_name,
+ IBaseFilter** filter) {
DCHECK(filter);
ScopedComPtr<ICreateDevEnum> dev_enum;
@@ -87,7 +83,8 @@ HRESULT GetDeviceFilter(const VideoCaptureDevice::Name& device_name,
}
// Check if a Pin matches a category.
-bool PinMatchesCategory(IPin* pin, REFGUID category) {
+// static
+bool VideoCaptureDeviceWin::PinMatchesCategory(IPin* pin, REFGUID category) {
DCHECK(pin);
bool found = false;
ScopedComPtr<IKsPropertySet> ks_property;
@@ -105,8 +102,10 @@ bool PinMatchesCategory(IPin* pin, REFGUID category) {
}
// Finds a IPin on a IBaseFilter given the direction an category.
-ScopedComPtr<IPin> GetPin(IBaseFilter* filter, PIN_DIRECTION pin_dir,
- REFGUID category) {
+// static
+ScopedComPtr<IPin> VideoCaptureDeviceWin::GetPin(IBaseFilter* filter,
+ PIN_DIRECTION pin_dir,
+ REFGUID category) {
ScopedComPtr<IPin> pin;
ScopedComPtr<IEnumPins> pin_emum;
HRESULT hr = filter->EnumPins(pin_emum.Receive());
@@ -129,60 +128,9 @@ ScopedComPtr<IPin> GetPin(IBaseFilter* filter, PIN_DIRECTION pin_dir,
return pin;
}
-// Release the format block for a media type.
-// http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
-void FreeMediaType(AM_MEDIA_TYPE* mt) {
- if (mt->cbFormat != 0) {
- CoTaskMemFree(mt->pbFormat);
- mt->cbFormat = 0;
- mt->pbFormat = NULL;
- }
- if (mt->pUnk != NULL) {
- NOTREACHED();
- // pUnk should not be used.
- mt->pUnk->Release();
- mt->pUnk = NULL;
- }
-}
-
-// Delete a media type structure that was allocated on the heap.
-// http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
-void DeleteMediaType(AM_MEDIA_TYPE* mt) {
- if (mt != NULL) {
- FreeMediaType(mt);
- CoTaskMemFree(mt);
- }
-}
-
-// A utility class that wraps the AM_MEDIA_TYPE type and guarantees that
-// we free the structure when exiting the scope. DCHECKing is also done to
-// avoid memory leaks.
-class ScopedMediaType {
- public:
- ScopedMediaType() : media_type_(NULL) {}
- ~ScopedMediaType() { Free(); }
-
- AM_MEDIA_TYPE* operator->() { return media_type_; }
- AM_MEDIA_TYPE* get() { return media_type_; }
-
- void Free() {
- if (!media_type_)
- return;
-
- DeleteMediaType(media_type_);
- media_type_= NULL;
- }
-
- AM_MEDIA_TYPE** Receive() {
- DCHECK(!media_type_);
- return &media_type_;
- }
-
- private:
- AM_MEDIA_TYPE* media_type_;
-};
-
-VideoPixelFormat TranslateMediaSubtypeToPixelFormat(const GUID& sub_type) {
+// static
+VideoPixelFormat VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat(
+ const GUID& sub_type) {
static struct {
const GUID& sub_type;
VideoPixelFormat format;
@@ -207,243 +155,66 @@ VideoPixelFormat TranslateMediaSubtypeToPixelFormat(const GUID& sub_type) {
return PIXEL_FORMAT_UNKNOWN;
}
-} // namespace
+void VideoCaptureDeviceWin::ScopedMediaType::Free() {
+ if (!media_type_)
+ return;
-// 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 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);
- }
+ DeleteMediaType(media_type_);
+ media_type_= NULL;
}
-// static
-void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device,
- 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);
- }
+AM_MEDIA_TYPE** VideoCaptureDeviceWin::ScopedMediaType::Receive() {
+ DCHECK(!media_type_);
+ return &media_type_;
}
-// static
-VideoCaptureDevice* VideoCaptureDevice::Create(
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- const Name& device_name) {
- VideoCaptureDevice* ret = NULL;
- if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) {
- DCHECK(VideoCaptureDeviceMFWin::PlatformSupported());
- scoped_ptr<VideoCaptureDeviceMFWin> device(
- new VideoCaptureDeviceMFWin(device_name));
- DVLOG(1) << " MediaFoundation Device: " << device_name.name();
- if (device->Init())
- ret = device.release();
- } else if (device_name.capture_api_type() == Name::DIRECT_SHOW) {
- scoped_ptr<VideoCaptureDeviceWin> device(
- new VideoCaptureDeviceWin(device_name));
- DVLOG(1) << " DirectShow Device: " << device_name.name();
- if (device->Init())
- ret = device.release();
- } else{
- NOTREACHED() << " Couldn't recognize VideoCaptureDevice type";
+// Release the format block for a media type.
+// http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
+void VideoCaptureDeviceWin::ScopedMediaType::FreeMediaType(AM_MEDIA_TYPE* mt) {
+ if (mt->cbFormat != 0) {
+ CoTaskMemFree(mt->pbFormat);
+ mt->cbFormat = 0;
+ mt->pbFormat = NULL;
}
+ if (mt->pUnk != NULL) {
+ NOTREACHED();
+ // pUnk should not be used.
+ mt->pUnk->Release();
+ mt->pUnk = NULL;
+ }
+}
- return ret;
+// Delete a media type structure that was allocated on the heap.
+// http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
+void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType(
+ AM_MEDIA_TYPE* mt) {
+ if (mt != NULL) {
+ FreeMediaType(mt);
+ CoTaskMemFree(mt);
+ }
}
+// TODO(mcasas): Remove the following static methods when they are no longer
+// referenced from VideoCaptureDeviceFactory, i.e. when all OS platforms have
+// splitted the VideoCaptureDevice into VideoCaptureDevice and
+// VideoCaptureDeviceFactory.
// static
-void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
- DCHECK(device_names);
-
- 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 exist. Therefore the FAILED macro can't be used.
- if (hr != S_OK)
- return;
-
- 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;
- while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
- ScopedComPtr<IPropertyBag> prop_bag;
- hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
- if (FAILED(hr)) {
- moniker.Release();
- continue;
- }
-
- // Find the description or friendly name.
- ScopedVariant name;
- hr = prop_bag->Read(L"Description", name.Receive(), 0);
- if (FAILED(hr))
- hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0);
-
- if (SUCCEEDED(hr) && name.type() == VT_BSTR) {
- // Ignore all VFW drivers and the special Google Camera Adapter.
- // Google Camera Adapter is not a real DirectShow camera device.
- // VFW are very old Video for Windows drivers that can not be used.
- const wchar_t* str_ptr = V_BSTR(&name);
- const int name_length = arraysize(kGoogleCameraAdapter) - 1;
-
- if ((wcsstr(str_ptr, L"(VFW)") == NULL) &&
- lstrlenW(str_ptr) < name_length ||
- (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length,
- kGoogleCameraAdapter)))) {
- std::string id;
- std::string device_name(base::SysWideToUTF8(str_ptr));
- name.Reset();
- hr = prop_bag->Read(L"DevicePath", name.Receive(), 0);
- if (FAILED(hr) || name.type() != VT_BSTR) {
- id = device_name;
- } else {
- DCHECK_EQ(name.type(), VT_BSTR);
- id = base::SysWideToUTF8(V_BSTR(&name));
- }
-
- device_names->push_back(Name(device_name, id, Name::DIRECT_SHOW));
- }
- }
- moniker.Release();
- }
+void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
+ NOTIMPLEMENTED();
}
// static
-void VideoCaptureDeviceWin::GetDeviceSupportedFormats(const Name& device,
+void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device,
VideoCaptureFormats* formats) {
- DVLOG(1) << "GetDeviceSupportedFormats 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 "google camera adapter",
- // since this is already skipped in the enumeration of GetDeviceNames().
- ScopedComPtr<IMoniker> moniker;
- int index = 0;
- ScopedVariant device_id;
- while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
- ScopedComPtr<IPropertyBag> prop_bag;
- hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
- if (FAILED(hr)) {
- moniker.Release();
- continue;
- }
-
- device_id.Reset();
- hr = prop_bag->Read(L"DevicePath", device_id.Receive(), 0);
- if (FAILED(hr)) {
- DVLOG(1) << "Couldn't read a device's DevicePath.";
- return;
- }
- if (device.id() == base::SysWideToUTF8(V_BSTR(&device_id)))
- break;
- moniker.Release();
- }
-
- if (moniker.get()) {
- base::win::ScopedComPtr<IBaseFilter> capture_filter;
- hr = GetDeviceFilter(device, capture_filter.Receive());
- if (!capture_filter) {
- DVLOG(2) << "Failed to create capture filter.";
- return;
- }
-
- base::win::ScopedComPtr<IPin> output_capture_pin(
- GetPin(capture_filter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE));
- if (!output_capture_pin) {
- DVLOG(2) << "Failed to get capture output pin";
- return;
- }
-
- ScopedComPtr<IAMStreamConfig> stream_config;
- hr = output_capture_pin.QueryInterface(stream_config.Receive());
- if (FAILED(hr)) {
- DVLOG(2) << "Failed to get IAMStreamConfig interface from "
- "capture device";
- return;
- }
-
- int count = 0, size = 0;
- hr = stream_config->GetNumberOfCapabilities(&count, &size);
- if (FAILED(hr)) {
- DVLOG(2) << "Failed to GetNumberOfCapabilities";
- return;
- }
-
- scoped_ptr<BYTE[]> caps(new BYTE[size]);
- for (int i = 0; i < count; ++i) {
- 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) {
- DVLOG(2) << "Failed to GetStreamCaps";
- return;
- }
+ NOTIMPLEMENTED();
+}
- if (media_type->majortype == MEDIATYPE_Video &&
- media_type->formattype == FORMAT_VideoInfo) {
- VideoCaptureFormat format;
- format.pixel_format =
- 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) ?
- static_cast<int>(kSecondsToReferenceTime / h->AvgTimePerFrame) :
- 0;
- formats->push_back(format);
- DVLOG(1) << device.name() << " resolution: "
- << format.frame_size.ToString() << ", fps: " << format.frame_rate
- << ", pixel format: " << format.pixel_format;
- }
- }
- }
+// static
+VideoCaptureDevice* VideoCaptureDevice::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
+ const Name& device_name) {
+ NOTIMPLEMENTED();
+ return NULL;
}
VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698