]> git.sesse.net Git - casparcg/commitdiff
2.0. Refactoring
authorRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 6 Aug 2011 15:16:44 +0000 (15:16 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 6 Aug 2011 15:16:44 +0000 (15:16 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1068 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/producer/audio/audio_decoder.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/filter/filter.h
modules/ffmpeg/producer/frame_muxer.cpp
modules/ffmpeg/producer/frame_muxer.h
modules/ffmpeg/producer/input.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index 0f555db2d7d71233f677c00b66b6aba45c5e39a5..55e550647f9ad22db5605f4a62fde3ea8ae6728a 100644 (file)
@@ -103,7 +103,7 @@ public:
                , device_index_(device_index)\r
                , frame_factory_(frame_factory)\r
                , filter_(filter)\r
-               , muxer_(double_rate(filter) ? format_desc.fps * 2.0 : format_desc.fps, frame_factory->get_video_format_desc(), frame_factory)\r
+               , muxer_(double_rate(filter) ? format_desc.fps * 2.0 : format_desc.fps, frame_factory)\r
        {\r
                frame_buffer_.set_capacity(2);\r
                \r
index 4e3bf0d0dacd123b0526ca02a10ca56e4c07053e..519f1a5a666c8f5533c5a0d67fa5ee0d8d26029b 100644 (file)
@@ -21,6 +21,8 @@
 \r
 #include "audio_decoder.h"\r
 \r
+#include "../../ffmpeg_error.h"\r
+\r
 #include <tbb/task_group.h>\r
 \r
 #if defined(_MSC_VER)\r
@@ -57,17 +59,38 @@ public:
        explicit implementation(const std::shared_ptr<AVFormatContext>& context, const core::video_format_desc& format_desc) \r
                : format_desc_(format_desc)     \r
                , nb_frames_(0)\r
-       {                          \r
-               AVCodec* dec;\r
-               index_ = av_find_best_stream(context.get(), AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);\r
+       {                                       \r
+               try\r
+               {\r
+                       AVCodec* dec;\r
+                       index_ = av_find_best_stream(context.get(), AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);\r
 \r
-               if(index_ < 0)\r
-                       return;\r
+                       if(index_ < 0)\r
+                       {\r
+                               BOOST_THROW_EXCEPTION(\r
+                                       file_read_error() <<\r
+                                       msg_info(av_error_str(index_)) <<\r
+                                       boost::errinfo_api_function("av_find_best_stream") <<\r
+                                       boost::errinfo_errno(AVUNERROR(index_)));\r
+                       }\r
 \r
-               int errn = avcodec_open(context->streams[index_]->codec, dec);\r
-               if(errn < 0)\r
+                       const int ret = avcodec_open(context->streams[index_]->codec, dec);\r
+                       if(ret < 0)\r
+                       {                               \r
+                               BOOST_THROW_EXCEPTION(\r
+                                       file_read_error() <<\r
+                                       msg_info(av_error_str(ret)) <<\r
+                                       boost::errinfo_api_function("avcodec_open") <<\r
+                                       boost::errinfo_errno(AVUNERROR(ret)));\r
+                       }\r
+               }\r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(warning) << "[audio_decoder] Failed to open audio. Running without audio.";\r
                        return;\r
-                               \r
+               }\r
+\r
                codec_context_.reset(context->streams[index_]->codec, avcodec_close);\r
 \r
                //nb_frames_ = context->streams[index_]->nb_frames;\r
@@ -141,6 +164,7 @@ public:
                {       \r
                        BOOST_THROW_EXCEPTION(\r
                                invalid_operation() <<\r
+                               msg_info(av_error_str(ret)) <<\r
                                boost::errinfo_api_function("avcodec_decode_audio2") <<\r
                                boost::errinfo_errno(AVUNERROR(ret)));\r
                }\r
index 5105081a84d608f1ec724f9b26afef78d1ad5438..26dd41f70f635e282a0e7a789ce733111804a2e7 100644 (file)
@@ -82,7 +82,7 @@ public:
                , input_(graph_, filename_, loop, start, length)\r
                , video_decoder_(input_.context(), frame_factory, filter)\r
                , audio_decoder_(input_.context(), frame_factory->get_video_format_desc())\r
-               , muxer_(video_decoder_.fps(), format_desc_, frame_factory)\r
+               , muxer_(video_decoder_.fps(), frame_factory)\r
                , start_(start)\r
                , nb_frames_(video_decoder_.nb_frames() - start)\r
                , loop_(loop)\r
index ef6aed320e5a30c5d93666692d88a2f7be35d81d..5e2f94277545b184e1179fbf3b79c6eb4540ccf9 100644 (file)
@@ -23,7 +23,7 @@ static bool double_rate(const std::wstring& filters)
 class filter\r
 {\r
 public:\r
-       filter(const std::wstring& filters);\r
+       filter(const std::wstring& filters = L"");\r
 \r
        std::vector<safe_ptr<AVFrame>> execute(const std::shared_ptr<AVFrame>& frame);\r
 \r
index b9fc4f597e28775c640dfe4a7d73cf4f56d438d0..f3c273e4797724906380c40f273c6771a50c2e00 100644 (file)
@@ -113,19 +113,19 @@ struct frame_muxer::implementation : boost::noncopyable
        size_t                                                                                  processed_audio_sample_count_;\r
        size_t                                                                                  processed_video_frame_count_;\r
 \r
-       std::unique_ptr<filter>                                                 filter_;\r
+       filter                                                                                  filter_;\r
        safe_ptr<core::frame_factory>                                   frame_factory_;\r
                \r
-       implementation(double in_fps, const video_format_desc& format_desc, const safe_ptr<core::frame_factory>& frame_factory)\r
-               : display_mode_(display_mode::invalid)\r
+       implementation(double in_fps, const safe_ptr<core::frame_factory>& frame_factory)\r
+               : video_streams_(1)\r
+               , audio_streams_(1)\r
+               , display_mode_(display_mode::invalid)\r
                , in_fps_(in_fps)\r
-               , format_desc_(format_desc)\r
+               , format_desc_(frame_factory->get_video_format_desc())\r
                , auto_mode_(env::properties().get("configuration.auto-mode", false))\r
                , audio_sample_count_(0)\r
                , video_frame_count_(0)\r
                , frame_factory_(frame_factory)\r
-               , video_streams_(1)\r
-               , audio_streams_(1)\r
        {\r
        }\r
 \r
@@ -143,43 +143,35 @@ struct frame_muxer::implementation : boost::noncopyable
                {\r
                        video_streams_.back().push(make_safe<core::write_frame>(this));\r
                        ++video_frame_count_;\r
-                       process(frame_buffer_);\r
+                       put_frames(frame_buffer_);\r
                        return;\r
                }\r
                \r
                if(display_mode_ == display_mode::invalid)\r
                {\r
-                       auto in_mode = get_mode(*video_frame);\r
-                       display_mode_ = auto_mode_ ? get_display_mode(in_mode, in_fps_, format_desc_.mode, format_desc_.fps) : display_mode::simple;\r
+                       if(auto_mode_)\r
+                       {\r
+                               auto in_mode = get_mode(*video_frame);\r
+                               display_mode_ = get_display_mode(in_mode, in_fps_, format_desc_.mode, format_desc_.fps);\r
                        \r
-                       if(display_mode_ == display_mode::simple && in_mode != core::video_mode::progressive && format_desc_.mode != core::video_mode::progressive && video_frame->height != static_cast<int>(format_desc_.height))\r
-                               display_mode_ = display_mode::deinterlace_bob_reinterlace; // The frame will most likely be scaled, we need to deinterlace->reinterlace         \r
-               }\r
-               \r
-               std::vector<safe_ptr<core::write_frame>> frames;\r
-\r
-               if(display_mode_ == display_mode::deinterlace)\r
-               {\r
-                       if(!filter_)\r
-                               filter_.reset(new filter(L"YADIF=0:-1"));\r
-\r
-                       BOOST_FOREACH(auto& frame, filter_->execute(video_frame))\r
-                               frames.push_back(make_write_frame(this, frame, frame_factory_));\r
-\r
+                               if(display_mode_ == display_mode::simple && in_mode != core::video_mode::progressive && format_desc_.mode != core::video_mode::progressive && video_frame->height != static_cast<int>(format_desc_.height))\r
+                                       display_mode_ = display_mode::deinterlace_bob_reinterlace; // The frame will most likely be scaled, we need to deinterlace->reinterlace \r
+                               \r
+                               if(display_mode_ == display_mode::deinterlace)\r
+                                       filter_ = filter(L"YADIF=0:-1");\r
+                               else if(display_mode_ == display_mode::deinterlace_bob || display_mode_ == display_mode::deinterlace_bob_reinterlace)\r
+                                       filter_ = filter(L"YADIF=1:-1");\r
+                       }\r
+                       else\r
+                               display_mode_ = display_mode::simple;\r
+\r
+                       CASPAR_LOG(info) << "frame_muxer: " << display_mode::print(display_mode_);\r
                }\r
-               else if(display_mode_ == display_mode::deinterlace_bob || display_mode_ == display_mode::deinterlace_bob_reinterlace)\r
+                                               \r
+               BOOST_FOREACH(auto& av_frame, filter_.execute(video_frame))\r
                {\r
-                       if(!filter_)\r
-                               filter_.reset(new filter(L"YADIF=1:-1"));\r
+                       auto frame = make_write_frame(this, av_frame, frame_factory_);\r
 \r
-                       BOOST_FOREACH(auto& frame, filter_->execute(video_frame))\r
-                               frames.push_back(make_write_frame(this, frame, frame_factory_));\r
-               }\r
-               else\r
-                       frames.push_back(make_write_frame(this, make_safe(video_frame), frame_factory_));\r
-\r
-               BOOST_FOREACH(auto& frame, frames)\r
-               {\r
                        // Fix field-order if needed\r
                        if(frame->get_type() == core::video_mode::lower && format_desc_.mode == core::video_mode::upper)\r
                                frame->get_image_transform().set_fill_translation(0.0f, 0.5/static_cast<double>(frame->get_pixel_format_desc().planes[0].height));\r
@@ -189,7 +181,7 @@ struct frame_muxer::implementation : boost::noncopyable
                        video_streams_.back().push(frame);\r
                        ++video_frame_count_;\r
 \r
-                       process(frame_buffer_);\r
+                       put_frames(frame_buffer_);\r
                }\r
        }\r
 \r
@@ -206,7 +198,7 @@ struct frame_muxer::implementation : boost::noncopyable
                audio_sample_count_ += audio_samples->size();\r
 \r
                boost::range::push_back(audio_streams_.back(), *audio_samples);\r
-               process(frame_buffer_);\r
+               put_frames(frame_buffer_);\r
        }\r
 \r
        safe_ptr<basic_frame> pop()\r
@@ -262,7 +254,7 @@ struct frame_muxer::implementation : boost::noncopyable
                return audio_streams_.back().size() / format_desc_.audio_samples_per_frame;\r
        }\r
        \r
-       void process(std::deque<safe_ptr<basic_frame>>& dest)\r
+       void put_frames(std::deque<safe_ptr<basic_frame>>& dest)\r
        {\r
                if(video_streams_.size() > 1 && audio_streams_.size() > 1 &&\r
                        (video_streams_.front().empty() || audio_streams_.front().empty()))\r
@@ -345,8 +337,8 @@ struct frame_muxer::implementation : boost::noncopyable
        }\r
 };\r
 \r
-frame_muxer::frame_muxer(double in_fps, const video_format_desc& format_desc, const safe_ptr<core::frame_factory>& frame_factory)\r
-       : impl_(new implementation(in_fps, format_desc, frame_factory)){}\r
+frame_muxer::frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory)\r
+       : impl_(new implementation(in_fps, frame_factory)){}\r
 void frame_muxer::push(const std::shared_ptr<AVFrame>& video_frame){impl_->push(video_frame);}\r
 void frame_muxer::push(const std::shared_ptr<std::vector<int16_t>>& audio_samples){return impl_->push(audio_samples);}\r
 safe_ptr<basic_frame> frame_muxer::pop(){return impl_->pop();}\r
index 5eb65085020ec965d67f05db3fc85cd3b6f46b5b..065ef8695e74cb744194660f39fd5355d222ebb5 100644 (file)
@@ -21,7 +21,7 @@ struct frame_factory;
 class frame_muxer : boost::noncopyable\r
 {\r
 public:\r
-       frame_muxer(double in_fps, const core::video_format_desc& format_desc, const safe_ptr<core::frame_factory>& frame_factory);\r
+       frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory);\r
        \r
        void push(const std::shared_ptr<AVFrame>& video_frame);\r
        void push(const std::shared_ptr<std::vector<int16_t>>& audio_samples);\r
index 153de3799a17e3c987bd187d2d6a79584fd27365..56f340fb71a54610380b918853e19c7c6aec1ce1 100644 (file)
@@ -181,7 +181,7 @@ private:
                av_init_packet(read_packet.get());\r
 \r
                const int ret = av_read_frame(format_context_.get(), read_packet.get()); // read_packet is only valid until next call of av_read_frame.\r
-               if(is_eof(ret))                                                                                                           // Use av_dup_packet to extend its life.\r
+               if(is_eof(ret))                                                                                                              // Use av_dup_packet to extend its life.\r
                {\r
                        if(loop_)\r
                        {\r
@@ -206,13 +206,22 @@ private:
                }\r
                else\r
                {               \r
-                       av_dup_packet(read_packet.get());\r
+                       const int ret = av_dup_packet(read_packet.get());\r
+                       if(ret < 0)\r
+                       {\r
+                               BOOST_THROW_EXCEPTION(\r
+                                       invalid_operation() <<\r
+                                       msg_info(av_error_str(ret)) <<\r
+                                       source_info(narrow(print())) << \r
+                                       boost::errinfo_api_function("av_dup_packet") <<\r
+                                       boost::errinfo_errno(AVUNERROR(ret)));\r
+                       }\r
                                \r
                        // Make sure that the packet is correctly deallocated even if size and data is modified during decoding.\r
                        auto size = read_packet->size;\r
                        auto data = read_packet->data;\r
 \r
-                       read_packet = std::shared_ptr<AVPacket>(read_packet.get(), [=](AVPacket* pkt)\r
+                       read_packet = std::shared_ptr<AVPacket>(read_packet.get(), [=](AVPacket*)\r
                        {\r
                                read_packet->size = size;\r
                                read_packet->data = data;\r
index 6251fc3f2aa274df021de961403ea20dd0c7baba..1408c6e0a3fb6b35182fb9f8cd7bfffa2f39d05e 100644 (file)
@@ -75,16 +75,37 @@ public:
                , fps_(frame_factory_->get_video_format_desc().fps)\r
                , nb_frames_(0)\r
        {\r
-               AVCodec* dec;\r
-               index_ = av_find_best_stream(context.get(), AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);\r
+               try\r
+               {\r
+                       AVCodec* dec;\r
+                       index_ = av_find_best_stream(context.get(), AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);\r
 \r
-               if(index_ < 0)\r
-                       return;\r
-                       \r
-               int errn = tbb_avcodec_open(context->streams[index_]->codec, dec);\r
-               if(errn < 0)\r
+                       if(index_ < 0)\r
+                       {\r
+                               BOOST_THROW_EXCEPTION(\r
+                                       file_read_error() <<\r
+                                       msg_info(av_error_str(index_)) <<\r
+                                       boost::errinfo_api_function("av_find_best_stream") <<\r
+                                       boost::errinfo_errno(AVUNERROR(index_)));\r
+                       }\r
+\r
+                       const int ret = tbb_avcodec_open(context->streams[index_]->codec, dec);\r
+                       if(ret < 0)\r
+                       {                               \r
+                               BOOST_THROW_EXCEPTION(\r
+                                       file_read_error() <<\r
+                                       msg_info(av_error_str(ret)) <<\r
+                                       boost::errinfo_api_function("tbb_avcodec_open") <<\r
+                                       boost::errinfo_errno(AVUNERROR(ret)));\r
+                       }\r
+               }\r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(warning) << "[video_decoder] Failed to open video. Running without audio.";\r
                        return;\r
-                               \r
+               }\r
+                                                               \r
                codec_context_.reset(context->streams[index_]->codec, tbb_avcodec_close);\r
                \r
                // Some files give an invalid time_base numerator, try to fix it.\r