From a435daa494fde52118acdde96952a9847180f79c Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sat, 14 Mar 2020 10:55:26 +0100 Subject: [PATCH] Fixed Media Player behavior --- ImGuiToolkit.cpp | 2 +- MediaPlayer.cpp | 7 +++++- main.cpp | 55 ++++++++++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index fd96101..05a4cb9 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -220,7 +220,7 @@ bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 begi bool value_changed = ImGui::SliderBehavior(slider_bbox, id, ImGuiDataType_Float, &time_slider, &time_zero, &time_end, "%.2f", 1.f, ImGuiSliderFlags_None, &grab_bb); if (value_changed){ - //ImGuiToolkit::Log("slider %f %ld \n", time_slider, static_cast ( static_cast(time_slider) * static_cast(duration) )); +// g_print("slider %f %ld \n", time_slider, static_cast ( static_cast(time_slider) * static_cast(duration) )); *time = static_cast ( static_cast(time_slider) * static_cast(duration) ); } diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index 7ee18a3..a404b8f 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -365,8 +365,13 @@ void MediaPlayer::SeekTo(GstClockTime pos) if (!seekable) return; + // remember pos + GstClockTime previous_pos = Position(); + + // apply seek GstClockTime target = CLAMP(pos, 0, duration); execute_seek_command(target); + } void MediaPlayer::FastForward() @@ -467,7 +472,7 @@ void MediaPlayer::execute_seek_command(GstClockTime target) else if ( ABS_DIFF(target, Position()) < frame_duration) { // ignore request #ifdef MEDIA_PLAYER_DEBUG - Log::Info("%s: Media Player ignored seek to current position\n", id); + Log::Info("%s: Media Player ignored seek to current position\n", id.c_str()); #endif return; } diff --git a/main.cpp b/main.cpp index c8f1339..d0ec587 100644 --- a/main.cpp +++ b/main.cpp @@ -201,9 +201,11 @@ void drawMediaBackgound() void drawMediaPlayer() { + if ( !testmedia.isOpen() ) return; + testmedia.Update(); ImGui::Begin("Media Player"); @@ -217,13 +219,14 @@ void drawMediaPlayer() testmedia.Rewind(); ImGui::SameLine(0, spacing); - static bool media_playing = testmedia.isPlaying(); + // remember playing mode of the GUI + static bool media_playing_mode = testmedia.isPlaying(); - // display buttons Play/Stop depending on current playing state - if (media_playing) { + // display buttons Play/Stop depending on current playing mode + if (media_playing_mode) { if (ImGui::Button(ICON_FA_STOP " Stop")) - testmedia.Play(false); + media_playing_mode = false; ImGui::SameLine(0, spacing); ImGui::PushButtonRepeat(true); @@ -234,7 +237,7 @@ void drawMediaPlayer() else { if (ImGui::Button(ICON_FA_PLAY " Play")) - testmedia.Play(true); + media_playing_mode = true; ImGui::SameLine(0, spacing); ImGui::PushButtonRepeat(true); @@ -271,30 +274,32 @@ void drawMediaPlayer() } guint64 current_t = testmedia.Position(); - guint64 t = current_t; + guint64 seek_t = current_t; guint64 begin = testmedia.Duration() / 5; guint64 end = 4 * testmedia.Duration() / 5; - static bool slider_was_pressed = false; - bool slider_pressed = ImGuiToolkit::TimelineSlider( "timeline", &t, begin, end, + bool slider_pressed = ImGuiToolkit::TimelineSlider( "timeline", &seek_t, begin, end, testmedia.Duration(), testmedia.FrameDuration()); - // change status only - if (slider_pressed != slider_was_pressed) { + // if the seek target time is different from the current position time + // (i.e. the difference is less than one frame) + if ( ABS_DIFF (current_t, seek_t) > testmedia.FrameDuration() ) { - // if was playing, pause during slider press - if ( media_playing ) - testmedia.Play( !slider_pressed ); - - slider_was_pressed = slider_pressed; + // request seek (ASYNC) + testmedia.SeekTo(seek_t); + } + + // play/stop command should be following the playing mode (buttons) + // AND force to stop when the slider is pressed + bool media_play = media_playing_mode & (!slider_pressed); + + // apply play action to media only if status should change + // NB: The seek command performed an ASYNC state change, but + // gst_element_get_state called in isPlaying() will wait for the state change to complete. + if ( testmedia.isPlaying() != media_play ) { + testmedia.Play( media_play ); } - // normal update of media status - if (!slider_was_pressed) - media_playing = testmedia.isPlaying(); - // seek only if position is new - if (current_t != t) - testmedia.SeekTo(t); // display info ImGui::Text("Dimension %d x %d", testmedia.Width(), testmedia.Height()); @@ -337,8 +342,8 @@ int main(int, char**) // testmedia.Open("file:///home/bhbn/Videos/balls.gif"); // testmedia.Open("file:///home/bhbn/Videos/SIGGRAPH92_1.avi"); // testmedia.Open("file:///home/bhbn/Videos/fish.mp4"); - testmedia.Open("file:///home/bhbn/Videos/iss.mov"); - // testmedia.Open("file:///home/bhbn/Videos/TearsOfSteel_720p_h265.mkv"); +// testmedia.Open("file:///home/bhbn/Videos/iss.mov"); + testmedia.Open("file:///home/bhbn/Videos/TearsOfSteel_720p_h265.mkv"); // testmedia.Open("file:///home/bhbn/Videos/TestFormats/_h264GoldenLamps.mkv"); // testmedia.Open("file:///home/bhbn/Videos/TestEncoding/vpxvp9high.webm"); @@ -347,8 +352,8 @@ int main(int, char**) Rendering::AddDrawCallback(drawMediaPlayer); // 2 -// testmedia2.Open("file:///home/bhbn/Videos/iss.mov"); - testmedia2.Open("file:///home/bhbn/Images/svg/drawing.svg"); + testmedia2.Open("file:///home/bhbn/Videos/iss.mov"); +// testmedia2.Open("file:///home/bhbn/Images/svg/drawing.svg"); // testmedia2.Open("file:///home/bhbn/Videos/Upgrade.2018.720p.AMZN.WEB-DL.DDP5.1.H.264-NTG.m4v"); testmedia2.Play(true); // create our geometries