diff --git a/DeviceSource.cpp b/DeviceSource.cpp index 683e16f..b56861f 100644 --- a/DeviceSource.cpp +++ b/DeviceSource.cpp @@ -27,14 +27,14 @@ void Device::open( uint device ) { device_ = CLAMP(device, 0, 2); - live_ = true; - // std::string desc = "v4l2src ! video/x-raw,width=320,height=240,framerate=30/1 ! videoconvert"; // std::string desc = "v4l2src ! jpegdec ! videoconvert"; -// std::string desc = "v4l2src ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegdec ! videoconvert"; + std::string desc = "v4l2src ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegdec ! videoscale ! videoconvert"; + +// std::string desc = "v4l2src ! jpegdec ! videoscale ! videoconvert"; // std::string desc = "videotestsrc pattern=snow is-live=true "; - std::string desc = "ximagesrc endx=640 endy=480 ! video/x-raw,framerate=5/1 ! videoconvert ! queue"; +// std::string desc = "ximagesrc endx=800 endy=600 ! video/x-raw,framerate=15/1 ! videoscale ! videoconvert"; // (private) open stream Stream::open(desc); @@ -45,14 +45,14 @@ DeviceSource::DeviceSource() : StreamSource() // create stream stream_ = (Stream *) new Device(); - // icon in mixing view + // set icons TODO 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); + Log::Notify("Creating Source with device '%d'", id); device()->open(id); stream_->play(true); diff --git a/MediaSource.cpp b/MediaSource.cpp index d4411f6..6c659fa 100644 --- a/MediaSource.cpp +++ b/MediaSource.cpp @@ -33,11 +33,11 @@ MediaSource::~MediaSource() void MediaSource::setPath(const std::string &p) { + Log::Notify("Creating Source with media '%s'", p.c_str()); + path_ = p; mediaplayer_->open(path_); mediaplayer_->play(true); - - Log::Notify("Opening %s", p.c_str()); } std::string MediaSource::path() const @@ -97,7 +97,7 @@ void MediaSource::init() // done init initialized_ = true; - Log::Info("Source Media linked to Media %s.", mediaplayer()->uri().c_str()); + Log::Info("Source '%s' linked to Media %s.", name().c_str(), mediaplayer()->uri().c_str()); // force update of activation mode active_ = true; diff --git a/PatternSource.cpp b/PatternSource.cpp index de255ed..30c7279 100644 --- a/PatternSource.cpp +++ b/PatternSource.cpp @@ -135,16 +135,14 @@ PatternSource::PatternSource(glm::ivec2 resolution) : StreamSource() // create stream stream_ = (Stream *) new Pattern(resolution); -// // create surface -// surface_ = new Surface(renderingshader_); - + // set icons 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()); + Log::Notify("Creating Source with pattern '%s'", Pattern::pattern_types[id].c_str()); pattern()->open( (uint) id ); stream_->play(true); @@ -162,94 +160,3 @@ Pattern *PatternSource::pattern() const } -//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(), projection); -// renderbuffer_->end(); -// } -//} diff --git a/Source.cpp b/Source.cpp index e451403..3b876d2 100644 --- a/Source.cpp +++ b/Source.cpp @@ -468,7 +468,7 @@ void CloneSource::init() // done init initialized_ = true; - Log::Info("Source Clone %s linked to source %s.", name().c_str(), origin_->name().c_str() ); + Log::Info("Source %s cloning source %s.", name().c_str(), origin_->name().c_str() ); } } diff --git a/Stream.cpp b/Stream.cpp index 68436fb..a1d3a47 100644 --- a/Stream.cpp +++ b/Stream.cpp @@ -34,6 +34,7 @@ Stream::Stream() width_ = 800; height_ = 600; single_frame_ = false; + live_ = false; ready_ = false; failed_ = false; enabled_ = true; @@ -89,6 +90,12 @@ std::string Stream::description() const return description_; } +int Stream::id() const +{ + return id_; +} + + void Stream::execute_open() { // reset @@ -102,7 +109,7 @@ void Stream::execute_open() GError *error = NULL; pipeline_ = gst_parse_launch (description.c_str(), &error); if (error != NULL) { - Log::Warning("Stream %s Could not construct pipeline %s:\n%s", std::to_string(id_).c_str(), description.c_str(), error->message); + Log::Warning("Stream %d Could not construct pipeline %s:\n%s", id_, description.c_str(), error->message); g_clear_error (&error); failed_ = true; return; @@ -113,8 +120,8 @@ void Stream::execute_open() string capstring = "video/x-raw,format=RGBA,width="+ std::to_string(width_) + ",height=" + std::to_string(height_); GstCaps *caps = gst_caps_from_string(capstring.c_str()); - if (!gst_video_info_from_caps (&v_frame_video_info_, caps)) { - Log::Warning("Stream %s Could not configure video frame info", std::to_string(id_).c_str()); + if (!caps || !gst_video_info_from_caps (&v_frame_video_info_, caps)) { + Log::Warning("Stream %d Could not configure video frame info", id_); failed_ = true; return; } @@ -122,8 +129,8 @@ void Stream::execute_open() // setup appsink GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline_), "sink"); if (sink) { - // instruct the sink to send samples synched in time - gst_base_sink_set_sync (GST_BASE_SINK(sink), true); +// // instruct the sink to send samples synched in time +// gst_base_sink_set_sync (GST_BASE_SINK(sink), false); // instruct sink to use the required caps gst_app_sink_set_caps (GST_APP_SINK(sink), caps); @@ -140,11 +147,6 @@ void Stream::execute_open() callbacks.eos = NULL; callbacks.new_sample = NULL; } -// else if (live_) { -// callbacks.new_preroll = NULL; -// callbacks.eos = NULL; -// callbacks.new_sample = callback_new_sample; -// } else { callbacks.new_preroll = callback_new_preroll; callbacks.eos = callback_end_of_stream; @@ -161,35 +163,35 @@ void Stream::execute_open() } gst_app_sink_set_emit_signals (GST_APP_SINK(sink), true); #endif - // done with ref to sink - gst_object_unref (sink); } else { - Log::Warning("Stream %s Could not configure sink", std::to_string(id_).c_str()); + Log::Warning("Stream %d Could not configure sink", id_); failed_ = true; return; } - gst_caps_unref (caps); // set to desired state (PLAY or PAUSE) GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_); if (ret == GST_STATE_CHANGE_FAILURE) { - Log::Warning("Stream %s Could not open '%s'", std::to_string(id_).c_str(), description_.c_str()); + Log::Warning("Stream %d Could not open '%s'", id_, description_.c_str()); failed_ = true; return; - } else if (ret == GST_STATE_CHANGE_NO_PREROLL) { - Log::Info("Stream %s is a live stream", std::to_string(id_).c_str()); + } + else if (ret == GST_STATE_CHANGE_NO_PREROLL) { + Log::Info("Stream %d is a live stream", id_); live_ = true; } + // instruct the sink to send samples synched in time if not live source + gst_base_sink_set_sync (GST_BASE_SINK(sink), !live_); + // all good Log::Info("Stream %d Opened '%s' (%d x %d)", id_, description.c_str(), width_, height_); -// if (desired_state_ == GST_STATE_PLAYING) -// Log::Info("Stream %d Playing", id_); -// else -// Log::Info("Stream %d Paused", id_); - ready_ = true; + + // done with refs + gst_object_unref (sink); + gst_caps_unref (caps); } bool Stream::isOpen() const @@ -282,14 +284,14 @@ void Stream::enable(bool on) // apply state change GstStateChangeReturn ret = gst_element_set_state (pipeline_, requested_state); if (ret == GST_STATE_CHANGE_FAILURE) { - Log::Warning("Stream %s Failed to enable", std::to_string(id_).c_str()); + Log::Warning("Stream %d Failed to enable", id_); failed_ = true; } } } -bool Stream::isEnabled() const +bool Stream::enabled() const { return enabled_; } @@ -327,26 +329,20 @@ void Stream::play(bool on) // all ready, apply state change immediately GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_); if (ret == GST_STATE_CHANGE_FAILURE) { - Log::Warning("Stream %s Failed to play", std::to_string(id_).c_str()); + Log::Warning("Stream %d Failed to play", id_); failed_ = true; } #ifdef STREAM_DEBUG else if (on) - Log::Info("Stream %s Start", std::to_string(id_).c_str()); + Log::Info("Stream %d Start", id_); else - Log::Info("Stream %s Stop", std::to_string(id_).c_str()); + Log::Info("Stream %d Stop", id_); #endif - // DEBUG : LIVE SOURCE ?? + // activate live-source if (live_) { GstState state; gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE); - - while (state != desired_state_) { - Log::Info("Stream %s Live stream did not change state", std::to_string(id_).c_str()); - gst_element_set_state (pipeline_, desired_state_); - gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE); - } } // reset time counter @@ -417,7 +413,7 @@ void Stream::init_texture(guint index) pbo_next_index_ = 1; #ifdef STREAM_DEBUG - Log::Info("Stream %s Using Pixel Buffer Object texturing.", std::to_string(id_).c_str()); + Log::Info("Stream %d Use Pixel Buffer Object texturing.", id_); #endif } @@ -485,10 +481,6 @@ void Stream::update() // if (!enabled_) // return; -// // DEBUG : LIVE SOURCE ?? -// GstState state; -// gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE); - // local variables before trying to update guint read_index = 0; bool need_loop = false; @@ -576,7 +568,7 @@ bool Stream::fill_frame(GstBuffer *buf, FrameStatus status) // get the frame from buffer if ( !gst_video_frame_map (&frame_[write_index_].vframe, &v_frame_video_info_, buf, GST_MAP_READ ) ) { - Log::Info("Stream %s Failed to map the video buffer", std::to_string(id_).c_str()); + Log::Info("Stream %d Failed to map the video buffer", id_); // free access to frame & exit frame_[write_index_].status = INVALID; frame_[write_index_].access.unlock(); @@ -596,7 +588,7 @@ bool Stream::fill_frame(GstBuffer *buf, FrameStatus status) // full but invalid frame : will be deleted next iteration // (should never happen) else { - Log::Info("Stream %s Invalid frame", std::to_string(id_).c_str()); + Log::Info("Stream %d Received an Invalid frame", id_); frame_[write_index_].status = INVALID; frame_[write_index_].access.unlock(); return false; @@ -606,7 +598,7 @@ bool Stream::fill_frame(GstBuffer *buf, FrameStatus status) else { frame_[write_index_].status = EOS; #ifdef STREAM_DEBUG - Log::Info("Stream EOS"); + Log::Info("Stream %d Reached End Of Stream", id_); #endif } diff --git a/Stream.h b/Stream.h index 04dea9e..e1702d7 100644 --- a/Stream.h +++ b/Stream.h @@ -29,7 +29,7 @@ public: /** * Open a media using gstreamer pipeline keyword * */ - void open(const std::string &gstreamer_description ); + void open(const std::string &gstreamer_description); /** * Get description string * */ @@ -60,7 +60,7 @@ public: /** * True if enabled * */ - bool isEnabled() const; + bool enabled() const; /** * True if its an image * */ @@ -108,6 +108,8 @@ public: * */ void accept(Visitor& v); + int id() const; + protected: // video player description diff --git a/StreamSource.cpp b/StreamSource.cpp index 2e8beaa..aabad6c 100644 --- a/StreamSource.cpp +++ b/StreamSource.cpp @@ -24,7 +24,7 @@ GenericStreamSource::GenericStreamSource() : StreamSource() void GenericStreamSource::setDescription(const std::string &desc) { - Log::Notify("Creating Stream %s", desc); + Log::Notify("Creating Source with Stream description '%s'", desc.c_str()); stream_->open(desc); stream_->play(true); @@ -87,7 +87,7 @@ void StreamSource::init() // done init initialized_ = true; - Log::Info("Source Stream linked to Stream %d.", stream_->description().c_str()); + Log::Info("Source '%s' linked to Stream %d.", name().c_str(), stream_->id()); // force update of activation mode active_ = true; diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 6529b21..8f826e4 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -872,15 +872,16 @@ void ToolBox::Render() ImGui::EndMenuBar(); } - - static char buf1[64] = ""; - ImGui::InputText("gstreamer pipeline", buf1, 64); + static char buf1[128] = "videotestsrc pattern=smpte"; + ImGui::InputText("gstreamer pipeline", buf1, 128); if (ImGui::Button("Create Generic Stream Source") ) { // GenericStreamSource *s = Mixer::manager().addSource( Mixer::manager().createSourceStream(buf1) ); } + + // // display histogram of update time and plot framerate //