From 6c3492396c6d32b28b5f63d94d89c392503e052f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 23 Jan 2009 04:15:58 +0100 Subject: [PATCH] Refactoring: switch gui::PlaybackController to use the player service --- src/gui/controller/controller.hpp | 5 +- src/gui/controller/playback-controller.cpp | 132 ++++++--------------- src/gui/controller/playback-controller.hpp | 14 ++- src/proc/play/dummy-image-generator.cpp | 9 +- src/proc/play/dummy-image-generator.hpp | 4 + src/proc/play/dummy-player-service.cpp | 10 +- src/proc/play/dummy-player-service.hpp | 11 +- 7 files changed, 82 insertions(+), 103 deletions(-) diff --git a/src/gui/controller/controller.hpp b/src/gui/controller/controller.hpp index 27f185e97..594f5e19e 100644 --- a/src/gui/controller/controller.hpp +++ b/src/gui/controller/controller.hpp @@ -23,11 +23,12 @@ ** This file contains the definition of the controller object */ -#include "playback-controller.hpp" - #ifndef CONTROLLER_HPP #define CONTROLLER_HPP +#include "playback-controller.hpp" + + namespace gui { namespace model { diff --git a/src/gui/controller/playback-controller.cpp b/src/gui/controller/playback-controller.cpp index d68373025..90b3ec29d 100644 --- a/src/gui/controller/playback-controller.cpp +++ b/src/gui/controller/playback-controller.cpp @@ -20,32 +20,46 @@ * *****************************************************/ -#include "playback-controller.hpp" -#include "../gtk-lumiera.hpp" +#include "gui/controller/playback-controller.hpp" +#include "lib/error.hpp" +#include namespace gui { namespace controller { PlaybackController::PlaybackController() : finish_playback_thread(false), - playing(false) -{ - start_playback_thread(); -} + playing(false), + playHandle(0) +{ } + PlaybackController::~PlaybackController() { mutex.lock(); finish_playback_thread = true; mutex.unlock(); - thread->join(); + if (thread) + thread->join(); } void PlaybackController::play() { Glib::Mutex::Lock lock(mutex); - playing = true; + try + { + playHandle = & (proc::DummyPlayer::facade().start()); + start_playback_thread(); + playing = true; + + } + catch (lumiera::error::State& err) + { + WARN (operate, "failed to start playback: %s" ,err.what()); + lumiera_error(); + playing = false; + } } void @@ -53,6 +67,8 @@ PlaybackController::pause() { Glib::Mutex::Lock lock(mutex); playing = false; + if (playHandle) + playHandle->pause(true); } void @@ -60,6 +76,7 @@ PlaybackController::stop() { Glib::Mutex::Lock lock(mutex); playing = false; + // TODO: stop player somehow? } bool @@ -97,108 +114,37 @@ PlaybackController::playback_thread() if(is_playing()) pull_frame(); - + + ////////////////////////////////TODO: usleep Glib::Thread::yield(); } } -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(int 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; - } -} void PlaybackController::pull_frame() { - static int frame = 0; - unsigned char in[320 * 240 * 3]; + REQUIRE (is_playing()); + REQUIRE (playHandle); - frame--; + unsigned char * newBuffer = reinterpret_cast (playHandle->getFrame()); - if(frame <= 0) - frame = 200; - - if(frame > 150) - { - for(int i = 0; i < 320*240*3; i+=3) - { - byte value = (byte)rand(); - in[i] = value; - in[i+1] = value; - in[i+2] = value; - } - } - else - { - unsigned char row[320 * 3]; - - 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; - } - - for(int y = 0; y < 240; y++) + if (newBuffer != currentBuffer) { - memcpy(in + y*320*3, row, sizeof(row)); + currentBuffer = newBuffer; + dispatcher.emit(); + } + else + { + TRACE (render, "frame dropped?"); } - } - - rgb_buffer_to_yuy2(in, buffer); - - dispatcher.emit(); } + void PlaybackController::on_frame() { - frame_signal.emit(buffer); + frame_signal.emit(currentBuffer); } } // namespace controller diff --git a/src/gui/controller/playback-controller.hpp b/src/gui/controller/playback-controller.hpp index 9333fcbc2..52a7d0b42 100644 --- a/src/gui/controller/playback-controller.hpp +++ b/src/gui/controller/playback-controller.hpp @@ -23,16 +23,20 @@ ** This file contains the definition of the playback controller object */ -#include -#include - #ifndef PLAYBACK_CONTROLLER_HPP #define PLAYBACK_CONTROLLER_HPP +#include "include/dummy-player-facade.h" + +#include +#include +#include + namespace gui { namespace controller { class PlaybackController + : boost::noncopyable { public: @@ -72,7 +76,9 @@ private: volatile bool playing; - unsigned char buffer[320 * 240 * 4]; + proc::DummyPlayer::Process *playHandle; + + unsigned char * currentBuffer; sigc::signal frame_signal; }; diff --git a/src/proc/play/dummy-image-generator.cpp b/src/proc/play/dummy-image-generator.cpp index ba1cef9c5..29d58a1ac 100644 --- a/src/proc/play/dummy-image-generator.cpp +++ b/src/proc/play/dummy-image-generator.cpp @@ -154,7 +154,14 @@ namespace proc { return outBuff; } - + + + void * const + DummyImageGenerator::current() + { + if (!current_) return outFrame_A_; + else return outFrame_B_; + } diff --git a/src/proc/play/dummy-image-generator.hpp b/src/proc/play/dummy-image-generator.hpp index 0cab60404..e24a4592e 100644 --- a/src/proc/play/dummy-image-generator.hpp +++ b/src/proc/play/dummy-image-generator.hpp @@ -69,6 +69,10 @@ namespace proc { * @return the buffer containing the new frame */ void * const next(); + + /** just re-return a pointer to the current frame + * without generating any new image data */ + void * const current(); private: diff --git a/src/proc/play/dummy-player-service.cpp b/src/proc/play/dummy-player-service.cpp index 2d86a07c5..378d7d7ff 100644 --- a/src/proc/play/dummy-player-service.cpp +++ b/src/proc/play/dummy-player-service.cpp @@ -22,6 +22,7 @@ #include "proc/play/dummy-player-service.hpp" +#include "proc/play/dummy-image-generator.hpp" #include "lib/singleton.hpp" extern "C" { @@ -273,6 +274,9 @@ namespace proc { fps_ = fps; play_ = (fps != 0); + + if (play_) + imageGen_.reset(new DummyImageGenerator(fps)); } @@ -290,8 +294,12 @@ namespace proc { ProcessImpl::getFrame() { REQUIRE (isActive()); + ASSERT (imageGen_); - UNIMPLEMENTED ("actually deliver a frame"); + if (play_) + return imageGen_->next(); + else + return imageGen_->current(); } diff --git a/src/proc/play/dummy-player-service.hpp b/src/proc/play/dummy-player-service.hpp index 1d7c9f9aa..8f7a045e6 100644 --- a/src/proc/play/dummy-player-service.hpp +++ b/src/proc/play/dummy-player-service.hpp @@ -43,6 +43,7 @@ #include "common/instancehandle.hpp" #include "lib/singleton-ref.hpp" +#include #include @@ -53,6 +54,9 @@ namespace proc { using lumiera::Subsys; + class DummyImageGenerator; + + class ProcessImpl : public DummyPlayer::Process { @@ -60,10 +64,13 @@ namespace proc { void* const getFrame(); uint fps_; - bool play_; + bool play_; + + boost::scoped_ptr imageGen_; + public: - ProcessImpl() : fps_(0), play_(false) {} + ProcessImpl() : fps_(0), play_(false), imageGen_(0) {} /* Implementation-level API to be used By DummyPlayerService */