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

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

Issue 535983002: Mac Video Capture: Support for Blackmagic DeckLink SDK video capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@crbug408493__1__Enumerate_blackmagic_devices__2__branched_from_master
Patch Set: Rebased against master Created 6 years, 2 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
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/video/capture/mac/video_capture_device_decklink_mac.h" 5 #include "media/video/capture/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/synchronization/lock.h"
9 #include "base/strings/sys_string_conversions.h" 10 #include "base/strings/sys_string_conversions.h"
10 #include "third_party/decklink/mac/include/DeckLinkAPI.h" 11 #include "third_party/decklink/mac/include/DeckLinkAPI.h"
11 12
12 namespace { 13 namespace {
13 14
14 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only 15 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only
15 // available for Windows builds. This is a verbatim knock-off of the needed 16 // available for Windows builds. This is a verbatim knock-off of the needed
16 // parts of base::win::ScopedComPtr<> for ref counting. 17 // parts of base::win::ScopedComPtr<> for ref counting.
17 template <class T> 18 template <class T>
18 class ScopedDeckLinkPtr : public scoped_refptr<T> { 19 class ScopedDeckLinkPtr : public scoped_refptr<T> {
19 public: 20 public:
20 using scoped_refptr<T>::ptr_; 21 using scoped_refptr<T>::ptr_;
tommi (sloooow) - chröme 2014/09/22 20:26:38 see comment about this from a previous patch set
mcasas 2014/09/23 08:54:54 Made private, but I need it there otherwise clang
21 22
22 T** Receive() { 23 T** Receive() {
23 DCHECK(!ptr_) << "Object leak. Pointer must be NULL"; 24 DCHECK(!ptr_) << "Object leak. Pointer must be NULL";
24 return &ptr_; 25 return &ptr_;
25 } 26 }
26 27
27 void** ReceiveVoid() { 28 void** ReceiveVoid() {
28 return reinterpret_cast<void**>(Receive()); 29 return reinterpret_cast<void**>(Receive());
29 } 30 }
30 31
31 void Release() { 32 void Release() {
32 if (ptr_ != NULL) { 33 if (ptr_ != NULL) {
33 ptr_->Release(); 34 ptr_->Release();
34 ptr_ = NULL; 35 ptr_ = NULL;
35 } 36 }
36 } 37 }
37 }; 38 };
38 39
40 // This class is used to interact directly with DeckLink SDK for video capture.
41 // Implements the reference counted interface IUnknown. Has a weak reference to
42 // VideoCaptureDeviceDeckLinkMac for sending captured frames, error messages and
43 // logs.
44 class DeckLinkCaptureDelegate : private IDeckLinkInputCallback {
45 public:
46 DeckLinkCaptureDelegate(const media::VideoCaptureDevice::Name& device_name,
47 media::VideoCaptureDeviceDeckLinkMac* frame_receiver);
48 virtual ~DeckLinkCaptureDelegate();
49
50 // IDeckLinkInputCallback interface implementation.
51 virtual HRESULT VideoInputFormatChanged (
tommi (sloooow) - chröme 2014/09/22 20:26:38 make all of these private?
mcasas 2014/09/23 08:54:54 Made IDeckLinkInputCallback interface methods priv
tommi (sloooow) - chröme 2014/09/23 12:59:53 ah, makes sense. (ultra nit could we add scoped_r
mcasas 2014/09/23 15:03:46 Done.
52 BMDVideoInputFormatChangedEvents notification_events,
53 IDeckLinkDisplayMode *new_display_mode,
54 BMDDetectedVideoInputFormatFlags detected_signal_flags) OVERRIDE;
55 virtual HRESULT VideoInputFrameArrived (
56 IDeckLinkVideoInputFrame* video_frame,
57 IDeckLinkAudioInputPacket* audio_packet) OVERRIDE;
58
59 // IUnknown interface implementation.
60 virtual HRESULT QueryInterface (REFIID iid, LPVOID *ppv) OVERRIDE;
61 virtual ULONG AddRef() OVERRIDE;
62 virtual ULONG Release() OVERRIDE;
63
64 void AllocateAndStart(const media::VideoCaptureParams& params);
65 void StopAndDeAllocate();
66
67 // Remove the VideoCaptureDeviceDeckLinkMac's weak reference.
68 void ResetVideoCaptureDeviceReference();
69
70 private:
71 // Forwarder to VideoCaptureDeviceDeckLinkMac::sendErrorString().
72 void sendErrorString(const std::string& reason);
tommi (sloooow) - chröme 2014/09/22 20:26:38 why the lower case 's'?
mcasas 2014/09/23 08:54:54 My bad, that would be Obj-C.
73
74 // Forwarder to VideoCaptureDeviceDeckLinkMac::sendLogString().
75 void sendLogString(const std::string& message);
76
77 const media::VideoCaptureDevice::Name device_name_;
78
79 // Protects concurrent setting and using of |frame_receiver_|.
80 base::Lock lock_;
81 media::VideoCaptureDeviceDeckLinkMac* frame_receiver_; // Weak.
tommi (sloooow) - chröme 2014/09/22 20:26:38 explain lifetime?
mcasas 2014/09/23 08:54:54 Done.
82
83 // This is used to control the video capturing device input interface.
84 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_;
85 // |decklink_| represents a physical device attached to the host.
86 ScopedDeckLinkPtr<IDeckLink> decklink_;
87 // Internal counter for IUnknown interface implementation.
88 int32_t ref_count_;
89
90 base::ThreadChecker thread_checker_;
91
92 DISALLOW_COPY_AND_ASSIGN(DeckLinkCaptureDelegate);
93 };
94
95 static float GetDisplayModeFrameRate(
96 const ScopedDeckLinkPtr<IDeckLinkDisplayMode>& display_mode) {
97 BMDTimeValue time_value, time_scale;
98 float display_mode_frame_rate = 0.0f;
99 if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK &&
100 time_value > 0) {
101 display_mode_frame_rate = static_cast<float>(time_scale) / time_value;
102 }
103 // Interlaced formats are going to be marked as double the frame rate,
104 // which follows the general naming convention.
105 if (display_mode->GetFieldDominance() == bmdLowerFieldFirst ||
106 display_mode->GetFieldDominance() == bmdUpperFieldFirst) {
107 display_mode_frame_rate *= 2.0f;
108 }
109 return display_mode_frame_rate;
110 }
111
112 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate(
113 const media::VideoCaptureDevice::Name& device_name,
114 media::VideoCaptureDeviceDeckLinkMac* frame_receiver)
115 : device_name_(device_name),
116 frame_receiver_(frame_receiver) {
117 }
118
119 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() {}
120
121 void DeckLinkCaptureDelegate::AllocateAndStart(
122 const media::VideoCaptureParams& params) {
123 DCHECK(thread_checker_.CalledOnValidThread());
124 scoped_refptr<IDeckLinkIterator> decklink_iter(
125 CreateDeckLinkIteratorInstance());
126 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator";
127 if (!decklink_iter.get())
128 return;
129
130 while (decklink_iter->Next(decklink_.Receive()) == S_OK) {
131 CFStringRef device_model_name = NULL;
132 if ((decklink_->GetModelName(&device_model_name) == S_OK) ||
133 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) {
134 break;
135 }
136 decklink_.Release();
137 }
138 if (!decklink_.get()) {
139 sendErrorString("Device id not found in the system");
140 return;
141 }
142
143 if (decklink_->QueryInterface(IID_IDeckLinkInput,
144 decklink_input_.ReceiveVoid()) != S_OK) {
tommi (sloooow) - chröme 2014/09/22 20:26:38 indent
mcasas 2014/09/23 08:54:54 Done.
145 sendErrorString("Error querying input interface.");
146 return;
147 }
148
149 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
150 if (decklink_input_->GetDisplayModeIterator(display_mode_iter.Receive()) !=
151 S_OK) {
152 sendErrorString("Error creating Display Mode Iterator");
153 return;
154 }
155
156 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
157 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
158 float min_diff = FLT_MAX;
159 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
160 const float diff = abs(display_mode->GetWidth() -
161 params.requested_format.frame_size.width()) +
162 abs(params.requested_format.frame_size.height() -
163 display_mode->GetHeight()) + fabs(params.requested_format.frame_rate -
164 GetDisplayModeFrameRate(display_mode));
165 if (diff < min_diff) {
166 chosen_display_mode = display_mode;
167 min_diff = diff;
168 }
169 display_mode.Release();
170 }
171 if (!chosen_display_mode.get()) {
172 sendErrorString("Could not find a display mode");
173 return;
174 }
175 #if !defined(NDEBUG)
176 DVLOG(1) << "Requested format: " << params.requested_format.ToString();
177 CFStringRef format_name = NULL;
178 if (chosen_display_mode->GetName(&format_name) == S_OK)
179 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name);
180 #endif
181
182 // Enable video input. Configure for no input video format change detection,
183 // this in turn will disable calls to VideoInputFormatChanged().
184 if (decklink_input_->EnableVideoInput(chosen_display_mode->GetDisplayMode(),
185 bmdFormat8BitYUV, bmdVideoInputFlagDefault) != S_OK) {
tommi (sloooow) - chröme 2014/09/22 20:26:38 indent
mcasas 2014/09/23 08:54:54 Done.
186 sendErrorString("Could not select the video format we like.");
187 return;
188 }
189
190 decklink_input_->SetCallback(this);
191 if (decklink_input_->StartStreams() != S_OK)
192 sendErrorString("Could not start capturing");
193 }
194
195 void DeckLinkCaptureDelegate::StopAndDeAllocate() {
196 DCHECK(thread_checker_.CalledOnValidThread());
197 if (!decklink_input_.get()) {
tommi (sloooow) - chröme 2014/09/22 20:26:38 no {} (see next 'if')
mcasas 2014/09/23 08:54:54 Done.
198 return;
199 }
200 if (decklink_input_->StopStreams() != S_OK)
201 sendLogString("Problem stopping capture.");
202 decklink_input_->SetCallback(NULL);
203 decklink_input_->DisableVideoInput();
204 ResetVideoCaptureDeviceReference();
205 }
206
207 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged (
208 BMDVideoInputFormatChangedEvents notification_events,
209 IDeckLinkDisplayMode *new_display_mode,
210 BMDDetectedVideoInputFormatFlags detected_signal_flags) {
211 DCHECK(thread_checker_.CalledOnValidThread());
212 return S_OK;
213 }
214
215 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived (
216 IDeckLinkVideoInputFrame* video_frame,
217 IDeckLinkAudioInputPacket* /* audio_packet */) {
218 // Capture frames are manipulated as an IDeckLinkVideoFrame.
219 void *video_data = NULL;
tommi (sloooow) - chröme 2014/09/22 20:26:38 void* video_data = NULL; should this perhaps be u
mcasas 2014/09/23 08:54:54 Done.
220 video_frame->GetBytes(&video_data);
221
222 media::VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN;
223 switch (video_frame->GetPixelFormat()) {
224 case bmdFormat8BitYUV: // A.k.a. '2vuy';
225 pixel_format = media::PIXEL_FORMAT_UYVY;
226 break;
227 case bmdFormat8BitARGB:
228 pixel_format = media::PIXEL_FORMAT_ARGB;
229 break;
230 default:
231 sendErrorString("Unsupported pixel format");
232 break;
233 }
234
235 const media::VideoCaptureFormat capture_format(
236 gfx::Size(video_frame->GetWidth(), video_frame->GetHeight()),
237 0.0f, // Frame rate is not needed for captured data callback.
238 pixel_format);
239 base::AutoLock lock(lock_);
240 if (frame_receiver_) {
241 frame_receiver_->OnIncomingCapturedData(
242 static_cast<uint8*>(video_data),
243 video_frame->GetRowBytes() * video_frame->GetHeight(),
244 capture_format,
245 0, // Rotation.
246 base::TimeTicks::Now());
247 }
248 return S_OK;
249 }
250
251 HRESULT DeckLinkCaptureDelegate::QueryInterface(REFIID iid, LPVOID *ppv) {
252 DCHECK(thread_checker_.CalledOnValidThread());
253 CFUUIDBytes iunknown = CFUUIDGetUUIDBytes(IUnknownUUID);
254 if (memcmp(&iid, &iunknown, sizeof(REFIID)) == 0 ||
255 memcmp(&iid, &IID_IDeckLinkNotificationCallback, sizeof(REFIID)) == 0) {
256 *ppv = reinterpret_cast<IDeckLinkNotificationCallback*>(this);
tommi (sloooow) - chröme 2014/09/22 20:26:38 static_cast
mcasas 2014/09/23 08:54:54 According to clang, static_cast from 'DeckLinkCap
tommi (sloooow) - chröme 2014/09/23 12:59:53 yeah, that's because the inheritance was set to 'p
mcasas 2014/09/23 15:03:46 Actually, thanks for insisting here. The code is w
tommi (sloooow) - chröme 2014/09/23 17:15:28 Actually, we still need the cast in there to be sa
257 AddRef();
258 return S_OK;
259 }
260 return E_NOINTERFACE;
261 }
262
263 ULONG DeckLinkCaptureDelegate::AddRef(void) {
264 DCHECK(thread_checker_.CalledOnValidThread());
265 return OSAtomicIncrement32(&ref_count_);
266 }
267
268 ULONG DeckLinkCaptureDelegate::Release(void) {
269 DCHECK(thread_checker_.CalledOnValidThread());
270 int32_t newRefValue = OSAtomicDecrement32(&ref_count_);
271 if (newRefValue == 0)
272 delete this;
273 return newRefValue;
274 }
275
276 void DeckLinkCaptureDelegate::sendErrorString(const std::string& reason) {
277 base::AutoLock lock(lock_);
278 if (frame_receiver_)
279 frame_receiver_->sendErrorString(reason);
280 }
281
282 void DeckLinkCaptureDelegate::sendLogString(const std::string& message) {
283 base::AutoLock lock(lock_);
284 if (frame_receiver_)
285 frame_receiver_->sendLogString(message);
286 }
287
288 void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() {
289 DCHECK(thread_checker_.CalledOnValidThread());
290 base::AutoLock lock(lock_);
291 frame_receiver_ = NULL;
292 }
293
39 } // namespace 294 } // namespace
40 295
41 namespace media { 296 namespace media {
42 297
43 std::string JoinDeviceNameAndFormat(CFStringRef name, CFStringRef format) { 298 static std::string JoinDeviceNameAndFormat(CFStringRef name,
299 CFStringRef format) {
44 return base::SysCFStringRefToUTF8(name) + " - " + 300 return base::SysCFStringRefToUTF8(name) + " - " +
45 base::SysCFStringRefToUTF8(format); 301 base::SysCFStringRefToUTF8(format);
46 } 302 }
47 303
48 //static 304 //static
49 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices( 305 void VideoCaptureDeviceDeckLinkMac::EnumerateDevices(
50 VideoCaptureDevice::Names* device_names) { 306 VideoCaptureDevice::Names* device_names) {
51 scoped_refptr<IDeckLinkIterator> decklink_iter( 307 scoped_refptr<IDeckLinkIterator> decklink_iter(
52 CreateDeckLinkIteratorInstance()); 308 CreateDeckLinkIteratorInstance());
53 // At this point, not being able to create a DeckLink iterator means that 309 // At this point, not being able to create a DeckLink iterator means that
54 // there are no Blackmagic devices in the system but this isn't an error. 310 // there are no Blackmagic DeckLink devices in the system, don't print error.
55 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator"; 311 DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator";
56 if (!decklink_iter.get()) 312 if (!decklink_iter.get())
57 return; 313 return;
58 314
59 ScopedDeckLinkPtr<IDeckLink> decklink; 315 ScopedDeckLinkPtr<IDeckLink> decklink;
60 while (decklink_iter->Next(decklink.Receive()) == S_OK) { 316 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
61 ScopedDeckLinkPtr<IDeckLink> decklink_local; 317 ScopedDeckLinkPtr<IDeckLink> decklink_local;
62 decklink_local.swap(decklink); 318 decklink_local.swap(decklink);
63 319
64 CFStringRef device_model_name = NULL; 320 CFStringRef device_model_name = NULL;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if (!decklink_iter.get()) 369 if (!decklink_iter.get())
114 return; 370 return;
115 371
116 ScopedDeckLinkPtr<IDeckLink> decklink; 372 ScopedDeckLinkPtr<IDeckLink> decklink;
117 while (decklink_iter->Next(decklink.Receive()) == S_OK) { 373 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
118 ScopedDeckLinkPtr<IDeckLink> decklink_local; 374 ScopedDeckLinkPtr<IDeckLink> decklink_local;
119 decklink_local.swap(decklink); 375 decklink_local.swap(decklink);
120 376
121 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input; 377 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
122 if (decklink_local->QueryInterface(IID_IDeckLinkInput, 378 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
123 decklink_input.ReceiveVoid()) != S_OK) { 379 decklink_input.ReceiveVoid()) != S_OK) {
124 DLOG(ERROR) << "Error Blackmagic querying input interface."; 380 DLOG(ERROR) << "Error Blackmagic querying input interface.";
125 return; 381 return;
126 } 382 }
127 383
128 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter; 384 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
129 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) != 385 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
130 S_OK) { 386 S_OK) {
131 continue; 387 continue;
132 } 388 }
133 389
134 CFStringRef device_model_name = NULL; 390 CFStringRef device_model_name = NULL;
135 if (decklink_local->GetModelName(&device_model_name) != S_OK) 391 if (decklink_local->GetModelName(&device_model_name) != S_OK)
136 continue; 392 continue;
137 393
138 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode; 394 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
139 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) { 395 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
140 CFStringRef format_name = NULL; 396 CFStringRef format_name = NULL;
141 if (display_mode->GetName(&format_name) == S_OK && device.id() != 397 if (display_mode->GetName(&format_name) == S_OK && device.id() !=
142 JoinDeviceNameAndFormat(device_model_name, format_name)) { 398 JoinDeviceNameAndFormat(device_model_name, format_name)) {
143 display_mode.Release(); 399 display_mode.Release();
144 continue; 400 continue;
145 } 401 }
146 402
147 // IDeckLinkDisplayMode does not have information on pixel format, this 403 // IDeckLinkDisplayMode does not have information on pixel format, this
148 // is only available on capture. 404 // is only available on capture.
149 media::VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN; 405 const media::VideoCaptureFormat format(
150 BMDTimeValue time_value, time_scale;
151 float frame_rate = 0.0f;
152 if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK &&
153 time_value > 0) {
154 frame_rate = static_cast<float>(time_scale) / time_value;
155 }
156 media::VideoCaptureFormat format(
157 gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()), 406 gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()),
158 frame_rate, 407 GetDisplayModeFrameRate(display_mode),
159 pixel_format); 408 PIXEL_FORMAT_UNKNOWN);
160 supported_formats->push_back(format); 409 supported_formats->push_back(format);
161 DVLOG(2) << device.name() << " " << format.ToString(); 410 DVLOG(2) << device.name() << " " << format.ToString();
162 display_mode.Release(); 411 display_mode.Release();
163 } 412 }
164 return; 413 return;
165 } 414 }
166 } 415 }
167 416
168 VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac( 417 VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac(
169 const Name& device_name) {} 418 const Name& device_name)
419 : decklink_capture_delegate_(
420 new DeckLinkCaptureDelegate(device_name, this)) {
421 }
170 422
171 VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() {} 423 VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() {
424 decklink_capture_delegate_->ResetVideoCaptureDeviceReference();
425 }
426
427 void VideoCaptureDeviceDeckLinkMac::OnIncomingCapturedData(
428 const uint8* data,
429 int length,
430 const VideoCaptureFormat& frame_format,
431 int rotation, // Clockwise.
432 base::TimeTicks timestamp) {
433 base::AutoLock lock(lock_);
434 if (client_) {
435 client_->OnIncomingCapturedData(data, length, frame_format, rotation,
436 timestamp);
437 }
438 }
439
440 void VideoCaptureDeviceDeckLinkMac::sendErrorString(const std::string& reason) {
441 DCHECK(thread_checker_.CalledOnValidThread());
442 base::AutoLock lock(lock_);
443 if (client_)
444 client_->OnError(reason);
445 }
446
447 void VideoCaptureDeviceDeckLinkMac::sendLogString(const std::string& message) {
448 DCHECK(thread_checker_.CalledOnValidThread());
449 base::AutoLock lock(lock_);
450 if (client_)
451 client_->OnLog(message);
452 }
172 453
173 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart( 454 void VideoCaptureDeviceDeckLinkMac::AllocateAndStart(
174 const VideoCaptureParams& params, 455 const VideoCaptureParams& params,
175 scoped_ptr<VideoCaptureDevice::Client> client) { 456 scoped_ptr<VideoCaptureDevice::Client> client) {
176 NOTIMPLEMENTED(); 457 DCHECK(thread_checker_.CalledOnValidThread());
458 client_ = client.Pass();
459 if (decklink_capture_delegate_.get())
460 decklink_capture_delegate_->AllocateAndStart(params);
177 } 461 }
178 462
179 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { 463 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
180 NOTIMPLEMENTED(); 464 if (decklink_capture_delegate_.get())
465 decklink_capture_delegate_->StopAndDeAllocate();
181 } 466 }
182 467
183 } // namespace media 468 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698