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

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: Created 4 years, 9 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 media {
17 static std::string JoinDeviceNameAndFormat(CFStringRef name,
mcasas 2016/04/12 17:54:42 If this function is only used in this file, we can
jensf 2016/04/21 07:29:47 Done.
18 CFStringRef format);
19 };
20
16 namespace { 21 namespace {
17 22
18 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only 23 // DeckLink SDK uses ScopedComPtr-style APIs. Chrome ScopedComPtr is only
19 // available for Windows builds. This is a verbatim knock-off of the needed 24 // available for Windows builds. This is a verbatim knock-off of the needed
20 // parts of base::win::ScopedComPtr<> for ref counting. 25 // parts of base::win::ScopedComPtr<> for ref counting.
21 template <class T> 26 template <class T>
22 class ScopedDeckLinkPtr : public scoped_refptr<T> { 27 class ScopedDeckLinkPtr : public scoped_refptr<T> {
23 private: 28 private:
24 using scoped_refptr<T>::ptr_; 29 using scoped_refptr<T>::ptr_;
25 30
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 133
129 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() { 134 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() {
130 } 135 }
131 136
132 void DeckLinkCaptureDelegate::AllocateAndStart( 137 void DeckLinkCaptureDelegate::AllocateAndStart(
133 const media::VideoCaptureParams& params) { 138 const media::VideoCaptureParams& params) {
134 DCHECK(thread_checker_.CalledOnValidThread()); 139 DCHECK(thread_checker_.CalledOnValidThread());
135 scoped_refptr<IDeckLinkIterator> decklink_iter( 140 scoped_refptr<IDeckLinkIterator> decklink_iter(
136 CreateDeckLinkIteratorInstance()); 141 CreateDeckLinkIteratorInstance());
137 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator"; 142 DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator";
138 if (!decklink_iter.get()) 143 if (!decklink_iter.get()) {
mcasas 2016/04/12 17:54:42 No {} for one-line bodies.
jensf 2016/04/21 07:29:47 Done.
139 return;
140
141 ScopedDeckLinkPtr<IDeckLink> decklink_local;
142 while (decklink_iter->Next(decklink_local.Receive()) == S_OK) {
143 CFStringRef device_model_name = NULL;
144 if ((decklink_local->GetModelName(&device_model_name) == S_OK) ||
145 (device_name_.id() == base::SysCFStringRefToUTF8(device_model_name))) {
146 break;
147 }
148 }
149 if (!decklink_local.get()) {
150 SendErrorString(FROM_HERE, "Device id not found in the system");
151 return; 144 return;
152 } 145 }
153 146
154 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local; 147 ScopedDeckLinkPtr<IDeckLink> chosen_device;
155 if (decklink_local->QueryInterface( 148 ScopedDeckLinkPtr<IDeckLinkInput> chosen_input;
156 IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) { 149 ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
157 SendErrorString(FROM_HERE, "Error querying input interface."); 150 ScopedDeckLinkPtr<IDeckLink> decklink;
158 return; 151 while (decklink_iter->Next(decklink.Receive()) == S_OK) {
152 ScopedDeckLinkPtr<IDeckLink> decklink_local;
153 decklink_local.swap(decklink);
154
155 CFStringRef device_model_name = NULL;
mcasas 2016/04/12 17:54:42 nullptr? nil?
jensf 2016/04/21 07:29:47 Done.
156 HRESULT hr = decklink_local->GetModelName(&device_model_name);
157 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device model name";
mcasas 2016/04/12 17:54:42 Consider DLOG_IF(ERROR,...
jensf 2016/04/21 07:29:46 Done.
158 CFStringRef device_display_name = NULL;
159 hr = decklink_local->GetDisplayName(&device_display_name);
160 DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device display name";
161 DVLOG_IF(1, hr == S_OK) << "Blackmagic device found with name: "
162 << base::SysCFStringRefToUTF8(device_display_name);
163
164 if (!device_model_name && !device_display_name)
165 continue;
166
167 ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
168 if (decklink_local->QueryInterface(IID_IDeckLinkInput,
169 decklink_input.ReceiveVoid()) != S_OK) {
170 DLOG(ERROR) << "Error Blackmagic querying input interface.";
171 return;
172 }
173
174 ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
175 if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
176 S_OK) {
177 continue;
178 }
179
180 ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
181 while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
182 CFStringRef format_name = NULL;
183 if (display_mode->GetName(&format_name) == S_OK) {
184 media::VideoCaptureDevice::Name name(
185 media::JoinDeviceNameAndFormat(device_display_name, format_name),
186 media::JoinDeviceNameAndFormat(device_model_name, format_name),
187 media::VideoCaptureDevice::Name::DECKLINK,
188 media::VideoCaptureDevice::Name::OTHER_TRANSPORT);
189
190 if (device_name_.id() == name.id()) {
191 chosen_device.swap(decklink_local);
192 chosen_input.swap(decklink_input);
193 chosen_display_mode.swap(display_mode);
194 break;
195 }
196
197 DVLOG(1) << "Blackmagic camera enumerated: " << name.name();
198 }
199 display_mode.Release();
200 }
159 } 201 }
160 202
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()) { 203 if (!chosen_display_mode.get()) {
185 SendErrorString(FROM_HERE, "Could not find a display mode"); 204 SendErrorString(FROM_HERE, "Could not find a display mode");
186 return; 205 return;
187 } 206 }
188 #if !defined(NDEBUG) 207 #if !defined(NDEBUG)
189 DVLOG(1) << "Requested format: " 208 DVLOG(1) << "Requested format: "
190 << media::VideoCaptureFormat::ToString(params.requested_format); 209 << media::VideoCaptureFormat::ToString(params.requested_format);
191 CFStringRef format_name = NULL; 210 CFStringRef format_name = NULL;
192 if (chosen_display_mode->GetName(&format_name) == S_OK) 211 if (chosen_display_mode->GetName(&format_name) == S_OK)
193 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name); 212 DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name);
194 #endif 213 #endif
195 214
196 // Enable video input. Configure for no input video format change detection, 215 // Enable video input. Configure for no input video format change detection,
197 // this in turn will disable calls to VideoInputFormatChanged(). 216 // this in turn will disable calls to VideoInputFormatChanged().
198 if (decklink_input_local->EnableVideoInput( 217 if (chosen_input->EnableVideoInput(chosen_display_mode->GetDisplayMode(),
199 chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV, 218 bmdFormat8BitYUV,
200 bmdVideoInputFlagDefault) != S_OK) { 219 bmdVideoInputFlagDefault) != S_OK) {
201 SendErrorString(FROM_HERE, "Could not select the video format we like."); 220 SendErrorString(FROM_HERE, "Could not select the video format we like.");
202 return; 221 return;
203 } 222 }
204 223
205 decklink_input_local->SetCallback(this); 224 chosen_input->SetCallback(this);
206 if (decklink_input_local->StartStreams() != S_OK) 225 if (chosen_input->StartStreams() != S_OK) {
207 SendErrorString(FROM_HERE, "Could not start capturing"); 226 SendErrorString(FROM_HERE, "Could not start capturing");
208 227 }
209 decklink_.swap(decklink_local); 228 decklink_.swap(chosen_device);
210 decklink_input_.swap(decklink_input_local); 229 decklink_input_.swap(chosen_input);
211 } 230 }
212 231
213 void DeckLinkCaptureDelegate::StopAndDeAllocate() { 232 void DeckLinkCaptureDelegate::StopAndDeAllocate() {
214 DCHECK(thread_checker_.CalledOnValidThread()); 233 DCHECK(thread_checker_.CalledOnValidThread());
215 if (!decklink_input_.get()) 234 if (!decklink_input_.get())
216 return; 235 return;
217 if (decklink_input_->StopStreams() != S_OK) 236 if (decklink_input_->StopStreams() != S_OK)
218 SendLogString("Problem stopping capture."); 237 SendLogString("Problem stopping capture.");
219 decklink_input_->SetCallback(NULL); 238 decklink_input_->SetCallback(NULL);
220 decklink_input_->DisableVideoInput(); 239 decklink_input_->DisableVideoInput();
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (decklink_capture_delegate_.get()) 502 if (decklink_capture_delegate_.get())
484 decklink_capture_delegate_->AllocateAndStart(params); 503 decklink_capture_delegate_->AllocateAndStart(params);
485 } 504 }
486 505
487 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() { 506 void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
488 if (decklink_capture_delegate_.get()) 507 if (decklink_capture_delegate_.get())
489 decklink_capture_delegate_->StopAndDeAllocate(); 508 decklink_capture_delegate_->StopAndDeAllocate();
490 } 509 }
491 510
492 } // namespace media 511 } // 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