OLD | NEW |
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" |
(...skipping 29 matching lines...) Expand all Loading... |
40 }; | 40 }; |
41 | 41 |
42 // This class is used to interact directly with DeckLink SDK for video capture. | 42 // This class is used to interact directly with DeckLink SDK for video capture. |
43 // Implements the reference counted interface IUnknown. Has a weak reference to | 43 // Implements the reference counted interface IUnknown. Has a weak reference to |
44 // VideoCaptureDeviceDeckLinkMac for sending captured frames, error messages and | 44 // VideoCaptureDeviceDeckLinkMac for sending captured frames, error messages and |
45 // logs. | 45 // logs. |
46 class DeckLinkCaptureDelegate | 46 class DeckLinkCaptureDelegate |
47 : public IDeckLinkInputCallback, | 47 : public IDeckLinkInputCallback, |
48 public base::RefCountedThreadSafe<DeckLinkCaptureDelegate> { | 48 public base::RefCountedThreadSafe<DeckLinkCaptureDelegate> { |
49 public: | 49 public: |
50 DeckLinkCaptureDelegate(const media::VideoCaptureDevice::Name& device_name, | 50 DeckLinkCaptureDelegate( |
51 media::VideoCaptureDeviceDeckLinkMac* frame_receiver); | 51 const media::VideoCaptureDeviceDescriptor& device_descriptor, |
| 52 media::VideoCaptureDeviceDeckLinkMac* frame_receiver); |
52 | 53 |
53 void AllocateAndStart(const media::VideoCaptureParams& params); | 54 void AllocateAndStart(const media::VideoCaptureParams& params); |
54 void StopAndDeAllocate(); | 55 void StopAndDeAllocate(); |
55 | 56 |
56 // Remove the VideoCaptureDeviceDeckLinkMac's weak reference. | 57 // Remove the VideoCaptureDeviceDeckLinkMac's weak reference. |
57 void ResetVideoCaptureDeviceReference(); | 58 void ResetVideoCaptureDeviceReference(); |
58 | 59 |
59 private: | 60 private: |
60 // IDeckLinkInputCallback interface implementation. | 61 // IDeckLinkInputCallback interface implementation. |
61 HRESULT VideoInputFormatChanged( | 62 HRESULT VideoInputFormatChanged( |
62 BMDVideoInputFormatChangedEvents notification_events, | 63 BMDVideoInputFormatChangedEvents notification_events, |
63 IDeckLinkDisplayMode* new_display_mode, | 64 IDeckLinkDisplayMode* new_display_mode, |
64 BMDDetectedVideoInputFormatFlags detected_signal_flags) override; | 65 BMDDetectedVideoInputFormatFlags detected_signal_flags) override; |
65 HRESULT VideoInputFrameArrived( | 66 HRESULT VideoInputFrameArrived( |
66 IDeckLinkVideoInputFrame* video_frame, | 67 IDeckLinkVideoInputFrame* video_frame, |
67 IDeckLinkAudioInputPacket* audio_packet) override; | 68 IDeckLinkAudioInputPacket* audio_packet) override; |
68 | 69 |
69 // IUnknown interface implementation. | 70 // IUnknown interface implementation. |
70 HRESULT QueryInterface(REFIID iid, void** ppv) override; | 71 HRESULT QueryInterface(REFIID iid, void** ppv) override; |
71 ULONG AddRef() override; | 72 ULONG AddRef() override; |
72 ULONG Release() override; | 73 ULONG Release() override; |
73 | 74 |
74 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString(). | 75 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString(). |
75 void SendErrorString(const tracked_objects::Location& from_here, | 76 void SendErrorString(const tracked_objects::Location& from_here, |
76 const std::string& reason); | 77 const std::string& reason); |
77 | 78 |
78 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString(). | 79 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString(). |
79 void SendLogString(const std::string& message); | 80 void SendLogString(const std::string& message); |
80 | 81 |
81 const media::VideoCaptureDevice::Name device_name_; | 82 const media::VideoCaptureDeviceDescriptor device_descriptor_; |
82 | 83 |
83 // Protects concurrent setting and using of |frame_receiver_|. | 84 // Protects concurrent setting and using of |frame_receiver_|. |
84 base::Lock lock_; | 85 base::Lock lock_; |
85 // Weak reference to the captured frames client, used also for error messages | 86 // Weak reference to the captured frames client, used also for error messages |
86 // and logging. Initialized on construction and used until cleared by calling | 87 // and logging. Initialized on construction and used until cleared by calling |
87 // ResetVideoCaptureDeviceReference(). | 88 // ResetVideoCaptureDeviceReference(). |
88 media::VideoCaptureDeviceDeckLinkMac* frame_receiver_; | 89 media::VideoCaptureDeviceDeckLinkMac* frame_receiver_; |
89 | 90 |
90 // This is used to control the video capturing device input interface. | 91 // This is used to control the video capturing device input interface. |
91 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_; | 92 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_; |
(...skipping 24 matching lines...) Expand all Loading... |
116 // Interlaced formats are going to be marked as double the frame rate, | 117 // Interlaced formats are going to be marked as double the frame rate, |
117 // which follows the general naming convention. | 118 // which follows the general naming convention. |
118 if (display_mode->GetFieldDominance() == bmdLowerFieldFirst || | 119 if (display_mode->GetFieldDominance() == bmdLowerFieldFirst || |
119 display_mode->GetFieldDominance() == bmdUpperFieldFirst) { | 120 display_mode->GetFieldDominance() == bmdUpperFieldFirst) { |
120 display_mode_frame_rate *= 2.0f; | 121 display_mode_frame_rate *= 2.0f; |
121 } | 122 } |
122 return display_mode_frame_rate; | 123 return display_mode_frame_rate; |
123 } | 124 } |
124 | 125 |
125 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate( | 126 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate( |
126 const media::VideoCaptureDevice::Name& device_name, | 127 const media::VideoCaptureDeviceDescriptor& device_descriptor, |
127 media::VideoCaptureDeviceDeckLinkMac* frame_receiver) | 128 media::VideoCaptureDeviceDeckLinkMac* frame_receiver) |
128 : device_name_(device_name), frame_receiver_(frame_receiver) { | 129 : device_descriptor_(device_descriptor), frame_receiver_(frame_receiver) {} |
129 } | |
130 | 130 |
131 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() { | 131 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() { |
132 } | 132 } |
133 | 133 |
134 void DeckLinkCaptureDelegate::AllocateAndStart( | 134 void DeckLinkCaptureDelegate::AllocateAndStart( |
135 const media::VideoCaptureParams& params) { | 135 const media::VideoCaptureParams& params) { |
136 DCHECK(thread_checker_.CalledOnValidThread()); | 136 DCHECK(thread_checker_.CalledOnValidThread()); |
137 scoped_refptr<IDeckLinkIterator> decklink_iter( | 137 scoped_refptr<IDeckLinkIterator> decklink_iter( |
138 CreateDeckLinkIteratorInstance()); | 138 CreateDeckLinkIteratorInstance()); |
139 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; | 139 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; |
140 if (!decklink_iter.get()) | 140 if (!decklink_iter.get()) |
141 return; | 141 return; |
142 | 142 |
143 ScopedDeckLinkPtr<IDeckLink> decklink_local; | 143 ScopedDeckLinkPtr<IDeckLink> decklink_local; |
144 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { | 144 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { |
145 CFStringRef device_model_name = NULL; | 145 CFStringRef device_model_name = NULL; |
146 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || | 146 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || |
147 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) { | 147 (device_descriptor_.device_id == |
| 148 base::SysCFStringRefToUTF8(device_model_name))) { |
148 break; | 149 break; |
149 } | 150 } |
150 } | 151 } |
151 if (!decklink_local.get()) { | 152 if (!decklink_local.get()) { |
152 SendErrorString(FROM_HERE, "Device id not found in the system"); | 153 SendErrorString(FROM_HERE, "Device id not found in the system"); |
153 return; | 154 return; |
154 } | 155 } |
155 | 156 |
156 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local; | 157 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local; |
157 if (decklink_local->QueryInterface( | 158 if (decklink_local->QueryInterface( |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 namespace media { | 333 namespace media { |
333 | 334 |
334 static std::string JoinDeviceNameAndFormat(CFStringRef name, | 335 static std::string JoinDeviceNameAndFormat(CFStringRef name, |
335 CFStringRef format) { | 336 CFStringRef format) { |
336 return base::SysCFStringRefToUTF8(name) + " - " + | 337 return base::SysCFStringRefToUTF8(name) + " - " + |
337 base::SysCFStringRefToUTF8(format); | 338 base::SysCFStringRefToUTF8(format); |
338 } | 339 } |
339 | 340 |
340 // static | 341 // static |
341 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices( | 342 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices( |
342 VideoCaptureDevice::Names* device_names) { | 343 VideoCaptureDeviceDescriptors* device_descriptors) { |
343 scoped_refptr<IDeckLinkIterator> decklink_iter( | 344 scoped_refptr<IDeckLinkIterator> decklink_iter( |
344 CreateDeckLinkIteratorInstance()); | 345 CreateDeckLinkIteratorInstance()); |
345 // At this point, not being able to create a DeckLink iterator means that | 346 // At this point, not being able to create a DeckLink iterator means that |
346 // there are no Blackmagic DeckLink devices in the system, don't print error. | 347 // there are no Blackmagic DeckLink devices in the system, don't print error. |
347 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator"; | 348 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator"; |
348 if (!decklink_iter.get()) | 349 if (!decklink_iter.get()) |
349 return; | 350 return; |
350 | 351 |
351 ScopedDeckLinkPtr<IDeckLink> decklink; | 352 ScopedDeckLinkPtr<IDeckLink> decklink; |
352 while (decklink_iter->Next(decklink.Receive()) == S_OK) { | 353 while (decklink_iter->Next(decklink.Receive()) == S_OK) { |
(...skipping 22 matching lines...) Expand all Loading... |
375 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter; | 376 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter; |
376 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) != | 377 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) != |
377 S_OK) { | 378 S_OK) { |
378 continue; | 379 continue; |
379 } | 380 } |
380 | 381 |
381 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; | 382 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; |
382 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { | 383 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { |
383 CFStringRef format_name = NULL; | 384 CFStringRef format_name = NULL; |
384 if (display_mode->GetName(&format_name) == S_OK) { | 385 if (display_mode->GetName(&format_name) == S_OK) { |
385 VideoCaptureDevice::Name name( | 386 VideoCaptureDeviceDescriptor descriptor; |
386 JoinDeviceNameAndFormat(device_display_name, format_name), | 387 descriptor.display_name = |
387 JoinDeviceNameAndFormat(device_model_name, format_name), | 388 JoinDeviceNameAndFormat(device_display_name, format_name); |
388 VideoCaptureDevice::Name::DECKLINK, | 389 descriptor.device_id = |
389 VideoCaptureDevice::Name::OTHER_TRANSPORT); | 390 JoinDeviceNameAndFormat(device_model_name, format_name); |
390 device_names->push_back(name); | 391 descriptor.capture_api = VideoCaptureApi::MACOSX_DECKLINK; |
391 DVLOG(1) << "Blackmagic camera enumerated: " << name.name(); | 392 descriptor.transport_type = VideoCaptureTransportType::OTHER_TRANSPORT; |
| 393 device_descriptors->push_back(descriptor); |
| 394 DVLOG(1) << "Blackmagic camera enumerated: " << descriptor.display_name; |
392 } | 395 } |
393 display_mode.Release(); | 396 display_mode.Release(); |
394 } | 397 } |
395 } | 398 } |
396 } | 399 } |
397 | 400 |
398 // static | 401 // static |
399 void VideoCaptureDeviceDeckLinkMac::EnumerateDeviceCapabilities( | 402 void VideoCaptureDeviceDeckLinkMac::EnumerateDeviceCapabilities( |
400 const VideoCaptureDevice::Name& device, | 403 const VideoCaptureDeviceDescriptor& device, |
401 VideoCaptureFormats* supported_formats) { | 404 VideoCaptureFormats* supported_formats) { |
402 scoped_refptr<IDeckLinkIterator> decklink_iter( | 405 scoped_refptr<IDeckLinkIterator> decklink_iter( |
403 CreateDeckLinkIteratorInstance()); | 406 CreateDeckLinkIteratorInstance()); |
404 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; | 407 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; |
405 if (!decklink_iter.get()) | 408 if (!decklink_iter.get()) |
406 return; | 409 return; |
407 | 410 |
408 ScopedDeckLinkPtr<IDeckLink> decklink; | 411 ScopedDeckLinkPtr<IDeckLink> decklink; |
409 while (decklink_iter->Next(decklink.Receive()) == S_OK) { | 412 while (decklink_iter->Next(decklink.Receive()) == S_OK) { |
410 ScopedDeckLinkPtr<IDeckLink> decklink_local; | 413 ScopedDeckLinkPtr<IDeckLink> decklink_local; |
(...skipping 13 matching lines...) Expand all Loading... |
424 } | 427 } |
425 | 428 |
426 CFStringRef device_model_name = NULL; | 429 CFStringRef device_model_name = NULL; |
427 if (decklink_local->GetModelName(&device_model_name) != S_OK) | 430 if (decklink_local->GetModelName(&device_model_name) != S_OK) |
428 continue; | 431 continue; |
429 | 432 |
430 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; | 433 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; |
431 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { | 434 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { |
432 CFStringRef format_name = NULL; | 435 CFStringRef format_name = NULL; |
433 if (display_mode->GetName(&format_name) == S_OK && | 436 if (display_mode->GetName(&format_name) == S_OK && |
434 device.id() != | 437 device.device_id != |
435 JoinDeviceNameAndFormat(device_model_name, format_name)) { | 438 JoinDeviceNameAndFormat(device_model_name, format_name)) { |
436 display_mode.Release(); | 439 display_mode.Release(); |
437 continue; | 440 continue; |
438 } | 441 } |
439 | 442 |
440 // IDeckLinkDisplayMode does not have information on pixel format, this | 443 // IDeckLinkDisplayMode does not have information on pixel format, this |
441 // is only available on capture. | 444 // is only available on capture. |
442 const media::VideoCaptureFormat format( | 445 const media::VideoCaptureFormat format( |
443 gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()), | 446 gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()), |
444 GetDisplayModeFrameRate(display_mode), | 447 GetDisplayModeFrameRate(display_mode), |
445 PIXEL_FORMAT_UNKNOWN); | 448 PIXEL_FORMAT_UNKNOWN); |
446 supported_formats->push_back(format); | 449 supported_formats->push_back(format); |
447 DVLOG(2) << device.name() << " " << VideoCaptureFormat::ToString(format); | 450 DVLOG(2) << device.display_name << " " |
| 451 << VideoCaptureFormat::ToString(format); |
448 display_mode.Release(); | 452 display_mode.Release(); |
449 } | 453 } |
450 return; | 454 return; |
451 } | 455 } |
452 } | 456 } |
453 | 457 |
454 VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac( | 458 VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac( |
455 const Name& device_name) | 459 const VideoCaptureDeviceDescriptor& device_descriptor) |
456 : decklink_capture_delegate_( | 460 : decklink_capture_delegate_( |
457 new DeckLinkCaptureDelegate(device_name, this)) { | 461 new DeckLinkCaptureDelegate(device_descriptor, this)) {} |
458 } | |
459 | 462 |
460 VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() { | 463 VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() { |
461 decklink_capture_delegate_->ResetVideoCaptureDeviceReference(); | 464 decklink_capture_delegate_->ResetVideoCaptureDeviceReference(); |
462 } | 465 } |
463 | 466 |
464 void VideoCaptureDeviceDeckLinkMac::OnIncomingCapturedData( | 467 void VideoCaptureDeviceDeckLinkMac::OnIncomingCapturedData( |
465 const uint8_t* data, | 468 const uint8_t* data, |
466 size_t length, | 469 size_t length, |
467 const VideoCaptureFormat& frame_format, | 470 const VideoCaptureFormat& frame_format, |
468 int rotation, // Clockwise. | 471 int rotation, // Clockwise. |
(...skipping 30 matching lines...) Expand all Loading... |
499 if (decklink_capture_delegate_.get()) | 502 if (decklink_capture_delegate_.get()) |
500 decklink_capture_delegate_->AllocateAndStart(params); | 503 decklink_capture_delegate_->AllocateAndStart(params); |
501 } | 504 } |
502 | 505 |
503 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { | 506 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { |
504 if (decklink_capture_delegate_.get()) | 507 if (decklink_capture_delegate_.get()) |
505 decklink_capture_delegate_->StopAndDeAllocate(); | 508 decklink_capture_delegate_->StopAndDeAllocate(); |
506 } | 509 } |
507 | 510 |
508 } // namespace media | 511 } // namespace media |
OLD | NEW |