--- /dev/null
+#pragma once\r
+\r
+#include <core/video_format.h>\r
+\r
+namespace caspar { namespace ffmpeg {\r
+ \r
+struct display_mode\r
+{\r
+ enum type\r
+ {\r
+ simple,\r
+ duplicate,\r
+ half,\r
+ interlace,\r
+ deinterlace_bob,\r
+ deinterlace_bob_reinterlace,\r
+ deinterlace,\r
+ count,\r
+ invalid\r
+ };\r
+\r
+ static std::wstring print(display_mode::type value)\r
+ {\r
+ switch(value)\r
+ {\r
+ case simple: return L"simple";\r
+ case duplicate: return L"duplicate";\r
+ case half: return L"half";\r
+ case interlace: return L"interlace";\r
+ case deinterlace_bob: return L"deinterlace_bob";\r
+ case deinterlace_bob_reinterlace: return L"deinterlace_bob_reinterlace";\r
+ case deinterlace: return L"deinterlace";\r
+ default: return L"invalid";\r
+ }\r
+ }\r
+};\r
+\r
+display_mode::type get_display_mode(const core::field_mode::type in_mode, double in_fps, const core::field_mode::type out_mode, double out_fps)\r
+{ \r
+ static const auto epsilon = 2.0;\r
+\r
+ if(in_fps < 20.0 || in_fps > 80.0)\r
+ {\r
+ //if(out_mode != core::field_mode::progressive && in_mode == core::field_mode::progressive)\r
+ // return display_mode::interlace;\r
+ \r
+ if(out_mode == core::field_mode::progressive && in_mode != core::field_mode::progressive)\r
+ {\r
+ if(in_fps < 35.0)\r
+ return display_mode::deinterlace;\r
+ else\r
+ return display_mode::deinterlace_bob;\r
+ }\r
+ }\r
+\r
+ if(std::abs(in_fps - out_fps) < epsilon)\r
+ {\r
+ if(in_mode != core::field_mode::progressive && out_mode == core::field_mode::progressive)\r
+ return display_mode::deinterlace;\r
+ //else if(in_mode == core::field_mode::progressive && out_mode != core::field_mode::progressive)\r
+ // simple(); // interlace_duplicate();\r
+ else\r
+ return display_mode::simple;\r
+ }\r
+ else if(std::abs(in_fps/2.0 - out_fps) < epsilon)\r
+ {\r
+ if(in_mode != core::field_mode::progressive)\r
+ return display_mode::invalid;\r
+\r
+ if(out_mode != core::field_mode::progressive)\r
+ return display_mode::interlace;\r
+ else\r
+ return display_mode::half;\r
+ }\r
+ else if(std::abs(in_fps - out_fps/2.0) < epsilon)\r
+ {\r
+ if(out_mode != core::field_mode::progressive)\r
+ return display_mode::invalid;\r
+\r
+ if(in_mode != core::field_mode::progressive)\r
+ return display_mode::deinterlace_bob;\r
+ else\r
+ return display_mode::duplicate;\r
+ }\r
+\r
+ return display_mode::invalid;\r
+}\r
+\r
+}}
\ No newline at end of file
#include "filter/filter.h"\r
\r
#include "util.h"\r
+#include "display_mode.h"\r
\r
#include <core/producer/frame_producer.h>\r
#include <core/producer/frame/basic_frame.h>\r
#pragma warning (pop)\r
#endif\r
\r
-#include <boost/foreach.hpp>\r
-\r
-#include <agents_extras.h>\r
-\r
-using namespace caspar::core;\r
+#include <agents.h>\r
\r
using namespace Concurrency;\r
\r
namespace caspar { namespace ffmpeg {\r
-\r
-struct display_mode\r
-{\r
- enum type\r
- {\r
- simple,\r
- duplicate,\r
- half,\r
- interlace,\r
- deinterlace_bob,\r
- deinterlace_bob_reinterlace,\r
- deinterlace,\r
- count,\r
- invalid\r
- };\r
-\r
- static std::wstring print(display_mode::type value)\r
- {\r
- switch(value)\r
- {\r
- case simple: return L"simple";\r
- case duplicate: return L"duplicate";\r
- case half: return L"half";\r
- case interlace: return L"interlace";\r
- case deinterlace_bob: return L"deinterlace_bob";\r
- case deinterlace_bob_reinterlace: return L"deinterlace_bob_reinterlace";\r
- case deinterlace: return L"deinterlace";\r
- default: return L"invalid";\r
- }\r
- }\r
-};\r
-\r
-display_mode::type get_display_mode(const core::field_mode::type in_mode, double in_fps, const core::field_mode::type out_mode, double out_fps)\r
-{ \r
- static const auto epsilon = 2.0;\r
-\r
- if(in_fps < 20.0 || in_fps > 80.0)\r
- {\r
- //if(out_mode != core::field_mode::progressive && in_mode == core::field_mode::progressive)\r
- // return display_mode::interlace;\r
- \r
- if(out_mode == core::field_mode::progressive && in_mode != core::field_mode::progressive)\r
- {\r
- if(in_fps < 35.0)\r
- return display_mode::deinterlace;\r
- else\r
- return display_mode::deinterlace_bob;\r
- }\r
- }\r
-\r
- if(std::abs(in_fps - out_fps) < epsilon)\r
- {\r
- if(in_mode != core::field_mode::progressive && out_mode == core::field_mode::progressive)\r
- return display_mode::deinterlace;\r
- //else if(in_mode == core::field_mode::progressive && out_mode != core::field_mode::progressive)\r
- // simple(); // interlace_duplicate();\r
- else\r
- return display_mode::simple;\r
- }\r
- else if(std::abs(in_fps/2.0 - out_fps) < epsilon)\r
- {\r
- if(in_mode != core::field_mode::progressive)\r
- return display_mode::invalid;\r
-\r
- if(out_mode != core::field_mode::progressive)\r
- return display_mode::interlace;\r
- else\r
- return display_mode::half;\r
- }\r
- else if(std::abs(in_fps - out_fps/2.0) < epsilon)\r
- {\r
- if(out_mode != core::field_mode::progressive)\r
- return display_mode::invalid;\r
-\r
- if(in_mode != core::field_mode::progressive)\r
- return display_mode::deinterlace_bob;\r
- else\r
- return display_mode::duplicate;\r
- }\r
-\r
- return display_mode::invalid;\r
-}\r
-\r
+ \r
struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopyable\r
{ \r
ITarget<safe_ptr<core::basic_frame>>& target_;\r
mutable single_assignment<display_mode::type> display_mode_;\r
const double in_fps_;\r
- const video_format_desc format_desc_;\r
- bool auto_transcode_;\r
+ const core::video_format_desc format_desc_;\r
+ const bool auto_transcode_;\r
\r
mutable single_assignment<safe_ptr<filter>> filter_;\r
const safe_ptr<core::frame_factory> frame_factory_;\r
\r
core::audio_buffer audio_data_;\r
\r
- Concurrency::overwrite_buffer<bool> is_running_;\r
+ overwrite_buffer<bool> is_running_;\r
\r
std::wstring filter_str_;\r
\r
auto video = receive(video_);\r
\r
if(!is_running_.value() || video == eof_video())\r
+ { \r
+ send(is_running_ , false);\r
return nullptr;\r
- \r
+ }\r
+\r
CASPAR_ASSERT(video != loop_video());\r
\r
try\r
auto audio = receive(audio_);\r
\r
if(!is_running_.value() || audio == eof_audio())\r
+ {\r
+ send(is_running_ , false);\r
return nullptr;\r
- \r
+ }\r
+\r
CASPAR_ASSERT(audio != loop_audio());\r
\r
try\r
auto video = receive_video();\r
\r
if(!audio)\r
- {\r
- send(is_running_ , false);\r
break;\r
- }\r
\r
if(!video)\r
- {\r
- send(is_running_ , false);\r
break;\r
- }\r
\r
video->audio_data() = std::move(*audio);\r
\r
- auto frame = safe_ptr<core::basic_frame>(video);\r
-\r
switch(display_mode_.value())\r
{\r
case display_mode::simple: \r
case display_mode::deinterlace:\r
case display_mode::deinterlace_bob:\r
{\r
- send(target_, frame);\r
+ send(target_, safe_ptr<core::basic_frame>(std::move(video)));\r
\r
break;\r
}\r
case display_mode::duplicate: \r
{ \r
- send(target_, frame);\r
+ send(target_, safe_ptr<core::basic_frame>(video));\r
\r
auto audio2 = receive_audio();\r
if(audio2)\r
{\r
auto video2 = make_safe<core::write_frame>(*video);\r
video2->audio_data() = std::move(*audio2);\r
- auto frame2 = safe_ptr<core::basic_frame>(video2);\r
- send(target_, frame2);\r
+ send(target_, safe_ptr<core::basic_frame>(video2));\r
}\r
- else\r
- send(is_running_, false);\r
\r
break;\r
}\r
case display_mode::half: \r
{ \r
- send(target_, frame);\r
-\r
- if(!receive_video()) // throw away \r
- send(is_running_ , false);\r
-\r
+ send(target_, safe_ptr<core::basic_frame>(std::move(video)));\r
+ receive_video();\r
break;\r
}\r
case display_mode::deinterlace_bob_reinterlace:\r
case display_mode::interlace: \r
{ \r
+ auto frame = safe_ptr<core::basic_frame>(std::move(video));\r
auto video2 = receive_video();\r
auto frame2 = core::basic_frame::empty();\r
\r
if(video2) \r
- frame2 = safe_ptr<core::basic_frame>(video2); \r
- else\r
- send(is_running_, false); \r
+ frame2 = safe_ptr<core::basic_frame>(video2); \r
\r
- frame = core::basic_frame::interlace(frame, frame2, format_desc_.field_mode); \r
+ frame = core::basic_frame::interlace(std::move(frame), std::move(frame2), format_desc_.field_mode); \r
send(target_, frame);\r
\r
break;\r