From: Ronag Date: Fri, 26 Aug 2011 21:22:39 +0000 (+0000) Subject: 2.0. ogl_consumer: Deinterlacer enabled when running in interlaced channel. X-Git-Tag: 2.0.1~47 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;ds=sidebyside;h=ea8490603358f327d8e0c2c90c1401165e7015b4;p=casparcg 2.0. ogl_consumer: Deinterlacer enabled when running in interlaced channel. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1297 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- diff --git a/modules/ffmpeg/producer/filter/filter.cpp b/modules/ffmpeg/producer/filter/filter.cpp index 9478d523f..2475bf710 100644 --- a/modules/ffmpeg/producer/filter/filter.cpp +++ b/modules/ffmpeg/producer/filter/filter.cpp @@ -31,20 +31,6 @@ extern "C" namespace caspar { -PixelFormat pix_fmts[] = -{ - PIX_FMT_YUV420P, - PIX_FMT_YUVA420P, - PIX_FMT_YUV422P, - PIX_FMT_YUV444P, - PIX_FMT_YUV411P, - PIX_FMT_ARGB, - PIX_FMT_RGBA, - PIX_FMT_ABGR, - PIX_FMT_GRAY8, - PIX_FMT_NONE -}; - struct filter::implementation { std::string filters_; @@ -52,11 +38,29 @@ struct filter::implementation AVFilterContext* buffersink_ctx_; AVFilterContext* buffersrc_ctx_; std::shared_ptr parallel_yadif_ctx_; + std::vector pix_fmts_; - implementation(const std::wstring& filters) + implementation(const std::wstring& filters, const std::vector& pix_fmts) : filters_(narrow(filters)) , parallel_yadif_ctx_(nullptr) + , pix_fmts_(pix_fmts) { + if(pix_fmts_.empty()) + { + pix_fmts_.push_back(PIX_FMT_YUV420P); + pix_fmts_.push_back(PIX_FMT_YUVA420P); + pix_fmts_.push_back(PIX_FMT_YUV422P); + pix_fmts_.push_back(PIX_FMT_YUV444P); + pix_fmts_.push_back(PIX_FMT_YUV411P); + pix_fmts_.push_back(PIX_FMT_ARGB); + pix_fmts_.push_back(PIX_FMT_RGBA); + pix_fmts_.push_back(PIX_FMT_ABGR); + pix_fmts_.push_back(PIX_FMT_GRAY8); + pix_fmts_.push_back(PIX_FMT_NONE); + } + else + pix_fmts_.push_back(PIX_FMT_NONE); + std::transform(filters_.begin(), filters_.end(), filters_.begin(), ::tolower); } @@ -84,7 +88,7 @@ struct filter::implementation THROW_ON_ERROR2(avfilter_graph_create_filter(&buffersrc_ctx_, avfilter_get_by_name("buffer"), "src", args.str().c_str(), NULL, graph_.get()), "[filter]"); // OPIX_FMT_BGRAutput - THROW_ON_ERROR2(avfilter_graph_create_filter(&buffersink_ctx_, avfilter_get_by_name("buffersink"), "out", NULL, pix_fmts, graph_.get()), "[filter]"); + THROW_ON_ERROR2(avfilter_graph_create_filter(&buffersink_ctx_, avfilter_get_by_name("buffersink"), "out", NULL, pix_fmts_.data(), graph_.get()), "[filter]"); AVFilterInOut* outputs = avfilter_inout_alloc(); AVFilterInOut* inputs = avfilter_inout_alloc(); @@ -159,7 +163,7 @@ struct filter::implementation } }; -filter::filter(const std::wstring& filters) : impl_(new implementation(filters)){} +filter::filter(const std::wstring& filters, const std::vector& pix_fmts) : impl_(new implementation(filters, pix_fmts)){} filter::filter(filter&& other) : impl_(std::move(other.impl_)){} filter& filter::operator=(filter&& other){impl_ = std::move(other.impl_); return *this;} std::vector> filter::execute(const std::shared_ptr& frame) {return impl_->execute(frame);} diff --git a/modules/ffmpeg/producer/filter/filter.h b/modules/ffmpeg/producer/filter/filter.h index de89332b9..6fabbd673 100644 --- a/modules/ffmpeg/producer/filter/filter.h +++ b/modules/ffmpeg/producer/filter/filter.h @@ -8,6 +8,7 @@ #include struct AVFrame; +enum PixelFormat; namespace caspar { @@ -25,7 +26,7 @@ static bool double_rate(const std::wstring& filters) class filter : boost::noncopyable { public: - filter(const std::wstring& filters = L""); + filter(const std::wstring& filters = L"", const std::vector& pix_fmts = std::vector()); filter(filter&& other); filter& operator=(filter&& other); diff --git a/modules/ogl/consumer/ogl_consumer.cpp b/modules/ogl/consumer/ogl_consumer.cpp index 4cdfa93fe..34951a72c 100644 --- a/modules/ogl/consumer/ogl_consumer.cpp +++ b/modules/ogl/consumer/ogl_consumer.cpp @@ -32,6 +32,8 @@ #include #include +#include + #include #include #include @@ -44,9 +46,26 @@ #include #include +#include + #include #include +#if defined(_MSC_VER) +#pragma warning (push) +#pragma warning (disable : 4244) +#endif +extern "C" +{ + #define __STDC_CONSTANT_MACROS + #define __STDC_LIMIT_MACROS + #include + #include +} +#if defined(_MSC_VER) +#pragma warning (pop) +#endif + namespace caspar { enum stretch @@ -90,6 +109,9 @@ struct ogl_consumer : boost::noncopyable boost::thread thread_; tbb::atomic is_running_; + + filter filter_; + const bool key_only_; public: ogl_consumer(unsigned int screen_index, stretch stretch, bool windowed, const core::video_format_desc& format_desc, bool key_only) @@ -106,7 +128,11 @@ public: , graph_(diagnostics::create_graph(narrow(print()))) , input_buffer_(core::consumer_buffer_depth()-1) , key_only_(key_only) + , filter_(format_desc.field_mode == core::field_mode::progressive ? L"" : L"YADIF=0:-1", boost::assign::list_of(PIX_FMT_BGRA)) { + if(format_desc.field_mode != core::field_mode::progressive) + CASPAR_LOG(info) << print() << L" Deinterlacer enabled."; + frame_buffer_.set_capacity(2); graph_->add_guide("frame-time", 0.5); @@ -260,10 +286,51 @@ public: return format_desc_; } + safe_ptr get_av_frame() + { + safe_ptr av_frame(avcodec_alloc_frame(), av_free); + avcodec_get_frame_defaults(av_frame.get()); + + av_frame->linesize[0] = format_desc_.width*4; + av_frame->format = PIX_FMT_BGRA; + av_frame->width = format_desc_.width; + av_frame->height = format_desc_.height; + av_frame->interlaced_frame = format_desc_.field_mode != core::field_mode::progressive; + av_frame->top_field_first = format_desc_.field_mode == core::field_mode::upper ? 1 : 0; + + return av_frame; + } + void render(const safe_ptr& frame) { if(frame->image_data().empty()) return; + + auto av_frame = get_av_frame(); + av_frame->data[0] = const_cast(frame->image_data().begin()); + + auto frames = filter_.execute(av_frame); + + if(frames.empty()) + return; + + av_frame = frames[0]; + + if(av_frame->linesize[0] != static_cast(format_desc_.width*4)) + { + const uint8_t *src_data[4] = {0}; + memcpy(const_cast(&src_data[0]), av_frame->data, 4); + const int src_linesizes[4] = {0}; + memcpy(const_cast(&src_linesizes[0]), av_frame->linesize, 4); + + auto av_frame2 = get_av_frame(); + av_image_alloc(av_frame2->data, av_frame2->linesize, av_frame2->width, av_frame2->height, PIX_FMT_BGRA, 16); + av_image_copy(av_frame2->data, av_frame2->linesize, src_data, src_linesizes, PIX_FMT_BGRA, av_frame2->width, av_frame2->height); + av_frame = safe_ptr(av_frame2.get(), [=](AVFrame*) + { + av_freep(&av_frame2->data[0]); + }); + } glBindTexture(GL_TEXTURE_2D, texture_); @@ -277,9 +344,9 @@ public: if(ptr) { if(key_only_) - fast_memshfl(reinterpret_cast(ptr), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303); + fast_memshfl(reinterpret_cast(ptr), av_frame->data[0], frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303); else - fast_memcpy(reinterpret_cast(ptr), frame->image_data().begin(), frame->image_data().size()); + fast_memcpy(reinterpret_cast(ptr), av_frame->data[0], frame->image_data().size()); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer } diff --git a/modules/ogl/ogl.vcxproj b/modules/ogl/ogl.vcxproj index 9570b7045..d5be95f40 100644 --- a/modules/ogl/ogl.vcxproj +++ b/modules/ogl/ogl.vcxproj @@ -72,7 +72,7 @@ $(ProjectDir)tmp\$(Configuration)\ $(ProjectDir)tmp\$(Configuration)\ $(ProjectDir)tmp\$(Configuration)\ - ..\..\;..\..\dependencies\boost_1_44_0\;..\..\dependencies\glew-1.6.0\include;..\..\dependencies\tbb\include\;..\..\dependencies\SFML-1.6\include;$(IncludePath) + ..\..\;..\..\dependencies\boost_1_44_0\;..\..\dependencies\glew-1.6.0\include;..\..\dependencies\tbb\include\;..\..\dependencies\SFML-1.6\include;..\..\dependencies\ffmpeg 0.8\include;$(IncludePath) ..\..\;..\..\dependencies\boost_1_44_0\;..\..\dependencies\glew-1.6.0\include;..\..\dependencies\tbb\include\;..\..\dependencies\SFML-1.6\include;$(IncludePath) ..\..\;..\..\dependencies\boost_1_44_0\;..\..\dependencies\glew-1.6.0\include;..\..\dependencies\tbb\include\;..\..\dependencies\SFML-1.6\include;$(IncludePath) ..\..\;..\..\dependencies\boost_1_44_0\;..\..\dependencies\glew-1.6.0\include;..\..\dependencies\tbb\include\;..\..\dependencies\SFML-1.6\include;$(IncludePath) @@ -249,6 +249,9 @@ {79388c20-6499-4bf6-b8b9-d8c33d7d4ddd} + + {f6223af3-be0b-4b61-8406-98922ce521c2} +