]> git.sesse.net Git - casparcg/blobdiff - core/consumer/frame_consumer.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / core / consumer / frame_consumer.cpp
index 35f651b8f602e54aaf9902af6fff3bc401dfae4d..49309380f1df92baa6e0bca9437461b0d281ade5 100644 (file)
@@ -1,22 +1,24 @@
 /*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
 *\r
-*  This file is part of CasparCG.\r
+* This file is part of CasparCG (www.casparcg.com).\r
 *\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
+* CasparCG is free software: you can redistribute it and/or modify\r
+* it under the terms of the GNU General Public License as published by\r
+* the Free Software Foundation, either version 3 of the License, or\r
+* (at your option) any later version.\r
 *\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+* CasparCG is distributed in the hope that it will be useful,\r
+* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+* GNU General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU General Public License\r
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
 *\r
+* Author: Robert Nagy, ronag89@gmail.com\r
 */\r
+\r
 #include "../StdAfx.h"\r
 \r
 #include "frame_consumer.h"\r
@@ -25,7 +27,7 @@
 #include <common/memory/safe_ptr.h>\r
 #include <common/exception/exceptions.h>\r
 #include <core/video_format.h>\r
-#include <core/mixer/read_frame.h>\r
+#include <core/frame.h>\r
 \r
 #include <boost/circular_buffer.hpp>\r
 \r
@@ -67,42 +69,40 @@ safe_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>&
 class cadence_guard : public frame_consumer\r
 {\r
        safe_ptr<frame_consumer>                consumer_;\r
-       std::vector<size_t>                             audio_cadence_;\r
-       boost::circular_buffer<size_t>  sync_buffer_;\r
-       bool                                                    synced_;\r
+       std::vector<int>                                audio_cadence_;\r
+       boost::circular_buffer<int>     sync_buffer_;\r
 public:\r
-       cadence_guard(safe_ptr<frame_consumer>&& consumer)\r
-               : consumer_(std::move(consumer))\r
+       cadence_guard(const safe_ptr<frame_consumer>& consumer)\r
+               : consumer_(consumer)\r
        {\r
        }\r
        \r
-       virtual void initialize(const video_format_desc& format_desc, int channel_index, int sub_index) override\r
+       virtual void initialize(const video_format_desc& format_desc, int channel_index) override\r
        {\r
                audio_cadence_  = format_desc.audio_cadence;\r
-               sync_buffer_    = boost::circular_buffer<size_t>(format_desc.audio_cadence.size());\r
-               consumer_->initialize(format_desc, channel_index, sub_index);\r
+               sync_buffer_    = boost::circular_buffer<int>(format_desc.audio_cadence.size());\r
+               consumer_->initialize(format_desc, channel_index);\r
        }\r
 \r
-       virtual bool send(const safe_ptr<read_frame>& frame) override\r
+       virtual bool send(const safe_ptr<const frame>& frame) override\r
        {               \r
-               sync_buffer_.push_back(static_cast<size_t>(frame->audio_data().size()));\r
+               if(audio_cadence_.size() == 1)\r
+                       return consumer_->send(frame);\r
+\r
+               bool result = true;\r
                \r
-               if(!boost::range::equal(sync_buffer_, audio_cadence_))\r
-               {\r
-                       synced_ = false;\r
-                       CASPAR_LOG(trace) << L"[cadence_guard] Audio cadence unsynced. Skipping frame.";\r
-                       return true;\r
-               }\r
-               else if(!synced_)\r
-               {\r
-                       synced_ = true;\r
+               if(boost::range::equal(sync_buffer_, audio_cadence_) && audio_cadence_.front() == static_cast<int>(frame->audio_data().size())) \r
+               {       \r
+                       // Audio sent so far is in sync, now we can send the next chunk.\r
+                       result = consumer_->send(frame);\r
                        boost::range::rotate(audio_cadence_, std::begin(audio_cadence_)+1);\r
-                       return true;\r
                }\r
+               else\r
+                       CASPAR_LOG(trace) << print() << L" Syncing audio.";\r
 \r
-               boost::range::rotate(audio_cadence_, std::begin(audio_cadence_)+1);\r
-\r
-               return consumer_->send(frame);\r
+               sync_buffer_.push_back(static_cast<int>(frame->audio_data().size()));\r
+               \r
+               return result;\r
        }\r
 \r
        virtual std::wstring print() const override\r
@@ -110,20 +110,51 @@ public:
                return consumer_->print();\r
        }\r
 \r
+       virtual boost::property_tree::wptree info() const override\r
+       {\r
+               return consumer_->info();\r
+       }\r
+\r
        virtual bool has_synchronization_clock() const override\r
        {\r
                return consumer_->has_synchronization_clock();\r
        }\r
 \r
-       virtual size_t buffer_depth() const override\r
+       virtual int buffer_depth() const override\r
        {\r
                return consumer_->buffer_depth();\r
        }\r
+\r
+       virtual int index() const override\r
+       {\r
+               return consumer_->index();\r
+       }\r
 };\r
 \r
-safe_ptr<frame_consumer> create_consumer_cadence_guard(safe_ptr<frame_consumer>&& consumer)\r
+safe_ptr<frame_consumer> create_consumer_cadence_guard(const safe_ptr<frame_consumer>& consumer)\r
 {\r
        return make_safe<cadence_guard>(std::move(consumer));\r
 }\r
 \r
+const safe_ptr<frame_consumer>& frame_consumer::empty()\r
+{\r
+       struct empty_frame_consumer : public frame_consumer\r
+       {\r
+               virtual bool send(const safe_ptr<const frame>&) override {return false;}\r
+               virtual void initialize(const video_format_desc&, int) override{}\r
+               virtual std::wstring print() const override {return L"empty";}\r
+               virtual bool has_synchronization_clock() const override {return false;}\r
+               virtual int buffer_depth() const override {return 0;};\r
+               virtual int index() const{return -1;}\r
+               virtual boost::property_tree::wptree info() const override\r
+               {\r
+                       boost::property_tree::wptree info;\r
+                       info.add(L"type", L"empty-consumer");\r
+                       return info;\r
+               }\r
+       };\r
+       static safe_ptr<frame_consumer> consumer = make_safe<empty_frame_consumer>();\r
+       return consumer;\r
+}\r
+\r
 }}
\ No newline at end of file