(duration),\\r
(m == video_mode::progressive ? 1 : 2),\\r
((w)*(h)*4),\\r
- (name)\\r
+ (name),\\r
+ (2),\\r
+ (48000),\\r
+ (2),\\r
+ (static_cast<size_t>(48000.0*2.0/((double)scale/(double)duration)))\\r
}\r
\r
namespace caspar { namespace core {\r
DEFINE_VIDEOFORMATDESC(video_format::x1080p2997 ,1920, 1080, video_mode::progressive, 30000, 1001, TEXT("1080p2997")),\r
DEFINE_VIDEOFORMATDESC(video_format::x1080p3000 ,1920, 1080, video_mode::progressive, 30, 1, TEXT("1080p3000")),\r
DEFINE_VIDEOFORMATDESC(video_format::x1080p5000 ,1920, 1080, video_mode::progressive, 50, 1, TEXT("1080p5000")),\r
- DEFINE_VIDEOFORMATDESC(video_format::invalid ,0, 0, video_mode::invalid, 0, 1, TEXT("invalid"))\r
+ DEFINE_VIDEOFORMATDESC(video_format::invalid ,0, 0, video_mode::invalid, 1, 1, TEXT("invalid"))\r
};\r
\r
const video_format_desc& video_format_desc::get(video_format::type format) \r
\r
#include "../interop/DeckLinkAPI_h.h"\r
\r
-#include <core/video_format.h>\r
-\r
#include <core/consumer/frame/read_frame.h>\r
\r
#include <common/concurrency/com_context.h>\r
#include <boost/circular_buffer.hpp>\r
#include <boost/timer.hpp>\r
\r
-#include <vector>\r
-\r
-#pragma warning(push)\r
-#pragma warning(disable : 4996)\r
-\r
- #include <atlbase.h>\r
-\r
- #include <atlcom.h>\r
- #include <atlhost.h>\r
-\r
-#pragma warning(push)\r
-\r
namespace caspar { \r
\r
enum key\r
\r
struct configuration\r
{\r
- size_t device_index;\r
- bool embedded_audio;\r
- key keyer;\r
+ size_t device_index;\r
+ bool embedded_audio;\r
+ key keyer;\r
latency latency;\r
\r
configuration()\r
\r
class decklink_frame_adapter : public IDeckLinkVideoFrame\r
{\r
- safe_ptr<const core::read_frame> frame_;\r
- core::video_format_desc format_desc_;\r
+ const safe_ptr<const core::read_frame> frame_;\r
+ const core::video_format_desc format_desc_;\r
public:\r
decklink_frame_adapter(const safe_ptr<const core::read_frame>& frame, const core::video_format_desc& format_desc)\r
: frame_(frame)\r
std::shared_ptr<diagnostics::graph> graph_;\r
boost::timer tick_timer_;\r
\r
-\r
public:\r
decklink_consumer(const configuration& config, const core::video_format_desc& format_desc) \r
: config_(config)\r
if(config.embedded_audio)\r
output_->BeginAudioPreroll();\r
else\r
- {\r
- if(FAILED(output_->StartScheduledPlayback(0, format_desc_.time_scale, 1.0))) \r
- BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to schedule playback."));\r
- }\r
+ start_playback();\r
\r
CASPAR_LOG(info) << print() << L" Buffer depth: " << buffer_size_; \r
CASPAR_LOG(info) << print() << L" Successfully initialized for " << format_desc_.name; \r
if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
}\r
+\r
+ void start_playback()\r
+ {\r
+ if(FAILED(output_->StartScheduledPlayback(0, format_desc_.time_scale, 1.0))) \r
+ BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to schedule playback."));\r
+ }\r
\r
STDMETHOD (QueryInterface(REFIID, LPVOID*)) {return E_NOINTERFACE;}\r
STDMETHOD_(ULONG, AddRef()) {return 1;}\r
else if(result == bmdOutputFrameFlushed)\r
graph_->add_tag("flushed-frame");\r
\r
- frame_container_.erase(std::remove_if(frame_container_.begin(), frame_container_.end(), [&](const decklink_frame_adapter& frame)\r
+ frame_container_.erase(std::find_if(frame_container_.begin(), frame_container_.end(), [&](const decklink_frame_adapter& frame)\r
{\r
return &frame == completed_frame;\r
- }), frame_container_.end());\r
+ }));\r
\r
std::shared_ptr<const core::read_frame> frame; \r
video_frame_buffer_.pop(frame); \r
\r
try\r
{\r
- if(preroll)\r
- {\r
- if(FAILED(output_->StartScheduledPlayback(0, format_desc_.time_scale, 1.0)))\r
- BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to schedule playback."));\r
- }\r
-\r
std::shared_ptr<const core::read_frame> frame;\r
audio_frame_buffer_.pop(frame);\r
schedule_next_audio(safe_ptr<const core::read_frame>(frame)); \r
+\r
+ if(preroll)\r
+ start_playback();\r
}\r
catch(...)\r
{\r
void schedule_next_audio(const safe_ptr<const core::read_frame>& frame)\r
{\r
static std::vector<short> silence(48000, 0);\r
+ \r
+ const int sample_count = format_desc_.audio_samples_per_frame;\r
+ const int sample_frame_count = sample_count/2;\r
\r
- int audio_samples = static_cast<size_t>(48000.0 / format_desc_.fps)*2; // Audio samples per channel\r
-\r
- const short* frame_audio_data = frame->audio_data().size() == audio_samples ? frame->audio_data().begin() : silence.data();\r
- audio_container_.push_back(std::vector<short>(frame_audio_data, frame_audio_data+audio_samples));\r
+ const short* frame_audio_data = frame->audio_data().size() == sample_count ? frame->audio_data().begin() : silence.data();\r
+ audio_container_.push_back(std::vector<short>(frame_audio_data, frame_audio_data+sample_count));\r
\r
- if(FAILED(output_->ScheduleAudioSamples(audio_container_.back().data(), audio_samples/2, (audio_scheduled_++) * audio_samples/2, 48000, nullptr)))\r
+ if(FAILED(output_->ScheduleAudioSamples(audio_container_.back().data(), sample_frame_count, (audio_scheduled_++) * sample_frame_count, format_desc_.audio_sample_rate, nullptr)))\r
CASPAR_LOG(error) << print() << L" Failed to schedule audio.";\r
}\r
\r