X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fimage%2Fconsumer%2Fimage_consumer.cpp;h=4730402d7566fae1dba51a455bcf176811e4ff5a;hb=9e4b08cde6c6de9e83a3fff42d90affc3cd8e5bc;hp=660c5505a0d21a52f158b16fb343f3963cf590bf;hpb=28d3e7c5efbf12eb494650aeb31d1a379befff21;p=casparcg diff --git a/modules/image/consumer/image_consumer.cpp b/modules/image/consumer/image_consumer.cpp index 660c5505a..4730402d7 100644 --- a/modules/image/consumer/image_consumer.cpp +++ b/modules/image/consumer/image_consumer.cpp @@ -27,13 +27,17 @@ #include #include #include +#include #include #include #include +#include +#include #include #include +#include #include @@ -48,26 +52,31 @@ namespace caspar { namespace image { - void write_cropped_png( +void write_cropped_png( const core::const_frame& frame, const core::video_format_desc& format_desc, - const boost::filesystem::wpath& output_file, + const boost::filesystem::path& output_file, int width, int height) - { - auto bitmap = std::shared_ptr(FreeImage_Allocate(width, height, 32), FreeImage_Unload); - image_view destination_view(FreeImage_GetBits(bitmap.get()), width, height); - image_view complete_frame(const_cast(frame.image_data().begin()), format_desc.width, format_desc.height); - auto thumbnail_view = complete_frame.subview(0, 0, width, height); - - std::copy(thumbnail_view.begin(), thumbnail_view.end(), destination_view.begin()); - FreeImage_FlipVertical(bitmap.get()); - FreeImage_SaveU(FIF_PNG, bitmap.get(), output_file.wstring().c_str(), 0); - } +{ + auto bitmap = std::shared_ptr(FreeImage_Allocate(width, height, 32), FreeImage_Unload); + image_view destination_view(FreeImage_GetBits(bitmap.get()), width, height); + image_view complete_frame(const_cast(frame.image_data().begin()), format_desc.width, format_desc.height); + auto thumbnail_view = complete_frame.subview(0, 0, width, height); + + std::copy(thumbnail_view.begin(), thumbnail_view.end(), destination_view.begin()); + FreeImage_FlipVertical(bitmap.get()); +#ifdef WIN32 + FreeImage_SaveU(FIF_PNG, bitmap.get(), output_file.wstring().c_str(), 0); +#else + FreeImage_Save(FIF_PNG, bitmap.get(), u8(output_file.wstring()).c_str(), 0); +#endif +} struct image_consumer : public core::frame_consumer { - std::wstring filename_; + core::monitor::subject monitor_subject_; + std::wstring filename_; public: // frame_consumer @@ -77,20 +86,27 @@ public: { } - void initialize(const core::video_format_desc&, int) override + void initialize(const core::video_format_desc&, const core::audio_channel_layout&, int) override { } - - boost::unique_future send(core::const_frame frame) override + + int64_t presentation_frame_age_millis() const override + { + return 0; + } + + std::future send(core::const_frame frame) override { auto filename = filename_; boost::thread async([frame, filename] { + ensure_gpf_handler_installed_for_thread("image-consumer"); + try { auto filename2 = filename; - + if (filename2.empty()) filename2 = env::media_folder() + boost::posix_time::to_iso_wstring(boost::posix_time::second_clock::local_time()) + L".png"; else @@ -99,7 +115,11 @@ public: auto bitmap = std::shared_ptr(FreeImage_Allocate(static_cast(frame.width()), static_cast(frame.height()), 32), FreeImage_Unload); A_memcpy(FreeImage_GetBits(bitmap.get()), frame.image_data().begin(), frame.image_data().size()); FreeImage_FlipVertical(bitmap.get()); +#ifdef WIN32 FreeImage_SaveU(FIF_PNG, bitmap.get(), filename2.c_str(), 0); +#else + FreeImage_Save(FIF_PNG, bitmap.get(), u8(filename2).c_str(), 0); +#endif } catch(...) { @@ -108,14 +128,14 @@ public: }); async.detach(); - return wrap_as_future(false); + return make_ready_future(false); } std::wstring print() const override { return L"image[]"; } - + std::wstring name() const override { return L"image"; @@ -130,7 +150,7 @@ public: int buffer_depth() const override { - return 0; + return -1; } int index() const override @@ -138,21 +158,34 @@ public: return 100; } - monitor::source& monitor_output() + core::monitor::subject& monitor_output() { - static monitor::subject monitor_subject(""); return monitor_subject; + return monitor_subject_; } }; -spl::shared_ptr create_consumer(const std::vector& params) +void describe_consumer(core::help_sink& sink, const core::help_repository& repo) +{ + sink.short_description(L"Writes a single PNG snapshot of a video channel."); + sink.syntax(L"IMAGE {[filename:string]|yyyyMMddTHHmmss}"); + sink.para() + ->text(L"Writes a single PNG snapshot of a video channel. ")->code(L".png")->text(L" will be appended to ") + ->code(L"filename")->text(L". The PNG image will be stored under the ")->code(L"media")->text(L" folder."); + sink.para()->text(L"Examples:"); + sink.example(L">> ADD 1 IMAGE screenshot", L"creating media/screenshot.png"); + sink.example(L">> ADD 1 IMAGE", L"creating media/20130228T210946.png if the current time is 2013-02-28 21:09:46."); +} + +spl::shared_ptr create_consumer( + const std::vector& params, core::interaction_sink*, std::vector> channels) { - if (params.size() < 1 || params[0] != L"IMAGE") + if (params.size() < 1 || !boost::iequals(params.at(0), L"IMAGE")) return core::frame_consumer::empty(); std::wstring filename; if (params.size() > 1) - filename = params[1]; + filename = params.at(1); return spl::make_shared(filename); }