]> git.sesse.net Git - casparcg/blobdiff - core/producer/cg_proxy.cpp
[ffmpeg_producer] Recognize .mkv and .mxf files as playable without probing
[casparcg] / core / producer / cg_proxy.cpp
index 8faa0a3b6d5732d5ce01164895bfe0ef40354be8..74a1318e83112232f24990856b8773a04755e3cd 100644 (file)
@@ -38,7 +38,7 @@
 #include <boost/optional.hpp>
 
 #include <future>
-#include <vector>
+#include <map>
 
 namespace caspar { namespace core {
 
@@ -69,18 +69,14 @@ private:
        struct record
        {
                std::wstring                    name;
-               std::set<std::wstring>  file_extensions;
                meta_info_extractor             info_extractor;
                cg_proxy_factory                proxy_factory;
                cg_producer_factory             producer_factory;
                bool                                    reusable_producer_instance;
        };
 
-       struct name {};
-       struct extension {};
-
-       mutable boost::mutex    mutex_;
-       std::vector<record>             records_;
+       mutable boost::mutex                    mutex_;
+       std::map<std::wstring, record>  records_by_extension_;
 public:
        void register_cg_producer(
                        std::wstring cg_producer_name,
@@ -92,19 +88,23 @@ public:
        {
                boost::lock_guard<boost::mutex> lock(mutex_);
 
-               records_.push_back(
+               record rec
                {
                        std::move(cg_producer_name),
-                       std::move(file_extensions),
                        std::move(info_extractor),
                        std::move(proxy_factory),
                        std::move(producer_factory),
                        reusable_producer_instance
-               });
+               };
+
+               for (auto& extension : file_extensions)
+               {
+                       records_by_extension_.insert(std::make_pair(extension, rec));
+               }
        }
 
        spl::shared_ptr<frame_producer> create_producer(
-                       const spl::shared_ptr<video_channel>& video_channel,
+                       const frame_producer_dependencies& dependencies,
                        const std::wstring& filename) const
        {
                auto found = find_record(filename);
@@ -112,10 +112,7 @@ public:
                if (!found)
                        return frame_producer::empty();
 
-               return found->producer_factory(
-                               video_channel->frame_factory(),
-                               video_channel->video_format_desc(),
-                               filename);
+               return found->producer_factory(dependencies, filename);
        }
 
        spl::shared_ptr<cg_proxy> get_proxy(const spl::shared_ptr<frame_producer>& producer) const
@@ -124,17 +121,17 @@ public:
 
                boost::lock_guard<boost::mutex> lock(mutex_);
 
-               for (auto& elem : records_)
+               for (auto& elem : records_by_extension_)
                {
-                       if (elem.name == producer_name)
-                               return elem.proxy_factory(producer);
+                       if (elem.second.name == producer_name)
+                               return elem.second.proxy_factory(producer);
                }
 
                return cg_proxy::empty();
        }
 
        spl::shared_ptr<cg_proxy> get_proxy(
-                       const spl::shared_ptr<class video_channel>& video_channel,
+                       const spl::shared_ptr<video_channel>& video_channel,
                        int render_layer) const
        {
                auto producer = spl::make_shared_ptr(video_channel->stage().foreground(render_layer).get());
@@ -143,7 +140,8 @@ public:
        }
 
        spl::shared_ptr<cg_proxy> get_or_create_proxy(
-                       const spl::shared_ptr<class video_channel>& video_channel,
+                       const spl::shared_ptr<video_channel>& video_channel,
+                       const frame_producer_dependencies& dependencies,
                        int render_layer,
                        const std::wstring& filename) const
        {
@@ -164,10 +162,7 @@ public:
                        diagnostics::call_context::for_thread().video_channel = video_channel->index();
                        diagnostics::call_context::for_thread().layer = render_layer;
 
-                       producer = found->producer_factory(
-                                       video_channel->frame_factory(),
-                                       video_channel->video_format_desc(),
-                                       filename);
+                       producer = found->producer_factory(dependencies, filename);
                        video_channel->stage().load(render_layer, producer);
                        video_channel->stage().play(render_layer);
                }
@@ -183,36 +178,33 @@ public:
 
                boost::lock_guard<boost::mutex> lock(mutex_);
 
-               for (auto& rec : records_)
+               for (auto& rec : records_by_extension_)
                {
-                       for (auto& file_extension : rec.file_extensions)
-                       {
-                               auto p = path(basepath.wstring() + file_extension);
-
-                               if (exists(p))
-                               {
-                                       return rec.info_extractor(filename);
-                               }
-                       }
+                       auto p = path(basepath.wstring() + rec.first);
+                       auto found = find_case_insensitive(p.wstring());
+
+                       if (found)
+                               return rec.second.info_extractor(*found);
                }
 
-               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(L"No meta info extractor for " + filename));
+               CASPAR_THROW_EXCEPTION(user_error() << msg_info(L"No meta info extractor for " + filename));
        }
 
        bool is_cg_extension(const std::wstring& extension) const
        {
                boost::lock_guard<boost::mutex> lock(mutex_);
 
-               for (auto& rec : records_)
-               {
-                       for (auto& file_extension : rec.file_extensions)
-                       {
-                               if (boost::algorithm::iequals(file_extension, extension))
-                                       return true;
-                       }
-               }
+               return records_by_extension_.find(extension) != records_by_extension_.end();
+       }
+
+       std::wstring get_cg_producer_name(const std::wstring& filename) const
+       {
+               auto record = find_record(filename);
+
+               if (!record)
+                       CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info(filename + L" is not a cg template."));
 
-               return false;
+               return record->name;
        }
 private:
        boost::optional<record> find_record(const std::wstring& filename) const
@@ -223,15 +215,12 @@ private:
 
                boost::lock_guard<boost::mutex> lock(mutex_);
 
-               for (auto& rec : records_)
+               for (auto& rec : records_by_extension_)
                {
-                       for (auto& file_extension : rec.file_extensions)
-                       {
-                               auto p = path(basepath.wstring() + file_extension);
+                       auto p = path(basepath.wstring() + rec.first);
 
-                               if (find_case_insensitive(p.wstring()))
-                                       return rec;
-                       }
+                       if (find_case_insensitive(p.wstring()))
+                               return rec.second;
                }
 
                return boost::none;
@@ -258,10 +247,10 @@ void cg_producer_registry::register_cg_producer(
 }
 
 spl::shared_ptr<frame_producer> cg_producer_registry::create_producer(
-               const spl::shared_ptr<video_channel>& video_channel,
+               const frame_producer_dependencies& dependencies,
                const std::wstring& filename) const
 {
-       return impl_->create_producer(video_channel, filename);
+       return impl_->create_producer(dependencies, filename);
 }
 
 spl::shared_ptr<cg_proxy> cg_producer_registry::get_proxy(
@@ -279,10 +268,11 @@ spl::shared_ptr<cg_proxy> cg_producer_registry::get_proxy(
 
 spl::shared_ptr<cg_proxy> cg_producer_registry::get_or_create_proxy(
                const spl::shared_ptr<video_channel>& video_channel,
+               const frame_producer_dependencies& dependencies,
                int render_layer,
                const std::wstring& filename) const
 {
-       return impl_->get_or_create_proxy(video_channel, render_layer, filename);
+       return impl_->get_or_create_proxy(video_channel, dependencies, render_layer, filename);
 }
 
 std::string cg_producer_registry::read_meta_info(const std::wstring& filename) const
@@ -295,4 +285,9 @@ bool cg_producer_registry::is_cg_extension(const std::wstring& extension) const
        return impl_->is_cg_extension(extension);
 }
 
+std::wstring cg_producer_registry::get_cg_producer_name(const std::wstring& filename) const
+{
+       return impl_->get_cg_producer_name(filename);
+}
+
 }}