From 25e4bd9d8d3b87eb486e06e6e4af992b142831ca Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 9 Dec 2018 15:44:17 +1100 Subject: [PATCH] added routines for alpha channel editing --- olive.pro | 392 +++++++++++++++++++++--------------------- playback/playback.cpp | 29 +++- playback/playback.h | 1 + project/effect.cpp | 25 +-- project/effect.h | 4 +- project/effectgizmo.h | 2 + ui/viewerwidget.cpp | 22 ++- 7 files changed, 263 insertions(+), 212 deletions(-) diff --git a/olive.pro b/olive.pro index 52a855dab..78d642345 100644 --- a/olive.pro +++ b/olive.pro @@ -1,195 +1,197 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-05-11T10:31:59 -# -#------------------------------------------------- - -QT += core gui multimedia opengl - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = Olive -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - mainwindow.cpp \ - panels/project.cpp \ - panels/effectcontrols.cpp \ - panels/viewer.cpp \ - panels/timeline.cpp \ - ui/sourcetable.cpp \ - dialogs/aboutdialog.cpp \ - ui/timelinewidget.cpp \ - io/media.cpp \ - project/sequence.cpp \ - project/clip.cpp \ - playback/playback.cpp \ - playback/audio.cpp \ - io/config.cpp \ - dialogs/newsequencedialog.cpp \ - ui/viewerwidget.cpp \ - ui/viewercontainer.cpp \ - dialogs/exportdialog.cpp \ - ui/collapsiblewidget.cpp \ - panels/panels.cpp \ - playback/cacher.cpp \ - io/exportthread.cpp \ - ui/timelineheader.cpp \ - io/previewgenerator.cpp \ - ui/labelslider.cpp \ - dialogs/preferencesdialog.cpp \ - ui/audiomonitor.cpp \ - project/undo.cpp \ - ui/scrollarea.cpp \ - ui/comboboxex.cpp \ - ui/colorbutton.cpp \ - dialogs/replaceclipmediadialog.cpp \ - ui/fontcombobox.cpp \ - ui/checkboxex.cpp \ - ui/keyframeview.cpp \ - ui/texteditex.cpp \ - dialogs/demonotice.cpp \ - project/marker.cpp \ - dialogs/speeddialog.cpp \ - dialogs/mediapropertiesdialog.cpp \ - io/crc32.cpp \ - dialogs/loaddialog.cpp \ - debug.cpp \ - io/path.cpp \ - effects/internal/linearfadetransition.cpp \ - effects/internal/transformeffect.cpp \ - effects/internal/solideffect.cpp \ - effects/internal/texteffect.cpp \ - effects/internal/timecodeeffect.cpp \ - effects/internal/audionoiseeffect.cpp \ - effects/internal/paneffect.cpp \ - effects/internal/toneeffect.cpp \ - effects/internal/volumeeffect.cpp \ - effects/internal/crossdissolvetransition.cpp \ - effects/internal/shakeeffect.cpp \ - effects/internal/exponentialfadetransition.cpp \ - effects/internal/logarithmicfadetransition.cpp \ - effects/internal/cornerpineffect.cpp \ - io/math.cpp \ - io/qpainterwrapper.cpp \ - project/effect.cpp \ - project/transition.cpp \ - project/effectrow.cpp \ - project/effectfield.cpp \ - effects/internal/cubetransition.cpp \ - project/effectgizmo.cpp \ - io/clipboard.cpp - -HEADERS += \ - mainwindow.h \ - panels/project.h \ - panels/effectcontrols.h \ - panels/viewer.h \ - panels/timeline.h \ - ui/sourcetable.h \ - dialogs/aboutdialog.h \ - ui/timelinewidget.h \ - io/media.h \ - project/sequence.h \ - project/clip.h \ - playback/playback.h \ - playback/audio.h \ - io/config.h \ - dialogs/newsequencedialog.h \ - ui/viewerwidget.h \ - ui/viewercontainer.h \ - dialogs/exportdialog.h \ - ui/collapsiblewidget.h \ - panels/panels.h \ - playback/cacher.h \ - io/exportthread.h \ - ui/timelinetools.h \ - ui/timelineheader.h \ - io/previewgenerator.h \ - ui/labelslider.h \ - dialogs/preferencesdialog.h \ - ui/audiomonitor.h \ - project/undo.h \ - ui/scrollarea.h \ - ui/comboboxex.h \ - ui/colorbutton.h \ - dialogs/replaceclipmediadialog.h \ - ui/fontcombobox.h \ - ui/checkboxex.h \ - ui/keyframeview.h \ - ui/texteditex.h \ - dialogs/demonotice.h \ - project/marker.h \ - project/selection.h \ - dialogs/speeddialog.h \ - dialogs/mediapropertiesdialog.h \ - io/crc32.h \ - dialogs/loaddialog.h \ - debug.h \ - io/path.h \ - effects/internal/transformeffect.h \ - effects/internal/solideffect.h \ - effects/internal/texteffect.h \ - effects/internal/timecodeeffect.h \ - effects/internal/audionoiseeffect.h \ - effects/internal/paneffect.h \ - effects/internal/toneeffect.h \ - effects/internal/volumeeffect.h \ - effects/internal/shakeeffect.h \ - effects/internal/linearfadetransition.h \ - effects/internal/crossdissolvetransition.h \ - effects/internal/exponentialfadetransition.h \ - effects/internal/logarithmicfadetransition.h \ - effects/internal/cornerpineffect.h \ - io/math.h \ - io/qpainterwrapper.h \ - project/effect.h \ - project/transition.h \ - project/effectrow.h \ - project/effectfield.h \ - effects/internal/cubetransition.h \ - project/effectgizmo.h \ - io/clipboard.h - -FORMS += \ - mainwindow.ui \ - panels/project.ui \ - panels/effectcontrols.ui \ - panels/viewer.ui \ - panels/timeline.ui \ - dialogs/aboutdialog.ui \ - dialogs/newsequencedialog.ui \ - dialogs/exportdialog.ui \ - dialogs/preferencesdialog.ui \ - dialogs/demonotice.ui - -win32 { - RC_FILE = icons/resources.rc - LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -} - -mac { - LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample - ICON = icons/olive.icns - INCLUDEPATH = /usr/local/include -} - -linux { - LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -} - -RESOURCES += \ - icons/icons.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2018-05-11T10:31:59 +# +#------------------------------------------------- + +QT += core gui multimedia opengl + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = Olive +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + panels/project.cpp \ + panels/effectcontrols.cpp \ + panels/viewer.cpp \ + panels/timeline.cpp \ + ui/sourcetable.cpp \ + dialogs/aboutdialog.cpp \ + ui/timelinewidget.cpp \ + io/media.cpp \ + project/sequence.cpp \ + project/clip.cpp \ + playback/playback.cpp \ + playback/audio.cpp \ + io/config.cpp \ + dialogs/newsequencedialog.cpp \ + ui/viewerwidget.cpp \ + ui/viewercontainer.cpp \ + dialogs/exportdialog.cpp \ + ui/collapsiblewidget.cpp \ + panels/panels.cpp \ + playback/cacher.cpp \ + io/exportthread.cpp \ + ui/timelineheader.cpp \ + io/previewgenerator.cpp \ + ui/labelslider.cpp \ + dialogs/preferencesdialog.cpp \ + ui/audiomonitor.cpp \ + project/undo.cpp \ + ui/scrollarea.cpp \ + ui/comboboxex.cpp \ + ui/colorbutton.cpp \ + dialogs/replaceclipmediadialog.cpp \ + ui/fontcombobox.cpp \ + ui/checkboxex.cpp \ + ui/keyframeview.cpp \ + ui/texteditex.cpp \ + dialogs/demonotice.cpp \ + project/marker.cpp \ + dialogs/speeddialog.cpp \ + dialogs/mediapropertiesdialog.cpp \ + io/crc32.cpp \ + dialogs/loaddialog.cpp \ + debug.cpp \ + io/path.cpp \ + effects/internal/linearfadetransition.cpp \ + effects/internal/transformeffect.cpp \ + effects/internal/solideffect.cpp \ + effects/internal/texteffect.cpp \ + effects/internal/timecodeeffect.cpp \ + effects/internal/audionoiseeffect.cpp \ + effects/internal/paneffect.cpp \ + effects/internal/toneeffect.cpp \ + effects/internal/volumeeffect.cpp \ + effects/internal/crossdissolvetransition.cpp \ + effects/internal/shakeeffect.cpp \ + effects/internal/exponentialfadetransition.cpp \ + effects/internal/logarithmicfadetransition.cpp \ + effects/internal/cornerpineffect.cpp \ + io/math.cpp \ + io/qpainterwrapper.cpp \ + project/effect.cpp \ + project/transition.cpp \ + project/effectrow.cpp \ + project/effectfield.cpp \ + effects/internal/cubetransition.cpp \ + project/effectgizmo.cpp \ + io/clipboard.cpp \ + effects/internal/maskeffect.cpp + +HEADERS += \ + mainwindow.h \ + panels/project.h \ + panels/effectcontrols.h \ + panels/viewer.h \ + panels/timeline.h \ + ui/sourcetable.h \ + dialogs/aboutdialog.h \ + ui/timelinewidget.h \ + io/media.h \ + project/sequence.h \ + project/clip.h \ + playback/playback.h \ + playback/audio.h \ + io/config.h \ + dialogs/newsequencedialog.h \ + ui/viewerwidget.h \ + ui/viewercontainer.h \ + dialogs/exportdialog.h \ + ui/collapsiblewidget.h \ + panels/panels.h \ + playback/cacher.h \ + io/exportthread.h \ + ui/timelinetools.h \ + ui/timelineheader.h \ + io/previewgenerator.h \ + ui/labelslider.h \ + dialogs/preferencesdialog.h \ + ui/audiomonitor.h \ + project/undo.h \ + ui/scrollarea.h \ + ui/comboboxex.h \ + ui/colorbutton.h \ + dialogs/replaceclipmediadialog.h \ + ui/fontcombobox.h \ + ui/checkboxex.h \ + ui/keyframeview.h \ + ui/texteditex.h \ + dialogs/demonotice.h \ + project/marker.h \ + project/selection.h \ + dialogs/speeddialog.h \ + dialogs/mediapropertiesdialog.h \ + io/crc32.h \ + dialogs/loaddialog.h \ + debug.h \ + io/path.h \ + effects/internal/transformeffect.h \ + effects/internal/solideffect.h \ + effects/internal/texteffect.h \ + effects/internal/timecodeeffect.h \ + effects/internal/audionoiseeffect.h \ + effects/internal/paneffect.h \ + effects/internal/toneeffect.h \ + effects/internal/volumeeffect.h \ + effects/internal/shakeeffect.h \ + effects/internal/linearfadetransition.h \ + effects/internal/crossdissolvetransition.h \ + effects/internal/exponentialfadetransition.h \ + effects/internal/logarithmicfadetransition.h \ + effects/internal/cornerpineffect.h \ + io/math.h \ + io/qpainterwrapper.h \ + project/effect.h \ + project/transition.h \ + project/effectrow.h \ + project/effectfield.h \ + effects/internal/cubetransition.h \ + project/effectgizmo.h \ + io/clipboard.h \ + effects/internal/maskeffect.h + +FORMS += \ + mainwindow.ui \ + panels/project.ui \ + panels/effectcontrols.ui \ + panels/viewer.ui \ + panels/timeline.ui \ + dialogs/aboutdialog.ui \ + dialogs/newsequencedialog.ui \ + dialogs/exportdialog.ui \ + dialogs/preferencesdialog.ui \ + dialogs/demonotice.ui + +win32 { + RC_FILE = icons/resources.rc + LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 +} + +mac { + LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample + ICON = icons/olive.icns + INCLUDEPATH = /usr/local/include +} + +linux { + LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample +} + +RESOURCES += \ + icons/icons.qrc diff --git a/playback/playback.cpp b/playback/playback.cpp index 638a4ec43..c8295e0ba 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -111,6 +111,10 @@ void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVectorget_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); +} + void get_clip_frame(Clip* c, long playhead) { if (c->finished_opening) { MediaStream* ms = static_cast(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream); @@ -220,8 +224,29 @@ void get_clip_frame(Clip* c, long playhead) { if (target_frame != NULL) { // add gate if this is the same frame - glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/4); - c->texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, target_frame->data[0]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/4); + + bool copied = false; + uint8_t* data = target_frame->data[0]; + int frame_size; + + for (int i=0;ieffects.size();i++) { + Effect* e = c->effects.at(i); + if (e->enable_image) { + if (!copied) { + frame_size = target_frame->linesize[0]*target_frame->height; + data = new uint8_t[frame_size]; + memcpy(data, target_frame->data[0], frame_size); + copied = true; + } + e->process_image(get_timecode(c, playhead), data, frame_size); + } + } + + c->texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, data); + + if (copied) delete [] data; + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } diff --git a/playback/playback.h b/playback/playback.h index af1d742f6..ba7062a2a 100644 --- a/playback/playback.h +++ b/playback/playback.h @@ -20,6 +20,7 @@ void cache_video_worker(Clip* c, long playhead); void handle_media(Sequence* sequence, long playhead, bool multithreaded); void reset_cache(Clip* c, long target_frame); void get_clip_frame(Clip* c, long playhead); +double get_timecode(Clip* c, long playhead); long playhead_to_clip_frame(Clip* c, long playhead); double playhead_to_clip_seconds(Clip* c, long playhead); diff --git a/project/effect.cpp b/project/effect.cpp index 8255631ce..7bee62a95 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -27,6 +27,7 @@ #include "effects/internal/paneffect.h" #include "effects/internal/shakeeffect.h" #include "effects/internal/cornerpineffect.h" +#include "effects/internal/maskeffect.h" #include #include @@ -59,6 +60,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) { case EFFECT_INTERNAL_TONE: return new ToneEffect(c, em); case EFFECT_INTERNAL_SHAKE: return new ShakeEffect(c, em); case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em); + case EFFECT_INTERNAL_MASK: return new MaskEffect(c, em); } } else { dout << "[ERROR] Invalid effect data"; @@ -107,8 +109,15 @@ void load_internal_effects() { effects.append(em); em.name = "Corner Pin"; - em.category = "Distort"; em.internal = EFFECT_INTERNAL_CORNERPIN; + effects.append(em); + + em.name = "Mask"; + em.internal = EFFECT_INTERNAL_MASK; + effects.append(em); + + em.name = "Shake"; + em.internal = EFFECT_INTERNAL_SHAKE; effects.append(em); em.name = "Text"; @@ -117,20 +126,13 @@ void load_internal_effects() { effects.append(em); em.name = "Timecode"; - em.category = "Render"; em.internal = EFFECT_INTERNAL_TIMECODE; effects.append(em); - em.name = "Solid"; - em.category = "Render"; + em.name = "Solid"; em.internal = EFFECT_INTERNAL_SOLID; effects.append(em); - em.name = "Shake"; - em.category = "Distort"; - em.internal = EFFECT_INTERNAL_SHAKE; - effects.append(em); - // internal transitions em.type = EFFECT_TYPE_TRANSITION; em.category = ""; @@ -230,6 +232,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) : enable_shader(false), enable_coords(false), enable_superimpose(false), + enable_image(false), glslProgram(NULL), texture(NULL), isOpen(false), @@ -767,9 +770,11 @@ void Effect::startEffect() { void Effect::endEffect() { if (bound) glslProgram->release(); - bound = false; + bound = false; } +void Effect::process_image(double, uint8_t *, int) {} + Effect* Effect::copy(Clip* c) { Effect* copy = create_effect(c, meta); copy->set_enabled(is_enabled()); diff --git a/project/effect.h b/project/effect.h index 4f15a4123..08fcc13b4 100644 --- a/project/effect.h +++ b/project/effect.h @@ -62,7 +62,7 @@ extern QMutex effects_loaded; #define EFFECT_INTERNAL_TONE 6 #define EFFECT_INTERNAL_SHAKE 7 #define EFFECT_INTERNAL_TIMECODE 8 - +#define EFFECT_INTERNAL_MASK 9 #define EFFECT_INTERNAL_CORNERPIN 12 @@ -147,12 +147,14 @@ public: bool enable_shader; bool enable_coords; bool enable_superimpose; + bool enable_image; int getIterations(); void setIterations(int i); const char* ffmpeg_filter; + virtual void process_image(double timecode, uint8_t* data, int size); virtual void process_shader(double timecode, GLTextureCoords&); virtual void process_coords(double timecode, GLTextureCoords& coords, int data); virtual GLuint process_superimpose(double timecode); diff --git a/project/effectgizmo.h b/project/effectgizmo.h index befe4bcd3..ec10f4b09 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -3,8 +3,10 @@ #define GIZMO_TYPE_DOT 0 #define GIZMO_TYPE_POLY 1 +#define GIZMO_TYPE_TARGET 2 #define GIZMO_DOT_SIZE 2.5F +#define GIZMO_TARGET_SIZE 5.0F #include #include diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 53c3c47ee..81e22ae7e 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -153,15 +153,12 @@ void ViewerWidget::seek_from_click(int x) { viewer->seek(getFrameFromScreenPoint(waveform_zoom, x+waveform_scroll)); } -double get_timecode(Clip* c, long playhead) { - return ((double)(playhead-c->get_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); -} - EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { if (gizmos != NULL) { double multiplier = (double) viewer->seq->width / (double) width(); QPoint mouse_pos(qRound(x*multiplier), qRound(y*multiplier)); int dot_size = 2 * qRound(GIZMO_DOT_SIZE * multiplier); + int target_size = 2 * qRound(GIZMO_TARGET_SIZE * multiplier); for (int i=0;igizmo_count();i++) { EffectGizmo* g = gizmos->gizmo(i); @@ -179,6 +176,14 @@ EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { return g; } break; + case GIZMO_TYPE_TARGET: + if (mouse_pos.x() > g->screen_pos[0].x() - target_size + && mouse_pos.y() > g->screen_pos[0].y() - target_size + && mouse_pos.x() < g->screen_pos[0].x() + target_size + && mouse_pos.y() < g->screen_pos[0].y() + target_size) { + return g; + } + break; } } @@ -813,6 +818,7 @@ void ViewerWidget::paintGL() { glGetFloatv(GL_CURRENT_COLOR, color); float dot_size = GIZMO_DOT_SIZE / width() * viewer->seq->width; + float target_size = GIZMO_TARGET_SIZE / width() * viewer->seq->width; glPushMatrix(); glLoadIdentity(); @@ -840,6 +846,14 @@ void ViewerWidget::paintGL() { glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y(), gizmo_z); glEnd(); break; + case GIZMO_TYPE_DOT: // draw target + glBegin(GL_QUADS); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glEnd(); + break; } } glPopMatrix();