Refactoring: switch gui::PlaybackController to use the player service
This commit is contained in:
parent
791b09142a
commit
6c3492396c
7 changed files with 82 additions and 103 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -20,32 +20,46 @@
|
|||
|
||||
* *****************************************************/
|
||||
|
||||
#include "playback-controller.hpp"
|
||||
#include "../gtk-lumiera.hpp"
|
||||
#include "gui/controller/playback-controller.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include <nobug.h>
|
||||
|
||||
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<unsigned char*> (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
|
||||
|
|
|
|||
|
|
@ -23,16 +23,20 @@
|
|||
** This file contains the definition of the playback controller object
|
||||
*/
|
||||
|
||||
#include <sigc++/sigc++.h>
|
||||
#include <glibmm.h>
|
||||
|
||||
#ifndef PLAYBACK_CONTROLLER_HPP
|
||||
#define PLAYBACK_CONTROLLER_HPP
|
||||
|
||||
#include "include/dummy-player-facade.h"
|
||||
|
||||
#include <sigc++/sigc++.h>
|
||||
#include <glibmm.h>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
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<void, void*> frame_signal;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -154,7 +154,14 @@ namespace proc {
|
|||
return outBuff;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void * const
|
||||
DummyImageGenerator::current()
|
||||
{
|
||||
if (!current_) return outFrame_A_;
|
||||
else return outFrame_B_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "common/instancehandle.hpp"
|
||||
#include "lib/singleton-ref.hpp"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
|
@ -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<DummyImageGenerator> imageGen_;
|
||||
|
||||
|
||||
public:
|
||||
ProcessImpl() : fps_(0), play_(false) {}
|
||||
ProcessImpl() : fps_(0), play_(false), imageGen_(0) {}
|
||||
|
||||
/* Implementation-level API to be used By DummyPlayerService */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue