mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Creation of the base class StreamSource. It is intended to become the
base class for all gstreamer pipeline. DeviceSource and PatternSource inherit from it. A generic stream source class is created for development tests and hack.
This commit is contained in:
@@ -238,6 +238,7 @@ set(VMIX_SRCS
|
||||
Stream.cpp
|
||||
MediaPlayer.cpp
|
||||
MediaSource.cpp
|
||||
StreamSource.cpp
|
||||
PatternSource.cpp
|
||||
DeviceSource.cpp
|
||||
FrameBuffer.cpp
|
||||
|
||||
124
DeviceSource.cpp
124
DeviceSource.cpp
@@ -27,7 +27,6 @@ void Device::open( uint device )
|
||||
{
|
||||
device_ = CLAMP(device, 0, 2);
|
||||
|
||||
single_frame_ = false;
|
||||
live_ = true;
|
||||
|
||||
// std::string desc = "v4l2src ! video/x-raw,width=320,height=240,framerate=30/1 ! videoconvert";
|
||||
@@ -38,133 +37,34 @@ void Device::open( uint device )
|
||||
std::string desc = "ximagesrc endx=640 endy=480 ! video/x-raw,framerate=5/1 ! videoconvert ! queue";
|
||||
|
||||
// (private) open stream
|
||||
open(desc);
|
||||
Stream::open(desc);
|
||||
}
|
||||
|
||||
void Device::open(std::string gstreamer_description)
|
||||
{
|
||||
// set gstreamer pipeline source
|
||||
description_ = gstreamer_description;
|
||||
|
||||
// close before re-openning
|
||||
if (isOpen())
|
||||
close();
|
||||
|
||||
execute_open();
|
||||
}
|
||||
|
||||
|
||||
DeviceSource::DeviceSource() : Source()
|
||||
DeviceSource::DeviceSource() : StreamSource()
|
||||
{
|
||||
// create stream
|
||||
stream_ = new Device();
|
||||
stream_ = (Stream *) new Device();
|
||||
|
||||
// create surface
|
||||
devicesurface_ = new Surface(renderingshader_);
|
||||
}
|
||||
|
||||
DeviceSource::~DeviceSource()
|
||||
{
|
||||
// delete media surface & stream
|
||||
delete devicesurface_;
|
||||
delete stream_;
|
||||
}
|
||||
|
||||
bool DeviceSource::failed() const
|
||||
{
|
||||
return stream_->failed();
|
||||
}
|
||||
|
||||
uint DeviceSource::texture() const
|
||||
{
|
||||
return stream_->texture();
|
||||
}
|
||||
|
||||
void DeviceSource::replaceRenderingShader()
|
||||
{
|
||||
devicesurface_->replaceShader(renderingshader_);
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
}
|
||||
|
||||
void DeviceSource::setDevice(int id)
|
||||
{
|
||||
Log::Notify("Openning device %d", id);
|
||||
|
||||
stream_->open(id);
|
||||
device()->open(id);
|
||||
stream_->play(true);
|
||||
}
|
||||
|
||||
|
||||
void DeviceSource::init()
|
||||
{
|
||||
if ( stream_->isOpen() ) {
|
||||
|
||||
// update video
|
||||
stream_->update();
|
||||
|
||||
// once the texture of media player is created
|
||||
if (stream_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// get the texture index from media player, apply it to the media surface
|
||||
devicesurface_->setTextureIndex( stream_->texture() );
|
||||
|
||||
// create Frame buffer matching size of media player
|
||||
float height = float(stream_->width()) / stream_->aspectRatio();
|
||||
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, true);
|
||||
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source Device linked to Stream %d.", stream_->description().c_str());
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
touch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DeviceSource::setActive (bool on)
|
||||
{
|
||||
bool was_active = active_;
|
||||
|
||||
Source::setActive(on);
|
||||
|
||||
// change status of media player (only if status changed)
|
||||
if ( active_ != was_active ) {
|
||||
stream_->enable(active_);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSource::update(float dt)
|
||||
{
|
||||
Source::update(dt);
|
||||
|
||||
// update stream
|
||||
stream_->update();
|
||||
}
|
||||
|
||||
void DeviceSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
devicesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSource::accept(Visitor& v)
|
||||
{
|
||||
Source::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
Device *DeviceSource::device() const
|
||||
{
|
||||
return dynamic_cast<Device *>(stream_);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef DEVICESOURCE_H
|
||||
#define DEVICESOURCE_H
|
||||
|
||||
#include "Stream.h"
|
||||
#include "Source.h"
|
||||
#include "StreamSource.h"
|
||||
|
||||
class Device : public Stream
|
||||
{
|
||||
@@ -14,35 +13,24 @@ public:
|
||||
glm::ivec2 resolution();
|
||||
|
||||
private:
|
||||
void open( std::string description ) override;
|
||||
uint device_;
|
||||
};
|
||||
|
||||
class DeviceSource : public Source
|
||||
class DeviceSource : public StreamSource
|
||||
{
|
||||
public:
|
||||
DeviceSource();
|
||||
~DeviceSource();
|
||||
|
||||
// implementation of source API
|
||||
void update (float dt) override;
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
// Source interface
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
// Pattern specific interface
|
||||
inline Device *device() const { return stream_; }
|
||||
// StreamSource interface
|
||||
Stream *stream() const override { return stream_; }
|
||||
|
||||
// specific interface
|
||||
Device *device() const;
|
||||
void setDevice(int id);
|
||||
|
||||
protected:
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
|
||||
Surface *devicesurface_;
|
||||
Device *stream_;
|
||||
};
|
||||
|
||||
#endif // DEVICESOURCE_H
|
||||
|
||||
13
Mixer.cpp
13
Mixer.cpp
@@ -24,6 +24,7 @@ using namespace tinyxml2;
|
||||
#include "MediaSource.h"
|
||||
#include "PatternSource.h"
|
||||
#include "DeviceSource.h"
|
||||
#include "StreamSource.h"
|
||||
|
||||
#include "Mixer.h"
|
||||
|
||||
@@ -266,6 +267,18 @@ Source * Mixer::createSourceRender()
|
||||
return s;
|
||||
}
|
||||
|
||||
Source * Mixer::createSourceStream(const std::string &gstreamerpipeline)
|
||||
{
|
||||
// ready to create a source
|
||||
GenericStreamSource *s = new GenericStreamSource;
|
||||
s->setDescription(gstreamerpipeline);
|
||||
|
||||
// propose a new name based on pattern name
|
||||
renameSource(s, gstreamerpipeline.substr(0,10));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
Source * Mixer::createSourcePattern(int pattern, glm::ivec2 res)
|
||||
{
|
||||
// ready to create a source
|
||||
|
||||
1
Mixer.h
1
Mixer.h
@@ -39,6 +39,7 @@ public:
|
||||
Source * createSourceFile (const std::string &path);
|
||||
Source * createSourceClone (const std::string &namesource = "");
|
||||
Source * createSourceRender ();
|
||||
Source * createSourceStream (const std::string &gstreamerpipeline);
|
||||
Source * createSourcePattern(int pattern, glm::ivec2 res);
|
||||
Source * createSourceDevice (int id);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "defines.h"
|
||||
#include "ImageShader.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "Resource.h"
|
||||
#include "Primitives.h"
|
||||
#include "Stream.h"
|
||||
@@ -118,7 +117,6 @@ void Pattern::open( uint pattern )
|
||||
std::ostringstream oss;
|
||||
oss << " kx2=" << (int)(aspectRatio() * 10.f) << " ky2=10 kt=4";
|
||||
gstreamer_pattern += oss.str(); // Zone plate
|
||||
single_frame_ = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -129,133 +127,129 @@ void Pattern::open( uint pattern )
|
||||
single_frame_ = type_ < 15;
|
||||
|
||||
// (private) open stream
|
||||
open(gstreamer_pattern);
|
||||
Stream::open(gstreamer_pattern);
|
||||
}
|
||||
|
||||
void Pattern::open(std::string gstreamer_pattern)
|
||||
{
|
||||
// set gstreamer pipeline source
|
||||
description_ = gstreamer_pattern;
|
||||
|
||||
// close before re-openning
|
||||
if (isOpen())
|
||||
close();
|
||||
|
||||
execute_open();
|
||||
}
|
||||
|
||||
|
||||
PatternSource::PatternSource(glm::ivec2 resolution) : Source()
|
||||
PatternSource::PatternSource(glm::ivec2 resolution) : StreamSource()
|
||||
{
|
||||
// create stream
|
||||
stream_ = new Pattern(resolution);
|
||||
stream_ = (Stream *) new Pattern(resolution);
|
||||
|
||||
// create surface
|
||||
patternsurface_ = new Surface(renderingshader_);
|
||||
}
|
||||
// // create surface
|
||||
// surface_ = new Surface(renderingshader_);
|
||||
|
||||
PatternSource::~PatternSource()
|
||||
{
|
||||
// delete media surface & stream
|
||||
delete patternsurface_;
|
||||
delete stream_;
|
||||
}
|
||||
|
||||
bool PatternSource::failed() const
|
||||
{
|
||||
return stream_->failed();
|
||||
}
|
||||
|
||||
uint PatternSource::texture() const
|
||||
{
|
||||
return stream_->texture();
|
||||
}
|
||||
|
||||
void PatternSource::replaceRenderingShader()
|
||||
{
|
||||
patternsurface_->replaceShader(renderingshader_);
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
}
|
||||
|
||||
void PatternSource::setPattern(int id)
|
||||
{
|
||||
Log::Notify("Creating pattern %s", Pattern::pattern_types[id].c_str());
|
||||
|
||||
stream_->open(id);
|
||||
pattern()->open( (uint) id );
|
||||
stream_->play(true);
|
||||
}
|
||||
|
||||
|
||||
void PatternSource::init()
|
||||
{
|
||||
if ( stream_->isOpen() ) {
|
||||
|
||||
// update video
|
||||
stream_->update();
|
||||
|
||||
// once the texture of media player is created
|
||||
if (stream_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// get the texture index from media player, apply it to the media surface
|
||||
patternsurface_->setTextureIndex( stream_->texture() );
|
||||
|
||||
// create Frame buffer matching size of media player
|
||||
float height = float(stream_->width()) / stream_->aspectRatio();
|
||||
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, true);
|
||||
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source Pattern linked to Stream %d.", stream_->description().c_str());
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
touch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PatternSource::setActive (bool on)
|
||||
{
|
||||
bool was_active = active_;
|
||||
|
||||
Source::setActive(on);
|
||||
|
||||
// change status of media player (only if status changed)
|
||||
if ( active_ != was_active ) {
|
||||
stream_->enable(active_);
|
||||
}
|
||||
}
|
||||
|
||||
void PatternSource::update(float dt)
|
||||
{
|
||||
Source::update(dt);
|
||||
|
||||
// update stream
|
||||
stream_->update();
|
||||
}
|
||||
|
||||
void PatternSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
patternsurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
void PatternSource::accept(Visitor& v)
|
||||
{
|
||||
Source::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
Pattern *PatternSource::pattern() const
|
||||
{
|
||||
return dynamic_cast<Pattern *>(stream_);
|
||||
}
|
||||
|
||||
|
||||
//PatternSource::~PatternSource()
|
||||
//{
|
||||
// // delete media surface & stream
|
||||
// delete patternsurface_;
|
||||
// delete stream_;
|
||||
//}
|
||||
|
||||
//bool PatternSource::failed() const
|
||||
//{
|
||||
// return stream_->failed();
|
||||
//}
|
||||
|
||||
//uint PatternSource::texture() const
|
||||
//{
|
||||
// return stream_->texture();
|
||||
//}
|
||||
|
||||
//void PatternSource::replaceRenderingShader()
|
||||
//{
|
||||
// patternsurface_->replaceShader(renderingshader_);
|
||||
//}
|
||||
|
||||
|
||||
//void PatternSource::init()
|
||||
//{
|
||||
// if ( stream_->isOpen() ) {
|
||||
|
||||
// // update video
|
||||
// stream_->update();
|
||||
|
||||
// // once the texture of media player is created
|
||||
// if (stream_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// // get the texture index from media player, apply it to the media surface
|
||||
// patternsurface_->setTextureIndex( stream_->texture() );
|
||||
|
||||
// // create Frame buffer matching size of media player
|
||||
// float height = float(stream_->width()) / stream_->aspectRatio();
|
||||
// FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, true);
|
||||
|
||||
// // set the renderbuffer of the source and attach rendering nodes
|
||||
// attach(renderbuffer);
|
||||
|
||||
// // icon in mixing view
|
||||
// overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
// overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
|
||||
// // done init
|
||||
// initialized_ = true;
|
||||
// Log::Info("Source Pattern linked to Stream %d.", stream_->description().c_str());
|
||||
|
||||
// // force update of activation mode
|
||||
// active_ = true;
|
||||
// touch();
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//void PatternSource::setActive (bool on)
|
||||
//{
|
||||
// bool was_active = active_;
|
||||
|
||||
// Source::setActive(on);
|
||||
|
||||
// // change status of media player (only if status changed)
|
||||
// if ( active_ != was_active ) {
|
||||
// stream_->enable(active_);
|
||||
// }
|
||||
//}
|
||||
|
||||
//void PatternSource::update(float dt)
|
||||
//{
|
||||
// Source::update(dt);
|
||||
|
||||
// // update stream
|
||||
// stream_->update();
|
||||
//}
|
||||
|
||||
//void PatternSource::render()
|
||||
//{
|
||||
// if (!initialized_)
|
||||
// init();
|
||||
// else {
|
||||
// // render the media player into frame buffer
|
||||
// static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
// renderbuffer_->begin();
|
||||
// patternsurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
// renderbuffer_->end();
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Stream.h"
|
||||
#include "Source.h"
|
||||
#include "StreamSource.h"
|
||||
|
||||
class Pattern : public Stream
|
||||
{
|
||||
@@ -18,36 +17,24 @@ public:
|
||||
inline uint type() const { return type_; }
|
||||
|
||||
private:
|
||||
void open( std::string description ) override;
|
||||
uint type_;
|
||||
};
|
||||
|
||||
class PatternSource : public Source
|
||||
class PatternSource : public StreamSource
|
||||
{
|
||||
public:
|
||||
PatternSource(glm::ivec2 resolution);
|
||||
~PatternSource();
|
||||
|
||||
// implementation of source API
|
||||
void update (float dt) override;
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
// Source interface
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
// Pattern specific interface
|
||||
inline Pattern *pattern() const { return stream_; }
|
||||
// StreamSource interface
|
||||
Stream *stream() const override { return stream_; }
|
||||
|
||||
// specific interface
|
||||
Pattern *pattern() const;
|
||||
void setPattern(int id);
|
||||
|
||||
protected:
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
|
||||
Surface *patternsurface_;
|
||||
Pattern *stream_;
|
||||
|
||||
};
|
||||
|
||||
#endif // PATTERNSOURCE_H
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
#include "Source.h"
|
||||
#include "MediaSource.h"
|
||||
#include "SessionSource.h"
|
||||
#include "StreamSource.h"
|
||||
#include "PatternSource.h"
|
||||
#include "DeviceSource.h"
|
||||
#include "Session.h"
|
||||
#include "ImageShader.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
|
||||
@@ -179,7 +179,6 @@ void Source::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
Source::Mode Source::mode() const
|
||||
{
|
||||
return mode_;
|
||||
|
||||
20
Stream.cpp
20
Stream.cpp
@@ -33,7 +33,7 @@ Stream::Stream()
|
||||
|
||||
width_ = 800;
|
||||
height_ = 600;
|
||||
single_frame_ = true;
|
||||
single_frame_ = false;
|
||||
ready_ = false;
|
||||
failed_ = false;
|
||||
enabled_ = true;
|
||||
@@ -71,6 +71,18 @@ guint Stream::texture() const
|
||||
}
|
||||
|
||||
|
||||
void Stream::open(const std::string &gstreamer_description)
|
||||
{
|
||||
// set gstreamer pipeline source
|
||||
description_ = gstreamer_description;
|
||||
|
||||
// close before re-openning
|
||||
if (isOpen())
|
||||
close();
|
||||
|
||||
execute_open();
|
||||
}
|
||||
|
||||
|
||||
std::string Stream::description() const
|
||||
{
|
||||
@@ -541,7 +553,7 @@ double Stream::updateFrameRate() const
|
||||
|
||||
bool Stream::fill_frame(GstBuffer *buf, FrameStatus status)
|
||||
{
|
||||
Log::Info("Stream fill frame");
|
||||
// Log::Info("Stream fill frame");
|
||||
|
||||
// Do NOT overwrite an unread EOS
|
||||
if ( frame_[write_index_].status == EOS )
|
||||
@@ -593,7 +605,9 @@ bool Stream::fill_frame(GstBuffer *buf, FrameStatus status)
|
||||
// else; null buffer for EOS: give a position
|
||||
else {
|
||||
frame_[write_index_].status = EOS;
|
||||
#ifdef STREAM_DEBUG
|
||||
Log::Info("Stream EOS");
|
||||
#endif
|
||||
}
|
||||
|
||||
// unlock access to frame
|
||||
@@ -657,7 +671,7 @@ GstFlowReturn Stream::callback_new_sample (GstAppSink *sink, gpointer p)
|
||||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
Log::Info("callback_new_sample");
|
||||
// Log::Info("callback_new_sample");
|
||||
|
||||
// non-blocking read new sample
|
||||
GstSample *sample = gst_app_sink_pull_sample(sink);
|
||||
|
||||
4
Stream.h
4
Stream.h
@@ -29,11 +29,11 @@ public:
|
||||
/**
|
||||
* Open a media using gstreamer pipeline keyword
|
||||
* */
|
||||
virtual void open( std::string description ) = 0;
|
||||
void open(const std::string &gstreamer_description );
|
||||
/**
|
||||
* Get description string
|
||||
* */
|
||||
virtual std::string description() const;
|
||||
std::string description() const;
|
||||
/**
|
||||
* True if a media was oppenned
|
||||
* */
|
||||
|
||||
131
StreamSource.cpp
Normal file
131
StreamSource.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <sstream>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "StreamSource.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include "ImageShader.h"
|
||||
#include "Resource.h"
|
||||
#include "Primitives.h"
|
||||
#include "Stream.h"
|
||||
#include "Visitor.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
GenericStreamSource::GenericStreamSource() : StreamSource()
|
||||
{
|
||||
// create stream
|
||||
stream_ = new Stream;
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
}
|
||||
|
||||
void GenericStreamSource::setDescription(const std::string &desc)
|
||||
{
|
||||
Log::Notify("Creating Stream %s", desc);
|
||||
|
||||
stream_->open(desc);
|
||||
stream_->play(true);
|
||||
}
|
||||
|
||||
void GenericStreamSource::accept(Visitor& v)
|
||||
{
|
||||
Source::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
StreamSource::StreamSource() : Source()
|
||||
{
|
||||
// create surface
|
||||
surface_ = new Surface(renderingshader_);
|
||||
}
|
||||
|
||||
StreamSource::~StreamSource()
|
||||
{
|
||||
// delete media surface & stream
|
||||
delete surface_;
|
||||
delete stream_;
|
||||
}
|
||||
|
||||
bool StreamSource::failed() const
|
||||
{
|
||||
return stream_->failed();
|
||||
}
|
||||
|
||||
uint StreamSource::texture() const
|
||||
{
|
||||
return stream_->texture();
|
||||
}
|
||||
|
||||
void StreamSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
|
||||
void StreamSource::init()
|
||||
{
|
||||
if ( stream_->isOpen() ) {
|
||||
|
||||
// update video
|
||||
stream_->update();
|
||||
|
||||
// once the texture of media player is created
|
||||
if (stream_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// get the texture index from media player, apply it to the media surface
|
||||
surface_->setTextureIndex( stream_->texture() );
|
||||
|
||||
// create Frame buffer matching size of media player
|
||||
float height = float(stream_->width()) / stream_->aspectRatio();
|
||||
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, true);
|
||||
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source Stream linked to Stream %d.", stream_->description().c_str());
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
touch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StreamSource::setActive (bool on)
|
||||
{
|
||||
bool was_active = active_;
|
||||
|
||||
Source::setActive(on);
|
||||
|
||||
// change status of media player (only if status changed)
|
||||
if ( active_ != was_active ) {
|
||||
stream_->enable(active_);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSource::update(float dt)
|
||||
{
|
||||
Source::update(dt);
|
||||
|
||||
// update stream
|
||||
stream_->update();
|
||||
}
|
||||
|
||||
void StreamSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
73
StreamSource.h
Normal file
73
StreamSource.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef STREAMSOURCE_H
|
||||
#define STREAMSOURCE_H
|
||||
|
||||
|
||||
#include "Stream.h"
|
||||
#include "Source.h"
|
||||
|
||||
/**
|
||||
* @brief The StreamSource class
|
||||
*
|
||||
* StreamSource is a virtual base class
|
||||
* (because stream() = 0)
|
||||
* based on the virtual base class Source
|
||||
* that implements the update and display
|
||||
* of a Stream object (gstreamer generic)
|
||||
*
|
||||
* StreamSource does *not* create a stream
|
||||
* in its constructor to let this for the
|
||||
* specific implementation of the subclass.
|
||||
* Therefore it cannot be instanciated and
|
||||
* it cannot give access to its stream.
|
||||
*
|
||||
*/
|
||||
class StreamSource: public Source
|
||||
{
|
||||
public:
|
||||
StreamSource();
|
||||
virtual ~StreamSource();
|
||||
|
||||
// implementation of source API
|
||||
void update (float dt) override;
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
|
||||
// pure virtual interface
|
||||
virtual Stream *stream() const = 0;
|
||||
|
||||
protected:
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
|
||||
Surface *surface_;
|
||||
Stream *stream_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The GenericStreamSource class
|
||||
*
|
||||
* Implements the StreamSource
|
||||
* with an initialization
|
||||
* using a generic description
|
||||
* of the gstreamer pipeline.
|
||||
*
|
||||
* It can be instanciated.
|
||||
*/
|
||||
class GenericStreamSource : public StreamSource
|
||||
{
|
||||
public:
|
||||
GenericStreamSource();
|
||||
|
||||
// Source interface
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
// StreamSource interface
|
||||
Stream *stream() const override { return stream_; }
|
||||
|
||||
// specific interface
|
||||
void setDescription(const std::string &desc);
|
||||
};
|
||||
|
||||
#endif // STREAMSOURCE_H
|
||||
@@ -53,6 +53,8 @@ using namespace std;
|
||||
#include "MediaPlayer.h"
|
||||
#include "MediaSource.h"
|
||||
#include "PatternSource.h"
|
||||
#include "DeviceSource.h"
|
||||
#include "StreamSource.h"
|
||||
#include "PickingVisitor.h"
|
||||
#include "ImageShader.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
@@ -854,7 +856,7 @@ void ToolBox::Render()
|
||||
{
|
||||
if (ImGui::BeginMenu("Render"))
|
||||
{
|
||||
if ( ImGui::MenuItem( ICON_FA_CAMERA_RETRO " Screenshot") )
|
||||
if ( ImGui::MenuItem( ICON_FA_CAMERA_RETRO " Screenshot", "F12") )
|
||||
UserInterface::manager().StartScreenshot();
|
||||
|
||||
ImGui::EndMenu();
|
||||
@@ -871,6 +873,17 @@ void ToolBox::Render()
|
||||
}
|
||||
|
||||
|
||||
static char buf1[64] = "";
|
||||
ImGui::InputText("gstreamer pipeline", buf1, 64);
|
||||
if (ImGui::Button("Create Generic Stream Source") )
|
||||
{
|
||||
// GenericStreamSource *s =
|
||||
Mixer::manager().addSource( Mixer::manager().createSourceStream(buf1) );
|
||||
}
|
||||
|
||||
//
|
||||
// display histogram of update time and plot framerate
|
||||
//
|
||||
// keep array of 120 values, i.e. approx 2 seconds of recording
|
||||
static float framerate_values[2][120] = {{}};
|
||||
static float sum[2] = { 0.f, 0.f };
|
||||
|
||||
@@ -28,6 +28,8 @@ class ImageProcessingShader;
|
||||
class Source;
|
||||
class MediaSource;
|
||||
class PatternSource;
|
||||
class DeviceSource;
|
||||
class GenericStreamSource;
|
||||
class SessionSource;
|
||||
class RenderSource;
|
||||
class CloneSource;
|
||||
@@ -64,6 +66,8 @@ public:
|
||||
// utility
|
||||
virtual void visit (Source&) {}
|
||||
virtual void visit (MediaSource&) {}
|
||||
virtual void visit (GenericStreamSource&) {}
|
||||
virtual void visit (DeviceSource&) {}
|
||||
virtual void visit (PatternSource&) {}
|
||||
virtual void visit (SessionSource&) {}
|
||||
virtual void visit (RenderSource&) {}
|
||||
|
||||
Reference in New Issue
Block a user