\r
#include "../log/log.h"\r
\r
-#define __ASSERT_EXPR_STR(name) #name\r
+#ifdef _MSC_VER\r
+#define _CASPAR_DBG_BREAK _CrtDbgBreak()\r
+#else\r
+#define _CASPAR_DBG_BREAK\r
+#endif\r
\r
-#define CASPAR_ASSERT(expr) do{if(!(expr)) CASPAR_LOG(error) << "\nAssertion failed.\n " << __ASSERT_EXPR_STR(expr) << "\n" << __FILE__ << "\n" << __LINE__ << "\n\n";}while(0)
\ No newline at end of file
+#define CASPAR_ASSERT_EXPR_STR(str) #str\r
+\r
+#define CASPAR_ASSERT(expr) do{if(!(expr)) CASPAR_LOG(warning) << "\n\nAssertion Failed:\n" << \\r
+ CASPAR_ASSERT_EXPR_STR(expr) << "\n" \\r
+ __FILE__ << "\n"; \\r
+ _CASPAR_DBG_BREAK;\\r
+ }while(0);
\ No newline at end of file
switch(fmt)\r
{\r
case video_format::pal: return VID_FMT_PAL;\r
- //case video_format::ntsc: return VID_FMT_NTSC;\r
- //case video_format::x576p2500: return VID_FMT_INVALID; //not supported\r
+ case video_format::ntsc: return VID_FMT_NTSC;\r
+ case video_format::x576p2500: return VID_FMT_INVALID; //not supported\r
case video_format::x720p2500: return VID_FMT_720P_2500;\r
case video_format::x720p5000: return VID_FMT_720P_5000;\r
- //case video_format::x720p5994: return VID_FMT_720P_5994;\r
- //case video_format::x720p6000: return VID_FMT_720P_6000;\r
- //case video_format::x1080p2397: return VID_FMT_1080P_2397;\r
- //case video_format::x1080p2400: return VID_FMT_1080P_2400;\r
+ case video_format::x720p5994: return VID_FMT_720P_5994;\r
+ case video_format::x720p6000: return VID_FMT_720P_6000;\r
+ case video_format::x1080p2397: return VID_FMT_1080P_2397;\r
+ case video_format::x1080p2400: return VID_FMT_1080P_2400;\r
case video_format::x1080i5000: return VID_FMT_1080I_5000;\r
- //case video_format::x1080i5994: return VID_FMT_1080I_5994;\r
- //case video_format::x1080i6000: return VID_FMT_1080I_6000;\r
+ case video_format::x1080i5994: return VID_FMT_1080I_5994;\r
+ case video_format::x1080i6000: return VID_FMT_1080I_6000;\r
case video_format::x1080p2500: return VID_FMT_1080P_2500;\r
- //case video_format::x1080p2997: return VID_FMT_1080P_2997;\r
- //case video_format::x1080p3000: return VID_FMT_1080P_3000;\r
+ case video_format::x1080p2997: return VID_FMT_1080P_2997;\r
+ case video_format::x1080p3000: return VID_FMT_1080P_3000;\r
default: return VID_FMT_INVALID;\r
}\r
}\r
switch(fmt)\r
{\r
case video_format::pal: return bmdModePAL;\r
- //case video_format::ntsc: return bmdModeNTSC;\r
- //case video_format::x576p2500: return ULONG_MAX;\r
+ case video_format::ntsc: return bmdModeNTSC;\r
+ case video_format::x576p2500: return (BMDDisplayMode)ULONG_MAX;\r
case video_format::x720p2500: return (BMDDisplayMode)ULONG_MAX;\r
case video_format::x720p5000: return bmdModeHD720p50;\r
- //case video_format::x720p5994: return bmdModeHD720p5994;\r
- //case video_format::x720p6000: return bmdModeHD720p60;\r
- //case video_format::x1080p2397: return bmdModeHD1080p2398;\r
- //case video_format::x1080p2400: return bmdModeHD1080p24;\r
+ case video_format::x720p5994: return bmdModeHD720p5994;\r
+ case video_format::x720p6000: return bmdModeHD720p60;\r
+ case video_format::x1080p2397: return bmdModeHD1080p2398;\r
+ case video_format::x1080p2400: return bmdModeHD1080p24;\r
case video_format::x1080i5000: return bmdModeHD1080i50;\r
- //case video_format::x1080i5994: return bmdModeHD1080i5994;\r
- //case video_format::x1080i6000: return bmdModeHD1080i6000;\r
+ case video_format::x1080i5994: return bmdModeHD1080i5994;\r
+ case video_format::x1080i6000: return bmdModeHD1080i6000;\r
case video_format::x1080p2500: return bmdModeHD1080p25;\r
- //case video_format::x1080p2997: return bmdModeHD1080p2997;\r
- //case video_format::x1080p3000: return bmdModeHD1080p30;\r
+ case video_format::x1080p2997: return bmdModeHD1080p2997;\r
+ case video_format::x1080p3000: return bmdModeHD1080p30;\r
default: return (BMDDisplayMode)ULONG_MAX;\r
}\r
}\r
{\r
input input_; \r
std::unique_ptr<audio_decoder> audio_decoder_;\r
- video_decoder video_decoder_;\r
+ std::unique_ptr<video_decoder> video_decoder_;\r
\r
std::deque<safe_ptr<write_frame>> video_frame_channel_; \r
std::deque<std::vector<short>> audio_chunk_channel_;\r
const std::wstring filename_;\r
\r
safe_ptr<draw_frame> last_frame_;\r
+ std::shared_ptr<frame_factory> frame_factory_;\r
\r
public:\r
explicit ffmpeg_producer(const std::wstring& filename, bool loop) \r
: filename_(filename)\r
, last_frame_(draw_frame(draw_frame::empty()))\r
- , input_(filename, loop)\r
- , video_decoder_(input_.get_video_codec_context().get()) \r
- , audio_decoder_(input_.get_audio_codec_context().get() ? new audio_decoder(input_.get_audio_codec_context().get(), input_.fps()) : nullptr){}\r
+ , input_(filename, loop){}\r
\r
virtual void initialize(const safe_ptr<frame_factory>& frame_factory)\r
{\r
- video_decoder_.initialize(frame_factory);\r
+ frame_factory_ = frame_factory;\r
+ video_decoder_.reset(input_.get_video_codec_context().get() ? new video_decoder(input_.get_video_codec_context().get(), frame_factory) : nullptr);\r
+ audio_decoder_.reset(input_.get_audio_codec_context().get() ? new audio_decoder(input_.get_audio_codec_context().get(), frame_factory->get_video_format_desc().fps) : nullptr);\r
}\r
\r
virtual safe_ptr<draw_frame> receive()\r
while(ouput_channel_.empty() && !input_.is_eof())\r
{ \r
aligned_buffer video_packet;\r
- if(video_frame_channel_.size() < 3) \r
+ if(video_frame_channel_.size() < 3 && video_decoder_) \r
video_packet = input_.get_video_packet(); \r
\r
aligned_buffer audio_packet;\r
- if(audio_chunk_channel_.size() < 3) \r
+ if(audio_chunk_channel_.size() < 3 && audio_decoder_) \r
audio_packet = input_.get_audio_packet(); \r
\r
tbb::parallel_invoke(\r
[&]\r
{ // Video Decoding and Scaling\r
- if(!video_packet.empty())\r
+ if(!video_packet.empty() && video_decoder_)\r
{\r
- auto frame = video_decoder_.execute(video_packet);\r
- video_frame_channel_.push_back(std::move(frame));\r
+ try\r
+ {\r
+ auto frame = video_decoder_->execute(video_packet);\r
+ video_frame_channel_.push_back(std::move(frame));\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ video_decoder_.reset();\r
+ }\r
}\r
}, \r
[&] \r
}\r
});\r
\r
- while(!video_frame_channel_.empty() && (!audio_chunk_channel_.empty() || !audio_decoder_))\r
+ while((!video_frame_channel_.empty() || !video_decoder_) && (!audio_chunk_channel_.empty() || !audio_decoder_))\r
{\r
+ std::shared_ptr<write_frame> frame;\r
+\r
+ if(video_decoder_)\r
+ {\r
+ frame = video_frame_channel_.front();\r
+ video_frame_channel_.pop_front();\r
+ }\r
+\r
if(audio_decoder_) \r
{\r
- video_frame_channel_.front()->audio_data() = std::move(audio_chunk_channel_.front());\r
+ if(!frame)\r
+ {\r
+ frame = frame_factory_->create_frame(1, 1);\r
+ std::fill(frame->image_data().begin(), frame->image_data().end(), 0);\r
+ }\r
+ \r
+ frame->audio_data() = std::move(audio_chunk_channel_.front());\r
audio_chunk_channel_.pop_front();\r
}\r
\r
- ouput_channel_.push(std::move(video_frame_channel_.front()));\r
- video_frame_channel_.pop_front();\r
+ ouput_channel_.push(safe_ptr<write_frame>(frame)); \r
} \r
\r
if(ouput_channel_.empty() && video_packet.empty() && audio_packet.empty()) \r
if(!video_codec_context_ && !audio_codex_context_)\r
BOOST_THROW_EXCEPTION(file_read_error() << msg_info("No video or audio codec context found.")); \r
\r
-\r
executor_.start();\r
executor_.begin_invoke([this]{read_file();});\r
CASPAR_LOG(info) << print() << " started.";\r
const pixel_format_desc desc_;\r
\r
public:\r
- explicit implementation(AVCodecContext* codec_context) \r
- : codec_context_(codec_context)\r
+ explicit implementation(AVCodecContext* codec_context, const safe_ptr<frame_factory>& frame_factory) \r
+ : frame_factory_(frame_factory)\r
+ , codec_context_(codec_context)\r
, width_(codec_context_->width)\r
, height_(codec_context_->height)\r
, pix_fmt_(codec_context_->pix_fmt)\r
, desc_(get_pixel_format_desc(pix_fmt_, width_, height_))\r
{\r
+ double frame_rate = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
+ if(abs(frame_rate - frame_factory->get_video_format_desc().fps) > std::numeric_limits<double>::min())\r
+ BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid video framerate."));\r
+\r
if(desc_.pix_fmt == pixel_format::invalid)\r
{\r
CASPAR_LOG(warning) << "Hardware accelerated color transform not supported.";\r
return write;\r
} \r
}\r
-\r
- void initialize(const safe_ptr<frame_factory>& frame_factory)\r
- {\r
- frame_factory_ = frame_factory; \r
- double frame_rate = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
- if(abs(frame_rate - frame_factory->get_video_format_desc().fps) > std::numeric_limits<double>::min())\r
- BOOST_THROW_EXCEPTION(file_read_error() << msg_info("Invalid video framerate."));\r
- }\r
};\r
\r
-video_decoder::video_decoder(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
+video_decoder::video_decoder(AVCodecContext* codec_context, const safe_ptr<frame_factory>& frame_factory) : impl_(new implementation(codec_context, frame_factory)){}\r
safe_ptr<write_frame> video_decoder::execute(const aligned_buffer& video_packet){return impl_->execute(video_packet);}\r
-void video_decoder::initialize(const safe_ptr<frame_factory>& frame_factory){impl_->initialize(frame_factory); }\r
}}}
\ No newline at end of file
class video_decoder : boost::noncopyable\r
{\r
public:\r
- explicit video_decoder(AVCodecContext* codec_context);\r
+ explicit video_decoder(AVCodecContext* codec_context, const safe_ptr<frame_factory>& frame_factory);\r
safe_ptr<write_frame> execute(const aligned_buffer& video_packet); \r
- void initialize(const safe_ptr<frame_factory>& frame_factory);\r
private:\r
struct implementation;\r
safe_ptr<implementation> impl_;\r
const video_format_desc format_descs[video_format::count] = \r
{ \r
DEFINE_VIDEOFORMATDESC(720, 576, video_mode::upper, 50, TEXT("PAL"), video_format::pal ), \r
- //DEFINE_VIDEOFORMATDESC(720, 486, video_mode::lower, 60/1.001, TEXT("NTSC"), video_format::ntsc ), \r
- //DEFINE_VIDEOFORMATDESC(720, 576, video_mode::progressive, 25, TEXT("576p2500"), video_format::x576p2500 ),\r
+ DEFINE_VIDEOFORMATDESC(720, 486, video_mode::lower, 60/1.001, TEXT("NTSC"), video_format::ntsc ), \r
+ DEFINE_VIDEOFORMATDESC(720, 576, video_mode::progressive, 25, TEXT("576p2500"), video_format::x576p2500 ),\r
DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 25, TEXT("720p2500"), video_format::x720p2500 ), \r
DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 50, TEXT("720p5000"), video_format::x720p5000 ), \r
- //DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60/1.001, TEXT("720p5994"), video_format::x720p5994 ),\r
- //DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60, TEXT("720p6000"), video_format::x720p6000 ),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24/1.001, TEXT("1080p2397"), video_format::x1080p2397),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24, TEXT("1080p2400"), video_format::x1080p2400),\r
+ DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60/1.001, TEXT("720p5994"), video_format::x720p5994 ),\r
+ DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60, TEXT("720p6000"), video_format::x720p6000 ),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24/1.001, TEXT("1080p2397"), video_format::x1080p2397),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24, TEXT("1080p2400"), video_format::x1080p2400),\r
DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 50, TEXT("1080i5000"), video_format::x1080i5000),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60/1.001, TEXT("1080i5994"), video_format::x1080i5994),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60, TEXT("1080i6000"), video_format::x1080i6000),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60/1.001, TEXT("1080i5994"), video_format::x1080i5994),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60, TEXT("1080i6000"), video_format::x1080i6000),\r
DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 25, TEXT("1080p2500"), video_format::x1080p2500),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30/1.001, TEXT("1080p2997"), video_format::x1080p2997),\r
- //DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30, TEXT("1080p3000"), video_format::x1080p3000),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30/1.001, TEXT("1080p2997"), video_format::x1080p2997),\r
+ DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30, TEXT("1080p3000"), video_format::x1080p3000),\r
DEFINE_VIDEOFORMATDESC(0, 0, video_mode::invalid, -1, TEXT("invalid"), video_format::invalid )\r
};\r
\r
enum type\r
{\r
pal = 0,\r
- //ntsc,\r
- //x576p2500,\r
+ ntsc,\r
+ x576p2500,\r
x720p2500,\r
x720p5000,\r
- //x720p5994,\r
- //x720p6000,\r
- //x1080p2397,\r
- //x1080p2400,\r
+ x720p5994,\r
+ x720p6000,\r
+ x1080p2397,\r
+ x1080p2400,\r
x1080i5000,\r
- //x1080i5994,\r
- //x1080i6000,\r
+ x1080i5994,\r
+ x1080i6000,\r
x1080p2500,\r
- //x1080p2997,\r
- //x1080p3000,\r
+ x1080p2997,\r
+ x1080p3000,\r
invalid,\r
count\r
};\r