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

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

Issue 156583004: Add GetDeviceSupportedFormats to Win DirectShow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 | « no previous file | 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 c0bd9d27ca51880574fb7a6158932c7c7d873f1f..1dd96d9b9a66eef60cd41adab61f57d70c5d3527 100644
--- a/media/video/capture/win/video_capture_device_win.cc
+++ b/media/video/capture/win/video_capture_device_win.cc
@@ -150,6 +150,31 @@ void DeleteMediaType(AM_MEDIA_TYPE* mt) {
}
}
+VideoPixelFormat TranslateMediaSubtypeToPixelFormat(GUID subtype) {
tommi (sloooow) - chröme 2014/02/17 12:58:29 sub_type? Also, pass by const&?
mcasas 2014/02/17 14:56:20 Done.
+ // We can't use a GUID in a switch-case, this applies to |subtype|.
+ if (subtype == kMediaSubTypeI420) {
tommi (sloooow) - chröme 2014/02/17 12:58:29 I would like to see this data driven instead of mu
mcasas 2014/02/17 14:56:20 Done.
+ return PIXEL_FORMAT_I420;
+ } else if (subtype == MEDIASUBTYPE_IYUV) {
+ // This is identical to PIXEL_FORMAT_I420.
+ return PIXEL_FORMAT_I420;
+ } else if (subtype == MEDIASUBTYPE_RGB24) {
+ return PIXEL_FORMAT_RGB24;
+ } else if (subtype == MEDIASUBTYPE_YUY2) {
+ return PIXEL_FORMAT_YUY2;
+ } else if (subtype == MEDIASUBTYPE_MJPG) {
+ return PIXEL_FORMAT_MJPEG;
+ } else if (subtype == MEDIASUBTYPE_UYVY) {
+ return PIXEL_FORMAT_UYVY;
+ } else if (subtype == MEDIASUBTYPE_ARGB32) {
+ return PIXEL_FORMAT_ARGB;
+ } else {
+ WCHAR guid_str[128];
+ StringFromGUID2(subtype, guid_str, arraysize(guid_str));
tommi (sloooow) - chröme 2014/02/17 12:58:29 (I know this is just moved code) This should be in
mcasas 2014/02/17 14:56:20 Done.
+ DVLOG(2) << "Device supports (also) an unknown media type " << guid_str;
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+}
+
} // namespace
// static
@@ -254,7 +279,7 @@ void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
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 is very old Video for Windows drivers that can not be used.
+ // 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;
@@ -283,7 +308,107 @@ void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
// static
void VideoCaptureDeviceWin::GetDeviceSupportedFormats(const Name& device,
VideoCaptureFormats* formats) {
- NOTIMPLEMENTED();
+ 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".
tommi (sloooow) - chröme 2014/02/17 12:58:29 maybe elaborate on why not?
mcasas 2014/02/17 14:56:20 Done.
+ 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;
+ hr = GetPin(capture_filter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE,
+ output_capture_pin.Receive());
+ 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, size;
+ hr = stream_config->GetNumberOfCapabilities(&count, &size);
+ if (FAILED(hr)) {
+ DVLOG(2) << "Failed to GetNumberOfCapabilities";
+ return;
+ }
+
+ AM_MEDIA_TYPE* media_type = NULL;
+ VIDEO_STREAM_CONFIG_CAPS caps;
+ for (int i = 0; i < count; ++i) {
+ hr = stream_config->GetStreamCaps(i, &media_type,
+ reinterpret_cast<BYTE*>(&caps));
+ // 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;
+ }
+
+ if (media_type->majortype == MEDIATYPE_Video &&
+ media_type->formattype == FORMAT_VideoInfo) {
+ VIDEOINFOHEADER* h =
+ reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
+ VideoCaptureFormat format;
+ 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)
tommi (sloooow) - chröme 2014/02/17 12:58:29 nit: I think the convention is to have the operato
mcasas 2014/02/17 14:56:20 Done.
+ : 0;
+ format.pixel_format =
+ TranslateMediaSubtypeToPixelFormat(media_type->subtype);
+ formats->push_back(format);
+ DVLOG(1) << device.name() << " resolution: "
+ << format.frame_size.ToString() << ", fps: " << format.frame_rate
+ << ", pixel format: " << format.pixel_format;
+ }
+ }
+ }
}
VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
@@ -582,28 +707,8 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
capability.frame_rate_numerator = capability.supported_format.frame_rate;
capability.frame_rate_denominator = 1;
- // We can't switch MEDIATYPE :~(.
- if (media_type->subtype == kMediaSubTypeI420) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_I420;
- } else if (media_type->subtype == MEDIASUBTYPE_IYUV) {
- // This is identical to PIXEL_FORMAT_I420.
- capability.supported_format.pixel_format = PIXEL_FORMAT_I420;
- } else if (media_type->subtype == MEDIASUBTYPE_RGB24) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_RGB24;
- } else if (media_type->subtype == MEDIASUBTYPE_YUY2) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_YUY2;
- } else if (media_type->subtype == MEDIASUBTYPE_MJPG) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_MJPEG;
- } else if (media_type->subtype == MEDIASUBTYPE_UYVY) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_UYVY;
- } else if (media_type->subtype == MEDIASUBTYPE_ARGB32) {
- capability.supported_format.pixel_format = PIXEL_FORMAT_ARGB;
- } else {
- WCHAR guid_str[128];
- StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str));
- DVLOG(2) << "Device supports (also) an unknown media type " << guid_str;
- continue;
- }
+ capability.supported_format.pixel_format =
+ TranslateMediaSubtypeToPixelFormat(media_type->subtype);
capabilities_.Add(capability);
}
DeleteMediaType(media_type);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698