mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 15:30:00 +01:00
Implement broadcast manager functionality and enhance FrameGrabber info and type methods
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include "NetworkToolkit.h"
|
||||
#include "UserInterfaceManager.h"
|
||||
#include "Streamer.h"
|
||||
#include "VideoBroadcast.h"
|
||||
|
||||
#include "ControlManager.h"
|
||||
|
||||
@@ -605,6 +606,16 @@ bool Control::receiveOutputAttribute(const std::string &attribute,
|
||||
Mixer::manager().session()->setFadingTarget( Mixer::manager().session()->fading() + f * 0.01);
|
||||
need_feedback = true;
|
||||
}
|
||||
else if ( attribute.compare(OSC_OUTPUT_SRT_START) == 0) {
|
||||
float f = (float) Settings::application.broadcast_port;
|
||||
// if argument is given, it is the connection port
|
||||
if (!arguments.Eos())
|
||||
arguments >> f >> osc::EndMessage;
|
||||
Broadcast::manager().start( new VideoBroadcast((int) f), true);
|
||||
}
|
||||
else if ( attribute.compare(OSC_OUTPUT_SRT_STOP) == 0) {
|
||||
Broadcast::manager().stop(FrameGrabber::GRABBER_BROADCAST);
|
||||
}
|
||||
// inform of invalid attribute name
|
||||
else {
|
||||
Log::Info(CONTROL_OSC_MSG "Unknown attribute '%s' for target 'output'", attribute.c_str());
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#define OSC_OUTPUT_FADING "/fading"
|
||||
#define OSC_OUTPUT_FADE_IN "/fade-in"
|
||||
#define OSC_OUTPUT_FADE_OUT "/fade-out"
|
||||
#define OSC_OUTPUT_SRT_START "/srt-start"
|
||||
#define OSC_OUTPUT_SRT_STOP "/srt-stop"
|
||||
|
||||
#define OSC_ALL "/all"
|
||||
#define OSC_SELECTION "/selection"
|
||||
|
||||
@@ -106,6 +106,28 @@ FrameGrabber *FrameGrabbing::get(uint64_t id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct fgType
|
||||
{
|
||||
inline bool operator()(const FrameGrabber* elem) const {
|
||||
return (elem && elem->type() == _t);
|
||||
}
|
||||
explicit fgType(FrameGrabber::Type t) : _t(t) { }
|
||||
private:
|
||||
FrameGrabber::Type _t;
|
||||
};
|
||||
|
||||
FrameGrabber *FrameGrabbing::get(FrameGrabber::Type t)
|
||||
{
|
||||
if (grabbers_.size() > 0 )
|
||||
{
|
||||
std::list<FrameGrabber *>::iterator iter = std::find_if(grabbers_.begin(), grabbers_.end(), fgType(t));
|
||||
if (iter != grabbers_.end())
|
||||
return (*iter);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FrameGrabbing::stopAll()
|
||||
{
|
||||
std::list<FrameGrabber *>::iterator iter;
|
||||
@@ -349,8 +371,37 @@ void FrameGrabber::stop ()
|
||||
|
||||
}
|
||||
|
||||
std::string FrameGrabber::info() const
|
||||
std::string FrameGrabber::info(bool extended) const
|
||||
{
|
||||
if (extended) {
|
||||
std::string typestring;
|
||||
switch ( type() )
|
||||
{
|
||||
case GRABBER_PNG :
|
||||
typestring = "Portable Network Graphics frame grabber";
|
||||
break;
|
||||
case GRABBER_VIDEO :
|
||||
typestring = "Video file frame grabber";
|
||||
break;
|
||||
case GRABBER_P2P :
|
||||
typestring = "Peer-to-Peer stream frame grabber";
|
||||
break;
|
||||
case GRABBER_BROADCAST :
|
||||
typestring = "SRT Broarcast frame grabber";
|
||||
break;
|
||||
case GRABBER_SHM :
|
||||
typestring = "Shared Memory frame grabber";
|
||||
break;
|
||||
case GRABBER_LOOPBACK :
|
||||
typestring = "Loopback frame grabber";
|
||||
break;
|
||||
default:
|
||||
typestring = "Generic frame grabber";
|
||||
break;
|
||||
}
|
||||
return typestring;
|
||||
}
|
||||
|
||||
if (!initialized_)
|
||||
return "Initializing";
|
||||
if (active_)
|
||||
@@ -603,3 +654,56 @@ guint64 FrameGrabber::frames() const
|
||||
{
|
||||
return frame_count_;
|
||||
}
|
||||
|
||||
|
||||
uint64_t Broadcast::start(FrameGrabber *ptr, bool singleton)
|
||||
{
|
||||
if (singleton)
|
||||
stop( ptr->type() );
|
||||
|
||||
uint64_t b = ptr->id();
|
||||
FrameGrabbing::manager().add(ptr);
|
||||
return b;
|
||||
}
|
||||
|
||||
bool Broadcast::enabled(uint64_t b)
|
||||
{
|
||||
return ( FrameGrabbing::manager().get(b) != nullptr);
|
||||
}
|
||||
|
||||
bool Broadcast::busy(uint64_t b)
|
||||
{
|
||||
FrameGrabber *ptr = FrameGrabbing::manager().get(b);
|
||||
if (ptr != nullptr)
|
||||
return ptr->busy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Broadcast::info(uint64_t b, bool extended)
|
||||
{
|
||||
FrameGrabber *ptr = FrameGrabbing::manager().get(b);
|
||||
if (ptr != nullptr)
|
||||
return ptr->info(extended);
|
||||
|
||||
return "Disabled";
|
||||
}
|
||||
|
||||
void Broadcast::stop(uint64_t b)
|
||||
{
|
||||
FrameGrabber *ptr = FrameGrabbing::manager().get(b);
|
||||
if (ptr != nullptr)
|
||||
ptr->stop();
|
||||
|
||||
}
|
||||
|
||||
void Broadcast::stop(FrameGrabber::Type T)
|
||||
{
|
||||
FrameGrabber *prev = nullptr;
|
||||
do {
|
||||
prev = FrameGrabbing::manager().get( T );
|
||||
if (prev != nullptr)
|
||||
prev->stop();
|
||||
}
|
||||
while (prev != nullptr);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,21 @@ public:
|
||||
|
||||
inline uint64_t id() const { return id_; }
|
||||
|
||||
// types of sub-classes of FrameGrabber
|
||||
typedef enum {
|
||||
GRABBER_GENERIC = 0,
|
||||
GRABBER_PNG = 1,
|
||||
GRABBER_VIDEO = 2,
|
||||
GRABBER_P2P,
|
||||
GRABBER_BROADCAST,
|
||||
GRABBER_SHM,
|
||||
GRABBER_LOOPBACK,
|
||||
GRABBER_INVALID
|
||||
} Type;
|
||||
virtual Type type () const { return GRABBER_GENERIC; }
|
||||
|
||||
virtual void stop();
|
||||
virtual std::string info() const;
|
||||
virtual std::string info(bool extended = false) const;
|
||||
virtual uint64_t duration() const;
|
||||
virtual bool finished() const;
|
||||
virtual bool busy() const;
|
||||
@@ -133,6 +146,7 @@ public:
|
||||
void verify(FrameGrabber **rec);
|
||||
bool busy() const;
|
||||
FrameGrabber *get(uint64_t id);
|
||||
FrameGrabber *get(FrameGrabber::Type t);
|
||||
void stopAll();
|
||||
void clearAll();
|
||||
|
||||
@@ -154,6 +168,38 @@ private:
|
||||
GstCaps *caps_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Broadcast class gives a global access to launch and stop FrameGrabbers
|
||||
*
|
||||
* FrameGrabbers can terminate (normal behavior or failure) and the FrameGrabber
|
||||
* is deleted automatically; pointer is then invalid and cannot be accessed. To avoid this,
|
||||
* the Broadcast::manager() gives access to FrameGrabbers by id.
|
||||
*
|
||||
* Singleton mechanism also allows starting a unique instance of each FrameGrabber::Type
|
||||
*/
|
||||
class Broadcast
|
||||
{
|
||||
// Private Constructor
|
||||
Broadcast() {};
|
||||
Broadcast(Broadcast const& copy) = delete;
|
||||
Broadcast& operator=(Broadcast const& copy) = delete;
|
||||
|
||||
public:
|
||||
|
||||
static Broadcast& manager ()
|
||||
{
|
||||
// The only instance
|
||||
static Broadcast _instance;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
uint64_t start(FrameGrabber *ptr, bool singleton = false);
|
||||
bool enabled(uint64_t);
|
||||
bool busy(uint64_t);
|
||||
std::string info(uint64_t, bool extended = false);
|
||||
void stop(uint64_t);
|
||||
void stop(FrameGrabber::Type);
|
||||
};
|
||||
|
||||
|
||||
#endif // FRAMEGRABBER_H
|
||||
|
||||
@@ -175,16 +175,21 @@ void Loopback::stop ()
|
||||
active_ = false;
|
||||
}
|
||||
|
||||
std::string Loopback::info() const
|
||||
std::string Loopback::info(bool extended) const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
|
||||
if (!initialized_)
|
||||
ret << "Loopback starting..";
|
||||
else if (active_)
|
||||
ret << "V4L2 Loopback on " << device_name();
|
||||
else
|
||||
ret << "Loopback terminated";
|
||||
if (extended) {
|
||||
ret << device_name();
|
||||
}
|
||||
else {
|
||||
if (!initialized_)
|
||||
ret << "Loopback starting..";
|
||||
else if (active_)
|
||||
ret << "V4L2 Loopback on " << device_name();
|
||||
else
|
||||
ret << "Loopback terminated";
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
@@ -12,13 +12,15 @@ public:
|
||||
Loopback(int deviceid = LOOPBACK_DEFAULT_DEVICE);
|
||||
virtual ~Loopback() {}
|
||||
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_LOOPBACK; }
|
||||
|
||||
static bool available();
|
||||
|
||||
inline int device_id() const { return loopback_device_; }
|
||||
std::string device_name() const;
|
||||
|
||||
void stop() override;
|
||||
std::string info() const override;
|
||||
std::string info(bool extended = false) const override;
|
||||
|
||||
private:
|
||||
std::string init(GstCaps *caps) override;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
OutputPreviewWindow::OutputPreviewWindow() : WorkspaceWindow("OutputPreview"),
|
||||
video_recorder_(nullptr), video_broadcaster_(nullptr), loopback_broadcaster_(nullptr),
|
||||
video_recorder_(nullptr), srt_(0), shm_(0), loopback_(0),
|
||||
magnifying_glass(false)
|
||||
{
|
||||
|
||||
@@ -96,11 +96,6 @@ void OutputPreviewWindow::Update()
|
||||
video_recorder_->stop();
|
||||
}
|
||||
|
||||
// verify the frame grabbers are valid (change to nullptr if invalid)
|
||||
FrameGrabbing::manager().verify( (FrameGrabber**) &video_broadcaster_);
|
||||
FrameGrabbing::manager().verify( (FrameGrabber**) &shm_broadcaster_);
|
||||
FrameGrabbing::manager().verify( (FrameGrabber**) &loopback_broadcaster_);
|
||||
|
||||
}
|
||||
|
||||
VideoRecorder *delayTrigger(VideoRecorder *g, std::chrono::milliseconds delay) {
|
||||
@@ -140,22 +135,19 @@ void OutputPreviewWindow::ToggleRecordPause()
|
||||
|
||||
void OutputPreviewWindow::ToggleVideoBroadcast()
|
||||
{
|
||||
if (video_broadcaster_) {
|
||||
video_broadcaster_->stop();
|
||||
}
|
||||
if (Broadcast::manager().enabled(srt_) )
|
||||
Broadcast::manager().stop(srt_);
|
||||
else {
|
||||
if (Settings::application.broadcast_port<1000)
|
||||
Settings::application.broadcast_port = BROADCAST_DEFAULT_PORT;
|
||||
video_broadcaster_ = new VideoBroadcast(Settings::application.broadcast_port);
|
||||
FrameGrabbing::manager().add(video_broadcaster_);
|
||||
srt_ = Broadcast::manager().start( new VideoBroadcast(Settings::application.broadcast_port), true);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPreviewWindow::ToggleSharedMemory()
|
||||
{
|
||||
if (shm_broadcaster_) {
|
||||
shm_broadcaster_->stop();
|
||||
}
|
||||
if (Broadcast::manager().enabled(shm_) )
|
||||
Broadcast::manager().stop(shm_);
|
||||
else {
|
||||
// find a folder to put the socket for shm
|
||||
std::string _shm_socket_file = Settings::application.shm_socket_path;
|
||||
@@ -164,25 +156,22 @@ void OutputPreviewWindow::ToggleSharedMemory()
|
||||
_shm_socket_file = SystemToolkit::full_filename(_shm_socket_file, ".shm_vimix" + std::to_string(Settings::application.instance_id));
|
||||
|
||||
// create shhmdata broadcaster with method
|
||||
shm_broadcaster_ = new ShmdataBroadcast( (ShmdataBroadcast::Method) Settings::application.shm_method, _shm_socket_file);
|
||||
FrameGrabbing::manager().add(shm_broadcaster_);
|
||||
shm_ = Broadcast::manager().start( new ShmdataBroadcast( (ShmdataBroadcast::Method) Settings::application.shm_method, _shm_socket_file), true);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutputPreviewWindow::ToggleLoopbackCamera()
|
||||
{
|
||||
bool need_initialization = false;
|
||||
if (loopback_broadcaster_) {
|
||||
loopback_broadcaster_->stop();
|
||||
}
|
||||
if (Broadcast::manager().enabled(loopback_))
|
||||
Broadcast::manager().stop(loopback_);
|
||||
else {
|
||||
if (Settings::application.loopback_camera < 1)
|
||||
Settings::application.loopback_camera = LOOPBACK_DEFAULT_DEVICE;
|
||||
Settings::application.loopback_camera += Settings::application.instance_id;
|
||||
|
||||
try {
|
||||
loopback_broadcaster_ = new Loopback(Settings::application.loopback_camera);
|
||||
FrameGrabbing::manager().add(loopback_broadcaster_);
|
||||
loopback_ = Broadcast::manager().start( new Loopback(Settings::application.loopback_camera), true );
|
||||
}
|
||||
catch (const std::runtime_error &e) {
|
||||
need_initialization = true;
|
||||
@@ -400,26 +389,27 @@ void OutputPreviewWindow::Render()
|
||||
// Broadcasting menu
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.9f));
|
||||
if (VideoBroadcast::available()) {
|
||||
if ( ImGui::MenuItem( ICON_FA_GLOBE " SRT Broadcast", NULL, videoBroadcastEnabled()) )
|
||||
if ( ImGui::MenuItem( ICON_FA_GLOBE " SRT Broadcast", NULL, Broadcast::manager().enabled(srt_) ) )
|
||||
ToggleVideoBroadcast();
|
||||
}
|
||||
|
||||
// Shared Memory menu
|
||||
if (ShmdataBroadcast::available()) {
|
||||
if ( ImGui::MenuItem( ICON_FA_MEMORY " SHM Shared Memory", NULL, sharedMemoryEnabled()) )
|
||||
if ( ImGui::MenuItem( ICON_FA_MEMORY " SHM Shared Memory", NULL, Broadcast::manager().enabled(shm_) ) )
|
||||
ToggleSharedMemory();
|
||||
}
|
||||
|
||||
// Loopback camera menu
|
||||
if (Loopback::available()) {
|
||||
if ( ImGui::MenuItem( ICON_FA_VIDEO " Loopback Camera", NULL, loopbackCameraEnabled()) )
|
||||
if ( ImGui::MenuItem( ICON_FA_VIDEO " Loopback Camera", NULL, Broadcast::manager().enabled(loopback_)) )
|
||||
openInitializeSystemLoopback = ToggleLoopbackCamera();
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
// Display list of active stream
|
||||
if (ls.size()>0 || videoBroadcastEnabled() || sharedMemoryEnabled() || loopbackCameraEnabled()) {
|
||||
if (ls.size()>0 || Broadcast::manager().enabled(srt_) ||
|
||||
Broadcast::manager().enabled(shm_) || Broadcast::manager().enabled(loopback_)) {
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("Active streams:", nullptr, false, false);
|
||||
|
||||
@@ -428,37 +418,38 @@ void OutputPreviewWindow::Render()
|
||||
ImGui::Text(" %s ", (*it).c_str() );
|
||||
|
||||
// SRT broadcast description
|
||||
if (videoBroadcastEnabled()) {
|
||||
ImGui::Text(" %s ", video_broadcaster_->info().c_str());
|
||||
if (Broadcast::manager().enabled(srt_)) {
|
||||
ImGui::Text(" %s ", Broadcast::manager().info(srt_).c_str());
|
||||
// copy text icon to give user the srt link to connect to
|
||||
ImVec2 draw_pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) );
|
||||
char msg[256];
|
||||
ImFormatString(msg, IM_ARRAYSIZE(msg), "srt//%s:%d", NetworkToolkit::host_ips()[1].c_str(), Settings::application.broadcast_port );
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, msg))
|
||||
ImGui::SetClipboardText(msg);
|
||||
std::string moreinfo = Broadcast::manager().info(srt_, true);
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str()))
|
||||
ImGui::SetClipboardText(moreinfo.c_str());
|
||||
ImGui::SetCursorPos(draw_pos);
|
||||
}
|
||||
|
||||
// Shared memory broadcast description
|
||||
if (sharedMemoryEnabled()) {
|
||||
ImGui::Text(" %s ", shm_broadcaster_->info().c_str());
|
||||
if (Broadcast::manager().enabled(shm_)) {
|
||||
ImGui::Text(" %s ", Broadcast::manager().info(shm_).c_str());
|
||||
// copy text icon to give user the socket path to connect to
|
||||
ImVec2 draw_pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) );
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, shm_broadcaster_->gst_pipeline().c_str()))
|
||||
ImGui::SetClipboardText(shm_broadcaster_->gst_pipeline().c_str());
|
||||
std::string moreinfo = Broadcast::manager().info(shm_, true);
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str()))
|
||||
ImGui::SetClipboardText(moreinfo.c_str());
|
||||
ImGui::SetCursorPos(draw_pos);
|
||||
}
|
||||
|
||||
// Loopback camera description
|
||||
if (loopbackCameraEnabled()) {
|
||||
ImGui::Text(" %s ", loopback_broadcaster_->info().c_str());
|
||||
if (Broadcast::manager().enabled(loopback_)) {
|
||||
ImGui::Text(" %s ", Broadcast::manager().info(loopback_).c_str());
|
||||
// copy text icon to give user the device path to connect to
|
||||
ImVec2 draw_pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(draw_pos + ImVec2(ImGui::GetContentRegionAvailWidth() - 1.2 * ImGui::GetTextLineHeightWithSpacing(), -0.8 * ImGui::GetFrameHeight()) );
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, loopback_broadcaster_->device_name().c_str()))
|
||||
ImGui::SetClipboardText(loopback_broadcaster_->device_name().c_str());
|
||||
std::string moreinfo = Broadcast::manager().info(loopback_, true);
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_COPY, moreinfo.c_str()))
|
||||
ImGui::SetClipboardText(moreinfo.c_str());
|
||||
ImGui::SetCursorPos(draw_pos);
|
||||
}
|
||||
}
|
||||
@@ -558,10 +549,10 @@ void OutputPreviewWindow::Render()
|
||||
}
|
||||
// broadcast indicator
|
||||
float vertical = r;
|
||||
if (video_broadcaster_)
|
||||
if (Broadcast::manager().enabled(srt_))
|
||||
{
|
||||
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical));
|
||||
if (video_broadcaster_->busy())
|
||||
if (Broadcast::manager().busy(srt_))
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f));
|
||||
else
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f));
|
||||
@@ -570,10 +561,10 @@ void OutputPreviewWindow::Render()
|
||||
vertical += 2.f * r;
|
||||
}
|
||||
// shmdata indicator
|
||||
if (shm_broadcaster_)
|
||||
if (Broadcast::manager().enabled(shm_))
|
||||
{
|
||||
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical));
|
||||
if (shm_broadcaster_->busy())
|
||||
if (Broadcast::manager().busy(shm_))
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f));
|
||||
else
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f));
|
||||
@@ -582,10 +573,10 @@ void OutputPreviewWindow::Render()
|
||||
vertical += 2.f * r;
|
||||
}
|
||||
// loopback camera indicator
|
||||
if (loopback_broadcaster_)
|
||||
if (Broadcast::manager().enabled(loopback_))
|
||||
{
|
||||
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + imagesize.x - 2.5f * r, draw_pos.y + vertical));
|
||||
if (loopback_broadcaster_->busy())
|
||||
if (Broadcast::manager().busy(loopback_))
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.8f));
|
||||
else
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_BROADCAST, 0.4f));
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "WorkspaceWindow.h"
|
||||
|
||||
class VideoRecorder;
|
||||
class VideoBroadcast;
|
||||
class ShmdataBroadcast;
|
||||
class Loopback;
|
||||
|
||||
@@ -13,9 +12,9 @@ class OutputPreviewWindow : public WorkspaceWindow
|
||||
{
|
||||
// frame grabbers
|
||||
VideoRecorder *video_recorder_;
|
||||
VideoBroadcast *video_broadcaster_;
|
||||
ShmdataBroadcast *shm_broadcaster_;
|
||||
Loopback *loopback_broadcaster_;
|
||||
uint64_t srt_;
|
||||
uint64_t shm_;
|
||||
uint64_t loopback_;
|
||||
|
||||
// delayed trigger for recording
|
||||
std::vector< std::future<VideoRecorder *> > _video_recorders;
|
||||
@@ -34,13 +33,8 @@ public:
|
||||
inline bool isRecording() const { return video_recorder_ != nullptr; }
|
||||
|
||||
void ToggleVideoBroadcast();
|
||||
inline bool videoBroadcastEnabled() const { return video_broadcaster_ != nullptr; }
|
||||
|
||||
void ToggleSharedMemory();
|
||||
inline bool sharedMemoryEnabled() const { return shm_broadcaster_ != nullptr; }
|
||||
|
||||
bool ToggleLoopbackCamera();
|
||||
inline bool loopbackCameraEnabled() const { return loopback_broadcaster_!= nullptr; }
|
||||
|
||||
void Render();
|
||||
void setVisible(bool on);
|
||||
|
||||
@@ -516,8 +516,11 @@ void VideoRecorder::terminate()
|
||||
Settings::application.recentRecordings.remove(filename_);
|
||||
}
|
||||
|
||||
std::string VideoRecorder::info() const
|
||||
std::string VideoRecorder::info(bool extended) const
|
||||
{
|
||||
if (extended)
|
||||
return filename();
|
||||
|
||||
if (initialized_ && !active_ && !endofstream_)
|
||||
return "Saving file...";
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
PNGRecorder(const std::string &basename = std::string());
|
||||
std::string filename() const { return filename_; }
|
||||
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_PNG; }
|
||||
|
||||
protected:
|
||||
|
||||
std::string init(GstCaps *caps) override;
|
||||
@@ -60,7 +62,9 @@ public:
|
||||
static const int framerate_preset_value[3];
|
||||
|
||||
VideoRecorder(const std::string &basename = std::string());
|
||||
std::string info() const override;
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_VIDEO; }
|
||||
|
||||
std::string info(bool extended = false) const override;
|
||||
std::string filename() const { return filename_; }
|
||||
};
|
||||
|
||||
|
||||
@@ -203,16 +203,21 @@ std::string ShmdataBroadcast::gst_pipeline() const
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
std::string ShmdataBroadcast::info() const
|
||||
std::string ShmdataBroadcast::info(bool extended) const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
|
||||
if (!initialized_)
|
||||
ret << "Shared Memory starting..";
|
||||
else if (active_)
|
||||
ret << "Shared Memory " << socket_path_;
|
||||
else
|
||||
ret << "Shared Memory terminated";
|
||||
if (extended) {
|
||||
ret << gst_pipeline();
|
||||
}
|
||||
else {
|
||||
if (!initialized_)
|
||||
ret << "Shared Memory starting..";
|
||||
else if (active_)
|
||||
ret << "Shared Memory " << socket_path_;
|
||||
else
|
||||
ret << "Shared Memory terminated";
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
@@ -19,13 +19,15 @@ public:
|
||||
ShmdataBroadcast(Method m = SHM_SHMSINK, const std::string &socketpath = "");
|
||||
virtual ~ShmdataBroadcast() {}
|
||||
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_SHM; }
|
||||
|
||||
static bool available(Method m = SHM_SHMDATAANY);
|
||||
|
||||
inline Method method() const { return method_; }
|
||||
inline std::string socket_path() const { return socket_path_; }
|
||||
std::string gst_pipeline() const;
|
||||
|
||||
std::string info() const override;
|
||||
std::string info(bool extended = false) const override;
|
||||
|
||||
private:
|
||||
std::string init(GstCaps *caps) override;
|
||||
|
||||
@@ -516,17 +516,24 @@ void VideoStreamer::stop ()
|
||||
active_ = false;
|
||||
}
|
||||
|
||||
std::string VideoStreamer::info() const
|
||||
std::string VideoStreamer::info(bool extended) const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
if (!initialized_)
|
||||
ret << "Connecting";
|
||||
else if (active_) {
|
||||
ret << NetworkToolkit::stream_protocol_label[config_.protocol];
|
||||
ret << " to ";
|
||||
ret << config_.client_name;
|
||||
|
||||
if (extended) {
|
||||
ret << NetworkToolkit::stream_send_pipeline[config_.protocol];
|
||||
}
|
||||
else
|
||||
ret << "Streaming terminated.";
|
||||
else {
|
||||
if (!initialized_)
|
||||
ret << "Connecting";
|
||||
else if (active_) {
|
||||
ret << NetworkToolkit::stream_protocol_label[config_.protocol];
|
||||
ret << " to ";
|
||||
ret << config_.client_name;
|
||||
}
|
||||
else
|
||||
ret << "Streaming terminated.";
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ public:
|
||||
|
||||
VideoStreamer(const NetworkToolkit::StreamConfig &conf);
|
||||
virtual ~VideoStreamer() {}
|
||||
std::string info() const override;
|
||||
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_P2P; }
|
||||
std::string info(bool extended = false) const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "Log.h"
|
||||
#include "GstToolkit.h"
|
||||
#include "NetworkToolkit.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include "VideoBroadcast.h"
|
||||
@@ -210,16 +211,24 @@ void VideoBroadcast::stop ()
|
||||
active_ = false;
|
||||
}
|
||||
|
||||
std::string VideoBroadcast::info() const
|
||||
std::string VideoBroadcast::info(bool extended) const
|
||||
{
|
||||
std::ostringstream ret;
|
||||
|
||||
if (!initialized_)
|
||||
ret << "SRT starting..";
|
||||
else if (active_)
|
||||
ret << "SRT Broadcast on port " << port_;
|
||||
else
|
||||
ret << "SRT terminated";
|
||||
if (extended) {
|
||||
ret << "srt://";
|
||||
ret << NetworkToolkit::host_ips()[1];
|
||||
ret << ":";
|
||||
ret << port_;
|
||||
}
|
||||
else {
|
||||
if (!initialized_)
|
||||
ret << "SRT starting..";
|
||||
else if (active_)
|
||||
ret << "SRT Broadcast on port " << port_;
|
||||
else
|
||||
ret << "SRT terminated";
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ public:
|
||||
VideoBroadcast(int port = BROADCAST_DEFAULT_PORT);
|
||||
virtual ~VideoBroadcast() {}
|
||||
|
||||
FrameGrabber::Type type () const override { return FrameGrabber::GRABBER_BROADCAST; }
|
||||
|
||||
static bool available();
|
||||
inline int port() const { return port_; }
|
||||
|
||||
void stop() override;
|
||||
std::string info() const override;
|
||||
std::string info(bool extended = false) const override;
|
||||
|
||||
private:
|
||||
std::string init(GstCaps *caps) override;
|
||||
|
||||
Reference in New Issue
Block a user