merge: fixes/rework for fader, single frame ffmpeg, dissolve, silence
authorGood Guy <good1.2guy@gmail.com>
Sat, 26 Mar 2016 20:04:35 +0000 (14:04 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sat, 26 Mar 2016 20:04:35 +0000 (14:04 -0600)
24 files changed:
cinelerra-5.1/bld_scripts/bld_dynamic.sh
cinelerra-5.1/bld_scripts/bld_static.sh
cinelerra-5.1/cinelerra/assetedit.C
cinelerra-5.1/cinelerra/assetedit.h
cinelerra-5.1/cinelerra/cachebase.C
cinelerra-5.1/cinelerra/channelinfo.C
cinelerra-5.1/cinelerra/dbwindow.C
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/exportedl.C
cinelerra-5.1/cinelerra/file.C
cinelerra-5.1/cinelerra/filebase.C
cinelerra-5.1/cinelerra/filebase.h
cinelerra-5.1/cinelerra/fileffmpeg.C
cinelerra-5.1/cinelerra/framecache.C
cinelerra-5.1/cinelerra/mainmenu.C
cinelerra-5.1/cinelerra/overlayframe.C
cinelerra-5.1/cinelerra/playback3d.C
cinelerra-5.1/cinelerra/preferencesthread.C
cinelerra-5.1/cinelerra/render.C
cinelerra-5.1/cinelerra/swindow.C
cinelerra-5.1/cinelerra/virtualvnode.C
cinelerra-5.1/cinelerra/vrender.C
cinelerra-5.1/msg.txt
cinelerra-5.1/plugins/dissolve/dissolve.C

index 80438ea31d5e5f637ea9f179589c9da551eb5a4a..fdf546798fa8b52e78c9a15164a444be9123c0c0 100755 (executable)
@@ -39,5 +39,5 @@ make >> log 2>&1 $@
 make install >> log 2>&1
 
 echo "finished: scanning log for ***"
-grep -a "\*\*\*" log
+grep -ai "\*\*\*.*error" log
 
index c6157f77c0cd3d789c07733e4f319e6e35a5cafe..e41df88c1816a41ee4490ef3e7ee44833b04c339 100755 (executable)
@@ -39,5 +39,5 @@ make >> log 2>&1 $@
 make install >> log 2>&1
 
 echo "finished: scanning log for ***"
-grep -a "\*\*\*" log
+grep -ai "\*\*\*.*error" log
 
index 9d3e6869b3cec69fbc4bd5e36514250dbacee221..cb633437472323ed4709f55dbe992df32ab0bc8e 100644 (file)
@@ -108,6 +108,17 @@ void AssetEdit::edit_asset(Indexable *indexable)
        BC_DialogThread::start();
 }
 
+void AssetEdit::handle_done_event(int result)
+{
+       if( !result ) {
+               changed_params->tcstart = ceil(indexable->get_frame_rate() *
+                       (atoi(window->tc_hours_textbox->get_text()) * 3600 +
+                        atoi(window->tc_minutes_textbox->get_text()) * 60 +
+                        atoi(window->tc_seconds_textbox->get_text()))) +
+                        atoi(window->tc_rest_textbox->get_text());
+       }
+}
+
 void AssetEdit::handle_close_event(int result)
 {
        if(!result)
@@ -609,39 +620,24 @@ void AssetEditWindow::create_objects()
                x = x2;
 
 // Calculate values to enter into textboxes
-               char tc[12];
-
-               Units::totext(tc,
-                       asset->tcstart / asset->frame_rate,
-                       TIME_HMSF,
-                       asset->sample_rate,
-                       asset->frame_rate);
-
-               char *tc_hours = tc;
-               char *tc_minutes = strchr(tc, ':') + 1;
-               *(tc_minutes - 1) = 0;
-               char *tc_seconds = strchr(tc_minutes, ':') + 1;
-               *(tc_seconds - 1) = 0;
-               char *tc_rest = strchr(tc_seconds, ':') + 1;
-               *(tc_rest - 1) = 0;
-
-               add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_hours), x, y,
-                       (int) (asset->frame_rate * 60 * 60)));
-               x += 30;
-               add_subwindow(new BC_Title(x, y, ":"));
-               x += 10;
-               add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_minutes), x, y,
-                       (int) (asset->frame_rate * 60)));
-               x += 30;
-               add_subwindow(new BC_Title(x, y, ":"));
-               x += 10;
-               add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_seconds), x, y,
-                       (int) (asset->frame_rate)));
-               x += 30;
-               add_subwindow(new BC_Title(x, y, ":"));
-               x += 10;
-               add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_rest), x, y, 1));
-
+               char text[32], *tc = text;
+               Units::totext(tc, asset->tcstart / asset->frame_rate,
+                       TIME_HMSF, asset->sample_rate, asset->frame_rate);
+
+               const char *tc_hours = tc, *tc_minutes, *tc_seconds, *tc_rest;
+               tc = strchr(tc, ':');  *tc++ = 0;  tc_minutes = tc;
+               tc = strchr(tc, ':');  *tc++ = 0;  tc_seconds = tc;
+               tc = strchr(tc, ':');  *tc++ = 0;  tc_rest = tc;
+
+               int padw = BC_Title::calculate_w(this, ":", MEDIUMFONT);
+               int fldw = BC_Title::calculate_w(this, "00", MEDIUMFONT) + 5;
+               add_subwindow(tc_hours_textbox = new BC_TextBox(x, y, fldw, 1, tc_hours));
+               add_subwindow(new BC_Title(x += tc_hours_textbox->get_w(), y, ":"));
+               add_subwindow(tc_minutes_textbox = new BC_TextBox(x += padw, y, fldw, 1, tc_minutes));
+               add_subwindow(new BC_Title(x += tc_minutes_textbox->get_w(), y, ":"));
+               add_subwindow(tc_seconds_textbox = new BC_TextBox(x += padw, y , fldw, 1, tc_seconds));
+               add_subwindow(new BC_Title(x += tc_seconds_textbox->get_w(), y, ":"));
+               add_subwindow(tc_rest_textbox = new BC_TextBox(x += 10, y, fldw, 1, tc_rest));
 
                y += 30;
        }
@@ -1090,7 +1086,7 @@ void DetailAssetThread::run()
 
 
 AssetEditReelName::AssetEditReelName(AssetEditWindow *fwindow, int x, int y)
- : BC_TextBox(x, y, 300, 1,
+ : BC_TextBox(x, y, 220, 1,
        ((Asset *)fwindow->asset_edit->indexable)->reel_name,
        1, MEDIUMFONT, 1)
 {
@@ -1127,25 +1123,3 @@ int AssetEditReelNumber::handle_event()
 
 
 
-
-
-AssetEditTCStartTextBox::AssetEditTCStartTextBox(AssetEditWindow *fwindow, int value, int x, int y, int multiplier)
- : BC_TextBox(x, y, 30, 1, value)
-{
-       this->fwindow = fwindow;
-       this->multiplier = multiplier;
-       previous = value;
-}
-AssetEditTCStartTextBox::~AssetEditTCStartTextBox()
-{
-}
-int AssetEditTCStartTextBox::handle_event()
-{
-       Asset *asset = fwindow->asset_edit->changed_params;
-       asset->tcstart -= previous * multiplier;
-       asset->tcstart += atoi(get_text()) * multiplier;
-       previous = atoi(get_text());
-       return 1;
-}
-
-
index 98cbcc0c96179d5a7f36939f7bf427879552b6ca..bc5503c9a327cf9856c3c001d4919405af867066 100644 (file)
@@ -35,7 +35,6 @@
 #include "resizetrackthread.inc"
 
 
-class AssetEditTCStartTextBox;
 class AssetEditReelNumber;
 class AssetEditReelName;
 class AssetEditByteOrderHILO;
@@ -56,6 +55,7 @@ public:
 
        void edit_asset(Indexable *indexable);
        int set_asset(Indexable *indexable);
+       void handle_done_event(int result);
        void handle_close_event(int result);
        BC_Window* new_gui();
 
@@ -84,6 +84,8 @@ public:
        AssetEditPath *path_button;
        AssetEditByteOrderHILO *hilo;
        AssetEditByteOrderLOHI *lohi;
+       BC_TextBox *tc_hours_textbox, *tc_minutes_textbox;
+       BC_TextBox *tc_seconds_textbox, *tc_rest_textbox;
        BitsPopup *bitspopup;
        int allow_edits;
        MWindow *mwindow;
@@ -92,6 +94,7 @@ public:
        BC_Title *win_height;
        DetailAssetThread *detail_thread;
        void show_info_detail();
+
 };
 
 
@@ -295,20 +298,6 @@ public:
        AssetEditWindow *fwindow;
 };
 
-class AssetEditTCStartTextBox : public BC_TextBox
-{
-public:
-       AssetEditTCStartTextBox(AssetEditWindow *fwindow, int value, int x, int y, int multiplier);
-       ~AssetEditTCStartTextBox();
-       int handle_event();
-
-       AssetEditWindow *fwindow;
-// Multiplier is the # of frames for whatever unit of time this is.
-// fps dependent, and unit dependent
-       int multiplier;
-       int previous;
-};
-
 class DetailAssetWindow : public BC_Window
 {
         MWindow *mwindow;
index 267ff515e2bbe1674c847eea64a3c4eb151eeb94..8e02543aa5f855b5950201ded9ee8fcc0b74ff63 100644 (file)
@@ -120,7 +120,7 @@ int CacheBase::delete_oldest()
                if( current->age < oldest->age )
                        oldest = current;
        }
-       if( oldest ) {
+       if( oldest && oldest->position >= 0 ) {
                del_item(oldest);
                result = 1;
        }
index 03d8d84261edb1d61799127a17e4eb4aa830a353..140f3d30e509848b7cb26d7045228b6f806a68fd 100644 (file)
@@ -1787,7 +1787,7 @@ void ChannelInfo::delete_batch()
 }
 
 ChannelScan::ChannelScan(MWindow *mwindow)
- : BC_MenuItem(_("Scan"), _("Shift-S"), 'S')
+ : BC_MenuItem(_("Scan..."), _("Shift-S"), 'S')
 {
        set_shift();
        this->mwindow = mwindow;
index 2a6395cfe24d3a47d6db699d389135bd6c2c1d8f..c19b581e37e2a9763c9f264a053cd0af0a3852df 100644 (file)
@@ -199,7 +199,7 @@ keypress_event()
 
 DbWindowScan::
 DbWindowScan(MWindow *mwindow)
- : BC_MenuItem(_("Media DB"), _("Shift-M"), 'M')
+ : BC_MenuItem(_("Media DB..."), _("Shift-M"), 'M')
 {
        set_shift();
        this->mwindow = mwindow;
index d1d904aa795647605031cf3df393e4fbf5f7a181..e167e48ad4477a8006694d67d5cce620c12e444b 100644 (file)
@@ -35,6 +35,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "indexstate.h"
+#include "interlacemodes.h"
 #include "labels.h"
 #include "localsession.h"
 #include "mutex.h"
@@ -1448,20 +1449,23 @@ if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 // Edit is not a nested EDL
+       Asset *asset = (*playable_edit)->asset;
 // Edit is silence
-       if(!(*playable_edit)->asset) return 1;
+       if(!asset) return 1;
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
 
-
 // Asset and output device must have the same dimensions
-       if((*playable_edit)->asset->width != session->output_w ||
-               (*playable_edit)->asset->height != session->output_h)
+       if( asset->width != session->output_w ||
+           asset->height != session->output_h )
                return 1;
 
 
 if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__);
-
-
+// Asset and output device must have same resulting de-interlacing method
+       if( ilaceautofixmethod2(session->interlace_mode,
+           asset->interlace_autofixoption, asset->interlace_mode,
+           asset->interlace_fixmethod) != BC_ILACE_FIXMETHOD_NONE )
+               return 1;
 
 // If we get here the frame is going to be directly copied.  Whether it is
 // decompressed in hardware depends on the colormodel.
index 21e02bfede2b02ef96c4a4cc843d7121a4553d3e..04e22ebd5613688a104faf848b1bdfe477475cd2 100644 (file)
@@ -252,7 +252,7 @@ int ExportEDLAsset::save_defaults()
 
 
 ExportEDLItem::ExportEDLItem(MWindow *mwindow)
- : BC_MenuItem(_("Export EDL..."), "Shift+E", 'E')
+ : BC_MenuItem(_("Export EDL..."), "Shift-E", 'E')
 {
        this->mwindow = mwindow;
        set_shift(1);
index 103c9a4d3b5e1810021604ab2803719d3a677343..f5932e3e8f07a58a1e2b89ac9c50d126443b452d 100644 (file)
@@ -1171,13 +1171,11 @@ int File::read_frame(VFrame *frame, int is_thread)
        if(debug) PRINT_TRACE
        int supported_colormodel = colormodel_supported(frame->get_color_model());
        int advance_position = 1;
-
+       int cache_active = use_cache || asset->video_length < 0 ? 1 : 0;
+       int64_t cache_position = asset->video_length >= 0 ? current_frame : -1;
 // Test cache
-       if(use_cache &&
-               frame_cache->get_frame(frame,
-                       current_frame,
-                       current_layer,
-                       asset->frame_rate))
+       if( cache_active && frame_cache->get_frame(frame, cache_position,
+                       current_layer, asset->frame_rate) )
        {
 // Can't advance position if cache used.
 //printf("File::read_frame %d\n", __LINE__);
@@ -1245,11 +1243,9 @@ int File::read_frame(VFrame *frame, int is_thread)
 //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0;
        }
 
-//printf("File::read_frame %d use_cache=%d\n", __LINE__, use_cache);
-       if(use_cache)
-               frame_cache->put_frame(frame,
-                       current_frame, current_layer,
-                       asset->frame_rate, 1, 0);
+       if( cache_active && advance_position && frame->get_status() > 0 )
+               frame_cache->put_frame(frame, cache_position,
+                       current_layer, asset->frame_rate, 1, 0);
 //printf("File::read_frame %d\n", __LINE__);
 
        if(advance_position) current_frame++;
index b8a663164a99c748db78394a516347f8ff873cb2..5629f6c257229bba6951ab8fcd9140b88d00da0f 100644 (file)
@@ -37,7 +37,6 @@ FileBase::FileBase(Asset *asset, File *file)
        this->asset = asset;
        internal_byte_order = get_byte_order();
        reset_parameters();
-       overlayer = new OverlayFrame;
 }
 
 FileBase::~FileBase()
@@ -46,7 +45,6 @@ FileBase::~FileBase()
        if(row_pointers_in) delete [] row_pointers_in;
        if(row_pointers_out) delete [] row_pointers_out;
        if(float_buffer) delete [] float_buffer;
-       delete overlayer;
 }
 
 int FileBase::close_file()
index a4b14dc938ae0b7ae1e8d8c1860ad0acec9a300d..db9e5b06ffac1b7db93b6d992a35210ee0a27931 100644 (file)
@@ -221,8 +221,6 @@ private:
        int delete_ulaw_tables();
        float *ulawtofloat_table, *ulawtofloat_ptr;
        unsigned char *floattoulaw_table, *floattoulaw_ptr;
-
-       OverlayFrame *overlayer;
 };
 
 #endif
index f2a0c43dc98426a0cb19231171e8dd5262afdaf2..e311b25dca309af75a7a37cc6fd78feb00544f21 100644 (file)
@@ -183,6 +183,8 @@ int FileFFMPEG::select_video_stream(Asset *asset, int vstream)
        asset->width = ff->ff_video_width(vstream);
        asset->height = ff->ff_video_height(vstream);
        asset->video_length = ff->ff_video_frames(vstream);
+       if( (asset->video_length = ff->ff_video_frames(vstream)) < 2 )
+               asset->video_length = asset->video_length < 0 ? 0 : -1;
        asset->frame_rate = ff->ff_frame_rate(vstream);
        return 0;
 }
@@ -220,7 +222,9 @@ int FileFFMPEG::open_file(int rd, int wr)
                                asset->actual_height = ff->ff_video_height(0);
                                if( !asset->width ) asset->width = asset->actual_width;
                                if( !asset->height ) asset->height = asset->actual_height;
-                               if( !asset->video_length ) asset->video_length = ff->ff_video_frames(0);
+                               if( !asset->video_length &&
+                                   (asset->video_length = ff->ff_video_frames(0)) < 2 )
+                                       asset->video_length = asset->video_length < 0 ? 0 : -1;
                                if( !asset->frame_rate ) asset->frame_rate = ff->ff_frame_rate(0);
                        }
                        IndexState *index_state = asset->index_state;
@@ -283,7 +287,7 @@ int FileFFMPEG::read_frame(VFrame *frame)
 {
         if( !ff ) return -1;
        int layer = file->current_layer;
-       int64_t pos = file->current_frame;
+       int64_t pos = asset->video_length >= 0 ? file->current_frame : 0;
        int ret = ff->decode(layer, pos, frame);
        frame->set_status(ret);
        if( ret >= 0 ) return 0;
index a5f6deb25c128d48b35ed0eaabd1a1dc60e53353..afb149f0f885757cbba9bdfa00167e3e01b1aa27 100644 (file)
@@ -29,6 +29,7 @@
 #include "vframe.h"
 
 
+#include <limits.h>
 #include <math.h>
 #include <string.h>
 #include <unistd.h>
@@ -173,12 +174,8 @@ VFrame* FrameCache::get_frame_ptr(int64_t position,
 
 // Puts frame in cache if enough space exists and the frame doesn't already
 // exist.
-void FrameCache::put_frame(VFrame *frame, 
-       int64_t position,
-       int layer,
-       double frame_rate,
-       int use_copy,
-       Indexable *indexable)
+void FrameCache::put_frame(VFrame *frame, int64_t position,
+       int layer, double frame_rate, int use_copy, Indexable *indexable)
 {
        lock->lock("FrameCache::put_frame");
        FrameCacheItem *item = 0;
@@ -187,13 +184,7 @@ void FrameCache::put_frame(VFrame *frame,
 
 //printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position);
 
-       if(frame_exists(frame,
-               position, 
-               layer,
-               frame_rate,
-               &item,
-               source_id))
-       {
+       if(frame_exists(frame, position, layer, frame_rate, &item, source_id)) {
                item->age = get_age();
                lock->unlock();
                return;
@@ -202,14 +193,7 @@ void FrameCache::put_frame(VFrame *frame,
 
        item = new FrameCacheItem;
 
-       if(use_copy)
-       {
-               item->data = new VFrame(*frame);
-       }
-       else
-       {
-               item->data = frame;
-       }
+       item->data = use_copy ? new VFrame(*frame) : frame;
 
 // Copy metadata
        item->position = position;
@@ -219,7 +203,7 @@ void FrameCache::put_frame(VFrame *frame,
        if(indexable) 
                item->path = cstrdup(indexable->path);
 
-       item->age = get_age();
+       item->age = position < 0 ? INT_MAX : get_age();
 
 //printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position);
        put_item(item);
@@ -229,12 +213,8 @@ void FrameCache::put_frame(VFrame *frame,
 
 
 
-int FrameCache::frame_exists(VFrame *format,
-       int64_t position, 
-       int layer,
-       double frame_rate,
-       FrameCacheItem **item_return,
-       int source_id)
+int FrameCache::frame_exists(VFrame *format, int64_t position, 
+       int layer, double frame_rate, FrameCacheItem **item_return, int source_id)
 {
        FrameCacheItem *item = (FrameCacheItem*)get_item(position);
 // printf("FrameCache::frame_exists %d item=%p item->position=%jd position=%jd\n",
index b02812ace5a59e17e273c74b1685cac8cf4e29f1..b04800bb9cf4145a4b5fad7094b98319066612a2 100644 (file)
@@ -251,7 +251,7 @@ void MainMenu::create_objects()
        windowmenu->add_item(new BC_MenuItem("-"));
        windowmenu->add_item(split_x = new SplitX(mwindow));
        windowmenu->add_item(split_y = new SplitY(mwindow));
-       windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl+P"),'p'));
+       windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl-P"),'p'));
        windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0));
        windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1));
 }
@@ -627,7 +627,7 @@ int Undo::update_caption(const char *new_caption)
 }
 
 
-Redo::Redo(MWindow *mwindow) : BC_MenuItem(_("Redo"), _("Shift+Z"), 'Z')
+Redo::Redo(MWindow *mwindow) : BC_MenuItem(_("Redo"), _("Shift-Z"), 'Z')
 {
        set_shift(1);
        this->mwindow = mwindow;
@@ -891,7 +891,7 @@ int Clear::handle_event()
 }
 
 PasteSilence::PasteSilence(MWindow *mwindow)
- : BC_MenuItem(_("Paste silence"), _("Shift+Space"), ' ')
+ : BC_MenuItem(_("Paste silence"), _("Shift-Space"), ' ')
 {
        this->mwindow = mwindow;
        set_shift();
@@ -1146,7 +1146,7 @@ int DeleteTrack::handle_event()
 }
 
 MoveTracksUp::MoveTracksUp(MWindow *mwindow)
- : BC_MenuItem(_("Move tracks up"), _("Shift+Up"), UP)
+ : BC_MenuItem(_("Move tracks up"), _("Shift-Up"), UP)
 {
        set_shift(); this->mwindow = mwindow;
 }
@@ -1158,7 +1158,7 @@ int MoveTracksUp::handle_event()
 }
 
 MoveTracksDown::MoveTracksDown(MWindow *mwindow)
- : BC_MenuItem(_("Move tracks down"), _("Shift+Down"), DOWN)
+ : BC_MenuItem(_("Move tracks down"), _("Shift-Down"), DOWN)
 {
        set_shift(); this->mwindow = mwindow;
 }
@@ -1190,7 +1190,7 @@ int ConcatenateTracks::handle_event()
 
 
 LoopPlayback::LoopPlayback(MWindow *mwindow)
- : BC_MenuItem(_("Loop Playback"), _("Shift+L"), 'L')
+ : BC_MenuItem(_("Loop Playback"), _("Shift-L"), 'L')
 {
        this->mwindow = mwindow;
        set_checked(mwindow->edl->local_session->loop_playback);
@@ -1459,7 +1459,7 @@ int TileWindows::handle_event()
 }
 
 SplitX::SplitX(MWindow *mwindow)
- : BC_MenuItem(_("Split X pane"), _("Ctrl+1"), '1')
+ : BC_MenuItem(_("Split X pane"), _("Ctrl-1"), '1')
 {
        this->mwindow = mwindow;
        set_ctrl(1);
@@ -1472,7 +1472,7 @@ int SplitX::handle_event()
 }
 
 SplitY::SplitY(MWindow *mwindow)
- : BC_MenuItem(_("Split Y pane"), _("Ctrl+2"), '2')
+ : BC_MenuItem(_("Split Y pane"), _("Ctrl-2"), '2')
 {
        this->mwindow = mwindow;
        set_ctrl(1);
index 4de38e3670ce12afb261ea8983639e8b5496942f..098bf9dba97ab823475ef1c9c7d3d9fa1f2b89fa 100644 (file)
@@ -485,7 +485,7 @@ ZTYP(float);        ZTYP(double);
 
 #define ALPHA3_BLEND(FN, typ, inp, out, mx, ofs, rnd) \
   typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \
-  typ inp2 = (typ)inp[2] - ofs, inp3 = fade * mx + rnd; \
+  typ inp2 = (typ)inp[2] - ofs, inp3 = mx; \
   typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \
   typ out2 = (typ)out[2] - ofs, out3 = mx; \
   r = COLOR_##FN(mx, inp0, inp3, out0, out3); \
@@ -500,7 +500,7 @@ ZTYP(float);        ZTYP(double);
 
 #define ALPHA4_BLEND(FN, typ, inp, out, mx, ofs, rnd) \
   typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \
-  typ inp2 = (typ)inp[2] - ofs, inp3 = (typ)inp[3] * fade + rnd; \
+  typ inp2 = (typ)inp[2] - ofs, inp3 = inp[3]; \
   typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \
   typ out2 = (typ)out[2] - ofs, out3 = out[3]; \
   r = COLOR_##FN(mx, inp0, inp3, out0, out3); \
@@ -544,7 +544,7 @@ ZTYP(float);        ZTYP(double);
   out[3] = aclip(a, mx)
 
 #define XBLEND(FN, temp_type, type, max, components, chroma_offset, round) { \
-       temp_type opcty = alpha * max + round, trnsp = max - opcty; \
+       temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type** output_rows = (type**)output->get_rows(); \
        type** input_rows = (type**)input->get_rows(); \
        ix *= components;  ox *= components; \
@@ -608,8 +608,7 @@ void DirectUnit::process_package(LoadPackage *package)
        VFrame *output = engine->output;
        VFrame *input = engine->input;
        int mode = engine->mode;
-       float fade = engine->alpha;
-       float alpha =
+       float fade =
                BC_CModels::has_alpha(input->get_color_model()) &&
                mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
 
@@ -690,7 +689,7 @@ LoadPackage* DirectEngine::new_package()
 /* Nearest Neighbor scale / translate / blend ********************/
 
 #define XBLEND_3NN(FN, temp_type, type, max, components, chroma_offset, round) { \
-       temp_type opcty = alpha * max + round, trnsp = max - opcty; \
+       temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type** output_rows = (type**)output->get_rows(); \
        type** input_rows = (type**)input->get_rows(); \
        ox *= components; \
@@ -753,8 +752,7 @@ void NNUnit::process_package(LoadPackage *package)
        VFrame *output = engine->output;
        VFrame *input = engine->input;
        int mode = engine->mode;
-       float fade = engine->alpha;
-       float alpha =
+       float fade =
                BC_CModels::has_alpha(input->get_color_model()) &&
                mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
 
@@ -909,7 +907,7 @@ LoadPackage* NNEngine::new_package()
 
 #define XSAMPLE(FN, temp_type, type, max, components, chroma_offset, round) { \
        float temp[oh*components]; \
-       temp_type opcty = alpha * max + round, trnsp = max - opcty; \
+       temp_type opcty = fade * max + round, trnsp = max - opcty; \
        type **output_rows = (type**)voutput->get_rows() + o1i; \
        type **input_rows = (type**)vinput->get_rows(); \
  \
@@ -1027,8 +1025,7 @@ void SampleUnit::process_package(LoadPackage *package)
        VFrame *voutput = engine->output;
        VFrame *vinput = engine->input;
        int mode = engine->mode;
-       float fade = engine->alpha;
-       float alpha =
+       float fade =
                BC_CModels::has_alpha(vinput->get_color_model()) &&
                mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
 
index f733105ff231bb18b1b648c69b860f3fb7895701..a6a721ba80feb38266e5c60ca0a30c7e2947ba69 100644 (file)
@@ -149,9 +149,8 @@ static const char *blend_normal_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
-       "       vec4 result = canvas * (1.0 - gl_FragColor.a) + gl_FragColor * gl_FragColor.a;\n"
+       "       vec4 result = mix(canvas, gl_FragColor, gl_FragColor.a);\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
        "}\n";
 
@@ -161,7 +160,6 @@ static const char *blend_add_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = canvas + gl_FragColor;\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -174,7 +172,6 @@ static const char *blend_subtract_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = gl_FragColor - canvas;\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -187,7 +184,6 @@ static const char *blend_multiply_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = canvas * gl_FragColor;\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -199,7 +195,6 @@ static const char *blend_divide_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = gl_FragColor / canvas;\n"
        "       if(!canvas.r) result.r = 1.0;\n"
@@ -214,7 +209,6 @@ static const char *blend_divide_frag =
 static const char *blend_replace_frag =
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "}\n";
 
 // MAX
@@ -223,7 +217,6 @@ static const char *blend_max_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = max(canvas, gl_FragColor);\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -236,7 +229,6 @@ static const char *blend_min_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = min(canvas, gl_FragColor);\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -249,7 +241,6 @@ static const char *blend_average_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = (canvas + gl_FragColor) * 0.5;\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -262,7 +253,6 @@ static const char *blend_darken_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +"
                        " gl_FragColor.rgb * (1.0 - canvas.a) +"
@@ -278,7 +268,6 @@ static const char *blend_lighten_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +"
                        " gl_FragColor.rgb * (1.0 - canvas.a) +"
@@ -294,7 +283,6 @@ static const char *blend_dst_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-//     "       gl_FragColor.a *= alpha;\n"
 //     "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
 //     "       vec4 result = canvas;\n"
 //     "       gl_FragColor = mix(result, canvas, alpha);\n"
@@ -307,7 +295,6 @@ static const char *blend_dst_atop_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(canvas.rgb * gl_FragColor.a + "
                        "(1.0 - canvas.a) * gl_FragColor.rgb, gl_FragColor.a);\n"
@@ -320,7 +307,6 @@ static const char *blend_dst_in_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = canvas * gl_FragColor.a;\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -332,7 +318,6 @@ static const char *blend_dst_out_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = canvas * (1.0 - gl_FragColor.a);\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -344,7 +329,6 @@ static const char *blend_dst_over_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(canvas.rgb + (1.0 - canvas.a) * gl_FragColor.rgb, "
                        " gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n"
@@ -357,7 +341,6 @@ static const char *blend_src_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = gl_FragColor;\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -369,7 +352,6 @@ static const char *blend_src_atop_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(gl_FragColor.rgb * canvas.a + "
                        "canvas.rgb * (1.0 - gl_FragColor.a), canvas.a);\n"
@@ -382,7 +364,6 @@ static const char *blend_src_in_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = gl_FragColor * canvas.a;\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -394,7 +375,6 @@ static const char *blend_src_out_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = gl_FragColor * (1.0 - canvas.a);\n"
        "       gl_FragColor = mix(canvas, result, alpha);\n"
@@ -406,7 +386,6 @@ static const char *blend_src_over_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(gl_FragColor.rgb + (1.0 - gl_FragColor.a) * canvas.rgb, "
                                "gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n"
@@ -419,7 +398,6 @@ static const char *blend_or_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = canvas + gl_FragColor - canvas * gl_FragColor;\n"
        "       result = clamp(result, 0.0, 1.0);\n"
@@ -432,7 +410,6 @@ static const char *blend_xor_frag =
        "uniform vec2 tex2_dimensions;\n"
        "uniform float alpha;\n"
        "void main() {\n"
-       "       gl_FragColor.a *= alpha;\n"
        "       vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
        "       vec4 result = vec4(gl_FragColor.rgb * (1.0 - canvas.a) + "
                        "(1.0 - gl_FragColor.a) * canvas.rgb, "
index b27342e0d15805923d85a7a47d4b428122ce243f..2ee2e2cb4343cb62170ac35c9dc06871c7841e47 100644 (file)
@@ -66,7 +66,7 @@
 
 
 PreferencesMenuitem::PreferencesMenuitem(MWindow *mwindow)
- : BC_MenuItem(_("Preferences..."), _("Shift+P"), 'P')
+ : BC_MenuItem(_("Preferences..."), _("Shift-P"), 'P')
 {
        this->mwindow = mwindow;
 
index a1160a6463633600b88bc6cb2e5a7b9a03255ce2..0098afffd70ee4763105e19d6c210ed762b5d253 100644 (file)
@@ -82,7 +82,7 @@
 
 
 RenderItem::RenderItem(MWindow *mwindow)
- : BC_MenuItem(_("Render..."), _("Shift+R"), 'R')
+ : BC_MenuItem(_("Render..."), _("Shift-R"), 'R')
 {
        this->mwindow = mwindow;
        set_shift(1);
index 0c818825f62d66a9d3705c9bcddd928aaca08e83..65799c4bba5ac82c55fc71ee4588c1535ed16dda 100644 (file)
@@ -951,7 +951,7 @@ int SWindow::update_selection()
 
 
 SubttlSWin::SubttlSWin(MWindow *mwindow)
- : BC_MenuItem(_("SubTitle"), _("Alt-y"), 'y')
+ : BC_MenuItem(_("SubTitle..."), _("Alt-y"), 'y')
 {
        set_alt();
        this->mwindow = mwindow;
index 141a2a0c7b461197bf8ed528740538a0986ce681..1fb4846140f52c4fdc14393dbbe6f1ab2173f8f4 100644 (file)
@@ -414,7 +414,7 @@ int VirtualVNode::render_projector(VFrame *input, VFrame *output,
 // can do dissolves, although a blend equation is still required for 3 component
 // colormodels since fractional translation requires blending.
 
-// If this is the first playable video track and the mode_keyframe is "src_over"
+// If this is the first playable video track and the mode_keyframe is "src"
                        if(mode == TRANSFER_NORMAL &&
                                vconsole->current_exit_node == vconsole->total_exit_nodes - 1)
                                mode = TRANSFER_SRC;
index 4c3011622a01e0514c3ca20b05e11a77dbc2cded..0b424c6440d7714310a4af3bf3686644adce8b61 100644 (file)
@@ -29,7 +29,6 @@
 #include "edl.h"
 #include "edlsession.h"
 #include "file.h"
-#include "interlacemodes.h"
 #include "localsession.h"
 #include "mainsession.h"
 #include "mwindow.h"
@@ -144,28 +143,13 @@ int VRender::process_buffer(int64_t input_position,
        use_vconsole = get_use_vconsole(&playable_edit, input_position, use_brender);
        if(debug) printf("VRender::process_buffer %d use_vconsole=%d\n", __LINE__, use_vconsole);
 
-       if( playable_edit ) { 
-// Asset and output device must have same resulting de-interlacing method
-               Indexable *source = playable_edit->get_source();
-               if( source->is_asset ) {
-                       Asset *asset = (Asset *)source;
-                       if( ilaceautofixmethod2(renderengine->edl->session->interlace_mode,
-                                       asset->interlace_autofixoption, asset->interlace_mode,
-                                       asset->interlace_fixmethod) != BC_ILACE_FIXMETHOD_NONE )
-                               return 1;
-               }
-       }
-
 // Negotiate color model
        colormodel = get_colormodel(playable_edit, use_vconsole, use_brender);
        if(debug) printf("VRender::process_buffer %d\n", __LINE__);
 
 
-
-
 // Get output buffer from device
-       if(renderengine->command->realtime &&
-               !renderengine->is_nested)
+       if(renderengine->command->realtime && !renderengine->is_nested)
        {
                renderengine->video->new_output_buffer(&video_out, colormodel);
        }
@@ -260,8 +244,7 @@ int VRender::get_use_vconsole(VEdit **playable_edit,
 
 // Descend into EDL nest
        return renderengine->get_edl()->get_use_vconsole(playable_edit,
-               position,
-               renderengine->command->get_direction(),
+               position, renderengine->command->get_direction(),
                vconsole->playable_tracks);
 }
 
index f1a0ab3e8d640a4150bdb39f478cd1236ab0a63c..ca4de10a34a229758b8e83709f5ebdcb98fe45ba 100644 (file)
@@ -4,3 +4,4 @@ Testers are welcome to report and supply examples; join at cinelerra-cv.org
 If logged in as root, can capture crashes and email /tmp/cin*.dmp file 
 Volunteer to help with language translations which will help you
 Helpful videos: http://beccatoria.dreamwidth.org/144288.html#cutid2
+Also see: http://g-raffa.eu/Cinelerra/HOWTO/basics.html
index d264f6cf7091a7863df5032582ed5160faa73697..c0dbb7508dbd867cb1bd25f21ca21913f63235eb 100644 (file)
@@ -69,78 +69,10 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing)
 // Use software
        if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1);
 
-
-// There is a problem when dissolving from a big picture to a small picture.
-// In order to make it dissolve correctly, we have to manually decrese alpha of big picture.
-       switch (outgoing->get_color_model())
-       {
-               case BC_RGBA8888:
-               case BC_YUVA8888:
-               {
-                       uint8_t** data_rows = (uint8_t **)outgoing->get_rows();
-                       int w = outgoing->get_w();
-                       int h = outgoing->get_h(); 
-                       for(int i = 0; i < h; i++) 
-                       {
-                               uint8_t* alpha_chan = data_rows[i] + 3; 
-                               for(int j = 0; j < w; j++) 
-                               {
-                                       *alpha_chan = (uint8_t) (*alpha_chan * (1-fade));
-                                       alpha_chan+=4;
-                               }
-                       }
-                       break;
-               }
-               case BC_YUVA16161616:
-               {
-                       uint16_t** data_rows = (uint16_t **)outgoing->get_rows();
-                       int w = outgoing->get_w();
-                       int h = outgoing->get_h(); 
-                       for(int i = 0; i < h; i++)
-                       { 
-                               uint16_t* alpha_chan = data_rows[i] + 3; // 3 since this is uint16_t
-                               for(int j = 0; j < w; j++) 
-                               {
-                                       *alpha_chan = (uint16_t)(*alpha_chan * (1-fade));
-                                       alpha_chan += 8;
-                               } 
-                       }
-                       break;
-               }
-               case BC_RGBA_FLOAT:
-               {
-                       float** data_rows = (float **)outgoing->get_rows();
-                       int w = outgoing->get_w();
-                       int h = outgoing->get_h(); 
-                       for(int i = 0; i < h; i++) 
-                       { 
-                               float* alpha_chan = data_rows[i] + 3; // 3 since this is floats 
-                               for(int j = 0; j < w; j++) 
-                               {
-                                       *alpha_chan = *alpha_chan * (1-fade);
-                                       alpha_chan += sizeof(float);
-                               } 
-                       }
-                       break;
-               }
-               default:
-                       break;
-       }
-
-
-       overlayer->overlay(outgoing, 
-               incoming, 
-               0, 
-               0, 
-               incoming->get_w(),
-               incoming->get_h(),
-               0,
-               0,
-               incoming->get_w(),
-               incoming->get_h(),
-               fade,
-               TRANSFER_NORMAL,
-               NEAREST_NEIGHBOR);
+       overlayer->overlay(outgoing, incoming, 
+               0, 0, incoming->get_w(), incoming->get_h(),
+               0, 0, incoming->get_w(), incoming->get_h(),
+               fade, TRANSFER_SRC, NEAREST_NEIGHBOR);
 
        return 0;
 }
@@ -148,35 +80,64 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing)
 int DissolveMain::handle_opengl()
 {
 #ifdef HAVE_GL
+       static const char *blend_dissolve =
+               "uniform float fade;\n"
+               "uniform sampler2D src_tex;\n"
+               "uniform sampler2D dst_tex;\n"
+               "uniform vec2 dst_tex_dimensions;\n"
+               "uniform vec3 chroma_offset;\n"
+               "void main()\n"
+               "{\n"
+               "       vec4 result_color;\n"
+               "       vec4 dst_color = texture2D(dst_tex, gl_FragCoord.xy / dst_tex_dimensions);\n"
+               "       vec4 src_color = texture2D(src_tex, gl_TexCoord[0].st);\n"
+               "       src_color.rgb -= chroma_offset;\n"
+               "       dst_color.rgb -= chroma_offset;\n"
+               "       result_color = mix(dst_color, src_color, fade);\n"
+               "       result_color.rgb += chroma_offset;\n"
+               "       gl_FragColor = result_color;\n"
+               "}\n";
 
 // Read images from RAM
-       get_input()->to_texture();
-       get_output()->to_texture();
+       VFrame *src = get_input();
+       src->to_texture();
+       VFrame *dst = get_output();
+       dst->to_texture();
+       dst->enable_opengl();
+       dst->init_screen();
+       src->bind_texture(0);
+       dst->bind_texture(1);
+
+       const char *shader_stack[] = { 0, 0, 0 };
+       int current_shader = 0;
+       shader_stack[current_shader++] = blend_dissolve;
+
+       unsigned int shader_id = VFrame::make_shader(0,
+               shader_stack[0], shader_stack[1], shader_stack[2], 0);
+
+       glUseProgram(shader_id);
+       glUniform1f(glGetUniformLocation(shader_id, "fade"), fade);
+       glUniform1i(glGetUniformLocation(shader_id, "src_tex"), 0);
+       glUniform1i(glGetUniformLocation(shader_id, "dst_tex"), 1);
+       if(BC_CModels::is_yuv(dst->get_color_model()))
+               glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.5, 0.5);
+       else
+               glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.0, 0.0);
+       glUniform2f(glGetUniformLocation(shader_id, "dst_tex_dimensions"),
+               (float)dst->get_texture_w(),
+               (float)dst->get_texture_h());
 
-// Create output pbuffer
-       get_output()->enable_opengl();
-
-       VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
-
-// Enable output texture
-       get_output()->bind_texture(0);
-// Draw output texture
        glDisable(GL_BLEND);
-       glColor4f(1, 1, 1, 1);
-       get_output()->draw_texture();
-
-// Draw input texture
-       get_input()->bind_texture(0);
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glColor4f(1, 1, 1, fade);
-       get_input()->draw_texture();
-
+       src->draw_texture();
+       glUseProgram(0);
 
        glDisable(GL_BLEND);
-       get_output()->set_opengl_state(VFrame::SCREEN);
-
+       glActiveTexture(GL_TEXTURE1);
+       glDisable(GL_TEXTURE_2D);
+       glActiveTexture(GL_TEXTURE0);
+       glDisable(GL_TEXTURE_2D);
 
+       dst->set_opengl_state(VFrame::SCREEN);
 #endif
        return 0;
 }