| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // This is used to control the video capturing device input interface. | 91 // This is used to control the video capturing device input interface. |
| 92 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_; | 92 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_; |
| 93 // |decklink_| represents a physical device attached to the host. | 93 // |decklink_| represents a physical device attached to the host. |
| 94 ScopedDeckLinkPtr<IDeckLink> decklink_; | 94 ScopedDeckLinkPtr<IDeckLink> decklink_; |
| 95 | 95 |
| 96 base::TimeTicks first_ref_time_; | 96 base::TimeTicks first_ref_time_; |
| 97 | 97 |
| 98 // Checks for Device (a.k.a. Audio) thread. | 98 // Checks for Device (a.k.a. Audio) thread. |
| 99 base::ThreadChecker thread_checker_; | 99 base::ThreadChecker thread_checker_; |
| 100 | 100 |
| 101 bool capture_; |
| 102 |
| 101 friend class scoped_refptr<DeckLinkCaptureDelegate>; | 103 friend class scoped_refptr<DeckLinkCaptureDelegate>; |
| 102 friend class base::RefCountedThreadSafe<DeckLinkCaptureDelegate>; | 104 friend class base::RefCountedThreadSafe<DeckLinkCaptureDelegate>; |
| 103 | 105 |
| 104 ~DeckLinkCaptureDelegate() override; | 106 ~DeckLinkCaptureDelegate() override; |
| 105 | 107 |
| 106 DISALLOW_COPY_AND_ASSIGN(DeckLinkCaptureDelegate); | 108 DISALLOW_COPY_AND_ASSIGN(DeckLinkCaptureDelegate); |
| 107 }; | 109 }; |
| 108 | 110 |
| 109 static float GetDisplayModeFrameRate( | 111 static float GetDisplayModeFrameRate( |
| 110 const ScopedDeckLinkPtr<IDeckLinkDisplayMode>& display_mode) { | 112 const ScopedDeckLinkPtr<IDeckLinkDisplayMode>& display_mode) { |
| 111 BMDTimeValue time_value, time_scale; | 113 BMDTimeValue time_value, time_scale; |
| 112 float display_mode_frame_rate = 0.0f; | 114 float display_mode_frame_rate = 0.0f; |
| 113 if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK && | 115 if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK && |
| 114 time_value > 0) { | 116 time_value > 0) { |
| 115 display_mode_frame_rate = static_cast<float>(time_scale) / time_value; | 117 display_mode_frame_rate = static_cast<float>(time_scale) / time_value; |
| 116 } | 118 } |
| 117 // Interlaced formats are going to be marked as double the frame rate, | 119 // Interlaced formats are going to be marked as double the frame rate, |
| 118 // which follows the general naming convention. | 120 // which follows the general naming convention. |
| 119 if (display_mode->GetFieldDominance() == bmdLowerFieldFirst || | 121 if (display_mode->GetFieldDominance() == bmdLowerFieldFirst || |
| 120 display_mode->GetFieldDominance() == bmdUpperFieldFirst) { | 122 display_mode->GetFieldDominance() == bmdUpperFieldFirst) { |
| 121 display_mode_frame_rate *= 2.0f; | 123 display_mode_frame_rate *= 2.0f; |
| 122 } | 124 } |
| 123 return display_mode_frame_rate; | 125 return display_mode_frame_rate; |
| 124 } | 126 } |
| 125 | 127 |
| 126 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate( | 128 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate( |
| 127 const media::VideoCaptureDeviceDescriptor& device_descriptor, | 129 const media::VideoCaptureDeviceDescriptor& device_descriptor, |
| 128 media::VideoCaptureDeviceDeckLinkMac* frame_receiver) | 130 media::VideoCaptureDeviceDeckLinkMac* frame_receiver) |
| 129 : device_descriptor_(device_descriptor), frame_receiver_(frame_receiver) {} | 131 : device_descriptor_(device_descriptor), |
| 132 frame_receiver_(frame_receiver), |
| 133 capture_(false) {} |
| 130 | 134 |
| 131 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() { | 135 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() { |
| 132 } | 136 } |
| 133 | 137 |
| 134 void DeckLinkCaptureDelegate::AllocateAndStart( | 138 void DeckLinkCaptureDelegate::AllocateAndStart( |
| 135 const media::VideoCaptureParams& params) { | 139 const media::VideoCaptureParams& params) { |
| 136 DCHECK(thread_checker_.CalledOnValidThread()); | 140 DCHECK(thread_checker_.CalledOnValidThread()); |
| 137 scoped_refptr<IDeckLinkIterator> decklink_iter( | 141 scoped_refptr<IDeckLinkIterator> decklink_iter( |
| 138 CreateDeckLinkIteratorInstance()); | 142 CreateDeckLinkIteratorInstance()); |
| 139 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; | 143 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, | 206 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, |
| 203 bmdVideoInputFlagDefault) != S_OK) { | 207 bmdVideoInputFlagDefault) != S_OK) { |
| 204 SendErrorString(FROM_HERE, "Could not select the video format we like."); | 208 SendErrorString(FROM_HERE, "Could not select the video format we like."); |
| 205 return; | 209 return; |
| 206 } | 210 } |
| 207 | 211 |
| 208 decklink_input_local->SetCallback(this); | 212 decklink_input_local->SetCallback(this); |
| 209 if (decklink_input_local->StartStreams() != S_OK) | 213 if (decklink_input_local->StartStreams() != S_OK) |
| 210 SendErrorString(FROM_HERE, "Could not start capturing"); | 214 SendErrorString(FROM_HERE, "Could not start capturing"); |
| 211 | 215 |
| 216 if (frame_receiver_) |
| 217 frame_receiver_->ReportStarted(); |
| 218 |
| 219 capture_ = true; |
| 220 |
| 212 decklink_.swap(decklink_local); | 221 decklink_.swap(decklink_local); |
| 213 decklink_input_.swap(decklink_input_local); | 222 decklink_input_.swap(decklink_input_local); |
| 214 } | 223 } |
| 215 | 224 |
| 216 void DeckLinkCaptureDelegate::StopAndDeAllocate() { | 225 void DeckLinkCaptureDelegate::StopAndDeAllocate() { |
| 217 DCHECK(thread_checker_.CalledOnValidThread()); | 226 DCHECK(thread_checker_.CalledOnValidThread()); |
| 227 capture_ = false; |
| 218 if (!decklink_input_.get()) | 228 if (!decklink_input_.get()) |
| 219 return; | 229 return; |
| 220 if (decklink_input_->StopStreams() != S_OK) | 230 if (decklink_input_->StopStreams() != S_OK) |
| 221 SendLogString("Problem stopping capture."); | 231 SendLogString("Problem stopping capture."); |
| 222 decklink_input_->SetCallback(NULL); | 232 decklink_input_->SetCallback(NULL); |
| 223 decklink_input_->DisableVideoInput(); | 233 decklink_input_->DisableVideoInput(); |
| 224 decklink_input_.Release(); | 234 decklink_input_.Release(); |
| 225 decklink_.Release(); | 235 decklink_.Release(); |
| 226 ResetVideoCaptureDeviceReference(); | 236 ResetVideoCaptureDeviceReference(); |
| 227 } | 237 } |
| 228 | 238 |
| 229 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged( | 239 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged( |
| 230 BMDVideoInputFormatChangedEvents notification_events, | 240 BMDVideoInputFormatChangedEvents notification_events, |
| 231 IDeckLinkDisplayMode* new_display_mode, | 241 IDeckLinkDisplayMode* new_display_mode, |
| 232 BMDDetectedVideoInputFormatFlags detected_signal_flags) { | 242 BMDDetectedVideoInputFormatFlags detected_signal_flags) { |
| 233 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK(thread_checker_.CalledOnValidThread()); |
| 234 return S_OK; | 244 return S_OK; |
| 235 } | 245 } |
| 236 | 246 |
| 237 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived( | 247 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived( |
| 238 IDeckLinkVideoInputFrame* video_frame, | 248 IDeckLinkVideoInputFrame* video_frame, |
| 239 IDeckLinkAudioInputPacket* /* audio_packet */) { | 249 IDeckLinkAudioInputPacket* /* audio_packet */) { |
| 250 if (!capture_) |
| 251 return S_OK; |
| 252 |
| 240 // Capture frames are manipulated as an IDeckLinkVideoFrame. | 253 // Capture frames are manipulated as an IDeckLinkVideoFrame. |
| 241 uint8_t* video_data = NULL; | 254 uint8_t* video_data = NULL; |
| 242 video_frame->GetBytes(reinterpret_cast<void**>(&video_data)); | 255 video_frame->GetBytes(reinterpret_cast<void**>(&video_data)); |
| 243 | 256 |
| 244 media::VideoPixelFormat pixel_format = | 257 media::VideoPixelFormat pixel_format = |
| 245 media::PIXEL_FORMAT_UNKNOWN; | 258 media::PIXEL_FORMAT_UNKNOWN; |
| 246 switch (video_frame->GetPixelFormat()) { | 259 switch (video_frame->GetPixelFormat()) { |
| 247 case bmdFormat8BitYUV: // A.k.a. '2vuy'; | 260 case bmdFormat8BitYUV: // A.k.a. '2vuy'; |
| 248 pixel_format = media::PIXEL_FORMAT_UYVY; | 261 pixel_format = media::PIXEL_FORMAT_UYVY; |
| 249 break; | 262 break; |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 client_->OnError(from_here, reason); | 500 client_->OnError(from_here, reason); |
| 488 } | 501 } |
| 489 | 502 |
| 490 void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) { | 503 void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) { |
| 491 DCHECK(thread_checker_.CalledOnValidThread()); | 504 DCHECK(thread_checker_.CalledOnValidThread()); |
| 492 base::AutoLock lock(lock_); | 505 base::AutoLock lock(lock_); |
| 493 if (client_) | 506 if (client_) |
| 494 client_->OnLog(message); | 507 client_->OnLog(message); |
| 495 } | 508 } |
| 496 | 509 |
| 510 void VideoCaptureDeviceDeckLinkMac::ReportStarted() { |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); |
| 512 base::AutoLock lock(lock_); |
| 513 if (client_) |
| 514 client_->OnStarted(); |
| 515 } |
| 516 |
| 497 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart( | 517 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart( |
| 498 const VideoCaptureParams& params, | 518 const VideoCaptureParams& params, |
| 499 std::unique_ptr<VideoCaptureDevice::Client> client) { | 519 std::unique_ptr<VideoCaptureDevice::Client> client) { |
| 500 DCHECK(thread_checker_.CalledOnValidThread()); | 520 DCHECK(thread_checker_.CalledOnValidThread()); |
| 501 client_ = std::move(client); | 521 client_ = std::move(client); |
| 502 if (decklink_capture_delegate_.get()) | 522 if (decklink_capture_delegate_.get()) |
| 503 decklink_capture_delegate_->AllocateAndStart(params); | 523 decklink_capture_delegate_->AllocateAndStart(params); |
| 504 } | 524 } |
| 505 | 525 |
| 506 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { | 526 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { |
| 507 if (decklink_capture_delegate_.get()) | 527 if (decklink_capture_delegate_.get()) |
| 508 decklink_capture_delegate_->StopAndDeAllocate(); | 528 decklink_capture_delegate_->StopAndDeAllocate(); |
| 509 } | 529 } |
| 510 | 530 |
| 511 } // namespace media | 531 } // namespace media |
| OLD | NEW |