mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-17 21:29:59 +01:00
Add Alpha fading mode to media player timeline
Fading color (to black) is not useful for media with transparency; there fading of alpha is necessary; the fading mode allows to select fade color or fade alpha. Also the source control window had to be adapted, with a checkerboard to show the alpha effect. The cropping of the image in control window was also fixed.
This commit is contained in:
@@ -72,6 +72,7 @@ MediaPlayer::MediaPlayer()
|
||||
video_filter_available_ = true;
|
||||
position_ = GST_CLOCK_TIME_NONE;
|
||||
loop_ = LoopMode::LOOP_REWIND;
|
||||
fading_mode_ = FadingMode::FADING_COLOR;
|
||||
|
||||
// default audio disabled
|
||||
audio_enabled_ = false;
|
||||
|
||||
@@ -206,8 +206,19 @@ public:
|
||||
*/
|
||||
Timeline *timeline();
|
||||
void setTimeline(const Timeline &tl);
|
||||
|
||||
/**
|
||||
* Get fading value at current time
|
||||
* */
|
||||
float currentTimelineFading();
|
||||
/**
|
||||
* Get fading mode
|
||||
* */
|
||||
typedef enum { FADING_COLOR = 0, FADING_ALPHA = 1 } FadingMode;
|
||||
FadingMode timelineFadingMode() { return fading_mode_; }
|
||||
/**
|
||||
* Set fading mode
|
||||
* */
|
||||
void setTimelineFadingMode(FadingMode m) { fading_mode_ = m; }
|
||||
/**
|
||||
* Get framerate of the media
|
||||
* */
|
||||
@@ -314,6 +325,7 @@ private:
|
||||
// general properties of media
|
||||
MediaInfo media_;
|
||||
Timeline timeline_;
|
||||
FadingMode fading_mode_;
|
||||
std::future<MediaInfo> discoverer_;
|
||||
|
||||
// GST & Play status
|
||||
|
||||
@@ -197,7 +197,10 @@ void MediaSource::render()
|
||||
// NB: this also applies the color correction shader
|
||||
renderbuffer_->begin();
|
||||
// apply fading
|
||||
if (mediaplayer_->timelineFadingMode() != MediaPlayer::FADING_ALPHA)
|
||||
texturesurface_->shader()->color = glm::vec4( glm::vec3(mediaplayer_->currentTimelineFading()), 1.f);
|
||||
else
|
||||
texturesurface_->shader()->color = glm::vec4( glm::vec3(1.f), mediaplayer_->currentTimelineFading());
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), renderbuffer_->projection());
|
||||
renderbuffer_->end();
|
||||
ready_ = true;
|
||||
|
||||
@@ -912,6 +912,9 @@ void SessionLoader::visit(MediaPlayer &n)
|
||||
if (fadingselement) {
|
||||
XMLElement* array = fadingselement->FirstChildElement("array");
|
||||
XMLElementDecodeArray(array, tl.fadingArray(), MAX_TIMELINE_ARRAY * sizeof(float));
|
||||
uint mode = 0;
|
||||
fadingselement->QueryUnsignedAttribute("mode", &mode);
|
||||
n.setTimelineFadingMode((MediaPlayer::FadingMode) mode);
|
||||
}
|
||||
n.setTimeline(tl);
|
||||
}
|
||||
|
||||
@@ -465,6 +465,7 @@ void SessionVisitor::visit(MediaPlayer &n)
|
||||
fadingelement->InsertEndChild(array);
|
||||
timelineelement->InsertEndChild(fadingelement);
|
||||
newelement->InsertEndChild(timelineelement);
|
||||
fadingelement->SetAttribute("mode", (uint) n.timelineFadingMode());
|
||||
}
|
||||
|
||||
xmlCurrent_->InsertEndChild(newelement);
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "SystemToolkit.h"
|
||||
#include "DialogToolkit.h"
|
||||
#include "GstToolkit.h"
|
||||
#include "Resource.h"
|
||||
#include "PatternSource.h"
|
||||
|
||||
#include "Mixer.h"
|
||||
#include "CloneSource.h"
|
||||
@@ -43,6 +45,8 @@
|
||||
|
||||
#include "SourceControlWindow.h"
|
||||
|
||||
#define CHECKER_RESOLUTION 6000
|
||||
class Stream *checker_background_ = new Stream;
|
||||
void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider = false, bool withinspector = false);
|
||||
ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector);
|
||||
|
||||
@@ -59,6 +63,14 @@ SourceControlWindow::SourceControlWindow() : WorkspaceWindow("SourceController")
|
||||
info_.setExtendedStringMode();
|
||||
|
||||
captureFolderDialog = new DialogToolkit::OpenFolderDialog("Capture frame Location");
|
||||
|
||||
// initialize checkerboard background texture
|
||||
checker_background_->open("videotestsrc pattern=checkers-8 ! "
|
||||
"videobalance saturation=0 contrast=1",
|
||||
CHECKER_RESOLUTION, CHECKER_RESOLUTION);
|
||||
checker_background_->play(true);
|
||||
while (checker_background_->texture() == Resource::getTextureBlack())
|
||||
checker_background_->update();
|
||||
}
|
||||
|
||||
|
||||
@@ -401,6 +413,13 @@ void SourceControlWindow::Render()
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
|
||||
bool _alpha_fading = mediaplayer_active_->timelineFadingMode()
|
||||
== MediaPlayer::FADING_ALPHA;
|
||||
if (ImGui::MenuItem(ICON_FA_FONT " Alpha fading", NULL, &_alpha_fading)) {
|
||||
mediaplayer_active_->setTimelineFadingMode(
|
||||
_alpha_fading ? MediaPlayer::FADING_ALPHA : MediaPlayer::FADING_COLOR);
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(LABEL_EDIT_FADING))
|
||||
mediaplayer_edit_fading_ = true;
|
||||
|
||||
@@ -1010,9 +1029,19 @@ void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider,
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
// pre-draw background with checkerboard pattern
|
||||
ImGui::Image((void*)(uintptr_t) checker_background_->texture(), framesize,
|
||||
ImVec2(0,0), ImVec2(framesize.x/CHECKER_RESOLUTION, framesize.y/CHECKER_RESOLUTION));
|
||||
|
||||
// get back to top image corner to draw
|
||||
ImGui::SetCursorScreenPos(top_image);
|
||||
|
||||
// info on source
|
||||
CloneSource *cloned = dynamic_cast<CloneSource *>(s);
|
||||
|
||||
// 100% opacity for the image (ensure true colors)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f);
|
||||
|
||||
// draw pre and post-processed parts if necessary
|
||||
if (s->imageProcessingEnabled() || s->textureTransformed() || cloned != nullptr) {
|
||||
|
||||
@@ -1027,8 +1056,14 @@ void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider,
|
||||
//
|
||||
// RIGHT of slider : post-processed image (after crop and color correction)
|
||||
//
|
||||
ImVec2 cropsize = framesize * ImVec2 ( s->frame()->projectionSize().x, s->frame()->projectionSize().y);
|
||||
ImVec2 croptop = (framesize - cropsize) * 0.5f;
|
||||
glm::vec4 _crop = s->frame()->projectionArea();
|
||||
ImVec2 cropsize = ImVec2(0.5f * (_crop[1] - _crop[0]),
|
||||
0.5f * (_crop[2] - _crop[3]));
|
||||
ImVec2 croptop = ImVec2(0.5f * (1.f + _crop[0]),
|
||||
0.5f * (1.f - _crop[2]) );
|
||||
cropsize = framesize * cropsize;
|
||||
croptop = framesize * croptop;
|
||||
|
||||
// no overlap of slider with cropped area
|
||||
if (slider.x < croptop.x) {
|
||||
// draw cropped area
|
||||
@@ -1076,6 +1111,8 @@ void DrawSource(Source *s, ImVec2 framesize, ImVec2 top_image, bool withslider,
|
||||
if ( withinspector && ImGui::IsItemHovered() )
|
||||
DrawInspector(s->texture(), framesize, framesize, top_image);
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_inspector)
|
||||
@@ -1105,11 +1142,14 @@ ImRect DrawSourceWithSlider(Source *s, ImVec2 top, ImVec2 rendersize, bool with_
|
||||
const ImVec2 top_image = top + corner;
|
||||
ImGui::SetCursorScreenPos(top_image);
|
||||
|
||||
// pre-draw background with checkerboard pattern
|
||||
ImGui::Image((void*)(uintptr_t) checker_background_->texture(), framesize,
|
||||
ImVec2(0,0), ImVec2(framesize.x/CHECKER_RESOLUTION, framesize.y/CHECKER_RESOLUTION));
|
||||
|
||||
// draw source
|
||||
if (s->ready()) {
|
||||
// 100% opacity for the image (ensure true colors)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.f);
|
||||
ImGui::SetCursorScreenPos(top_image);
|
||||
DrawSource(s, framesize, top_image, true, with_inspector);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
return ImRect( top_image, top_image + framesize);
|
||||
@@ -1643,14 +1683,14 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms)
|
||||
bottom += ImVec2(scrollwindow.x + 2.f, 0.f);
|
||||
draw_list->AddRectFilled(bottom, bottom + ImVec2(slider_zoom_width, timeline_height_ -1.f), ImGui::GetColorU32(ImGuiCol_FrameBg));
|
||||
ImGui::SetCursorScreenPos(bottom + ImVec2(1.f, 0.f));
|
||||
const char *tooltip[2] = {"Draw opacity tool", "Cut tool"};
|
||||
const char *tooltip[2] = {"Fading draw tool", "Timeline cut tool"};
|
||||
ImGuiToolkit::IconToggle(7,4,8,3, &Settings::application.widget.media_player_timeline_editmode, tooltip);
|
||||
|
||||
ImGui::SetCursorScreenPos(bottom + ImVec2(1.f, 0.5f * timeline_height_));
|
||||
if (Settings::application.widget.media_player_timeline_editmode) {
|
||||
// action cut
|
||||
if (mediaplayer_active_->isPlaying()) {
|
||||
ImGuiToolkit::Indication("Pause video to enable cut options", 9, 3);
|
||||
ImGuiToolkit::Indication("Pause to enable cut at cursor", 9, 3);
|
||||
}
|
||||
else if (ImGuiToolkit::IconButton(9, 3, "Cut at cursor")) {
|
||||
ImGui::OpenPopup("timeline_cut_context_menu");
|
||||
@@ -1676,7 +1716,7 @@ void SourceControlWindow::RenderMediaPlayer(MediaSource *ms)
|
||||
|
||||
// action smooth
|
||||
ImGui::PushButtonRepeat(true);
|
||||
if (ImGuiToolkit::IconButton(13, 12, "Smooth")){
|
||||
if (ImGuiToolkit::IconButton(13, 12, "Smooth fading curve")){
|
||||
mediaplayer_active_->timeline()->smoothFading( 5 );
|
||||
++_actionsmooth;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user