]> git.sesse.net Git - casparcg/commitdiff
Only memcpy on Linux if the decklink card will attempt DMA directly from BGRA buffer...
authorHelge Norberg <helge.norberg@svt.se>
Fri, 8 Jan 2016 15:32:26 +0000 (16:32 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 8 Jan 2016 15:32:26 +0000 (16:32 +0100)
modules/decklink/consumer/decklink_consumer.cpp
modules/decklink/producer/decklink_producer.cpp
modules/decklink/util/util.h

index 58a53e658f10e618ff4d1d752936df04ab9b5ba2..c8492e6538af9899db059ae9b0cf0d2d53ae65d6 100644 (file)
@@ -175,14 +175,23 @@ class decklink_frame : public IDeckLinkVideoFrame
        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
@@ -234,12 +243,12 @@ public:
                        {
                                *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(...)
@@ -354,6 +363,7 @@ struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLink
        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_);
@@ -418,7 +428,7 @@ public:
                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();
@@ -611,12 +621,12 @@ public:
        {
                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.";
 
index c099d878892c5cefc967cb0c333a43e454a0d031..b64c976568fb0966d1e5e7b4926bba00433d299f 100644 (file)
@@ -145,7 +145,8 @@ public:
                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))) 
index 1cfa95f597cf010badf9bf7fa29324f38bb2d6f8..e91a42e2babe374a80b68442305ca315c7940ae9 100644 (file)
@@ -115,8 +115,15 @@ static core::video_format get_caspar_video_format(BMDDisplayMode fmt)
        }
 }
 
+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;
@@ -137,21 +144,24 @@ BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixel
        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>