const core::video_format_desc format_desc_;
const bool key_only_;
+ bool needs_to_copy_;
cache_aligned_vector<no_init_proxy<uint8_t>> data_;
public:
- decklink_frame(core::const_frame frame, const core::video_format_desc& format_desc, bool key_only)
+ decklink_frame(core::const_frame frame, const core::video_format_desc& format_desc, bool key_only, bool will_attempt_dma)
: frame_(frame)
, format_desc_(format_desc)
, key_only_(key_only)
{
ref_count_ = 0;
+
+#if !defined(_MSC_VER)
+ // On Linux Decklink cannot DMA transfer from memory returned by glMapBuffer
+ needs_to_copy_ = will_attempt_dma;
+#else
+ // On Windows it does
+ needs_to_copy_ = false;
+#endif
}
// IUnknown
{
*buffer = const_cast<uint8_t*>(frame_.image_data().begin());
-#if !defined(_MSC_VER)
- // On Linux Decklink cannot DMA transfer from memory returned by glMapBuffer
- data_.resize(frame_.image_data().size());
- fast_memcpy(data_.data(), *buffer, frame_.image_data().size());
- *buffer = data_.data();
-#endif
+ if (needs_to_copy_)
+ {
+ data_.resize(frame_.image_data().size());
+ fast_memcpy(data_.data(), *buffer, frame_.image_data().size());
+ *buffer = data_.data();
+ }
}
}
catch(...)
tbb::atomic<bool> is_running_;
const std::wstring model_name_ = get_model_name(decklink_);
+ bool will_attempt_dma_;
const core::video_format_desc format_desc_;
const core::audio_channel_layout in_channel_layout_;
const core::audio_channel_layout out_channel_layout_ = config_.get_adjusted_layout(in_channel_layout_);
graph_->set_text(print());
diagnostics::register_graph(graph_);
- enable_video(get_display_mode(output_, format_desc_.format, bmdFormat8BitBGRA, bmdVideoOutputFlagDefault));
+ enable_video(get_display_mode(output_, format_desc_.format, bmdFormat8BitBGRA, bmdVideoOutputFlagDefault, will_attempt_dma_));
if(config.embedded_audio)
enable_audio();
{
if (key_context_)
{
- auto key_frame = wrap_raw<com_ptr, IDeckLinkVideoFrame>(new decklink_frame(frame, format_desc_, true));
+ auto key_frame = wrap_raw<com_ptr, IDeckLinkVideoFrame>(new decklink_frame(frame, format_desc_, true, will_attempt_dma_));
if (FAILED(key_context_->output_->ScheduleVideoFrame(get_raw(key_frame), video_scheduled_, format_desc_.duration, format_desc_.time_scale)))
CASPAR_LOG(error) << print() << L" Failed to schedule key video.";
}
- auto fill_frame = wrap_raw<com_ptr, IDeckLinkVideoFrame>(new decklink_frame(frame, format_desc_, config_.key_only));
+ auto fill_frame = wrap_raw<com_ptr, IDeckLinkVideoFrame>(new decklink_frame(frame, format_desc_, config_.key_only, will_attempt_dma_));
if (FAILED(output_->ScheduleVideoFrame(get_raw(fill_frame), video_scheduled_, format_desc_.duration, format_desc_.time_scale)))
CASPAR_LOG(error) << print() << L" Failed to schedule fill video.";
graph_->set_text(print());
diagnostics::register_graph(graph_);
- auto display_mode = get_display_mode(input_, in_format_desc.format, bmdFormat8BitYUV, bmdVideoInputFlagDefault);
+ bool will_attempt_dma;
+ auto display_mode = get_display_mode(input_, in_format_desc.format, bmdFormat8BitYUV, bmdVideoInputFlagDefault, will_attempt_dma);
// NOTE: bmdFormat8BitARGB is currently not supported by any decklink card. (2011-05-08)
if(FAILED(input_->EnableVideoInput(display_mode, bmdFormat8BitYUV, 0)))
}
}
+static std::wstring get_mode_name(const com_ptr<IDeckLinkDisplayMode>& mode)
+{
+ String mode_name;
+ mode->GetName(&mode_name);
+ return u16(mode_name);
+}
+
template<typename T, typename F>
-BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)
+BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag, bool& will_attempt_dma)
{
IDeckLinkDisplayMode* m = nullptr;
IDeckLinkDisplayModeIterator* iter;
com_ptr<IDeckLinkDisplayMode> mode = wrap_raw<com_ptr>(m, true);
BMDDisplayModeSupport displayModeSupport;
- if(FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)) || displayModeSupport == bmdDisplayModeNotSupported)
- CASPAR_LOG(warning) << L"Device does not support video-format: " << mode->GetDisplayMode();
- //CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Device does not support requested video-format.")
- // << arg_value_info(boost::lexical_cast<std::string>(format))
- // << arg_name_info("format"));
- else if(displayModeSupport == bmdDisplayModeSupportedWithConversion)
- CASPAR_LOG(warning) << L"Device supports video-format with conversion: " << mode->GetDisplayMode();
+ will_attempt_dma = false;
+
+ if (FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)))
+ CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info(L"Could not determine whether device supports requested video format: " + get_mode_name(mode)));
+ else if (displayModeSupport == bmdDisplayModeNotSupported)
+ CASPAR_LOG(warning) << L"Device does not support video-format: " << get_mode_name(mode);
+ else if (displayModeSupport == bmdDisplayModeSupportedWithConversion)
+ CASPAR_LOG(warning) << L"Device supports video-format with conversion: " << get_mode_name(mode);
+ else
+ will_attempt_dma = true;
return mode->GetDisplayMode();
}
template<typename T, typename F>
-static BMDDisplayMode get_display_mode(const T& device, core::video_format fmt, BMDPixelFormat pix_fmt, F flag)
+static BMDDisplayMode get_display_mode(const T& device, core::video_format fmt, BMDPixelFormat pix_fmt, F flag, bool& will_attempt_dma)
{
- return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);
+ return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag, will_attempt_dma);
}
template<typename T>