{
this->picon = picon;
this->length = length;
+ temp = 0;
}
AssetVIcon::~AssetVIcon()
{
+ delete temp;
}
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)
class AssetVIcon : public VIcon {
public:
AssetPicon *picon;
+ VFrame *temp;
int64_t length;
VFrame *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)
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);
}
}
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:
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;
}
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::
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;
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();
stop_drawing()
{
wdw->lock_window("VIconThread::stop_drawing");
+ set_view_popup(0);
interrupted = 1;
wdw->unlock_window();
}
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)
view_win = new_view_window(frame);
view_win->show_window();
}
+ wdw->set_active_subwindow(view_win);
return 1;
}
{
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;
}
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;
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();
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");
}
#define __VICON_H__
#include "arraylist.h"
+#include "bccmodels.h"
#include "bcpopup.h"
#include "bcwindowbase.h"
#include "thread.h"
~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;
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;
VIcon *viewing, *vicon;
int view_w, view_h;
int img_dirty, win_dirty;
- int64_t draw_flash;
ArrayList<VIcon *>t_heap;
VIcon *low_vicon();