X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fogl%2Fconsumer%2Fogl_consumer.cpp;h=34951a72c06da8a70c03fac0bdd5be44017709a5;hb=ea8490603358f327d8e0c2c90c1401165e7015b4;hp=4cdfa93fe036083e9bb6d388769dac9bea4faf78;hpb=6b8b752068674445e735f076ca96588c39e77f5e;p=casparcg 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 }