From 0c4a2f8b1eeef69a9fb35868e36c8772141e3c4b Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sun, 13 Dec 2015 11:37:52 -0700 Subject: [PATCH] fixes and upgrades for vicons --- cinelerra-5.0/cinelerra/awindowgui.C | 16 +++++-- cinelerra-5.0/cinelerra/awindowgui.h | 1 + cinelerra-5.0/cinelerra/dbwindow.C | 15 +++--- cinelerra-5.0/guicast/bccmodels.C | 4 +- cinelerra-5.0/guicast/vicon.C | 71 ++++++++++++++++------------ cinelerra-5.0/guicast/vicon.h | 20 ++++++-- 6 files changed, 81 insertions(+), 46 deletions(-) diff --git a/cinelerra-5.0/cinelerra/awindowgui.C b/cinelerra-5.0/cinelerra/awindowgui.C index 17354995..f340bb0e 100644 --- a/cinelerra-5.0/cinelerra/awindowgui.C +++ b/cinelerra-5.0/cinelerra/awindowgui.C @@ -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) diff --git a/cinelerra-5.0/cinelerra/awindowgui.h b/cinelerra-5.0/cinelerra/awindowgui.h index fc03cbc8..f80cbca1 100644 --- a/cinelerra-5.0/cinelerra/awindowgui.h +++ b/cinelerra-5.0/cinelerra/awindowgui.h @@ -95,6 +95,7 @@ public: class AssetVIcon : public VIcon { public: AssetPicon *picon; + VFrame *temp; int64_t length; VFrame *frame(); diff --git a/cinelerra-5.0/cinelerra/dbwindow.C b/cinelerra-5.0/cinelerra/dbwindow.C index 5c876bf1..6d479b37 100644 --- a/cinelerra-5.0/cinelerra/dbwindow.C +++ b/cinelerra-5.0/cinelerra/dbwindow.C @@ -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); } } diff --git a/cinelerra-5.0/guicast/bccmodels.C b/cinelerra-5.0/guicast/bccmodels.C index e50193c6..88ed1acd 100644 --- a/cinelerra-5.0/guicast/bccmodels.C +++ b/cinelerra-5.0/guicast/bccmodels.C @@ -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; } diff --git a/cinelerra-5.0/guicast/vicon.C b/cinelerra-5.0/guicast/vicon.C index 814ef2d4..269c96a2 100644 --- a/cinelerra-5.0/guicast/vicon.C +++ b/cinelerra-5.0/guicast/vicon.C @@ -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; iwrite_png(fn); + VFrame *img = *images[i]; + img->write_png(fn); } printf("\n"); } diff --git a/cinelerra-5.0/guicast/vicon.h b/cinelerra-5.0/guicast/vicon.h index b209af3a..da194c41 100644 --- a/cinelerra-5.0/guicast/vicon.h +++ b/cinelerra-5.0/guicast/vicon.h @@ -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 images; + ArrayList 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; ArrayListt_heap; VIcon *low_vicon(); -- 2.26.2