]> git.sesse.net Git - casparcg/commitdiff
2.0. ffmpeg_producer: Removed filter capabilities for now. Will add a more generic...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 19 Jun 2011 10:11:05 +0000 (10:11 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 19 Jun 2011 10:11:05 +0000 (10:11 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@913 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/video/video_decoder.cpp
modules/ffmpeg/producer/video/video_decoder.h

index 46a001cacf51236b264480df92df45e21dd8aa16..a30aed1c3d350f550d7b1a96b041181c14035e8b 100644 (file)
@@ -62,7 +62,7 @@ struct ffmpeg_producer : public core::frame_producer
        std::deque<std::pair<int, std::vector<short>>> audio_chunks_;\r
        std::deque<std::pair<int, safe_ptr<core::write_frame>>> video_frames_;\r
 public:\r
-       explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::string& filter, bool loop, int start, int length) \r
+       explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, bool loop, int start, int length) \r
                : filename_(filename)\r
                , graph_(diagnostics::create_graph(narrow(print())))\r
                , frame_factory_(frame_factory)         \r
@@ -78,7 +78,7 @@ public:
                        CASPAR_LOG(warning) << print() << L" Invalid framerate detected. This may cause distorted audio during playback. frame-time: " << frame_time;\r
                \r
                video_decoder_.reset(input_.get_video_codec_context() ? \r
-                       new video_decoder(input_, frame_factory, filter) : nullptr);\r
+                       new video_decoder(input_, frame_factory) : nullptr);\r
                        \r
                audio_decoder_.reset(input_.get_audio_codec_context() ? \r
                        new audio_decoder(input_, frame_factory->get_video_format_desc()) : nullptr);           \r
@@ -110,12 +110,12 @@ public:
                (\r
                        [&]\r
                        {\r
-                               if(video_decoder_ && video_frames_.size() < 3)\r
+                               if(video_decoder_ && video_frames_.size() < 2)\r
                                        boost::range::push_back(video_frames_, video_decoder_->receive());              \r
                        }, \r
                        [&]\r
                        {\r
-                               if(audio_decoder_ && audio_chunks_.size() < 3)\r
+                               if(audio_decoder_ && audio_chunks_.size() < 2)\r
                                        boost::range::push_back(audio_chunks_, audio_decoder_->receive());                              \r
                        }\r
                );\r
@@ -131,52 +131,27 @@ public:
                CASPAR_ASSERT(!(video_decoder_ && audio_decoder_ && !video_frames_.empty() && !audio_chunks_.empty()) ||\r
                                      video_frames_.front().first == audio_chunks_.front().first);\r
        }\r
-       \r
+\r
        safe_ptr<core::basic_frame> decode_frame()\r
        {\r
                decode_packets();\r
 \r
                if(video_decoder_ && audio_decoder_ && !video_frames_.empty() && !audio_chunks_.empty())\r
                {\r
-                       auto frame                = std::move(video_frames_.front().second);            \r
-                       auto frame_number = video_frames_.front().first;\r
+                       auto frame = std::move(video_frames_.front().second);                           \r
                        video_frames_.pop_front();\r
                                \r
                        frame->audio_data() = std::move(audio_chunks_.front().second);\r
                        audio_chunks_.pop_front();\r
                        \r
-                       if(!video_frames_.empty())\r
-                       {\r
-                               if(video_frames_.front().first == frame_number)\r
-                               {\r
-                                       auto frame2 = video_frames_.front().second;\r
-                                       video_frames_.pop_front();\r
-\r
-                                       return core::basic_frame::interlace(frame, frame2, frame_factory_->get_video_format_desc().mode);\r
-                               }\r
-                       }\r
-\r
                        return frame;\r
                }\r
                else if(video_decoder_ && !audio_decoder_ && !video_frames_.empty())\r
                {\r
-                       auto frame                = std::move(video_frames_.front().second);            \r
-                       auto frame_number = video_frames_.front().first;\r
+                       auto frame = std::move(video_frames_.front().second);                           \r
                        video_frames_.pop_front();\r
-\r
                        frame->get_audio_transform().set_has_audio(false);      \r
                        \r
-                       if(!video_frames_.empty())\r
-                       {\r
-                               if(video_frames_.front().first == frame_number)\r
-                               {\r
-                                       auto frame2 = video_frames_.front().second;\r
-                                       video_frames_.pop_front();\r
-\r
-                                       return core::basic_frame::interlace(frame, frame2, frame_factory_->get_video_format_desc().mode);\r
-                               }\r
-                       }\r
-\r
                        return frame;\r
                }\r
                else if(audio_decoder_ && !video_decoder_ && !audio_chunks_.empty())\r
@@ -228,17 +203,7 @@ safe_ptr<core::frame_producer> create_ffmpeg_producer(const safe_ptr<core::frame
                        start = boost::lexical_cast<int>(*seek_it);\r
        }\r
        \r
-       std::string filter;\r
-\r
-       auto filter_it = std::find(params.begin(), params.end(), L"FILTER");\r
-       if(filter_it != params.end())\r
-       {\r
-               if(++filter_it != params.end())\r
-                       filter = narrow(*filter_it);\r
-               std::transform(filter.begin(), filter.end(), filter.begin(), ::tolower);\r
-       }\r
-\r
-       return make_safe<ffmpeg_producer>(frame_factory, path, filter, loop, start, length);\r
+       return make_safe<ffmpeg_producer>(frame_factory, path, loop, start, length);\r
 }\r
 \r
 }
\ No newline at end of file
index ec7c15928d743fe3851d4a0e070e32a785c3ccaa..967dad5495937b432238ab74a0e84f3ce79d17cf 100644 (file)
@@ -21,8 +21,6 @@
 \r
 #include "video_decoder.h"\r
 #include "../../ffmpeg_error.h"\r
-#include "../../util/util.h"\r
-#include "../../util/filter.h"\r
 \r
 #include <common/memory/memcpy.h>\r
 \r
@@ -55,21 +53,84 @@ extern "C"
 \r
 namespace caspar {\r
        \r
+core::pixel_format::type get_pixel_format(PixelFormat pix_fmt)\r
+{\r
+       switch(pix_fmt)\r
+       {\r
+       case PIX_FMT_GRAY8:             return core::pixel_format::gray;\r
+       case PIX_FMT_BGRA:              return core::pixel_format::bgra;\r
+       case PIX_FMT_ARGB:              return core::pixel_format::argb;\r
+       case PIX_FMT_RGBA:              return core::pixel_format::rgba;\r
+       case PIX_FMT_ABGR:              return core::pixel_format::abgr;\r
+       case PIX_FMT_YUV444P:   return core::pixel_format::ycbcr;\r
+       case PIX_FMT_YUV422P:   return core::pixel_format::ycbcr;\r
+       case PIX_FMT_YUV420P:   return core::pixel_format::ycbcr;\r
+       case PIX_FMT_YUV411P:   return core::pixel_format::ycbcr;\r
+       case PIX_FMT_YUV410P:   return core::pixel_format::ycbcr;\r
+       case PIX_FMT_YUVA420P:  return core::pixel_format::ycbcra;\r
+       default:                                return core::pixel_format::invalid;\r
+       }\r
+}\r
+\r
+core::pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, size_t width, size_t height)\r
+{\r
+       // Get linesizes\r
+       AVPicture dummy_pict;   \r
+       avpicture_fill(&dummy_pict, nullptr, pix_fmt, width, height);\r
+\r
+       core::pixel_format_desc desc;\r
+       desc.pix_fmt = get_pixel_format(pix_fmt);\r
+               \r
+       switch(desc.pix_fmt)\r
+       {\r
+       case core::pixel_format::gray:\r
+               {\r
+                       desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[0]/4, height, 1));                                             \r
+                       return desc;\r
+               }\r
+       case core::pixel_format::bgra:\r
+       case core::pixel_format::argb:\r
+       case core::pixel_format::rgba:\r
+       case core::pixel_format::abgr:\r
+               {\r
+                       desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[0]/4, height, 4));                                             \r
+                       return desc;\r
+               }\r
+       case core::pixel_format::ycbcr:\r
+       case core::pixel_format::ycbcra:\r
+               {               \r
+                       // Find chroma height\r
+                       size_t size2 = dummy_pict.data[2] - dummy_pict.data[1];\r
+                       size_t h2 = size2/dummy_pict.linesize[1];                       \r
+\r
+                       desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[0], height, 1));\r
+                       desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[1], h2, 1));\r
+                       desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[2], h2, 1));\r
+\r
+                       if(desc.pix_fmt == core::pixel_format::ycbcra)                                          \r
+                               desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[3], height, 1));       \r
+                       return desc;\r
+               }               \r
+       default:                \r
+               desc.pix_fmt = core::pixel_format::invalid;\r
+               return desc;\r
+       }\r
+}\r
+\r
 struct video_decoder::implementation : boost::noncopyable\r
 {\r
        input& input_;\r
        std::shared_ptr<SwsContext>                                     sws_context_;\r
-       const safe_ptr<core::frame_factory>                     frame_factory_;\r
+       const std::shared_ptr<core::frame_factory>      frame_factory_;\r
        AVCodecContext&                                                         codec_context_;\r
        const int                                                                       width_;\r
        const int                                                                       height_;\r
        const PixelFormat                                                       pix_fmt_;\r
        core::pixel_format_desc                                         desc_;\r
        size_t                                                                          frame_number_;\r
-       std::shared_ptr<filter>                                         filter_;\r
 \r
 public:\r
-       explicit implementation(input& input, const safe_ptr<core::frame_factory>& frame_factory, const std::string& filter_str\r
+       explicit implementation(input& input, const safe_ptr<core::frame_factory>& frame_factory) \r
                : input_(input)\r
                , frame_factory_(frame_factory)\r
                , codec_context_(*input_.get_video_codec_context())\r
@@ -91,9 +152,6 @@ public:
                                                                          msg_info("Could not create software scaling context.") << \r
                                                                          boost::errinfo_api_function("sws_getContext"));\r
                }\r
-\r
-               if(!filter_str.empty())\r
-                       filter_.reset(new filter(filter_str));\r
        }\r
 \r
        std::deque<std::pair<int, safe_ptr<core::write_frame>>> receive()\r
@@ -133,25 +191,7 @@ public:
                }\r
                \r
                if(frame_finished != 0)         \r
-               {\r
-                       if(filter_)\r
-                       {\r
-                               filter_->push(decoded_frame);\r
-\r
-                               std::shared_ptr<AVFrame> frame;\r
-                               while(filter_->try_pop(frame))\r
-                                       result.push_back(std::make_pair(frame_number_, make_write_frame(make_safe(frame))));\r
-                       }\r
-                       else\r
-                               result.push_back(std::make_pair(frame_number_, make_write_frame(decoded_frame)));\r
-                       \r
-                       if(!result.empty())\r
-                               ++frame_number_;\r
-                       else\r
-                               CASPAR_LOG(trace) << " Filter delay.";\r
-               }\r
-               else\r
-                       CASPAR_LOG(trace) << " Decoder delay.";\r
+                       result.push_back(std::make_pair(frame_number_++, make_write_frame(decoded_frame)));\r
 \r
                return result;\r
        }\r
@@ -200,7 +240,7 @@ public:
        }\r
 };\r
 \r
-video_decoder::video_decoder(input& input, const safe_ptr<core::frame_factory>& frame_factory, const std::string& filter) : impl_(new implementation(input, frame_factory, filter)){}\r
+video_decoder::video_decoder(input& input, const safe_ptr<core::frame_factory>& frame_factory) : impl_(new implementation(input, frame_factory)){}\r
 std::deque<std::pair<int, safe_ptr<core::write_frame>>> video_decoder::receive(){return impl_->receive();}\r
 \r
 }
\ No newline at end of file
index 12b84251ea826039a4abf49e4432934e8dd66c23..e3bdf0d1815065c75d3d998a26b7fd61d89ac5da 100644 (file)
@@ -32,7 +32,7 @@ namespace core {
 class video_decoder : boost::noncopyable\r
 {\r
 public:\r
-       explicit video_decoder(input& input, const safe_ptr<core::frame_factory>& frame_factory, const std::string& filter);\r
+       explicit video_decoder(input& input, const safe_ptr<core::frame_factory>& frame_factory);\r
        std::deque<std::pair<int, safe_ptr<core::write_frame>>> receive();      \r
 \r
 private:\r