Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/beta'
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoherbelin committed Oct 3, 2024
2 parents 7660b07 + 8041816 commit d795fee
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 83 deletions.
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ if(UNIX)

else()
add_definitions(-DLINUX)
# add_definitions(-DUSE_GST_OPENGL_SYNC_HANDLER)
# add_definitions(-DUSE_GL_BUFFER_SUBDATA)

# CPACK
set(CPACK_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}")
Expand All @@ -112,6 +110,14 @@ elseif(WIN32)
add_definitions(-DMINGW32)
endif()

#####
##### Preprocessor options
#####

# add_definitions(-DUSE_GST_OPENGL_SYNC_HANDLER)
# add_definitions(-DUSE_GL_BUFFER_SUBDATA)
# add_definitions(-DIGNORE_GST_BUS_MESSAGE)

#####
##### Dependencies
#####
Expand Down
5 changes: 4 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,14 @@ IF(APPLE)

## POST INSTALL DMG SIGNING AND NOTARIZATION
## 1. SIGN DMG
## codesign --verify --verbose=2 ./_CPack_Packages/OSX_13_arm64/DragNDrop/vimix_0.8.2_OSX_13_arm64.dm
## codesign
## codesign --verify --verbose=2 ./_CPack_Packages/OSX_13_arm64/DragNDrop/vimix_0.8.2_OSX_13_arm64.dmg
##
## 2. SUBMIT TO NOTARIZATION
## xcrun notarytool submit ./_CPack_Packages/OSX_13_arm64/DragNDrop/vimix_0.8.2_OSX_13_arm64.dmg --keychain-profile "vimix" --wait
##
## verify with: xcrun notarytool log xxxx-xxxx-xxx --keychain-profile "vimix"
##
## NB: "vimix" is the name of the app-specific password in keychain
## generated online : https://support.apple.com/en-us/102654
##
Expand Down
2 changes: 1 addition & 1 deletion src/FrameGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ void FrameGrabber::addFrame (GstBuffer *buffer, GstCaps *caps)
// if initialization succeeded
if (initialized_) {

#ifdef IGNORE_GST_ERROR_MESSAGE
#ifdef IGNORE_GST_BUS_MESSAGE
// avoid filling up bus with messages
gst_bus_set_flushing(gst_element_get_bus(pipeline_), true);
#else
Expand Down
117 changes: 77 additions & 40 deletions src/MediaPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ MediaPlayer::~MediaPlayer()
// cleanup picture buffer
if (pbo_[0])
glDeleteBuffers(2, pbo_);

#ifdef MEDIA_PLAYER_DEBUG
g_printerr("MediaPlayer %s deleted\n", std::to_string(id_).c_str());
#endif
}

void MediaPlayer::accept(Visitor& v) {
Expand Down Expand Up @@ -360,6 +364,7 @@ GstBusSyncReply MediaPlayer::signal_handler(GstBus *, GstMessage *msg, gpointer
}

// drop all messages to avoid filling up the stack
gst_message_unref (msg);
return GST_BUS_DROP;
}

Expand Down Expand Up @@ -483,7 +488,7 @@ void MediaPlayer::execute_open()
#endif

// set to desired state (PLAY or PAUSE)
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
GstStateChangeReturn ret = gst_element_set_state (GST_ELEMENT(pipeline_), desired_state_);
if (ret == GST_STATE_CHANGE_FAILURE) {
Log::Warning("MediaPlayer %s Could not open '%s'", std::to_string(id_).c_str(), uri_.c_str());
failed_ = true;
Expand All @@ -497,13 +502,13 @@ void MediaPlayer::execute_open()
timeline_.setEnd(d);
}

#ifdef IGNORE_GST_ERROR_MESSAGE
bus_ = gst_element_get_bus(pipeline_);
#ifdef IGNORE_GST_BUS_MESSAGE
// avoid filling up bus with messages
gst_bus_set_flushing(gst_element_get_bus(pipeline_), true);
gst_bus_set_flushing(bus_, true);
#else
// set message handler for the pipeline's bus
gst_bus_set_sync_handler(gst_element_get_bus(pipeline_),
MediaPlayer::signal_handler, this, NULL);
gst_bus_set_sync_handler(bus_, MediaPlayer::signal_handler, this, NULL);
#endif

// all good
Expand All @@ -514,9 +519,8 @@ void MediaPlayer::execute_open()
Log::Info("MediaPlayer %s Timeline [%ld %ld] %ld frames, %d gaps", std::to_string(id_).c_str(),
timeline_.begin(), timeline_.end(), timeline_.numFrames(), timeline_.numGaps());

if (media_.hasaudio) {
if (media_.hasaudio)
Log::Info("MediaPlayer %s Audio track %s", std::to_string(id_).c_str(), audio_enabled_ ? "enabled" : "disabled");
}

opened_ = true;

Expand Down Expand Up @@ -602,8 +606,9 @@ void MediaPlayer::execute_open()
return;
}
#ifdef MEDIA_PLAYER_DEBUG
Log::Info("MediaPlayer %s Pipeline [%s]", std::to_string(id_).c_str(), description.c_str());
Log::Info("MediaPlayer %s Pipeline [%s]", std::to_string(id_).c_str(), description.c_str());
#endif
gst_object_ref(pipeline_);

// setup pipeline
g_object_set(G_OBJECT(pipeline_), "name", std::to_string(id_).c_str(), NULL);
Expand Down Expand Up @@ -684,6 +689,15 @@ void MediaPlayer::execute_open()
timeline_.setEnd(d);
}

bus_ = gst_element_get_bus(pipeline_);
#ifdef IGNORE_GST_BUS_MESSAGE
// avoid filling up bus with messages
gst_bus_set_flushing(bus_, true);
#else
// set message handler for the pipeline's bus
gst_bus_set_sync_handler(bus_, MediaPlayer::signal_handler, this, NULL);
#endif

// all good
Log::Info("MediaPlayer %s Opened '%s' (%s %d x %d)", std::to_string(id_).c_str(),
SystemToolkit::filename(uri_).c_str(), media_.codec_name.c_str(), media_.width, media_.height);
Expand Down Expand Up @@ -738,26 +752,43 @@ bool MediaPlayer::failed() const

void MediaPlayer::Frame::unmap()
{
if ( full )
if (full)
gst_video_frame_unmap(&vframe);

full = false;
}


void MediaPlayer::pipeline_terminate( GstElement *p )
void MediaPlayer::pipeline_terminate( GstElement *p, GstBus *b )
{
#ifdef MEDIA_PLAYER_DEBUG
gchar *name = gst_element_get_name(p);
g_printerr("MediaPlayer %s close\n", name);
Log::Info("MediaPlayer %s closed", name);
g_free(name);
#ifdef MEDIA_PLAYER_DEBUG
g_printerr("MediaPlayer %s closing\n", name);
#endif

#ifndef IGNORE_GST_BUS_MESSAGE
// empty pipeline bus (if used)
GstMessage *msg = NULL;
do {
if (msg)
gst_message_unref (msg);
msg = gst_bus_timed_pop_filtered(b, 1000000, GST_MESSAGE_ANY);
} while (msg != NULL);
#endif
// unref bus
gst_object_unref( GST_OBJECT(b) );

// end pipeline
gst_element_set_state (p, GST_STATE_NULL);
GstStateChangeReturn ret = gst_element_set_state(p, GST_STATE_NULL);
if (ret == GST_STATE_CHANGE_ASYNC)
gst_element_get_state(p, NULL, NULL, 1000000);

// unref to free pipeline
gst_object_unref ( p );
while (GST_OBJECT_REFCOUNT_VALUE(p) > 0)
gst_object_unref( GST_OBJECT(p) );

// all done
Log::Info("MediaPlayer %s Closed", name);
g_free(name);

// unregister
MediaPlayer::registered_.remove(p);
Expand All @@ -775,33 +806,34 @@ void MediaPlayer::close()
return;
}

// un-ready the media player
opened_ = false;
failed_ = false;
pending_ = false;
seeking_ = false;
force_update_ = false;
rate_ = 1.0;
rate_change_ = RATE_CHANGE_NONE;
position_ = GST_CLOCK_TIME_NONE;

// clean up GST
if (pipeline_ != nullptr) {
// end pipeline asynchronously
std::thread(MediaPlayer::pipeline_terminate, pipeline_).detach();
pipeline_ = nullptr;
}

// cleanup eventual remaining frame memory
for(guint i = 0; i < N_VFRAME; i++) {
frame_[i].access.lock();
frame_[i].unmap();
frame_[i].status = INVALID;
frame_[i].access.unlock();
}

// clean up GST
if (pipeline_ != nullptr) {
// end pipeline asynchronously
std::thread(MediaPlayer::pipeline_terminate, pipeline_, bus_).detach();
// immediately invalidate access for other methods
pipeline_ = nullptr;
bus_ = nullptr;
}

// un-ready the media player
write_index_ = 0;
last_index_ = 0;

opened_ = false;
failed_ = false;
pending_ = false;
seeking_ = false;
force_update_ = false;
rate_ = 1.0;
rate_change_ = RATE_CHANGE_NONE;
position_ = GST_CLOCK_TIME_NONE;
}


Expand Down Expand Up @@ -1209,11 +1241,10 @@ void MediaPlayer::fill_texture(guint index)
glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size_, 0, GL_STREAM_DRAW);
// map the buffer object into client's memory
GLubyte* ptr = (GLubyte*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
if (ptr) {
if (ptr)
memmove(ptr, frame_[index].vframe.data[0], pbo_size_);
// release pointer to mapping buffer
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
// release pointer to mapping buffer
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
#endif
// done with PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
Expand Down Expand Up @@ -1352,6 +1383,12 @@ void MediaPlayer::update()
if (need_loop && desired_state_ == GST_STATE_PLAYING) // avoid repeated call
execute_loop_command();

#ifndef IGNORE_GST_BUS_MESSAGE
GstMessage *msg = gst_bus_pop_filtered(bus_, GST_MESSAGE_ANY);
if (msg != NULL)
gst_message_unref(msg);
#endif

force_update_ = false;
}

Expand Down Expand Up @@ -1411,7 +1448,7 @@ void MediaPlayer::execute_seek_command(GstClockTime target, bool force)
if (seek_event && gst_element_send_event(pipeline_, seek_event) ) {
seeking_ = true;
#ifdef MEDIA_PLAYER_DEBUG
Log::Info("MediaPlayer %s Seek %ld %.1f", std::to_string(id_).c_str(), seek_pos, rate_);
g_printerr("MediaPlayer %s Seek %ld %.1f", std::to_string(id_).c_str(), seek_pos, rate_);
#endif
}
else
Expand Down
3 changes: 2 additions & 1 deletion src/MediaPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ class MediaPlayer {
LoopMode loop_;
GstState desired_state_;
GstElement *pipeline_;
GstBus *bus_;
GstVideoInfo v_frame_video_info_;
std::atomic<bool> opened_;
std::atomic<bool> failed_;
Expand Down Expand Up @@ -409,7 +410,7 @@ class MediaPlayer {
static void callback_element_setup (GstElement *pipeline, GstElement *element, MediaPlayer *mp);

// global list of registered media player
static void pipeline_terminate(GstElement *p);
static void pipeline_terminate(GstElement *p, GstBus *b);
static std::list<GstElement*> registered_;
};

Expand Down
3 changes: 3 additions & 0 deletions src/MultiFileRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ bool MultiFileRecorder::end_record ()
ret = false;
}

gst_message_unref (msg);
gst_object_unref (bus);

// stop the pipeline
GstStateChangeReturn r = gst_element_set_state (pipeline_, GST_STATE_NULL);
if (r == GST_STATE_CHANGE_ASYNC) {
Expand Down
3 changes: 2 additions & 1 deletion src/SourceControlWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ SourceControlWindow::SourceControlWindow() : WorkspaceWindow("SourceController")
checker_background_->play(false);
while (checker_background_->texture() == Resource::getTextureBlack())
checker_background_->update();
checker_background_->close();
}


Expand Down Expand Up @@ -2828,7 +2829,7 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms)
static uint _status = 0; // 0:unknown, 1:ok, 2:error
static std::string _status_message = "";
static std::vector< std::pair< std::string, std::string> > _examples = { {"Primary color", "frei0r-filter-primaries" },
{"Histogram", "frei0r-filter-rgb-parade mix=0.5"},
{"Histogram", "frei0r-filter-levels"},
{"Emboss", "frei0r-filter-emboss"},
{"Denoise", "frei0r-filter-hqdn3d spatial=0.05 temporal=0.1"},
{"Thermal", "coloreffects preset=heat"},
Expand Down
Loading

0 comments on commit d795fee

Please sign in to comment.