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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 HRESULT VideoInputFrameArrived( | 62 HRESULT VideoInputFrameArrived( |
63 IDeckLinkVideoInputFrame* video_frame, | 63 IDeckLinkVideoInputFrame* video_frame, |
64 IDeckLinkAudioInputPacket* audio_packet) override; | 64 IDeckLinkAudioInputPacket* audio_packet) override; |
65 | 65 |
66 // IUnknown interface implementation. | 66 // IUnknown interface implementation. |
67 HRESULT QueryInterface(REFIID iid, void** ppv) override; | 67 HRESULT QueryInterface(REFIID iid, void** ppv) override; |
68 ULONG AddRef() override; | 68 ULONG AddRef() override; |
69 ULONG Release() override; | 69 ULONG Release() override; |
70 | 70 |
71 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString(). | 71 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString(). |
72 void SendErrorString(const std::string& reason); | 72 void SendErrorString(const tracked_objects::Location& from_here, |
| 73 const std::string& reason); |
73 | 74 |
74 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString(). | 75 // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString(). |
75 void SendLogString(const std::string& message); | 76 void SendLogString(const std::string& message); |
76 | 77 |
77 const media::VideoCaptureDevice::Name device_name_; | 78 const media::VideoCaptureDevice::Name device_name_; |
78 | 79 |
79 // Protects concurrent setting and using of |frame_receiver_|. | 80 // Protects concurrent setting and using of |frame_receiver_|. |
80 base::Lock lock_; | 81 base::Lock lock_; |
81 // Weak reference to the captured frames client, used also for error messages | 82 // Weak reference to the captured frames client, used also for error messages |
82 // and logging. Initialized on construction and used until cleared by calling | 83 // and logging. Initialized on construction and used until cleared by calling |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 137 |
137 ScopedDeckLinkPtr<IDeckLink> decklink_local; | 138 ScopedDeckLinkPtr<IDeckLink> decklink_local; |
138 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { | 139 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) { |
139 CFStringRef device_model_name = NULL; | 140 CFStringRef device_model_name = NULL; |
140 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || | 141 if ((decklink_local->GetModelName(&device_model_name) == S_OK) || |
141 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) { | 142 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) { |
142 break; | 143 break; |
143 } | 144 } |
144 } | 145 } |
145 if (!decklink_local.get()) { | 146 if (!decklink_local.get()) { |
146 SendErrorString("Device id not found in the system"); | 147 SendErrorString(FROM_HERE, "Device id not found in the system"); |
147 return; | 148 return; |
148 } | 149 } |
149 | 150 |
150 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local; | 151 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local; |
151 if (decklink_local->QueryInterface( | 152 if (decklink_local->QueryInterface( |
152 IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) { | 153 IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) { |
153 SendErrorString("Error querying input interface."); | 154 SendErrorString(FROM_HERE, "Error querying input interface."); |
154 return; | 155 return; |
155 } | 156 } |
156 | 157 |
157 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter; | 158 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter; |
158 if (decklink_input_local->GetDisplayModeIterator( | 159 if (decklink_input_local->GetDisplayModeIterator( |
159 display_mode_iter.Receive()) != S_OK) { | 160 display_mode_iter.Receive()) != S_OK) { |
160 SendErrorString("Error creating Display Mode Iterator"); | 161 SendErrorString(FROM_HERE, "Error creating Display Mode Iterator"); |
161 return; | 162 return; |
162 } | 163 } |
163 | 164 |
164 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode; | 165 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode; |
165 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; | 166 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; |
166 float min_diff = FLT_MAX; | 167 float min_diff = FLT_MAX; |
167 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { | 168 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { |
168 const float diff = labs(display_mode->GetWidth() - | 169 const float diff = labs(display_mode->GetWidth() - |
169 params.requested_format.frame_size.width()) + | 170 params.requested_format.frame_size.width()) + |
170 labs(params.requested_format.frame_size.height() - | 171 labs(params.requested_format.frame_size.height() - |
171 display_mode->GetHeight()) + | 172 display_mode->GetHeight()) + |
172 fabs(params.requested_format.frame_rate - | 173 fabs(params.requested_format.frame_rate - |
173 GetDisplayModeFrameRate(display_mode)); | 174 GetDisplayModeFrameRate(display_mode)); |
174 if (diff < min_diff) { | 175 if (diff < min_diff) { |
175 chosen_display_mode = display_mode; | 176 chosen_display_mode = display_mode; |
176 min_diff = diff; | 177 min_diff = diff; |
177 } | 178 } |
178 display_mode.Release(); | 179 display_mode.Release(); |
179 } | 180 } |
180 if (!chosen_display_mode.get()) { | 181 if (!chosen_display_mode.get()) { |
181 SendErrorString("Could not find a display mode"); | 182 SendErrorString(FROM_HERE, "Could not find a display mode"); |
182 return; | 183 return; |
183 } | 184 } |
184 #if !defined(NDEBUG) | 185 #if !defined(NDEBUG) |
185 DVLOG(1) << "Requested format: " | 186 DVLOG(1) << "Requested format: " |
186 << media::VideoCaptureFormat::ToString(params.requested_format); | 187 << media::VideoCaptureFormat::ToString(params.requested_format); |
187 CFStringRef format_name = NULL; | 188 CFStringRef format_name = NULL; |
188 if (chosen_display_mode->GetName(&format_name) == S_OK) | 189 if (chosen_display_mode->GetName(&format_name) == S_OK) |
189 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name); | 190 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name); |
190 #endif | 191 #endif |
191 | 192 |
192 // Enable video input. Configure for no input video format change detection, | 193 // Enable video input. Configure for no input video format change detection, |
193 // this in turn will disable calls to VideoInputFormatChanged(). | 194 // this in turn will disable calls to VideoInputFormatChanged(). |
194 if (decklink_input_local->EnableVideoInput( | 195 if (decklink_input_local->EnableVideoInput( |
195 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, | 196 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, |
196 bmdVideoInputFlagDefault) != S_OK) { | 197 bmdVideoInputFlagDefault) != S_OK) { |
197 SendErrorString("Could not select the video format we like."); | 198 SendErrorString(FROM_HERE, "Could not select the video format we like."); |
198 return; | 199 return; |
199 } | 200 } |
200 | 201 |
201 decklink_input_local->SetCallback(this); | 202 decklink_input_local->SetCallback(this); |
202 if (decklink_input_local->StartStreams() != S_OK) | 203 if (decklink_input_local->StartStreams() != S_OK) |
203 SendErrorString("Could not start capturing"); | 204 SendErrorString(FROM_HERE, "Could not start capturing"); |
204 | 205 |
205 decklink_.swap(decklink_local); | 206 decklink_.swap(decklink_local); |
206 decklink_input_.swap(decklink_input_local); | 207 decklink_input_.swap(decklink_input_local); |
207 } | 208 } |
208 | 209 |
209 void DeckLinkCaptureDelegate::StopAndDeAllocate() { | 210 void DeckLinkCaptureDelegate::StopAndDeAllocate() { |
210 DCHECK(thread_checker_.CalledOnValidThread()); | 211 DCHECK(thread_checker_.CalledOnValidThread()); |
211 if (!decklink_input_.get()) | 212 if (!decklink_input_.get()) |
212 return; | 213 return; |
213 if (decklink_input_->StopStreams() != S_OK) | 214 if (decklink_input_->StopStreams() != S_OK) |
(...skipping 23 matching lines...) Expand all Loading... |
237 media::VideoPixelFormat pixel_format = | 238 media::VideoPixelFormat pixel_format = |
238 media::PIXEL_FORMAT_UNKNOWN; | 239 media::PIXEL_FORMAT_UNKNOWN; |
239 switch (video_frame->GetPixelFormat()) { | 240 switch (video_frame->GetPixelFormat()) { |
240 case bmdFormat8BitYUV: // A.k.a. '2vuy'; | 241 case bmdFormat8BitYUV: // A.k.a. '2vuy'; |
241 pixel_format = media::PIXEL_FORMAT_UYVY; | 242 pixel_format = media::PIXEL_FORMAT_UYVY; |
242 break; | 243 break; |
243 case bmdFormat8BitARGB: | 244 case bmdFormat8BitARGB: |
244 pixel_format = media::PIXEL_FORMAT_ARGB; | 245 pixel_format = media::PIXEL_FORMAT_ARGB; |
245 break; | 246 break; |
246 default: | 247 default: |
247 SendErrorString("Unsupported pixel format"); | 248 SendErrorString(FROM_HERE, "Unsupported pixel format"); |
248 break; | 249 break; |
249 } | 250 } |
250 | 251 |
251 const media::VideoCaptureFormat capture_format( | 252 const media::VideoCaptureFormat capture_format( |
252 gfx::Size(video_frame->GetWidth(), video_frame->GetHeight()), | 253 gfx::Size(video_frame->GetWidth(), video_frame->GetHeight()), |
253 0.0f, // Frame rate is not needed for captured data callback. | 254 0.0f, // Frame rate is not needed for captured data callback. |
254 pixel_format); | 255 pixel_format); |
255 base::AutoLock lock(lock_); | 256 base::AutoLock lock(lock_); |
256 if (frame_receiver_) { | 257 if (frame_receiver_) { |
257 frame_receiver_->OnIncomingCapturedData( | 258 frame_receiver_->OnIncomingCapturedData( |
(...skipping 23 matching lines...) Expand all Loading... |
281 return 1; | 282 return 1; |
282 } | 283 } |
283 | 284 |
284 ULONG DeckLinkCaptureDelegate::Release() { | 285 ULONG DeckLinkCaptureDelegate::Release() { |
285 DCHECK(thread_checker_.CalledOnValidThread()); | 286 DCHECK(thread_checker_.CalledOnValidThread()); |
286 bool ret_value = !HasOneRef(); | 287 bool ret_value = !HasOneRef(); |
287 base::RefCountedThreadSafe<DeckLinkCaptureDelegate>::Release(); | 288 base::RefCountedThreadSafe<DeckLinkCaptureDelegate>::Release(); |
288 return ret_value; | 289 return ret_value; |
289 } | 290 } |
290 | 291 |
291 void DeckLinkCaptureDelegate::SendErrorString(const std::string& reason) { | 292 void DeckLinkCaptureDelegate::SendErrorString( |
| 293 const tracked_objects::Location& from_here, |
| 294 const std::string& reason) { |
292 base::AutoLock lock(lock_); | 295 base::AutoLock lock(lock_); |
293 if (frame_receiver_) | 296 if (frame_receiver_) |
294 frame_receiver_->SendErrorString(reason); | 297 frame_receiver_->SendErrorString(from_here, reason); |
295 } | 298 } |
296 | 299 |
297 void DeckLinkCaptureDelegate::SendLogString(const std::string& message) { | 300 void DeckLinkCaptureDelegate::SendLogString(const std::string& message) { |
298 base::AutoLock lock(lock_); | 301 base::AutoLock lock(lock_); |
299 if (frame_receiver_) | 302 if (frame_receiver_) |
300 frame_receiver_->SendLogString(message); | 303 frame_receiver_->SendLogString(message); |
301 } | 304 } |
302 | 305 |
303 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() { | 306 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() { |
304 DCHECK(thread_checker_.CalledOnValidThread()); | 307 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 const VideoCaptureFormat& frame_format, | 449 const VideoCaptureFormat& frame_format, |
447 int rotation, // Clockwise. | 450 int rotation, // Clockwise. |
448 base::TimeTicks timestamp) { | 451 base::TimeTicks timestamp) { |
449 base::AutoLock lock(lock_); | 452 base::AutoLock lock(lock_); |
450 if (client_) { | 453 if (client_) { |
451 client_->OnIncomingCapturedData(data, length, frame_format, rotation, | 454 client_->OnIncomingCapturedData(data, length, frame_format, rotation, |
452 timestamp); | 455 timestamp); |
453 } | 456 } |
454 } | 457 } |
455 | 458 |
456 void VideoCaptureDeviceDeckLinkMac::SendErrorString(const std::string& reason) { | 459 void VideoCaptureDeviceDeckLinkMac::SendErrorString( |
| 460 const tracked_objects::Location& from_here, |
| 461 const std::string& reason) { |
457 DCHECK(thread_checker_.CalledOnValidThread()); | 462 DCHECK(thread_checker_.CalledOnValidThread()); |
458 base::AutoLock lock(lock_); | 463 base::AutoLock lock(lock_); |
459 if (client_) | 464 if (client_) |
460 client_->OnError(reason); | 465 client_->OnError(from_here, reason); |
461 } | 466 } |
462 | 467 |
463 void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) { | 468 void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) { |
464 DCHECK(thread_checker_.CalledOnValidThread()); | 469 DCHECK(thread_checker_.CalledOnValidThread()); |
465 base::AutoLock lock(lock_); | 470 base::AutoLock lock(lock_); |
466 if (client_) | 471 if (client_) |
467 client_->OnLog(message); | 472 client_->OnLog(message); |
468 } | 473 } |
469 | 474 |
470 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart( | 475 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart( |
471 const VideoCaptureParams& params, | 476 const VideoCaptureParams& params, |
472 scoped_ptr<VideoCaptureDevice::Client> client) { | 477 scoped_ptr<VideoCaptureDevice::Client> client) { |
473 DCHECK(thread_checker_.CalledOnValidThread()); | 478 DCHECK(thread_checker_.CalledOnValidThread()); |
474 client_ = client.Pass(); | 479 client_ = client.Pass(); |
475 if (decklink_capture_delegate_.get()) | 480 if (decklink_capture_delegate_.get()) |
476 decklink_capture_delegate_->AllocateAndStart(params); | 481 decklink_capture_delegate_->AllocateAndStart(params); |
477 } | 482 } |
478 | 483 |
479 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { | 484 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { |
480 if (decklink_capture_delegate_.get()) | 485 if (decklink_capture_delegate_.get()) |
481 decklink_capture_delegate_->StopAndDeAllocate(); | 486 decklink_capture_delegate_->StopAndDeAllocate(); |
482 } | 487 } |
483 | 488 |
484 } // namespace media | 489 } // namespace media |
OLD | NEW |