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

Side by Side Diff: media/video/capture/mac/video_capture_device_decklink_mac.mm

Issue 518073002: Mac VideoCapture: Support for Blackmagic DeckLink device & capabilities enumeration, using SDK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Change enumeration: instead of 1 dev x N format --> N devs x 1 format each. Created 6 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/video/capture/mac/video_capture_device_decklink_mac.h"
6
7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "third_party/decklink/mac/include/DeckLinkAPI.h"
11
12 namespace {
13
14 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only
15 // available for Windows builds. This is a verbatim knock-off of the needed
16 // parts of base::win::ScopedComPtr<> for ref counting.
17 template <class T>
18 class ScopedDeckLinkPtr : public scoped_refptr<T> {
19 public:
20 using scoped_refptr<T>::ptr_;
21
22 T** Receive() {
23 DCHECK(!ptr_) << "Object leak. Pointer must be NULL";
24 return &ptr_;
25 }
26
27 void** ReceiveVoid() {
28 return reinterpret_cast<void**>(Receive());
29 }
30
31 void Release() {
32 if (ptr_ != NULL) {
33 ptr_->Release();
34 ptr_ = NULL;
35 }
36 }
37 };
38
39 } // namespace
40
41 namespace media {
42
43 std::string JoinDeviceNameAndFormat(CFStringRef name, CFStringRef format) {
44 return base::SysCFStringRefToUTF8(name) + " - " +
45 base::SysCFStringRefToUTF8(format);
46 }
47
48 //static
49 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices(
50 VideoCaptureDevice::Names* device_names) {
51 scoped_refptr<IDeckLinkIterator> decklink_iter(
52 CreateDeckLinkIteratorInstance());
53 // At this point, not being able to create a DeckLink iterator means that
54 // there are no Blackmagic DeckLink devices in the system, don't print error.
perkj_chrome 2014/09/15 09:13:16 What do you mean by" don't print error." ?
mcasas 2014/09/22 08:39:09 Rewritten. What I meant is that l.55 is a DVLOG_IF
55 DVLOG_IF(1, !decklink_iter) << "Could not create DeckLink iterator";
56 if (!decklink_iter)
57 return;
58
59 ScopedDeckLinkPtr<IDeckLink> decklink;
60 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
61 ScopedDeckLinkPtr<IDeckLink> decklink_local;
62 decklink_local.swap(decklink);
63
64 CFStringRef device_model_name = NULL;
65 HRESULT hr = decklink_local->GetModelName(&device_model_name);
66 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device model name";
67 CFStringRef device_display_name = NULL;
68 hr = decklink_local->GetDisplayName(&device_display_name);
69 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device display name";
70 DVLOG_IF(1, hr == S_OK) << "Blackmagic device found with name: " <<
71 base::SysCFStringRefToUTF8(device_display_name);
72
73 if (!device_model_name && !device_display_name)
74 continue;
75
76 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
77 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
78 decklink_input.ReceiveVoid()) != S_OK) {
79 DLOG(ERROR) << "Error Blackmagic querying input interface.";
80 return;
81 }
82
83 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
84 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
85 S_OK) {
86 continue;
87 }
88
89 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
90 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
91 CFStringRef format_name = NULL;
92 if (display_mode->GetName(&format_name) == S_OK) {
93 VideoCaptureDevice::Name name(
94 JoinDeviceNameAndFormat(device_display_name, format_name),
95 JoinDeviceNameAndFormat(device_model_name, format_name),
96 VideoCaptureDevice::Name::DECKLINK,
97 VideoCaptureDevice::Name::OTHER_TRANSPORT);
98 device_names->push_back(name);
99 DVLOG(1) << "Blackmagic camera enumerated: " << name.name();
100 }
101 display_mode.Release();
102 }
103 }
104 }
105
106 // static
107 void VideoCaptureDeviceDeckLinkMac::EnumerateDeviceCapabilities(
108 const VideoCaptureDevice::Name& device,
109 VideoCaptureFormats* supported_formats) {
110 scoped_refptr<IDeckLinkIterator> decklink_iter(
111 CreateDeckLinkIteratorInstance());
112 DLOG_IF(ERROR, !decklink_iter) << "Error creating DeckLink iterator";
113 if (!decklink_iter)
114 return;
115
116 ScopedDeckLinkPtr<IDeckLink> decklink;
117 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
118 ScopedDeckLinkPtr<IDeckLink> decklink_local;
119 decklink_local.swap(decklink);
120
121 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
122 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
123 decklink_input.ReceiveVoid()) != S_OK) {
perkj_chrome 2014/09/15 09:13:16 4 more spaces right?
mcasas 2014/09/22 08:39:09 Done.
124 DLOG(ERROR) << "Error Blackmagic querying input interface.";
125 return;
126 }
127
128 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
129 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
130 S_OK) {
131 continue;
132 }
133
134 CFStringRef device_model_name = NULL;
135 if (decklink_local->GetModelName(&device_model_name) != S_OK)
136 continue;
137
138 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
139 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
140 CFStringRef format_name = NULL;
141 if (display_mode->GetName(&format_name) == S_OK && device.id() !=
perkj_chrome 2014/09/15 09:13:16 nit : prever to move device.id() != to the next li
mcasas 2014/09/22 08:39:09 Would love to but then I'd have to break the next
142 JoinDeviceNameAndFormat(device_model_name, format_name)) {
143 display_mode.Release();
144 continue;
145 }
146
147 // IDeckLinkDisplayMode does not have information on pixel format, this
148 // is only available on capture.
149 media::VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN;
150 BMDTimeValue time_value, time_scale;
151 float frame_rate = 0.0f;
152 if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK &&
153 time_value > 0) {
154 frame_rate = static_cast<float>(time_scale) / time_value;
155 }
156 media::VideoCaptureFormat format(
157 gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()),
158 frame_rate,
159 pixel_format);
160 supported_formats->push_back(format);
161 DVLOG(2) << device.name() << " " << format.ToString();
162 display_mode.Release();
163 }
164 return;
165 }
166 }
167
168 VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac(
169 const Name& device_name) {}
170
171 VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() {}
172
173 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart(
174 const VideoCaptureParams& params,
175 scoped_ptr<VideoCaptureDevice::Client> client) {
176 NOTIMPLEMENTED();
177 }
178
179 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
180 NOTIMPLEMENTED();
181 }
182
183 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698