]> git.sesse.net Git - casparcg/commitdiff
3560321: Merged patch from Robert Nagy, but haven't been able to play any swf myself...
authorhellgore <hellgore@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 24 Jan 2013 09:52:13 +0000 (09:52 +0000)
committerhellgore <hellgore@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 24 Jan 2013 09:52:13 +0000 (09:52 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/trunk@3706 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/flash/producer/cg_producer.cpp
modules/flash/producer/cg_producer.h
modules/flash/producer/flash_producer.cpp
modules/flash/producer/flash_producer.h
modules/flash/util/swf.cpp
modules/flash/util/swf.h

index 0322b56d438e2fe1fa2c1f3878a4d69e691dded1..e49cf2fd7830af256575e95459135588ca66dcfb 100644 (file)
@@ -239,11 +239,6 @@ safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_fac
        return create_cg_producer_and_autoplay_file(frame_factory, params, env::media_folder() + L"\\" + params[0] + L".ct");\r
 }\r
 \r
-safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
-{\r
-       return create_cg_producer_and_autoplay_file(frame_factory, params, env::media_folder() + L"\\" + params[0] + L".swf");\r
-}\r
-\r
 safe_ptr<core::frame_producer> create_cg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
 {\r
        if(params.empty() || params.at(0) != L"[CG]")\r
index 5abae049ff3976aee9b869cfc5b49d3b3e63e5f0..875b3cf303d2630832b1311425b824c69024de91 100644 (file)
@@ -68,6 +68,5 @@ safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<core::video_channel
 \r
 safe_ptr<core::frame_producer> create_ct_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 safe_ptr<core::frame_producer> create_cg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 }}
\ No newline at end of file
index 74ba5ba71f5a2515b4a445012d3caf803e5c1824..7afb1bdfdd1f9d097acfbd241cf7a054e9ab5c44 100644 (file)
@@ -29,6 +29,8 @@
 #include "flash_producer.h"\r
 #include "FlashAxContainer.h"\r
 \r
+#include "../util/swf.h"\r
+\r
 #include <core/video_format.h>\r
 \r
 #include <core/producer/frame/basic_frame.h>\r
@@ -266,7 +268,7 @@ public:
 \r
                ax_->Tick();\r
                if(ax_->InvalidRect())\r
-               {                       \r
+               {\r
                        fast_memclr(bmp_.data(), width_*height_*4);\r
                        ax_->DrawControl(bmp_);\r
                \r
@@ -352,6 +354,11 @@ public:
                graph_->set_color("late-frame", diagnostics::color(0.6f, 0.3f, 0.9f));\r
                graph_->set_text(print());\r
                diagnostics::register_graph(graph_);\r
+               \r
+               renderer_.reset(new flash_renderer(graph_, frame_factory_, filename_, width_, height_));\r
+\r
+               while(output_buffer_.size() < buffer_size_)\r
+                       output_buffer_.push(core::basic_frame::empty());\r
        }\r
 \r
        ~flash_producer()\r
@@ -372,7 +379,7 @@ public:
                        next();\r
                else\r
                        graph_->set_tag("late-frame");\r
-                                               \r
+\r
                return frame;\r
        }\r
 \r
@@ -497,6 +504,20 @@ safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factor
                        make_safe<flash_producer>(frame_factory, filename, template_host.width, template_host.height)));\r
 }\r
 \r
+safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params) \r
+{\r
+       auto filename = env::media_folder() + L"\\" + params.at(0) + L".swf";\r
+       \r
+       if(!boost::filesystem::exists(filename))\r
+               return core::frame_producer::empty();\r
+\r
+       swf_t::header_t header(filename);\r
+\r
+       return create_producer_destroy_proxy(\r
+                  create_producer_print_proxy(\r
+                       make_safe<flash_producer>(frame_factory, filename, header.frame_width, header.frame_height)));\r
+}\r
+\r
 std::wstring find_template(const std::wstring& template_name)\r
 {\r
        if(boost::filesystem::exists(template_name + L".ft")) \r
index a0a34764d68745e7b4bb0e5f105b6ac3a76ef3a3..fec8d1699926ffa7a5c83729d99b0cc797181f5e 100644 (file)
@@ -31,6 +31,7 @@
 namespace caspar { namespace flash {\r
 \r
 safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_producer> create_swf_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
 \r
 std::wstring find_template(const std::wstring& templateName);\r
 \r
index 3c85724d14ee87b3998120743f5191bb04231ad3..0c2cb95f26cbc6ae2702f18112adee1ecc010e9f 100644 (file)
@@ -21,6 +21,8 @@
 \r
 #include "../StdAfx.h"\r
 \r
+#include "swf.h"\r
+\r
 #include <common/exception/exceptions.h>\r
 \r
 #include <zlib.h>\r
@@ -92,4 +94,91 @@ std::string read_template_meta_info(const std::wstring& filename)
        return std::string(beg_it, end_it+end_str.size());\r
 }\r
 \r
+int extractDimensions(const unsigned char* _data);\r
+\r
+swf_t::header_t::header_t(const std::wstring& filename)\r
+       : valid(false)\r
+{\r
+       auto stream = std::fstream();\r
+       stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);\r
+       stream.open(filename, std::ios::in | std::ios::binary);\r
+       stream.read(reinterpret_cast<char*>(this), 8);\r
+               \r
+       const std::array<std::uint8_t, 3> s1 = {'F', 'W', 'S'};\r
+       const std::array<std::uint8_t, 3> s2 = {'C', 'W', 'S'};\r
+\r
+       if(this->signature != s1 && this->signature != s2)\r
+               return;\r
+       \r
+       _byteswap_ulong(this->file_length);\r
+                       \r
+       std::vector<char> file_data;\r
+       std::copy((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>(), std::back_inserter(file_data));\r
+\r
+       std::array<char, 32> data;\r
+       uLongf file_size = 32;\r
+       auto ret = uncompress(reinterpret_cast<Bytef*>(data.data()), &file_size, reinterpret_cast<const Bytef*>(file_data.data()), static_cast<uLong>(file_data.size()));\r
+       \r
+       if(ret == Z_DATA_ERROR)\r
+               BOOST_THROW_EXCEPTION(io_error());\r
+\r
+       // http://thenobody.blog.matfyz.sk/p13084-how-to-get-dimensions-of-a-swf-file\r
+\r
+       unsigned char nbits = reinterpret_cast<unsigned char*>(data.data())[0];\r
+\r
+       unsigned int size = nbits >> 3;                                                                         // remove overlaping 3 bits\r
+\r
+       unsigned long dims[4] = {};\r
+       unsigned long neg_root = 1 << (size-1);                                                         // numbers are signed, i.e. leftmost bit denotes -\r
+\r
+       unsigned int bi_offset = (size % 8) ? (8-(size % 8)) : 0;                       // offset of bit numbers depending on specified size\r
+       unsigned int by_offset = (size + bi_offset) / 8;                                        // offest of bytes\r
+       unsigned int ioffset;                                                                                           // floating byte offset during iteration\r
+       unsigned long ibuf = (unsigned long) (nbits % 8);                                       // actual result - starts with last 3 bits of first byte\r
+\r
+       for(auto i = 0; i < 4; ++i)\r
+       {\r
+               ioffset = by_offset * i;\r
+\r
+               for(unsigned int j = 0; j < by_offset; ++j)\r
+               {\r
+                       ibuf <<= 8;\r
+                       ibuf +=  reinterpret_cast<unsigned char*>(data.data())[1+ioffset+j];\r
+               }\r
+\r
+               dims[i] = (ibuf >> (3 + bi_offset + (i * bi_offset))) / 20;             // coordinates in twips, so divide by 20 for pixels\r
+\r
+               if(dims[i] >= neg_root)                                                                                 // if the leftmost bit is 1 number is negative          \r
+                       dims[i] = (-1) * ( neg_root - (dims[i] - neg_root) );           // convert to negative number           \r
+\r
+               int expn = 3 + bi_offset + (i * bi_offset);                                             // bit divider for ...\r
+               ibuf = ibuf % (1 << (expn-1));                                                                  // ... buffered number \r
+       }\r
+       \r
+       this->frame_width  = dims[1] - dims[0];                                                         // max - mix\r
+       this->frame_height = dims[3] - dims[2]; \r
+\r
+       this->valid = true;\r
+}\r
+\r
+swf_t::swf_t(const std::wstring& filename)\r
+       : header(filename)\r
+{\r
+       auto stream = std::fstream();\r
+       stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);\r
+       stream.open(filename, std::ios::in | std::ios::binary);         \r
+       stream.seekg(8, std::fstream::beg);\r
+\r
+       this->data.resize(this->header.file_length - 8);\r
+       \r
+       std::vector<char> file_data;\r
+       std::copy((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>(), std::back_inserter(file_data));\r
+\r
+       uLongf file_size = this->header.file_length;\r
+       auto ret = uncompress(reinterpret_cast<Bytef*>(this->data.data()), &file_size, reinterpret_cast<const Bytef*>(file_data.data()), static_cast<uLong>(file_data.size()));\r
+\r
+       if(ret != Z_OK)\r
+               BOOST_THROW_EXCEPTION(io_error());\r
+}\r
+\r
 }}
\ No newline at end of file
index cdd35ee4eada31ae487af03d0e4140a6b42d36ca..2017c6db8728802db93f2f081881b0bd72d0efa5 100644 (file)
 \r
 #pragma once\r
 \r
+#include <cstdint>\r
 #include <string>\r
 \r
 namespace caspar { namespace flash {\r
 \r
 std::string read_template_meta_info(const std::wstring& filename);\r
 \r
+struct swf_t\r
+{\r
+       struct header_t\r
+       {\r
+               header_t(const std::wstring& filename);\r
+\r
+               std::array<std::uint8_t, 3> signature;\r
+               std::uint8_t                            version;\r
+               std::uint32_t                           file_length;\r
+               std::uint32_t                           frame_width;\r
+               std::uint32_t                           frame_height;\r
+               std::uint16_t                           frame_rate;\r
+               std::uint16_t                           frame_count;\r
+\r
+               bool                                            valid;\r
+\r
+       } header;\r
+       \r
+       std::vector<char>                               data;\r
+       \r
+       swf_t(const std::wstring& filename);\r
+};\r
+\r
 }}
\ No newline at end of file