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

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: updated code style the next 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 namespace { 16 namespace {
17 17
18 static std::string JoinDeviceNameAndFormat(CFStringRef name,
19 CFStringRef format);
20
18 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only 21 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only
19 // available for Windows builds. This is a verbatim knock-off of the needed 22 // available for Windows builds. This is a verbatim knock-off of the needed
20 // parts of base::win::ScopedComPtr<> for ref counting. 23 // parts of base::win::ScopedComPtr<> for ref counting.
21 template <class T> 24 template <class T>
22 class ScopedDeckLinkPtr : public scoped_refptr<T> { 25 class ScopedDeckLinkPtr : public scoped_refptr<T> {
23 private: 26 private:
24 using scoped_refptr<T>::ptr_; 27 using scoped_refptr<T>::ptr_;
25 28
26 public: 29 public:
27 T** Receive() { 30 T** Receive() {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 134
132 void DeckLinkCaptureDelegate::AllocateAndStart( 135 void DeckLinkCaptureDelegate::AllocateAndStart(
133 const media::VideoCaptureParams& params) { 136 const media::VideoCaptureParams& params) {
134 DCHECK(thread_checker_.CalledOnValidThread()); 137 DCHECK(thread_checker_.CalledOnValidThread());
135 scoped_refptr<IDeckLinkIterator> decklink_iter( 138 scoped_refptr<IDeckLinkIterator> decklink_iter(
136 CreateDeckLinkIteratorInstance()); 139 CreateDeckLinkIteratorInstance());
137 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; 140 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator";
138 if (!decklink_iter.get()) 141 if (!decklink_iter.get())
139 return; 142 return;
140 143
141 ScopedDeckLinkPtr<IDeckLink> decklink_local; 144 ScopedDeckLinkPtr<IDeckLink> chosen_device;
142 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { 145 ScopedDeckLinkPtr<IDeckLinkInput> chosen_input;
143 CFStringRef device_model_name = NULL; 146 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
144 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || 147 ScopedDeckLinkPtr<IDeckLink> decklink;
145 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) { 148 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
146 break; 149 ScopedDeckLinkPtr<IDeckLink> decklink_local;
150 decklink_local.swap(decklink);
151
152 CFStringRef device_model_name = nil;
153 HRESULT hr = decklink_local->GetModelName(&device_model_name);
154 DLOG_IF(ERROR, hr != S_OK) << "Error reading Blackmagic device model name";
155 CFStringRef device_display_name = nullptr;
156 hr = decklink_local->GetDisplayName(&device_display_name);
157 DLOG_IF(ERROR, hr != S_OK)
158 << "Error reading Blackmagic device display name";
159 DLOG_IF(ERROR, hr == S_OK)
160 << "Blackmagic device found with name: "
161 << base::SysCFStringRefToUTF8(device_display_name);
162
163 if (!device_model_name && !device_display_name)
164 continue;
165
166 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
167 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
168 decklink_input.ReceiveVoid()) != S_OK) {
169 DLOG(ERROR) << "Error Blackmagic querying input interface.";
170 return;
171 }
172
173 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
174 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
175 S_OK) {
176 continue;
177 }
178
179 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
180 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
181 CFStringRef format_name = NULL;
182 if (display_mode->GetName(&format_name) == S_OK) {
183 media::VideoCaptureDevice::Name name(
184 JoinDeviceNameAndFormat(device_display_name, format_name),
185 JoinDeviceNameAndFormat(device_model_name, format_name),
186 media::VideoCaptureDevice::Name::DECKLINK,
187 media::VideoCaptureDevice::Name::OTHER_TRANSPORT);
188
189 if (device_name_.id() == name.id()) {
190 chosen_device.swap(decklink_local);
191 chosen_input.swap(decklink_input);
192 chosen_display_mode.swap(display_mode);
193 break;
194 }
195
196 DVLOG(1) << "Blackmagic camera enumerated: " << name.name();
197 }
198 display_mode.Release();
147 } 199 }
148 } 200 }
149 if (!decklink_local.get()) {
150 SendErrorString(FROM_HERE, "Device id not found in the system");
151 return;
152 }
153 201
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()) { 202 if (!chosen_display_mode.get()) {
185 SendErrorString(FROM_HERE, "Could not find a display mode"); 203 SendErrorString(FROM_HERE, "Could not find a display mode");
186 return; 204 return;
187 } 205 }
188 #if !defined(NDEBUG) 206 #if !defined(NDEBUG)
189 DVLOG(1) << "Requested format: " 207 DVLOG(1) << "Requested format: "
190 << media::VideoCaptureFormat::ToString(params.requested_format); 208 << media::VideoCaptureFormat::ToString(params.requested_format);
191 CFStringRef format_name = NULL; 209 CFStringRef format_name = NULL;
192 if (chosen_display_mode->GetName(&format_name) == S_OK) 210 if (chosen_display_mode->GetName(&format_name) == S_OK)
193 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name); 211 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name);
194 #endif 212 #endif
195 213
196 // Enable video input. Configure for no input video format change detection, 214 // Enable video input. Configure for no input video format change detection,
197 // this in turn will disable calls to VideoInputFormatChanged(). 215 // this in turn will disable calls to VideoInputFormatChanged().
198 if (decklink_input_local->EnableVideoInput( 216 if (chosen_input->EnableVideoInput(chosen_display_mode->GetDisplayMode(),
199 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, 217 bmdFormat8BitYUV,
200 bmdVideoInputFlagDefault) != S_OK) { 218 bmdVideoInputFlagDefault) != S_OK) {
201 SendErrorString(FROM_HERE, "Could not select the video format we like."); 219 SendErrorString(FROM_HERE, "Could not select the video format we like.");
202 return; 220 return;
203 } 221 }
204 222
205 decklink_input_local->SetCallback(this); 223 chosen_input->SetCallback(this);
206 if (decklink_input_local->StartStreams() != S_OK) 224 if (chosen_input->StartStreams() != S_OK) {
207 SendErrorString(FROM_HERE, "Could not start capturing"); 225 SendErrorString(FROM_HERE, "Could not start capturing");
208 226 }
209 decklink_.swap(decklink_local); 227 decklink_.swap(chosen_device);
210 decklink_input_.swap(decklink_input_local); 228 decklink_input_.swap(chosen_input);
211 } 229 }
212 230
213 void DeckLinkCaptureDelegate::StopAndDeAllocate() { 231 void DeckLinkCaptureDelegate::StopAndDeAllocate() {
214 DCHECK(thread_checker_.CalledOnValidThread()); 232 DCHECK(thread_checker_.CalledOnValidThread());
215 if (!decklink_input_.get()) 233 if (!decklink_input_.get())
216 return; 234 return;
217 if (decklink_input_->StopStreams() != S_OK) 235 if (decklink_input_->StopStreams() != S_OK)
218 SendLogString("Problem stopping capture."); 236 SendLogString("Problem stopping capture.");
219 decklink_input_->SetCallback(NULL); 237 decklink_input_->SetCallback(NULL);
220 decklink_input_->DisableVideoInput(); 238 decklink_input_->DisableVideoInput();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if (frame_receiver_) 323 if (frame_receiver_)
306 frame_receiver_->SendLogString(message); 324 frame_receiver_->SendLogString(message);
307 } 325 }
308 326
309 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() { 327 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() {
310 DCHECK(thread_checker_.CalledOnValidThread()); 328 DCHECK(thread_checker_.CalledOnValidThread());
311 base::AutoLock lock(lock_); 329 base::AutoLock lock(lock_);
312 frame_receiver_ = NULL; 330 frame_receiver_ = NULL;
313 } 331 }
314 332
315 } // namespace
316
317 namespace media {
318 333
319 static std::string JoinDeviceNameAndFormat(CFStringRef name, 334 static std::string JoinDeviceNameAndFormat(CFStringRef name,
320 CFStringRef format) { 335 CFStringRef format) {
321 return base::SysCFStringRefToUTF8(name) + " - " + 336 return base::SysCFStringRefToUTF8(name) + " - " +
322 base::SysCFStringRefToUTF8(format); 337 base::SysCFStringRefToUTF8(format);
323 } 338 }
324 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 DLOG_IF(ERROR, !decklink_iter.get()) << "Could not create DeckLink iterator";
333 if (!decklink_iter.get()) 352 if (!decklink_iter.get())
334 return; 353 return;
335 354
336 ScopedDeckLinkPtr<IDeckLink> decklink; 355 ScopedDeckLinkPtr<IDeckLink> decklink;
337 while (decklink_iter->Next(decklink.Receive()) == S_OK) { 356 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
338 ScopedDeckLinkPtr<IDeckLink> decklink_local; 357 ScopedDeckLinkPtr<IDeckLink> decklink_local;
339 decklink_local.swap(decklink); 358 decklink_local.swap(decklink);
340 359
341 CFStringRef device_model_name = NULL; 360 CFStringRef device_model_name = NULL;
342 HRESULT hr = decklink_local->GetModelName(&device_model_name); 361 HRESULT hr = decklink_local->GetModelName(&device_model_name);
343 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device model name"; 362 DLOG_IF(ERROR, hr != S_OK) << "Error reading Blackmagic device model name";
344 CFStringRef device_display_name = NULL; 363 CFStringRef device_display_name = NULL;
345 hr = decklink_local->GetDisplayName(&device_display_name); 364 hr = decklink_local->GetDisplayName(&device_display_name);
346 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device display name"; 365 DLOG_IF(ERROR, hr != S_OK)
347 DVLOG_IF(1, hr == S_OK) << "Blackmagic device found with name: " 366 << "Error reading Blackmagic device display name";
348 << base::SysCFStringRefToUTF8(device_display_name); 367 DLOG_IF(ERROR, hr == S_OK)
368 << "Blackmagic device found with name: "
369 << base::SysCFStringRefToUTF8(device_display_name);
349 370
350 if (!device_model_name && !device_display_name) 371 if (!device_model_name && !device_display_name)
351 continue; 372 continue;
352 373
353 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input; 374 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
354 if (decklink_local->QueryInterface(IID_IDeckLinkInput, 375 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
355 decklink_input.ReceiveVoid()) != S_OK) { 376 decklink_input.ReceiveVoid()) != S_OK) {
356 DLOG(ERROR) << "Error Blackmagic querying input interface."; 377 DLOG(ERROR) << "Error Blackmagic querying input interface.";
357 return; 378 return;
358 } 379 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (decklink_capture_delegate_.get()) 504 if (decklink_capture_delegate_.get())
484 decklink_capture_delegate_->AllocateAndStart(params); 505 decklink_capture_delegate_->AllocateAndStart(params);
485 } 506 }
486 507
487 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { 508 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
488 if (decklink_capture_delegate_.get()) 509 if (decklink_capture_delegate_.get())
489 decklink_capture_delegate_->StopAndDeAllocate(); 510 decklink_capture_delegate_->StopAndDeAllocate();
490 } 511 }
491 512
492 } // namespace media 513 } // 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