fixes and upgrades for vicons
authorGood Guy <[email protected]>
Sun, 13 Dec 2015 18:37:52 +0000 (11:37 -0700)
committerGood Guy <[email protected]>
Sun, 13 Dec 2015 18:37:52 +0000 (11:37 -0700)
cinelerra-5.0/cinelerra/awindowgui.C
cinelerra-5.0/cinelerra/awindowgui.h
cinelerra-5.0/cinelerra/dbwindow.C
cinelerra-5.0/guicast/bccmodels.C
cinelerra-5.0/guicast/vicon.C
cinelerra-5.0/guicast/vicon.h

index 17354995790f0079117fdda473b920ae2176452c..f340bb0e207f92b6b0bdbf2de80ee7a07af74293 100644 (file)
@@ -70,10 +70,12 @@ AssetVIcon::AssetVIcon(AssetPicon *picon, int w, int h, double framerate, int64_
 {
        this->picon = picon;
        this->length = length;
+       temp = 0;
 }
 
 AssetVIcon::~AssetVIcon()
 {
+       delete temp;
 }
 
 VFrame *AssetVIcon::frame()
@@ -82,19 +84,23 @@ VFrame *AssetVIcon::frame()
                MWindow *mwindow = picon->mwindow;
                Asset *asset = (Asset *)picon->indexable;
                File *file = mwindow->video_cache->check_out(asset, mwindow->edl, 1);
-               if( !file ) return 0;           
-               VFrame frame(asset->width, asset->height, BC_RGB888);
+               if( !file ) return 0;
+               if( temp && (temp->get_w() != asset->width || temp->get_h() != asset->height) ) {
+                       delete temp;  temp = 0;
+               }
+               if( !temp )
+                       temp = new VFrame(asset->width, asset->height, BC_RGB888);
                file->set_layer(0);
                file->set_video_position(images.size(),0);
                int ww = picon->gui->vicon_thread->view_w;
                int hh = picon->gui->vicon_thread->view_h;
                while( seq_no >= images.size() ) {
-                       file->read_frame(&frame);
-                       add_image(&frame, ww, hh, BC_RGB8);
+                       file->read_frame(temp);
+                       add_image(temp, ww, hh, BC_RGB8);
                }
                mwindow->video_cache->check_in(asset);
        }
-       return images[seq_no];
+       return *images[seq_no];
 }
 
 int64_t AssetVIcon::next_frame(int n)
index fc03cbc87d0c14d50a3f9912b97443d673dadab9..f80cbca1f683a08818ccbf82d748fb4c260a18f2 100644 (file)
@@ -95,6 +95,7 @@ public:
 class AssetVIcon : public VIcon {
 public:
        AssetPicon *picon;
+       VFrame *temp;
        int64_t length;
 
        VFrame *frame();
index 5c876bf1f692e36d3fc2baddb1aa078fa16877a5..6d479b37ed357372aa35da42cb197a5358401d8e 100644 (file)
@@ -389,7 +389,7 @@ VFrame *DbWindowVIcon::frame()
 {
        if( seq_no >= images.size() )
                load_frames(lbox->gui->dwindow->mdb);
-       return images[seq_no];
+       return *images[seq_no];
 }
 
 int64_t DbWindowVIcon::next_frame(int n)
@@ -418,13 +418,14 @@ void DbWindowVIcon::read_frames(DbWindow::MDb *mdb)
                int frame_id = mdb->timeline_frame_id();
                if( frame_id < 0 ) continue;
                int swidth = (SWIDTH+1) & ~1, sheight = (SHEIGHT+1) & ~1;
-               VFrame *frame = new VFrame(swidth, sheight, BC_YUV420P);
-               memset(frame->get_y(),0x00,swidth * sheight);
-               memset(frame->get_u(),0x80,swidth/2 * sheight/2);
-               memset(frame->get_v(),0x80,swidth/2 * sheight/2);
-               uint8_t *yp = frame->get_y();  int sw = -1, sh = -1;
+               VIFrame *vifrm = new VIFrame(swidth, sheight, BC_YUV420P);
+               VFrame *img = *vifrm;
+               memset(img->get_y(),0x00,swidth * sheight);
+               memset(img->get_u(),0x80,swidth/2 * sheight/2);
+               memset(img->get_v(),0x80,swidth/2 * sheight/2);
+               uint8_t *yp = img->get_y();  int sw = -1, sh = -1;
                mdb->get_image(frame_id, yp, sw, sh);
-               images.append(frame);
+               images.append(vifrm);
        }
 }
 
index e50193c63c14d0e53d50cf5ad301255d44c05396..88ed1acdb201402d7bd5477e0f868256aa69e455 100644 (file)
@@ -127,8 +127,6 @@ int BC_CModels::calculate_max(int colormodel)
 
 int BC_CModels::calculate_datasize(int w, int h, int bytes_per_line, int color_model)
 {
-       if( bytes_per_line < 0 )
-               bytes_per_line = w * calculate_pixelsize(color_model);
        switch(color_model) {
        case BC_YUV410P: return w * h + w * h / 8 + 4;
        case BC_YUV420P:
@@ -138,6 +136,8 @@ int BC_CModels::calculate_datasize(int w, int h, int bytes_per_line, int color_m
        case BC_RGB_FLOATP: return w * h * 3 * sizeof(float) + 4;
        case BC_RGBA_FLOATP: return w * h * 4 * sizeof(float) + 4;
        }
+       if( bytes_per_line < 0 )
+               bytes_per_line = w * calculate_pixelsize(color_model);
        return h * bytes_per_line + 4;
 }
 
index 814ef2d4c605c30d3d401e30814ad66700c6b230..269c96a2b23c18438366aa774a6cf6642bcfa060 100644 (file)
@@ -27,9 +27,10 @@ VIcon::
 void VIcon::
 add_image(VFrame *frm, int ww, int hh, int vcmdl)
 {
-       VFrame *img = new VFrame(ww, hh, vcmdl);
+       VIFrame *vifrm = new VIFrame(ww, hh, vcmdl);
+       VFrame *img = *vifrm;
        img->transfer_from(frm);
-       images.append(img);
+       images.append(vifrm);
 }
 
 void VIcon::
@@ -69,7 +70,7 @@ VIconThread(BC_WindowBase *wdw, int vw, int vh)
        this->wdw = wdw;
        this->view_win = 0;  this->vicon = 0;
        this->view_w = vw;   this->view_h = vh;
-       this->viewing = 0;   this->draw_flash = 0;
+       this->viewing = 0;
        draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
        timer = new Timer();
        done = 0;
@@ -95,6 +96,8 @@ void VIconThread::
 start_drawing()
 {
        wdw->lock_window("VIconThread::start_drawing");
+       if( view_win )
+               wdw->set_active_subwindow(view_win);
         if( interrupted )
                draw_lock->unlock();
        wdw->unlock_window();
@@ -104,6 +107,7 @@ void VIconThread::
 stop_drawing()
 {
        wdw->lock_window("VIconThread::stop_drawing");
+       set_view_popup(0);
        interrupted = 1;
        wdw->unlock_window();
 }
@@ -174,7 +178,6 @@ reset_images()
        for( int i=t_heap.size(); --i>=0; ) t_heap[i]->age = 0;
        timer->update();
        img_dirty = win_dirty = 0;
-       draw_flash = 0;
 }
 
 void VIconThread::add_vicon(VIcon *vip, double age)
@@ -210,6 +213,7 @@ update_view()
                view_win = new_view_window(frame);
                view_win->show_window();
        }
+       wdw->set_active_subwindow(view_win);
        return 1;
 }
 
@@ -226,7 +230,7 @@ flash()
 {
        if( !img_dirty && !win_dirty ) return;
        if( img_dirty ) wdw->flash();
-       if( win_dirty ) view_win->flash();
+       if( win_dirty && view_win ) view_win->flash();
        win_dirty = img_dirty = 0;
 }
 
@@ -237,6 +241,7 @@ draw(VIcon *vicon)
        int draw_img = visible(vicon, x, y);
        int draw_win = view_win && viewing == vicon ? 1 : 0;
        if( !draw_img && !draw_win ) return 0;
+       if( !vicon->frame() ) return 0;
        if( draw_img ) {
                vicon->draw_vframe(wdw, x, y);
                img_dirty = 1;
@@ -258,40 +263,47 @@ run()
                reset_images();
                interrupted = 0;
                drawing_started();
+               int64_t draw_flash = 0;
+               VIcon *first = 0;
                while( !interrupted ) {
                        if( viewing != vicon )
                                update_view();
                        VIcon *next = low_vicon();
                        if( !next ) break;
-                       if( !next->frame() ) {
-                               delete next;  next = 0;
+                       int64_t now = timer->get_difference();
+                       if( next == first || (draw_flash && now >= draw_flash) ) {
+                               add_vicon(next, next->age);
+                               if( !draw_flash ) draw_flash = now + 100;
+                               else if( now >= draw_flash ) draw_flash = now + 1; 
+                               wdw->unlock_window();
+                               while( !interrupted ) {
+                                       now = timer->get_difference();
+                                       int64_t ms = draw_flash - now;
+                                       if( ms <= 0 ) break;
+                                       if( ms > 100 ) ms = 100;
+                                       Timer::delay(ms);
+                               }
+                               wdw->lock_window("BC_WindowBase::run 2");
+                               now = timer->get_difference();
+                               int64_t late = now - draw_flash;
+                               if( late < 1000 ) flash();
+                               draw_flash = 0;
+                               first = 0;
                                continue;
                        }
-                       int64_t next_time = next->age;
-                       int64_t this_time = timer->get_difference();
-                       int64_t msec = this_time - next_time;
-                       int count = msec / next->period;
+                       if( !first ) first = next;
+                       if( draw(next) && !draw_flash )
+                               draw_flash = next->age;
+                       now = timer->get_difference();
+                       int64_t late = now - next->age;
+                       int count = late / next->period;
                        int nfrms = count > 0 ? count : 1;
                        if( !next->next_frame(nfrms) )
-                               next->age = this_time + 1000;
+                               next->age = now + 1000;
                        add_vicon(next, next->age);
-                       if( msec < 1000 && draw(next) && !draw_flash )
-                               draw_flash = next_time;
-                       wdw->unlock_window();
-                       msec = next_time - timer->get_difference();
-                       if( msec < 1 ) msec = 1;
-                       while( msec > 0 && !interrupted ) {
-                               int ms = msec > 100 ? 100 : msec;
-                               Timer::delay(ms);  msec -= ms;
-                       }
-                       wdw->lock_window("BC_WindowBase::run 2");
-                       if( interrupted ) break;
-                       if( draw_flash ) {
-                               int64_t msec = timer->get_difference() - draw_flash;
-                               if( msec < 1000 ) flash();
-                               draw_flash = 0;
-                       }
                }
+               if( viewing != vicon )
+                       update_view();
                drawing_stopped();
                interrupted = -1;
                wdw->unlock_window();
@@ -304,7 +316,8 @@ void VIcon::dump(const char *dir)
        for( int i=0; i<images.size(); ++i ) {
                char fn[1024];  sprintf(fn,"%s/img%05d.png",dir,i);
                printf("\r%s",fn);
-               images[i]->write_png(fn);
+               VFrame *img = *images[i];
+               img->write_png(fn);
        }
        printf("\n");
 }
index b209af3a60f019284d049284695ddf8393d9349e..da194c413525222537a27b8f489142782f72829b 100644 (file)
@@ -2,6 +2,7 @@
 #define __VICON_H__
 
 #include "arraylist.h"
+#include "bccmodels.h"
 #include "bcpopup.h"
 #include "bcwindowbase.h"
 #include "thread.h"
@@ -19,11 +20,25 @@ public:
        ~ViewPopup();
 };
 
+class VIFrame {
+       unsigned char *img_data;
+       VFrame *vfrm;
+public:
+       VIFrame(int ww, int hh, int vcmdl) {
+               int size = BC_CModels::calculate_datasize(ww, hh, -1, vcmdl);
+               img_data = new unsigned char[size];
+               vfrm = new VFrame(img_data, -1, ww, hh, vcmdl, -1);
+       }
+       ~VIFrame() { delete vfrm;  delete [] img_data; }
+
+       operator VFrame *() { return vfrm; }
+};
+
 class VIcon
 {
 public:
        int vw, vh, vcmdl, in_use;
-       ArrayList<VFrame *> images;
+       ArrayList<VIFrame *> images;
         int64_t seq_no;
         double age, period;
 
@@ -32,7 +47,7 @@ public:
        int64_t vframes() { return images.size(); }
        void clear_images() { images.remove_all_objects(); }
 
-       virtual VFrame *frame() { return images[seq_no]; }
+       virtual VFrame *frame() { return *images[seq_no]; }
        virtual int64_t next_frame(int n) {
                age += n * period;
                if( (seq_no+=n) >= images.size() ) seq_no = 0;
@@ -60,7 +75,6 @@ public:
        VIcon *viewing, *vicon;
        int view_w, view_h;
        int img_dirty, win_dirty;
-       int64_t draw_flash;
 
        ArrayList<VIcon *>t_heap;
        VIcon *low_vicon();