]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/producer/decklink_producer.cpp
[decklink] Added missing channel-layer in diag for the producer
[casparcg] / modules / decklink / producer / decklink_producer.cpp
index 19521f1f17dbcb72fe0051c949da700e816457cc..5200a6900c72f5c4568faad00657d7ed0d343dac 100644 (file)
@@ -44,6 +44,7 @@
 #include <core/frame/frame_factory.h>
 #include <core/producer/frame_producer.h>
 #include <core/monitor/monitor.h>
+#include <core/diagnostics/call_context.h>
 #include <core/mixer/audio/audio_mixer.h>
 #include <core/help/help_repository.h>
 #include <core/help/help_sink.h>
@@ -52,6 +53,7 @@
 
 #include <boost/algorithm/string.hpp>
 #include <boost/property_tree/ptree.hpp>
+#include <boost/range/adaptor/transformed.hpp>
 
 #if defined(_MSC_VER)
 #pragma warning (push)
@@ -84,6 +86,12 @@ core::audio_channel_layout get_adjusted_channel_layout(core::audio_channel_layou
 
        return layout;
 }
+
+template <typename T>
+std::wstring to_string(const T& cadence)
+{
+       return boost::join(cadence | boost::adaptors::transformed([](size_t i) { return boost::lexical_cast<std::wstring>(i); }), L", ");
+}
                
 class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback
 {      
@@ -138,7 +146,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))) 
@@ -228,32 +237,44 @@ public:
 
                        // Audio
 
-                       void* audio_bytes = nullptr;
-                       if(FAILED(audio->GetBytes(&audio_bytes)) || !audio_bytes)
-                               return S_OK;
-                       
                        auto audio_frame = ffmpeg::create_frame();
+                       audio_frame->format = AV_SAMPLE_FMT_S32;
+                       core::mutable_audio_buffer audio_buf;
 
-                       audio_frame->data[0]            = reinterpret_cast<uint8_t*>(audio_bytes);
-                       audio_frame->linesize[0]        = audio->GetSampleFrameCount() * channel_layout_.num_channels * sizeof(int32_t);
-                       audio_frame->nb_samples         = audio->GetSampleFrameCount();
-                       audio_frame->format                     = AV_SAMPLE_FMT_S32;
+                       if (audio)
+                       {
+                               void* audio_bytes = nullptr;
+                               if (FAILED(audio->GetBytes(&audio_bytes)) || !audio_bytes)
+                                       return S_OK;
+
+
+                               audio_frame->data[0] = reinterpret_cast<uint8_t*>(audio_bytes);
+                               audio_frame->linesize[0] = audio->GetSampleFrameCount() * channel_layout_.num_channels * sizeof(int32_t);
+                               audio_frame->nb_samples = audio->GetSampleFrameCount();
+                       }
+                       else
+                       {
+                               audio_buf.resize(audio_cadence_.front() * channel_layout_.num_channels, 0);
+                               audio_frame->data[0] = reinterpret_cast<uint8_t*>(audio_buf.data());
+                               audio_frame->linesize[0] = audio_cadence_.front() * channel_layout_.num_channels * sizeof(int32_t);
+                               audio_frame->nb_samples = audio_cadence_.front();
+                       }
                                                
                        // Note: Uses 1 step rotated cadence for 1001 modes (1602, 1602, 1601, 1602, 1601)
                        // This cadence fills the audio mixer most optimally.
 
-                       sync_buffer_.push_back(audio->GetSampleFrameCount());           
+                       sync_buffer_.push_back(audio_frame->nb_samples);
                        if(!boost::range::equal(sync_buffer_, audio_cadence_))
                        {
-                               CASPAR_LOG(trace) << print() << L" Syncing audio.";
+                               CASPAR_LOG(trace) << print() << L" Syncing audio. Expected cadence: " << to_string(audio_cadence_) << L" Got cadence: " << to_string(sync_buffer_);
                                return S_OK;
                        }
                        boost::range::rotate(audio_cadence_, std::begin(audio_cadence_)+1);
                        
                        // PUSH
 
-                       muxer_.push_video(video_frame); 
-                       muxer_.push_audio(audio_frame);                                                                                 
+                       muxer_.push_video(video_frame);
+                       muxer_.push_audio(audio_frame);
                        
                        // POLL
 
@@ -328,8 +349,10 @@ public:
                : executor_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")
                , length_(length)
        {
+               auto ctx = core::diagnostics::call_context::for_thread();
                executor_.invoke([=]
                {
+                       core::diagnostics::call_context::for_thread() = ctx;
                        com_initialize();
                        producer_.reset(new decklink_producer(in_format_desc, device_index, frame_factory, out_format_desc, channel_layout, filter_str));
                });
@@ -426,7 +449,7 @@ spl::shared_ptr<core::frame_producer> create_producer(const core::frame_producer
                auto found_layout = core::audio_channel_layout_repository::get_default()->get_layout(channel_layout_spec);
 
                if (!found_layout)
-                       CASPAR_THROW_EXCEPTION(file_not_found() << msg_info(L"Channel layout not found."));
+                       CASPAR_THROW_EXCEPTION(user_error() << msg_info(L"Channel layout not found."));
 
                channel_layout = *found_layout;
        }