-DbWindowTIconThread::
-DbWindowTIconThread(DbWindowGUI *gui)
- : Thread(1, 0, 0)
-{
- this->gui = gui;
- mdb = gui->dwindow->mdb;
- mdb->add_user();
- ticon_lock = new Mutex("DbWindowTIconThread::ticon_lock");
- draw_lock = new Condition(0, "DbWindowTIconThread::draw_lock", 0);
- stop_lock = new Condition(0, "DbWindowTIconThread::stop_lock", 0);
- timer = new Timer();
- done = 0; interrupted = 1;
- list_update = image_update = 0;
- Thread::start();
-}
-
-DbWindowTIconThread::
-~DbWindowTIconThread()
-{
- stop_drawing();
- done = 1;
- draw_lock->unlock();
- if( Thread::running() ) {
- Thread::cancel();
- Thread::join();
- }
- mdb->remove_user();
- t_heap.remove_all();
- ticons.remove_all_objects();
- delete draw_lock;
- delete stop_lock;
-}
-
-void DbWindowTIconThread::start_drawing()
-{
- if( interrupted ) {
- interrupted = 0;
- draw_lock->unlock();
- }
-}
-
-void DbWindowTIconThread::stop_drawing()
-{
- if( !interrupted ) {
- interrupted = 1;
- stop_lock->lock("DbWindowTIconThread::stop_draw");
- }
-}
-
-
-DbWindowTIcon::
-DbWindowTIcon(DbWindowGUI *gui, int (DbWindowTIcon::*draw)() )
-{
- this->gui = gui;
- this->draw = draw;
- age = 0; x = y = 0;
- swidth = (SWIDTH+1) & ~1;
- sheight = (SHEIGHT+1) & ~1;
- frame = new VFrame(swidth, sheight, BC_YUV420P);
- memset(frame->get_y(),0,swidth * sheight);
- memset(frame->get_u(),0x80,swidth/2 * sheight/2);
- memset(frame->get_v(),0x80,swidth/2 * sheight/2);
- clip_id = -1; clip_size = 0;
- frame_id = frames = -1;
- seq_no = 0;
- prefix_size = suffix_offset = -1;
- framerate = frame_period = 0;
-}
-
-DbWindowTIcon::
-~DbWindowTIcon()
-{
- delete frame;
-}
-
-
-void DbWindowTIcon::
-update_image(int clip_id, int x, int y)
-{
- DbWindowTIconThread *thread = gui->ticon_thread;
- DbWindow::MDb *mdb = gui->dwindow->mdb;
- if( !mdb->attach_rd() ) {
- if( !mdb->clip_id(clip_id) ) {
- this->clip_id = clip_id;
- this->x = x; this->y = y;
- this->clip_size = mdb->clip_size();;
- this->prefix_size = mdb->clip_prefix_size();
- this->suffix_offset = mdb->clip_frames() - clip_size;
- this->framerate = mdb->clip_framerate();;
- this->frame_period = 1000. / framerate;
- thread->add_ticon(this, 0);
- }
- mdb->detach();
- }
-}
-
-int DbWindowTIcon::
-get_seq_frame()
-{
- int ret, no = seq_no++;
- if( seq_no >= clip_size ) seq_no = 0;
- DbWindow::MDb *mdb = gui->dwindow->mdb;
- if( !mdb->attach_rd() ) {
- if( !no ) frame_id = -1;
- else if( no >= prefix_size ) no += suffix_offset;
- if( !(ret=mdb->get_sequences(clip_id, no)) ) {
- if( mdb->timeline_sequence_no() == no )
- frame_id = mdb->timeline_frame_id();
- uint8_t *yp = frame->get_y();
- if( frame_id >= 0 ) {
- int sw, sh;
- ret = mdb->get_image(frame_id, yp, sw, sh);
- }
- else
- memset(yp,0,swidth*sheight);
- }
- else if( no > 0 ) ret = 0;
- mdb->detach();
- }
- return ret;
-}
-
-int DbWindowTIcon::
-draw_frame()
-{
- gui->canvas->draw_frame(frame, x, y, swidth, sheight);
- return 0;
-}
-
-int DbWindowTIcon::
-draw_popup()
-{
- BC_Popup *vpopup = gui->search_list->view_popup;
- if( !vpopup ) return 1;
- vpopup->lock_window("DbWindowTIcon::draw_popup");
- vpopup->draw_vframe(frame, 0,0,vpopup->get_w(),vpopup->get_h(), 0,0,swidth,sheight, 0);
- vpopup->flash();
- vpopup->unlock_window();
- return 0;
-}
-
-DbWindowTIcon *DbWindowTIconThread::get_ticon(int i)
-{
- while( i >= ticons.size() ) {
- DbWindowTIcon *ticon = new DbWindowTIcon(gui, &DbWindowTIcon::draw_frame);
- ticons.append(ticon);
- }
- return ticons[i];
-}
-
-DbWindowTIcon *DbWindowTIconThread::low_ticon()
-{
- mLock by(ticon_lock);
- int sz = t_heap.size();
- if( !sz ) return 0;
- DbWindowTIcon *ticon = t_heap[0];
- int i = 0;
- for( int k; (k=2*(i+1)) < sz; i=k ) {
- if( t_heap[k]->age > t_heap[k-1]->age ) --k;
- t_heap[i] = t_heap[k];
- }
- DbWindowTIcon *last = t_heap[--sz];
- t_heap.remove_number(sz);
- double age = last->age;
- for( int k; i>0 && age<t_heap[k=(i-1)/2]->age; i=k )
- t_heap[i] = t_heap[k];
- t_heap[i] = last;
- return ticon;
-}
-
-void DbWindowTIconThread::add_ticon(DbWindowTIcon *ticon, double age)
-{
- mLock by(ticon_lock);
- ticon->age = age;
- int i = t_heap.size(); t_heap.append(ticon);
- for( int k; i>0 && age<t_heap[(k=(i-1)/2)]->age; i=k )
- t_heap[i] = t_heap[k];
- t_heap[i] = ticon;
-}
-
-int DbWindowList::
-selection_changed()
-{
- gui->stop_drawing(1);
- delete view_popup;
- view_popup = 0;
- int idx = get_selection_number(0, 0);
- if( idx >= 0 && get_selection_number(0, 1) < 0 ) {
- if( view_idx != idx ) {
- view_idx = idx;
- BC_ListBoxItem *item = gui->search_items[0][idx];
- int x = item->get_text_x() - get_xposition();
- int y = item->get_text_y() + get_title_h() - get_yposition();
- int w = 4*SWIDTH, h = 4*SHEIGHT;
- x += gui->get_x() - 2*SWIDTH;
- y += gui->get_y() - 4*SHEIGHT;
- view_popup = new BC_Popup(this, x, y, w, h, BLACK);
- view_ticon->update_image(gui->search_results[idx]->id, 0, 0);
- }
- }
- else
- view_idx = -1;
- gui->start_drawing(0);
- return 0;
-}
-
-void DbWindowTIconThread::
-run()
-{
-
- while(!done) {
- draw_lock->lock("DbWindowTIcon::run");
- if( done ) break;
- int do_flash = 0;
- int64_t last_flash = 0;
- while( !interrupted && !done ) {
- double period = 0;
- gui->lock_window("DbWindowTIconThread::run");
- if( list_update ) {
- list_update = 0;
- gui->update();
- }
- if( image_update ) {
- image_update = 0;
- gui->search_list->update_images();
- timer->update();
- do_flash = 0; last_flash = 0;
-
- }
- gui->unlock_window();
- DbWindowTIcon *ticon = low_ticon();
- if( !ticon ) interrupted = 1;
- if( interrupted ) break;
- int64_t past = timer->get_difference();
- int64_t delay = ticon->age - past;
-//printf("delay %6ld clip %3d seq %d\n",delay,ticon->clip_id, ticon->seq_no);
- if( delay < 10 ) {
- if( !ticon->get_seq_frame() ) ticon->draw_image();
- period = !ticon->seq_no ? 2000 : ticon->frame_period;
- if( past > last_flash + 100 ) do_flash = 1;
- }
- else
- do_flash = 1;
- if( do_flash ) {
- do_flash = 0;
- last_flash = past;
- gui->canvas->flash_canvas();
- }
- add_ticon(ticon, ticon->age + period);
- if( delay > 0 )
- Timer::delay(delay > 333 ? 333 : delay);
- }
- stop_lock->unlock();
- }
-
- t_heap.remove_all();
- ticons.remove_all_objects();
-}
-
-
-