]> git.sesse.net Git - casparcg/commitdiff
2.0. ffmpeg_producer: Fixed data race and frame timing.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 27 Jun 2011 07:19:12 +0000 (07:19 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 27 Jun 2011 07:19:12 +0000 (07:19 +0000)
     mixer: Added missing files.
     image_kernel: Fixed inverted field order.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@957 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/gpu/shader.cpp [new file with mode: 0644]
core/mixer/gpu/shader.h [new file with mode: 0644]
core/mixer/image/image_kernel.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp

diff --git a/core/mixer/gpu/shader.cpp b/core/mixer/gpu/shader.cpp
new file mode 100644 (file)
index 0000000..ca5a7f5
--- /dev/null
@@ -0,0 +1,115 @@
+#include "../../../stdafx.h"\r
+\r
+#include "shader.h"\r
+\r
+#include <common/gl/gl_check.h>\r
+\r
+#include <unordered_map>\r
+\r
+namespace caspar { namespace core {\r
+\r
+struct shader::implementation : boost::noncopyable\r
+{\r
+       GLuint program_;\r
+       std::unordered_map<std::string, GLint> locations_;\r
+public:\r
+\r
+       implementation(const std::string& vertex_source_str, const std::string& fragment_source_str) : program_(0)\r
+       {\r
+               GLint success;\r
+       \r
+               const char* vertex_source = vertex_source_str.c_str();\r
+                                               \r
+               auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
+                                       \r
+               GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
+               GL(glCompileShaderARB(vertex_shader));\r
+\r
+               GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
+               if (success == GL_FALSE)\r
+               {\r
+                       char info[2048];\r
+                       GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
+                       GL(glDeleteObjectARB(vertex_shader));\r
+                       std::stringstream str;\r
+                       str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
+               }\r
+                       \r
+               const char* fragment_source = fragment_source_str.c_str();\r
+                                               \r
+               auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
+                                       \r
+               GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
+               GL(glCompileShaderARB(fragmemt_shader));\r
+\r
+               GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
+               if (success == GL_FALSE)\r
+               {\r
+                       char info[2048];\r
+                       GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
+                       GL(glDeleteObjectARB(fragmemt_shader));\r
+                       std::stringstream str;\r
+                       str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
+               }\r
+                       \r
+               program_ = glCreateProgramObjectARB();\r
+                       \r
+               GL(glAttachObjectARB(program_, vertex_shader));\r
+               GL(glAttachObjectARB(program_, fragmemt_shader));\r
+\r
+               GL(glLinkProgramARB(program_));\r
+                       \r
+               GL(glDeleteObjectARB(vertex_shader));\r
+               GL(glDeleteObjectARB(fragmemt_shader));\r
+\r
+               GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
+               if (success == GL_FALSE)\r
+               {\r
+                       char info[2048];\r
+                       GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
+                       GL(glDeleteObjectARB(program_));\r
+                       std::stringstream str;\r
+                       str << "Failed to link shader program:" << std::endl << info << std::endl;\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
+               }\r
+               GL(glUseProgramObjectARB(program_));\r
+       }\r
+       \r
+       ~implementation()\r
+       {\r
+               glDeleteProgram(program_);\r
+       }\r
+\r
+       GLint get_location(const char* name)\r
+       {\r
+               auto it = locations_.find(name);\r
+               if(it == locations_.end())\r
+                       it = locations_.insert(std::make_pair(name, glGetUniformLocation(program_, name))).first;\r
+               return it->second;\r
+       }\r
+\r
+       void use()\r
+       {       \r
+               GL(glUseProgramObjectARB(program_));            \r
+       }\r
+\r
+       void set(const std::string& name, int value)\r
+       {\r
+               GL(glUniform1i(get_location(name.c_str()), value));\r
+       }\r
+       \r
+       void set(const std::string& name, float value)\r
+       {\r
+               GL(glUniform1f(get_location(name.c_str()), value));\r
+       }\r
+};\r
+\r
+\r
+shader::shader(const std::string& vertex_source_str, const std::string& fragment_source_str) : impl_(new implementation(vertex_source_str, fragment_source_str)){}\r
+void shader::use(){impl_->use();}\r
+void shader::set(const std::string& name, int value){impl_->set(name, value);}\r
+void shader::set(const std::string& name, float value){impl_->set(name, value);}\r
+\r
+}}
\ No newline at end of file
diff --git a/core/mixer/gpu/shader.h b/core/mixer/gpu/shader.h
new file mode 100644 (file)
index 0000000..08e8697
--- /dev/null
@@ -0,0 +1,23 @@
+#pragma once\r
+\r
+#include <string>\r
+\r
+#include <common/memory/safe_ptr.h>\r
+\r
+#include <boost/noncopyable.hpp>\r
+\r
+namespace caspar { namespace core {\r
+               \r
+class shader : boost::noncopyable\r
+{\r
+public:\r
+       shader(const std::string& vertex_source_str, const std::string& fragment_source_str);\r
+       void use();\r
+       void set(const std::string& name, int value);\r
+       void set(const std::string& name, float value);\r
+private:\r
+       struct implementation;\r
+       safe_ptr<implementation> impl_;\r
+};\r
+\r
+}}
\ No newline at end of file
index 1df01ad73deb4b3283b2820d3cdcce984a9fe024..322c3e0ba7d93414467e8b513e1b60175656002d 100644 (file)
@@ -219,14 +219,14 @@ struct image_kernel::implementation : boost::noncopyable
                        "       case 1: // lower                                                                                                                                \n"\r
                        "               {                                                                                                                                                       \n"\r
                        "                       bool odd = mod(floor(gl_FragCoord.y), 2.0) > 0.5;                                               \n"\r
-                       "                       if(odd)                                                                                                                                 \n"\r
+                       "                       if(!odd)                                                                                                                                \n"\r
                        "                               discard;                                                                                                                        \n"\r
                        "                       break;                                                                                                                                  \n"\r
                        "               }                                                                                                                                                       \n"\r
                        "       case 2: //upper                                                                                                                                 \n"\r
                        "               {                                                                                                                                                       \n"\r
                        "                       bool odd = mod(floor(gl_FragCoord.y), 2.0) > 0.5;                                               \n"\r
-                       "                       if(!odd)                                                                                                                                \n"\r
+                       "                       if(odd)                                                                                                                                 \n"\r
                        "                               discard;                                                                                                                        \n"\r
                        "                       break;                                                                                                                                  \n"\r
                        "               }                                                                                                                                                       \n"\r
index 325184f3826fe4997c7c2f9e8d154b563b14c353..cdcf36aa8b134096b7177d9cf4ca28519ca3eeb6 100644 (file)
@@ -92,12 +92,18 @@ public:
        }\r
 \r
        virtual safe_ptr<core::basic_frame> receive()\r
-       {\r
-               frame_timer_.restart();\r
+       {               \r
+               // "receive" is called on the same thread as the gpu mixer runs. Minimize "receive" time in order to allow gpu and cpu to run in parallel. \r
+               task_group_.wait();\r
 \r
-               auto result = decode_frame();\r
-                               \r
-               graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*frame_factory_->get_video_format_desc().fps*0.5));\r
+               auto result = get_frame();\r
+\r
+               task_group_.run([=]\r
+               {\r
+                       frame_timer_.restart();\r
+                       decode_packets();\r
+                       graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*frame_factory_->get_video_format_desc().fps*0.5));\r
+               });                             \r
                                        \r
                return result;\r
        }\r
@@ -177,15 +183,8 @@ public:
                return frame;\r
        }\r
 \r
-       safe_ptr<core::basic_frame> decode_frame()\r
+       safe_ptr<core::basic_frame> get_frame()\r
        {               \r
-               // "receive" is called on the same thread as the gpu mixer runs. Minimize "receive" time in order to allow gpu and cpu to run in parallel. \r
-               task_group_.wait();\r
-               task_group_.run([=]\r
-               {\r
-                       decode_packets();\r
-               });\r
-\r
                if(video_decoder_ && audio_decoder_ && !video_frames_.empty() && !audio_chunks_.empty())\r
                {\r
                        auto audio_chunk = std::move(audio_chunks_.front().second);\r