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

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

Issue 1806883004: Use the encoded video mode for capture setup of decklink devices. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update code style Created 4 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/capture/video/mac/video_capture_device_decklink_mac.h" 5 #include "media/capture/video/mac/video_capture_device_decklink_mac.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/strings/sys_string_conversions.h" 12 #include "base/strings/sys_string_conversions.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "third_party/decklink/mac/include/DeckLinkAPI.h" 14 #include "third_party/decklink/mac/include/DeckLinkAPI.h"
15 15
16
16 namespace { 17 namespace {
17 18
19 static std::string JoinDeviceNameAndFormat(CFStringRef name,
20 CFStringRef format);
21
18 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only 22 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only
19 // available for Windows builds. This is a verbatim knock-off of the needed 23 // available for Windows builds. This is a verbatim knock-off of the needed
20 // parts of base::win::ScopedComPtr<> for ref counting. 24 // parts of base::win::ScopedComPtr<> for ref counting.
21 template <class T> 25 template <class T>
22 class ScopedDeckLinkPtr : public scoped_refptr<T> { 26 class ScopedDeckLinkPtr : public scoped_refptr<T> {
23 private: 27 private:
24 using scoped_refptr<T>::ptr_; 28 using scoped_refptr<T>::ptr_;
25 29
26 public: 30 public:
27 T** Receive() { 31 T** Receive() {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 135
132 void DeckLinkCaptureDelegate::AllocateAndStart( 136 void DeckLinkCaptureDelegate::AllocateAndStart(
133 const media::VideoCaptureParams& params) { 137 const media::VideoCaptureParams& params) {
134 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
135 scoped_refptr<IDeckLinkIterator> decklink_iter( 139 scoped_refptr<IDeckLinkIterator> decklink_iter(
136 CreateDeckLinkIteratorInstance()); 140 CreateDeckLinkIteratorInstance());
137 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; 141 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator";
138 if (!decklink_iter.get()) 142 if (!decklink_iter.get())
139 return; 143 return;
140 144
141 ScopedDeckLinkPtr<IDeckLink> decklink_local; 145 ScopedDeckLinkPtr<IDeckLink> chosen_device;
142 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { 146 ScopedDeckLinkPtr<IDeckLinkInput> chosen_input;
143 CFStringRef device_model_name = NULL; 147 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
144 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || 148 ScopedDeckLinkPtr<IDeckLink> decklink;
145 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) { 149 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
146 break; 150 ScopedDeckLinkPtr<IDeckLink> decklink_local;
151 decklink_local.swap(decklink);
152
153 CFStringRef device_model_name = nil;
154 HRESULT hr = decklink_local->GetModelName(&device_model_name);
155 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device model name";
mcasas 2016/04/19 21:53:32 DLOG_IF(ERROR, condition) here and elsewhere.
jensf 2016/04/21 07:29:47 Done.
156 CFStringRef device_display_name = NULL;
mcasas 2016/04/19 21:53:32 Actually CFStringRef is a C++ construct, so it sho
jensf 2016/04/21 07:29:47 Done.
157 hr = decklink_local->GetDisplayName(&device_display_name);
158 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device display name";
159 DVLOG_IF(1, hr == S_OK) << "Blackmagic device found with name: "
160 << base::SysCFStringRefToUTF8(device_display_name);
161
162 if (!device_model_name && !device_display_name)
163 continue;
164
165 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
166 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
167 decklink_input.ReceiveVoid()) != S_OK) {
168 DLOG(ERROR) << "Error Blackmagic querying input interface.";
169 return;
170 }
171
172 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
173 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
174 S_OK) {
175 continue;
176 }
177
178 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
179 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
180 CFStringRef format_name = NULL;
181 if (display_mode->GetName(&format_name) == S_OK) {
182 media::VideoCaptureDevice::Name name(
183 JoinDeviceNameAndFormat(device_display_name, format_name),
184 JoinDeviceNameAndFormat(device_model_name, format_name),
185 media::VideoCaptureDevice::Name::DECKLINK,
186 media::VideoCaptureDevice::Name::OTHER_TRANSPORT);
187
188 if (device_name_.id() == name.id()) {
189 chosen_device.swap(decklink_local);
190 chosen_input.swap(decklink_input);
191 chosen_display_mode.swap(display_mode);
192 break;
193 }
194
195 DVLOG(1) << "Blackmagic camera enumerated: " << name.name();
196 }
197 display_mode.Release();
147 } 198 }
148 } 199 }
149 if (!decklink_local.get()) {
150 SendErrorString(FROM_HERE, "Device id not found in the system");
151 return;
152 }
153 200
154 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local;
155 if (decklink_local->QueryInterface(
156 IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) {
157 SendErrorString(FROM_HERE, "Error querying input interface.");
158 return;
159 }
160
161 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
162 if (decklink_input_local->GetDisplayModeIterator(
163 display_mode_iter.Receive()) != S_OK) {
164 SendErrorString(FROM_HERE, "Error creating Display Mode Iterator");
165 return;
166 }
167
168 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
169 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
170 float min_diff = FLT_MAX;
171 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
172 const float diff = labs(display_mode->GetWidth() -
173 params.requested_format.frame_size.width()) +
174 labs(params.requested_format.frame_size.height() -
175 display_mode->GetHeight()) +
176 fabs(params.requested_format.frame_rate -
177 GetDisplayModeFrameRate(display_mode));
178 if (diff < min_diff) {
179 chosen_display_mode = display_mode;
180 min_diff = diff;
181 }
182 display_mode.Release();
183 }
184 if (!chosen_display_mode.get()) { 201 if (!chosen_display_mode.get()) {
185 SendErrorString(FROM_HERE, "Could not find a display mode"); 202 SendErrorString(FROM_HERE, "Could not find a display mode");
186 return; 203 return;
187 } 204 }
188 #if !defined(NDEBUG) 205 #if !defined(NDEBUG)
189 DVLOG(1) << "Requested format: " 206 DVLOG(1) << "Requested format: "
190 << media::VideoCaptureFormat::ToString(params.requested_format); 207 << media::VideoCaptureFormat::ToString(params.requested_format);
191 CFStringRef format_name = NULL; 208 CFStringRef format_name = NULL;
192 if (chosen_display_mode->GetName(&format_name) == S_OK) 209 if (chosen_display_mode->GetName(&format_name) == S_OK)
193 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name); 210 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name);
194 #endif 211 #endif
195 212
196 // Enable video input. Configure for no input video format change detection, 213 // Enable video input. Configure for no input video format change detection,
197 // this in turn will disable calls to VideoInputFormatChanged(). 214 // this in turn will disable calls to VideoInputFormatChanged().
198 if (decklink_input_local->EnableVideoInput( 215 if (chosen_input->EnableVideoInput(chosen_display_mode->GetDisplayMode(),
199 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, 216 bmdFormat8BitYUV,
200 bmdVideoInputFlagDefault) != S_OK) { 217 bmdVideoInputFlagDefault) != S_OK) {
201 SendErrorString(FROM_HERE, "Could not select the video format we like."); 218 SendErrorString(FROM_HERE, "Could not select the video format we like.");
202 return; 219 return;
203 } 220 }
204 221
205 decklink_input_local->SetCallback(this); 222 chosen_input->SetCallback(this);
206 if (decklink_input_local->StartStreams() != S_OK) 223 if (chosen_input->StartStreams() != S_OK) {
207 SendErrorString(FROM_HERE, "Could not start capturing"); 224 SendErrorString(FROM_HERE, "Could not start capturing");
208 225 }
209 decklink_.swap(decklink_local); 226 decklink_.swap(chosen_device);
210 decklink_input_.swap(decklink_input_local); 227 decklink_input_.swap(chosen_input);
211 } 228 }
212 229
213 void DeckLinkCaptureDelegate::StopAndDeAllocate() { 230 void DeckLinkCaptureDelegate::StopAndDeAllocate() {
214 DCHECK(thread_checker_.CalledOnValidThread()); 231 DCHECK(thread_checker_.CalledOnValidThread());
215 if (!decklink_input_.get()) 232 if (!decklink_input_.get())
216 return; 233 return;
217 if (decklink_input_->StopStreams() != S_OK) 234 if (decklink_input_->StopStreams() != S_OK)
218 SendLogString("Problem stopping capture."); 235 SendLogString("Problem stopping capture.");
219 decklink_input_->SetCallback(NULL); 236 decklink_input_->SetCallback(NULL);
220 decklink_input_->DisableVideoInput(); 237 decklink_input_->DisableVideoInput();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if (frame_receiver_) 322 if (frame_receiver_)
306 frame_receiver_->SendLogString(message); 323 frame_receiver_->SendLogString(message);
307 } 324 }
308 325
309 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() { 326 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() {
310 DCHECK(thread_checker_.CalledOnValidThread()); 327 DCHECK(thread_checker_.CalledOnValidThread());
311 base::AutoLock lock(lock_); 328 base::AutoLock lock(lock_);
312 frame_receiver_ = NULL; 329 frame_receiver_ = NULL;
313 } 330 }
314 331
315 } // namespace
316
317 namespace media {
318 332
319 static std::string JoinDeviceNameAndFormat(CFStringRef name, 333 static std::string JoinDeviceNameAndFormat(CFStringRef name,
320 CFStringRef format) { 334 CFStringRef format) {
321 return base::SysCFStringRefToUTF8(name) + " - " + 335 return base::SysCFStringRefToUTF8(name) + " - " +
322 base::SysCFStringRefToUTF8(format); 336 base::SysCFStringRefToUTF8(format);
323 } 337 }
324 338
339
340 } // namespace
341
342 namespace media {
343
325 // static 344 // static
326 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices( 345 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices(
327 VideoCaptureDevice::Names* device_names) { 346 VideoCaptureDevice::Names* device_names) {
328 scoped_refptr<IDeckLinkIterator> decklink_iter( 347 scoped_refptr<IDeckLinkIterator> decklink_iter(
329 CreateDeckLinkIteratorInstance()); 348 CreateDeckLinkIteratorInstance());
330 // At this point, not being able to create a DeckLink iterator means that 349 // At this point, not being able to create a DeckLink iterator means that
331 // there are no Blackmagic DeckLink devices in the system, don't print error. 350 // there are no Blackmagic DeckLink devices in the system, don't print error.
332 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator"; 351 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator";
333 if (!decklink_iter.get()) 352 if (!decklink_iter.get())
334 return; 353 return;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (decklink_capture_delegate_.get()) 502 if (decklink_capture_delegate_.get())
484 decklink_capture_delegate_->AllocateAndStart(params); 503 decklink_capture_delegate_->AllocateAndStart(params);
485 } 504 }
486 505
487 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { 506 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
488 if (decklink_capture_delegate_.get()) 507 if (decklink_capture_delegate_.get())
489 decklink_capture_delegate_->StopAndDeAllocate(); 508 decklink_capture_delegate_->StopAndDeAllocate();
490 } 509 }
491 510
492 } // namespace media 511 } // namespace media
OLDNEW
« 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