From 791b09142a6aeb66ebf5cf4309fe888038fda3b0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 23 Jan 2009 03:05:21 +0100 Subject: [PATCH] Refactoring: extract test image generation code into a separate class --- src/proc/dummy-player-service.cpp | 310 ----------------------- src/proc/dummy-player-service.hpp | 130 ---------- src/proc/play/dummy-image-generator.cpp | 163 ++++++++++++ src/proc/play/dummy-image-generator.hpp | 85 +++++++ src/proc/play/dummy-player-service.cpp | 317 ++++++++++++++++++++++++ src/proc/play/dummy-player-service.hpp | 133 ++++++++++ 6 files changed, 698 insertions(+), 440 deletions(-) delete mode 100644 src/proc/dummy-player-service.cpp delete mode 100644 src/proc/dummy-player-service.hpp create mode 100644 src/proc/play/dummy-image-generator.cpp create mode 100644 src/proc/play/dummy-image-generator.hpp create mode 100644 src/proc/play/dummy-player-service.cpp create mode 100644 src/proc/play/dummy-player-service.hpp diff --git a/src/proc/dummy-player-service.cpp b/src/proc/dummy-player-service.cpp deleted file mode 100644 index 4984f9b45..000000000 --- a/src/proc/dummy-player-service.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - DummyPlayerService - access point and service implementing a dummy test player - - Copyright (C) Lumiera.org - 2009, Hermann Vosseler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -* *****************************************************/ - - -#include "proc/dummy-player-service.hpp" -#include "lib/singleton.hpp" - -extern "C" { -#include "common/interfacedescriptor.h" -} - -#include -#include - - -namespace proc { - - using std::string; - using lumiera::Subsys; - using boost::scoped_ptr; - - - namespace { // hidden local details of the service implementation.... - - /** details of how the DummyPlayer service can be started - * and used as independent "subsystem" within main() */ - class DummyPlayerSubsysDescriptor - : public Subsys - { - operator string () const { return "Dummy-Player"; } - - - bool - shouldStart (lumiera::Option&) - { - return false; // for now the DummyPlayerService only comes "up" as dependency, - } // but doesn't start as a subsystem on it's own. - - bool - start (lumiera::Option&, Subsys::SigTerm terminationHandle) - { - ASSERT (!thePlayer_); - - thePlayer_.reset (new DummyPlayerService (terminationHandle)); - return true; - } - - /** manages the actual (single) instance of the player service impl */ - scoped_ptr thePlayer_; - - - void - triggerShutdown () throw() - { - TODO ("implement waiting for any playback processes to terminate gracefully"); - //..... but this would require us to use a separate thread, so I skip it for now. - // Probably it's better design to manage the processes in a separate thread anyway... - - thePlayer_.reset(0); - } - - bool - checkRunningState () throw() - { - //note: not locking here... - return (thePlayer_); - } - }; - - lumiera::Singleton theDescriptor; - - - - - - /* ================== define an lumieraorg_GuiNotification instance ======================= */ - - LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0 - ,lumieraorg_DummyPlayerFacade_descriptor - , NULL, NULL, NULL - , LUMIERA_INTERFACE_INLINE (name, "\305\162\202\240\075\316\146\100\314\152\075\343\372\065\226\307", - const char*, (LumieraInterface ifa), - { (void)ifa; return "DummyPlayer"; } - ) - , LUMIERA_INTERFACE_INLINE (brief, "\317\045\366\076\064\072\156\274\220\346\262\207\062\367\057\232", - const char*, (LumieraInterface ifa), - { (void)ifa; return "Proc Interface: dummy player to test integration with the GUI"; } - ) - , LUMIERA_INTERFACE_INLINE (homepage, "\136\225\033\362\161\251\300\256\117\072\171\102\235\004\235\200", - const char*, (LumieraInterface ifa), - { (void)ifa; return "http://www.lumiera.org/develompent.html" ;} - ) - , LUMIERA_INTERFACE_INLINE (version, "\212\146\344\127\124\116\101\205\211\174\322\241\162\122\023\165", - const char*, (LumieraInterface ifa), - { (void)ifa; return "0.1~pre"; } - ) - , LUMIERA_INTERFACE_INLINE (author, "\064\226\072\300\054\345\042\357\337\226\155\025\306\051\117\105", - const char*, (LumieraInterface ifa), - { (void)ifa; return "Hermann Vosseler"; } - ) - , LUMIERA_INTERFACE_INLINE (email, "\041\075\220\112\246\304\261\135\003\135\060\202\230\327\303\206", - const char*, (LumieraInterface ifa), - { (void)ifa; return "Ichthyostega@web.de"; } - ) - , LUMIERA_INTERFACE_INLINE (copyright, "\232\305\163\271\174\025\270\075\012\201\331\256\327\375\066\210", - const char*, (LumieraInterface ifa), - { - (void)ifa; - return - "Copyright (C) Lumiera.org\n" - " 2009 Hermann Vosseler "; - } - ) - , LUMIERA_INTERFACE_INLINE (license, "\136\136\073\173\145\357\151\062\040\013\323\272\051\352\305\060", - const char*, (LumieraInterface ifa), - { - (void)ifa; - return - "This program is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n" - "\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n" - "\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program; if not, write to the Free Software\n" - "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"; - } - ) - , LUMIERA_INTERFACE_INLINE (state, "\224\251\004\001\165\140\116\246\126\311\115\234\023\026\331\350", - int, (LumieraInterface ifa), - {(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; } - ) - , LUMIERA_INTERFACE_INLINE (versioncmp, "\267\155\303\046\353\222\323\014\145\027\043\100\370\311\257\126", - int, (const char* a, const char* b), - {return 0;} ////////////////////////////////////////////TODO define version ordering - ) - ); - - - - - - using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE; - typedef lib::SingletonRef::Accessor InstanceRef; - - InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual DummyPlayer implementation... - - typedef DummyPlayer::Process* ProcP; - - - LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0 - ,lumieraorg_DummyPlayerFacade - , LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor) - , NULL /* on open */ - , NULL /* on close */ - , LUMIERA_INTERFACE_INLINE (startPlay, "\143\323\102\155\051\006\235\004\037\310\354\121\176\142\342\210", - LumieraPlayProcess, (void), - { - if (!_instance) - { - lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); - return 0; - } - - return static_cast (& (_instance->start())); - } - ) - , LUMIERA_INTERFACE_INLINE (pausePlay, "\275\157\316\220\210\053\226\134\057\016\273\265\240\053\112\307", - void, (LumieraPlayProcess handle, bool doPlay), - { - if (!_instance) - { - lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); - return; - } - - REQUIRE (handle); - ProcP proc = static_cast (handle); - - proc->pause(doPlay); - } - ) - , LUMIERA_INTERFACE_INLINE (terminate, "\005\265\115\021\076\143\010\215\373\252\370\174\235\136\340\004", - void, (LumieraPlayProcess handle), - { - if (!_instance) - { - lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); - return; - } - - REQUIRE (handle); - ProcP proc = static_cast (handle); - - UNIMPLEMENTED ("terminate a running playback process"); - } - ) - , LUMIERA_INTERFACE_INLINE (getFrame, "\230\130\101\300\047\065\170\052\226\164\026\112\150\166\074\134", - void *, (LumieraPlayProcess handle), - { - //skipping full checks for performance reasons - REQUIRE (_instance && !lumiera_error_peek()); - - REQUIRE (handle); - ProcP proc = static_cast (handle); - - return const_cast (proc->getFrame()); - } - ) - ); - - - - - } // (End) hidden service impl details - - - - - DummyPlayerService::DummyPlayerService (Subsys::SigTerm terminationHandle) - : error_("") - , notifyTermination_(terminationHandle) - , implInstance_(this,_instance) - , serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerFacade)) - { - INFO (operate, "DummyPlayer Facade opened."); - } - - - - - /** @internal intended for use by main(). */ - Subsys& - DummyPlayer::getDescriptor() - { - return theDescriptor(); - } - - // emit the vtable here into this translation unit within liblumieraproc.so ... - DummyPlayer::~DummyPlayer() { } - DummyPlayer::Process::~Process() { } - - - - DummyPlayer::Process& - DummyPlayerService::start() - { - REQUIRE (!theProcess_.isActive()); - theProcess_.setRate(25); - - return theProcess_; - } - - - - void - ProcessImpl::setRate (uint fps) - { - REQUIRE (fps==0 || fps_==0 ); - REQUIRE (fps==0 || !play_ ); - - fps_ = fps; - play_ = (fps != 0); - } - - - - void - ProcessImpl::pause(bool doPlay) - { - REQUIRE (isActive()); - play_ = doPlay; - } - - - - void* const - ProcessImpl::getFrame() - { - REQUIRE (isActive()); - - UNIMPLEMENTED ("actually deliver a frame"); - } - - -} // namespace proc diff --git a/src/proc/dummy-player-service.hpp b/src/proc/dummy-player-service.hpp deleted file mode 100644 index f007e5cf4..000000000 --- a/src/proc/dummy-player-service.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - DUMMY-PLAYER-SERVICE.hpp - service implementing a dummy test player - - - Copyright (C) Lumiera.org - 2009, Hermann Vosseler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file notification-service.hpp - ** A public service provided by the GUI, implementing the gui::GuiNotification facade interface. - ** The purpose of this service is to push state update and notification of events from the lower - ** layers into the Lumiera GUI. Typically, this happens asynchronously and triggered by events - ** within the lower layers. - ** - ** This service is the implementation of a layer separation facade interface. Clients should use - ** gui::GuiNotification#facade to access this service. This header defines the interface used - ** to \em provide this service, not to access it. - ** - ** @see gui::GuiFacade - ** @see guifacade.cpp starting this service - */ - - -#ifndef PROC_DUMMYPLAYER_SERVICE_H -#define PROC_DUMMYPLAYER_SERVICE_H - - -#include "include/dummy-player-facade.h" -#include "common/instancehandle.hpp" -#include "lib/singleton-ref.hpp" - -#include - - -namespace proc { - - using std::string; - using lumiera::Subsys; - - - class ProcessImpl - : public DummyPlayer::Process - { - void pause(bool doPlay); - void* const getFrame(); - - uint fps_; - bool play_; - - public: - ProcessImpl() : fps_(0), play_(false) {} - - /* Implementation-level API to be used By DummyPlayerService */ - - /** activate a playback process - * with given specification */ - void setRate (uint fps); - - bool isActive () { return fps_ != 0; } - bool isPlaying() { return play_; } - }; - - - /****************************************************** - * Actual implementation of the GuiNotification service - * within the Lumiera GTK GUI. Creating an instance of - * this class automatically registers the interface - * with the Lumiera Interface/Plugin system and creates - * a forwarding proxy within the application core to - * route calls through this interface. - * - * @todo the ctor of this class should take references - * to any internal service providers within the - * GUI which are needed to implement the service. - */ - class DummyPlayerService - : public DummyPlayer - { - - /* === Implementation of the Facade Interface === */ - - Process& start(); - - - /** for now we use an single inline Process... - * @todo actually implement multiple independent Playback processes! - * @todo I am aware holding this object inline may cause a segfault at shutdown! - */ - ProcessImpl theProcess_; - - string error_; - Subsys::SigTerm notifyTermination_; - - - - /* === Interface Lifecycle === */ - - typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0) - , DummyPlayer - > ServiceInstanceHandle; - - lib::SingletonRef implInstance_; - ServiceInstanceHandle serviceInstance_; - - public: - DummyPlayerService(Subsys::SigTerm terminationHandle); - - ~DummyPlayerService() { notifyTermination_(&error_); } - - }; - - - -} // namespace proc -#endif diff --git a/src/proc/play/dummy-image-generator.cpp b/src/proc/play/dummy-image-generator.cpp new file mode 100644 index 000000000..ba1cef9c5 --- /dev/null +++ b/src/proc/play/dummy-image-generator.cpp @@ -0,0 +1,163 @@ +/* + DummyImageGenerator - creating test output frames for simulated playback + + Copyright (C) Lumiera.org + 2009, Joel Holdsworth , + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/play/dummy-image-generator.hpp" + + +namespace proc { + namespace play { + + + + namespace { // implementation details + + + typedef unsigned char byte; + + inline int + clamp (const int &val, const int &maxval, const int &minval) + { + if(val > maxval) return maxval; + if(val < minval) return minval; + return val; + } + + inline void + rgb_to_yuv (int r, int g, int b, byte &y, byte &u, byte &v) + { + // This code isn't great, but it does the job + y = (byte)clamp((299 * r + 587 * g + 114 * b) / 1000, 235, 16); + v = (byte)clamp((500 * r - 419 * g - 81 * b) / 1000 + 127, 255, 0); + u = (byte)clamp((-169 * r - 331 * g + 500 * b) / 1000 + 127, 255, 0); + } + + + void + rgb_buffer_to_yuy2 (unsigned char *in, unsigned char *out) + { + for (uint i = 0; i < 320*240*2; i+=4) + { + byte y0, u0, v0; + const byte r0 = *(in++); + const byte g0 = *(in++); + const byte b0 = *(in++); + rgb_to_yuv(r0, g0, b0, y0, u0, v0); + + byte y1, u1, v1; + const byte r1 = *(in++); + const byte g1 = *(in++); + const byte b1 = *(in++); + rgb_to_yuv(r1, g1, b1, y1, u1, v1); + + out[i] = y0; + out[i + 1] = u0; + out[i + 2] = y1; + out[i + 3] = v0; + } } + + + } // (End) implementation details + + + + + DummyImageGenerator::DummyImageGenerator(uint fps) + : current_(0) + , frame_(0) + , fps_(fps) + { } + + + void * const + DummyImageGenerator::next() + { + + ++frame_; + if(frame_ > 2 * fps_) + frame_ = 0; + + if(frame_ < 1 * fps_) + { + // create random snow... + for(int i = 0; i < 320*240*3; i+=3) + { + byte value ( rand() ); + buf_[i] = value; + buf_[i+1] = value; + buf_[i+2] = value; + } + } + else + { // create a colour strip pattern + typedef unsigned char Row[320 * 3]; + + unsigned char * row = buf_; + + // create a colour strip pattern in the first row... + for(int x = 0; x < 320; ++x) + { + byte &r = row[x*3]; + byte &g = row[x*3+1]; + byte &b = row[x*3+2]; + + if (x < 1*320/7) r = 0xC0, g = 0xC0, b = 0xC0; + else if(x < 2*320/7) r = 0xC0, g = 0xC0, b = 0x00; + else if(x < 3*320/7) r = 0x00, g = 0xC0, b = 0xC0; + else if(x < 4*320/7) r = 0x00, g = 0xC0, b = 0x00; + else if(x < 5*320/7) r = 0xC0, g = 0x00, b = 0xC0; + else if(x < 6*320/7) r = 0xC0, g = 0x00, b = 0x00; + else r = 0x00, g = 0x00, b = 0xC0; + } + + // fill remaining rows of the frame with the same pattern + for(int y = 1; y < 240; ++y) + memcpy(buf_ + y*sizeof(Row), row, sizeof(Row)); + + } + + // select output buffer to return + unsigned char * outBuff; + + if (!current_) + { + outBuff = outFrame_A_; + current_= 1; + } + else + { + outBuff = outFrame_B_; + current_= 0; + } + + rgb_buffer_to_yuy2(buf_, outBuff); + return outBuff; + + } + + + + + } // namespace play + +} // namespace proc diff --git a/src/proc/play/dummy-image-generator.hpp b/src/proc/play/dummy-image-generator.hpp new file mode 100644 index 000000000..0cab60404 --- /dev/null +++ b/src/proc/play/dummy-image-generator.hpp @@ -0,0 +1,85 @@ +/* + DUMMY-IMAGE-GENERATOR.hpp - creating test output frames for simulated playback + + Copyright (C) Lumiera.org + 2009, Joel Holdsworth , + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file dummy-image-generator.hpp + ** Generator for test dummy video frames to simulate playback of rendered output. + ** As of 1/2009 the render engine and source reading functions are not ready yet. + ** So, in order to learn how to build up the GUI/Playback interfaces, we use + ** this dummy image generator to create visible output. First implemented + ** by Joel within PlaybackController, then factored out into a separate + ** dummy playback service. + ** + ** @see gui::controller::PlaybackController + ** @see proc::play::DummyPlayerService + ** + */ + + +#ifndef PROC_PLAY_DUMMY_IMAGE_GENERATOR_H +#define PROC_PLAY_DUMMY_IMAGE_GENERATOR_H + + +#include "lib/error.hpp" + + +namespace proc { + namespace play { + + + class DummyImageGenerator + { + + unsigned char buf_[320 * 240 * 3]; ///< working buffer for next frame + + unsigned char outFrame_A_[320 * 240 * 4]; ///< output frame 1 + unsigned char outFrame_B_[320 * 240 * 4]; ///< output frame 2 + + uint current_; + uint frame_; + uint fps_; + + + public: + DummyImageGenerator(uint fps); + + ~DummyImageGenerator() { } + + /** generate the next frame and + * occupy the alternate buffer. + * @return the buffer containing the new frame + */ + void * const next(); + + + private: + + }; + + + + + } // namespace play + +} // namespace proc +#endif // PROC_PLAY_DUMMY_IMAGE_GENERATOR_H + diff --git a/src/proc/play/dummy-player-service.cpp b/src/proc/play/dummy-player-service.cpp new file mode 100644 index 000000000..2d86a07c5 --- /dev/null +++ b/src/proc/play/dummy-player-service.cpp @@ -0,0 +1,317 @@ +/* + DummyPlayerService - access point and service implementing a dummy test player + + Copyright (C) Lumiera.org + 2009, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/play/dummy-player-service.hpp" +#include "lib/singleton.hpp" + +extern "C" { +#include "common/interfacedescriptor.h" +} + +#include +#include + + +namespace proc { + namespace play{ + + using std::string; + using lumiera::Subsys; + using boost::scoped_ptr; + + + namespace { // hidden local details of the service implementation.... + + /** details of how the DummyPlayer service can be started + * and used as independent "subsystem" within main() */ + class DummyPlayerSubsysDescriptor + : public Subsys + { + operator string () const { return "Dummy-Player"; } + + + bool + shouldStart (lumiera::Option&) + { + return false; // for now the DummyPlayerService only comes "up" as dependency, + } // but doesn't start as a subsystem on it's own. + + bool + start (lumiera::Option&, Subsys::SigTerm terminationHandle) + { + ASSERT (!thePlayer_); + + thePlayer_.reset (new DummyPlayerService (terminationHandle)); + return true; + } + + /** manages the actual (single) instance of the player service impl */ + scoped_ptr thePlayer_; + + + void + triggerShutdown () throw() + { + TODO ("implement waiting for any playback processes to terminate gracefully"); + //..... but this would require us to use a separate thread, so I skip it for now. + // Probably it's better design to manage the processes in a separate thread anyway... + + thePlayer_.reset(0); + } + + bool + checkRunningState () throw() + { + //note: not locking here... + return (thePlayer_); + } + }; + + lumiera::Singleton theDescriptor; + + + + + + /* ================== define an lumieraorg_GuiNotification instance ======================= */ + + LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0 + ,lumieraorg_DummyPlayerFacade_descriptor + , NULL, NULL, NULL + , LUMIERA_INTERFACE_INLINE (name, "\305\162\202\240\075\316\146\100\314\152\075\343\372\065\226\307", + const char*, (LumieraInterface ifa), + { (void)ifa; return "DummyPlayer"; } + ) + , LUMIERA_INTERFACE_INLINE (brief, "\317\045\366\076\064\072\156\274\220\346\262\207\062\367\057\232", + const char*, (LumieraInterface ifa), + { (void)ifa; return "Proc Interface: dummy player to test integration with the GUI"; } + ) + , LUMIERA_INTERFACE_INLINE (homepage, "\136\225\033\362\161\251\300\256\117\072\171\102\235\004\235\200", + const char*, (LumieraInterface ifa), + { (void)ifa; return "http://www.lumiera.org/develompent.html" ;} + ) + , LUMIERA_INTERFACE_INLINE (version, "\212\146\344\127\124\116\101\205\211\174\322\241\162\122\023\165", + const char*, (LumieraInterface ifa), + { (void)ifa; return "0.1~pre"; } + ) + , LUMIERA_INTERFACE_INLINE (author, "\064\226\072\300\054\345\042\357\337\226\155\025\306\051\117\105", + const char*, (LumieraInterface ifa), + { (void)ifa; return "Hermann Vosseler"; } + ) + , LUMIERA_INTERFACE_INLINE (email, "\041\075\220\112\246\304\261\135\003\135\060\202\230\327\303\206", + const char*, (LumieraInterface ifa), + { (void)ifa; return "Ichthyostega@web.de"; } + ) + , LUMIERA_INTERFACE_INLINE (copyright, "\232\305\163\271\174\025\270\075\012\201\331\256\327\375\066\210", + const char*, (LumieraInterface ifa), + { + (void)ifa; + return + "Copyright (C) Lumiera.org\n" + " 2009 Hermann Vosseler "; + } + ) + , LUMIERA_INTERFACE_INLINE (license, "\136\136\073\173\145\357\151\062\040\013\323\272\051\352\305\060", + const char*, (LumieraInterface ifa), + { + (void)ifa; + return + "This program is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 2 of the License, or\n" + "(at your option) any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program; if not, write to the Free Software\n" + "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"; + } + ) + , LUMIERA_INTERFACE_INLINE (state, "\224\251\004\001\165\140\116\246\126\311\115\234\023\026\331\350", + int, (LumieraInterface ifa), + {(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; } + ) + , LUMIERA_INTERFACE_INLINE (versioncmp, "\267\155\303\046\353\222\323\014\145\027\043\100\370\311\257\126", + int, (const char* a, const char* b), + {return 0;} ////////////////////////////////////////////TODO define version ordering + ) + ); + + + + + + using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE; + typedef lib::SingletonRef::Accessor InstanceRef; + + InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual DummyPlayer implementation... + + typedef DummyPlayer::Process* ProcP; + + + LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0 + ,lumieraorg_DummyPlayerFacade + , LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor) + , NULL /* on open */ + , NULL /* on close */ + , LUMIERA_INTERFACE_INLINE (startPlay, "\143\323\102\155\051\006\235\004\037\310\354\121\176\142\342\210", + LumieraPlayProcess, (void), + { + if (!_instance) + { + lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); + return 0; + } + + return static_cast (& (_instance->start())); + } + ) + , LUMIERA_INTERFACE_INLINE (pausePlay, "\275\157\316\220\210\053\226\134\057\016\273\265\240\053\112\307", + void, (LumieraPlayProcess handle, bool doPlay), + { + if (!_instance) + { + lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); + return; + } + + REQUIRE (handle); + ProcP proc = static_cast (handle); + + proc->pause(doPlay); + } + ) + , LUMIERA_INTERFACE_INLINE (terminate, "\005\265\115\021\076\143\010\215\373\252\370\174\235\136\340\004", + void, (LumieraPlayProcess handle), + { + if (!_instance) + { + lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0); + return; + } + + REQUIRE (handle); + ProcP proc = static_cast (handle); + + UNIMPLEMENTED ("terminate a running playback process"); + } + ) + , LUMIERA_INTERFACE_INLINE (getFrame, "\230\130\101\300\047\065\170\052\226\164\026\112\150\166\074\134", + void *, (LumieraPlayProcess handle), + { + //skipping full checks for performance reasons + REQUIRE (_instance && !lumiera_error_peek()); + + REQUIRE (handle); + ProcP proc = static_cast (handle); + + return const_cast (proc->getFrame()); + } + ) + ); + + + + + } // (End) hidden service impl details + + + + + DummyPlayerService::DummyPlayerService (Subsys::SigTerm terminationHandle) + : error_("") + , notifyTermination_(terminationHandle) + , implInstance_(this,_instance) + , serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerFacade)) + { + INFO (operate, "DummyPlayer Facade opened."); + } + + + + + DummyPlayer::Process& + DummyPlayerService::start() + { + REQUIRE (!theProcess_.isActive()); + theProcess_.setRate(25); + + return theProcess_; + } + + + + void + ProcessImpl::setRate (uint fps) + { + REQUIRE (fps==0 || fps_==0 ); + REQUIRE (fps==0 || !play_ ); + + fps_ = fps; + play_ = (fps != 0); + } + + + + void + ProcessImpl::pause(bool doPlay) + { + REQUIRE (isActive()); + play_ = doPlay; + } + + + + void* const + ProcessImpl::getFrame() + { + REQUIRE (isActive()); + + UNIMPLEMENTED ("actually deliver a frame"); + } + + + + } // namespace play + + + + /** @internal intended for use by main(). */ + lumiera::Subsys& + DummyPlayer::getDescriptor() + { + return play::theDescriptor(); + } + + // emit the vtable here into this translation unit within liblumieraproc.so ... + DummyPlayer::~DummyPlayer() { } + DummyPlayer::Process::~Process() { } + + + + +} // namespace proc diff --git a/src/proc/play/dummy-player-service.hpp b/src/proc/play/dummy-player-service.hpp new file mode 100644 index 000000000..1d7c9f9aa --- /dev/null +++ b/src/proc/play/dummy-player-service.hpp @@ -0,0 +1,133 @@ +/* + DUMMY-PLAYER-SERVICE.hpp - service implementing a dummy test player + + Copyright (C) Lumiera.org + 2009, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file notification-service.hpp + ** A public service provided by the GUI, implementing the gui::GuiNotification facade interface. + ** The purpose of this service is to push state update and notification of events from the lower + ** layers into the Lumiera GUI. Typically, this happens asynchronously and triggered by events + ** within the lower layers. + ** + ** This service is the implementation of a layer separation facade interface. Clients should use + ** gui::GuiNotification#facade to access this service. This header defines the interface used + ** to \em provide this service, not to access it. + ** + ** @see gui::GuiFacade + ** @see guifacade.cpp starting this service + */ + + +#ifndef PROC_DUMMYPLAYER_SERVICE_H +#define PROC_DUMMYPLAYER_SERVICE_H + + +#include "include/dummy-player-facade.h" +#include "common/instancehandle.hpp" +#include "lib/singleton-ref.hpp" + +#include + + +namespace proc { + namespace play { + + using std::string; + using lumiera::Subsys; + + + class ProcessImpl + : public DummyPlayer::Process + { + void pause(bool doPlay); + void* const getFrame(); + + uint fps_; + bool play_; + + public: + ProcessImpl() : fps_(0), play_(false) {} + + /* Implementation-level API to be used By DummyPlayerService */ + + /** activate a playback process + * with given specification */ + void setRate (uint fps); + + bool isActive () { return fps_ != 0; } + bool isPlaying() { return play_; } + }; + + + /****************************************************** + * Actual implementation of the GuiNotification service + * within the Lumiera GTK GUI. Creating an instance of + * this class automatically registers the interface + * with the Lumiera Interface/Plugin system and creates + * a forwarding proxy within the application core to + * route calls through this interface. + * + * @todo the ctor of this class should take references + * to any internal service providers within the + * GUI which are needed to implement the service. + */ + class DummyPlayerService + : public DummyPlayer + { + + /* === Implementation of the Facade Interface === */ + + Process& start(); + + + /** for now we use an single inline Process... + * @todo actually implement multiple independent Playback processes! + * @todo I am aware holding this object inline may cause a segfault at shutdown! + */ + ProcessImpl theProcess_; + + string error_; + Subsys::SigTerm notifyTermination_; + + + + /* === Interface Lifecycle === */ + + typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0) + , DummyPlayer + > ServiceInstanceHandle; + + lib::SingletonRef implInstance_; + ServiceInstanceHandle serviceInstance_; + + public: + DummyPlayerService(Subsys::SigTerm terminationHandle); + + ~DummyPlayerService() { notifyTermination_(&error_); } + + }; + + + + + } // namespace play + +} // namespace proc +#endif