int64_t ATrack::to_units(double position, int round)
{
- if(round)
- return Units::round(position * edl->session->sample_rate);
- else
- return Units::to_int64(position * edl->session->sample_rate);
+ return round ? Units::round(position * edl->session->sample_rate) :
+ Units::to_int64(position * edl->session->sample_rate + 1e-6);
}
double ATrack::to_doubleunits(double position)
}
}
-
-
-
+void CWindow::stop_playback()
+{
+ int locked = gui->get_window_lock();
+ if( locked ) gui->unlock_window();
+ playback_engine->interrupt_playback(1);
+ if( locked ) gui->lock_window("CWindow::stop_playback");
+}
void CWindow::run()
{
void show_window();
void hide_window();
int update_position(double position);
+ void stop_playback();
int destination;
MWindow *mwindow;
user_title[0] = 0;
nested_edl = 0;
is_plugin = 0;
+ hard_left = 0;
+ hard_right = 0;
}
Indexable* Edit::get_source()
file->tag.set_property("STARTSOURCE", startsource_in_selection);
file->tag.set_property("CHANNEL", (int64_t)channel);
file->tag.set_property("LENGTH", length_in_selection);
+ file->tag.set_property("HARD_LEFT", hard_left);
+ file->tag.set_property("HARD_RIGHT", hard_right);
if(user_title[0]) file->tag.set_property("USER_TITLE", user_title);
//printf("Edit::copy 5\n");
this->startsource = edit->startsource;
this->startproject = edit->startproject;
this->length = edit->length;
+ this->hard_left = edit->hard_left;
+ this->hard_right = edit->hard_right;
strcpy (this->user_title, edit->user_title);
if(edit->transition)
this->startsource == edit.startsource &&
this->startproject == edit.startproject &&
this->length == edit.length &&
+ this->hard_left == edit.hard_left &&
+ this->hard_right == edit.hard_right &&
this->transition == edit.transition &&
this->channel == edit.channel);
return result;
fprintf(fp," TRANSITION %p\n", transition);
transition->dump(fp);
}
- fprintf(fp," startsource %jd startproject %jd length %jd\n",
- startsource, startproject, length); fflush(fp);
+ fprintf(fp," startsource %jd startproject %jd hard lt/rt %d/%d length %jd\n",
+ startsource, startproject, hard_left, hard_right, length); fflush(fp);
return 0;
}
{
startsource = file->tag.get_property("STARTSOURCE", (int64_t)0);
length = file->tag.get_property("LENGTH", (int64_t)0);
+ hard_left = file->tag.get_property("HARD_LEFT", (int64_t)0);
+ hard_right = file->tag.get_property("HARD_RIGHT", (int64_t)0);
user_title[0] = 0;
file->tag.get_property("USER_TITLE", user_title);
this->startproject = startproject;
// User defined title for timeline
char user_title[BCTEXTLEN];
int is_plugin;
-
+// edge cannot be optimized
+ int hard_left, hard_right;
// Transition if one is present at the beginning of this edit
// This stores the length of the transition
EDL *edl;
-
-
-
-
-
-
-
-
-
// ============================= initialization
int load_properties(FileXML *xml, int64_t &startproject);
for(current = first; !result && current && current->next; ) {
Edit *next_edit = current->next;
-
// printf("Edits::optimize %d %lld=%lld %d=%d %p=%p %p=%p\n",
// __LINE__, current->startsource + current->length, next_edit->startsource,
// current->channel, next_edit->channel, current->asset, next_edit->asset,
// current->nested_edl, next_edit->nested_edl);
+// both edges are not hard edges
// both edits are silence & not a plugin
// source channels are identical, assets are identical
- if( (current->silence() && next_edit->silence() && !current->is_plugin) ||
+ if( !current->hard_right && !next_edit->hard_left && (
+ (current->silence() && next_edit->silence() && !current->is_plugin) ||
(current->startsource + current->length == next_edit->startsource &&
current->channel == next_edit->channel &&
current->asset == next_edit->asset &&
- current->nested_edl == next_edit->nested_edl)) {
+ current->nested_edl == next_edit->nested_edl)) ) {
//printf("Edits::optimize %d\n", __LINE__);
current->length += next_edit->length;
remove(next_edit);
}
}
+int EDL::blade(double position)
+{
+ return tracks->blade(align_to_frame(position,0));
+}
+
int EDL::clear(double start, double end,
int clear_labels, int clear_plugins, int edit_autos)
{
int edit_autos);
void remove_from_project(ArrayList<Indexable*> *assets);
void remove_from_project(ArrayList<EDL*> *clips);
+ int blade(double position);
int clear(double start,
double end,
int clear_labels,
theme->build_menus();
init_menus();
+ theme->sort_image_sets();
theme->check_used();
-
//printf("MWindow::init_theme %d total_time=%d\n", __LINE__, (int)timer.get_difference());
}
{
int locked = gui->get_window_lock();
if( locked ) gui->unlock_window();
+ gui->stop_drawing();
- cwindow->playback_engine->stop_playback();
+ cwindow->stop_playback();
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
- vwindow->playback_engine->stop_playback();
+ vwindow->stop_playback();
}
for(int i = 0; i < zwindows.size(); i++) {
ZWindow *zwindow = zwindows[i];
if( !zwindow->is_running() ) continue;
- zwindow->zgui->playback_engine->stop_playback();
+ zwindow->stop_playback();
}
if( locked ) gui->lock_window("MWindow::stop_playback");
}
void MWindow::reset_caches()
{
- gui->resource_thread->get_video_source(0);
- gui->resource_thread->get_audio_source(0);
+ stop_playback(1);
+ int locked = gui->get_window_lock();
+ if( locked ) gui->unlock_window();
+ gui->resource_thread->stop_draw(1);
+ gui->resource_thread->source_lock->lock("MWindow::reset_caches");
frame_cache->remove_all();
wave_cache->remove_all();
audio_cache->remove_all();
video_cache->remove_all();
- if( cwindow->playback_engine && cwindow->playback_engine->audio_cache )
- cwindow->playback_engine->audio_cache->remove_all();
- if( cwindow->playback_engine && cwindow->playback_engine->video_cache )
- cwindow->playback_engine->video_cache->remove_all();
-
+ gui->resource_thread->source_lock->unlock();
+ if( locked ) gui->lock_window("MWindow::reset_caches");
+ if( cwindow->playback_engine ) {
+ if( cwindow->playback_engine->audio_cache )
+ cwindow->playback_engine->audio_cache->remove_all();
+ if( cwindow->playback_engine->video_cache )
+ cwindow->playback_engine->video_cache->remove_all();
+ }
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
- if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
+ if( !vwindow->playback_engine ) continue;
+ if( vwindow->playback_engine->audio_cache )
vwindow->playback_engine->audio_cache->remove_all();
- if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
+ if( vwindow->playback_engine->video_cache )
vwindow->playback_engine->video_cache->remove_all();
}
}
void MWindow::remove_asset_from_caches(Asset *asset)
{
- gui->resource_thread->get_video_source(0);
- gui->resource_thread->get_audio_source(0);
+ stop_playback(1);
+ int locked = gui->get_window_lock();
+ if( locked ) gui->unlock_window();
+ gui->resource_thread->stop_draw(1);
+ gui->resource_thread->source_lock->lock("MWindow::remove_asset_from_caches");
frame_cache->remove_asset(asset);
wave_cache->remove_asset(asset);
audio_cache->delete_entry(asset);
video_cache->delete_entry(asset);
+ gui->resource_thread->source_lock->unlock();
+ if( locked ) gui->lock_window("MWindow::remove_asset_from_caches");
if( cwindow->playback_engine && cwindow->playback_engine->audio_cache )
cwindow->playback_engine->audio_cache->delete_entry(asset);
if( cwindow->playback_engine && cwindow->playback_engine->video_cache )
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
- if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
+ if( !vwindow->playback_engine ) continue;
+ if( vwindow->playback_engine->audio_cache )
vwindow->playback_engine->audio_cache->delete_entry(asset);
- if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
+ if( vwindow->playback_engine->video_cache )
vwindow->playback_engine->video_cache->delete_entry(asset);
}
}
void copy();
int copy(double start, double end);
void cut();
+ void blade(double position);
void cut(double start, double end, double new_position=-1);
// snap off edit from current position to handle/label
void snap_left_edit();
{
double start = edl->local_session->get_selectionstart();
double end = edl->local_session->get_selectionend();
- cut(start, end);
+ if( EQUIV(start,end) )
+ blade(start);
+ else
+ cut(start, end);
+}
+
+void MWindow::blade(double position)
+{
+ undo->update_undo_before();
+ edl->blade(position);
+ edl->optimize();
+ save_backup();
+ undo->update_undo_after(_("blade"), LOAD_EDITS | LOAD_TIMEBAR);
+ restart_brender();
+ update_plugin_guis();
+ gui->update(1, 2, 1, 1, 1, 1, 0);
+ cwindow->update(1, 0, 0, 0, 1);
+ awindow->gui->async_update_assets();
+ cwindow->playback_engine->que->
+ send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
}
void MWindow::cut(double start, double end, double new_position)
temp_picon = 0;
temp_picon2 = 0;
draw_lock = new Condition(0, "ResourceThread::draw_lock", 0);
-// interrupted_lock = new Condition(0, "ResourceThread::interrupted_lock", 0);
+ source_lock = new Condition(1, "ResourceThread::source_lock", 0);
item_lock = new Mutex("ResourceThread::item_lock");
audio_buffer = 0;
for(int i = 0; i < MAXCHANNELS; i++)
{
stop();
delete draw_lock;
-// delete interrupted_lock;
+ delete source_lock;
delete item_lock;
delete temp_picon;
delete temp_picon2;
{
draw_lock->lock("ResourceThread::run");
-
+ source_lock->lock("ResourceThread::run");
while(!interrupted)
{
// Pull off item
get_audio_source(0);
get_video_source(0);
mwindow->age_caches();
+ source_lock->unlock();
}
}
MWindow *mwindow;
MWindowGUI *gui;
Condition *draw_lock;
-// Condition *interrupted_lock;
+ Condition *source_lock;
Mutex *item_lock;
ArrayList<ResourceThreadItem*> items;
int interrupted;
return 0;
}
+int Track::blade(double position)
+{
+ int64_t start = to_units(position, 1);
+ Edit *edit = edits->split_edit(start);
+ if( !edit ) return 1;
+ edit->hard_left = 1;
+ if( edit->previous ) edit->previous->hard_right = 1;
+ return 0;
+}
int Track::clear(double start, double end,
int edit_edits, int edit_labels, int edit_plugins,
void get_source_dimensions(double position, int &w, int &h);
// Editing
- void insert_asset(Asset *asset,
- EDL *nested_edl,
- double length,
- double position,
- int track_number);
- Plugin* insert_effect(const char *title,
- SharedLocation *shared_location,
- KeyFrame *keyframe,
- PluginSet *plugin_set,
- double start,
- double length,
- int plugin_type);
- void insert_plugin_set(Track *track,
- int64_t position,
- int64_t min_length,
- int edit_autos);
+ void insert_asset(Asset *asset, EDL *nested_edl,
+ double length, double position, int track_number);
+ Plugin* insert_effect(const char *title, SharedLocation *shared_location,
+ KeyFrame *keyframe, PluginSet *plugin_set,
+ double start, double length, int plugin_type);
+ void insert_plugin_set(Track *track, int64_t position,
+ int64_t min_length, int edit_autos);
void detach_effect(Plugin *plugin);
// Insert a track from another EDL
- void insert_track(Track *track,
- double position,
- int replace_default,
- int edit_plugins,
- int edit_autos,
+ void insert_track(Track *track, double position,
+ int replace_default, int edit_plugins, int edit_autos,
// Pad pasted sections to a minimum of this length.
double edl_length);
void shuffle_edits(double start, double end, int first_track);
void reverse_edits(double start, double end, int first_track);
- void align_edits(double start,
- double end,
- ArrayList<double> *times);
+ void align_edits(double start, double end, ArrayList<double> *times);
// Optimize editing
void optimize();
int is_muted(int64_t position, int direction); // Test muting status
virtual double from_units(int64_t position);
-
// Positions are identical for handle modifications
virtual int identical(int64_t sample1, int64_t sample2) { return 0; };
// Get the plugin belonging to the set.
Plugin* get_current_plugin(double position,
- int plugin_set,
- int direction,
- int convert_units,
- int use_nudge);
+ int plugin_set, int direction, int convert_units, int use_nudge);
Plugin* get_current_transition(double position,
- int direction,
- int convert_units,
- int use_nudge);
+ int direction, int convert_units, int use_nudge);
// detach shared effects referencing module
void detach_shared_effects(int module);
// Called by playable tracks to test for playable server.
// Descends the plugin tree without creating a virtual console.
// Used by PlayableTracks::is_playable.
- int is_synthesis(int64_t position,
- int direction);
+ int is_synthesis(int64_t position, int direction);
// Used by PlayableTracks::is_playable
// Returns 1 if the track is in the output boundaries.
- virtual int is_playable(int64_t position,
- int direction);
+ virtual int is_playable(int64_t position, int direction);
// Test direct copy conditions common to all the rendering routines
virtual int direct_copy_possible(int64_t start, int direction, int use_nudge);
virtual int copy_settings(Track *track);
void shift_keyframes(int64_t position, int64_t length);
void shift_effects(int64_t position, int64_t length, int edit_autos);
- void change_plugins(SharedLocation &old_location,
- SharedLocation &new_location,
- int do_swap);
- void change_modules(int old_location,
- int new_location,
- int do_swap);
+ void change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap);
+ void change_modules(int old_location, int new_location, int do_swap);
int plugin_exists(Plugin *plugin);
EDL *edl;
virtual int change_channels(int oldchannels, int newchannels) { return 0; };
virtual int dump(FILE *fp);
-
-
// ===================================== editing
int copy(double start, double end,
FileXML *file, const char *output_path = "");
double end,
ArrayList<Asset*> *asset_list);
virtual int copy_derived(int64_t start, int64_t end, FileXML *file) { return 0; };
- virtual int paste_derived(int64_t start, int64_t end, int64_t total_length, FileXML *file, int ¤t_channel) { return 0; };
- int clear(double start,
- double end,
- int edit_edits,
- int edit_labels,
- int clear_plugins,
- int edit_autos,
- int convert_units,
- Edits *trim_edits);
+ virtual int paste_derived(int64_t start, int64_t end,
+ int64_t total_length, FileXML *file, int ¤t_channel) { return 0; };
+ int blade(double position);
+ int clear(double start, double end,
+ int edit_edits, int edit_labels, int clear_plugins,
+ int edit_autos, int convert_units, Edits *trim_edits);
// Returns the point to restart background rendering at.
// -1 means nothing changed.
- void clear_automation(double selectionstart,
- double selectionend,
+ void clear_automation(double selectionstart, double selectionend,
int shift_autos /* = 1 */,
int default_only /* = 0 */);
- void set_automation_mode(double selectionstart,
- double selectionend,
+ void set_automation_mode(double selectionstart, double selectionend,
int mode);
virtual int clear_automation_derived(AutoConf *auto_conf,
- double selectionstart,
- double selectionend,
+ double selectionstart, double selectionend,
int shift_autos = 1) { return 0; };
virtual int clear_derived(double start,
double end) { return 0; };
- int copy_automation(double selectionstart,
- double selectionend,
- FileXML *file,
- int default_only,
- int active_only);
+ int copy_automation(double selectionstart, double selectionend,
+ FileXML *file, int default_only, int active_only);
virtual int copy_automation_derived(AutoConf *auto_conf,
- double selectionstart,
- double selectionend,
+ double selectionstart, double selectionend,
FileXML *file) { return 0; };
- int paste_automation(double selectionstart,
- double total_length,
- double frame_rate,
- int64_t sample_rate,
- FileXML *file,
- int default_only,
- int active_only);
- virtual int paste_automation_derived(double selectionstart,
- double selectionend,
- double total_length,
- FileXML *file,
- int shift_autos,
- int ¤t_pan) { return 0; };
+ int paste_automation(double selectionstart, double total_length,
+ double frame_rate, int64_t sample_rate, FileXML *file,
+ int default_only, int active_only);
+ virtual int paste_automation_derived(double selectionstart, double selectionend,
+ double total_length, FileXML *file, int shift_autos, int ¤t_pan) { return 0; };
int paste_auto_silence(double start, double end);
virtual int paste_auto_silence_derived(int64_t start, int64_t end) { return 0; };
int scale_time(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end);
virtual int scale_time_derived(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end) { return 0; };
int purge_asset(Asset *asset);
int asset_used(Asset *asset);
- int clear_handle(double start,
- double end,
- int clear_labels,
- int clear_plugins,
- int edit_autos,
+ int clear_handle(double start, double end,
+ int clear_labels, int clear_plugins, int edit_autos,
double &distance);
int paste_silence(double start, double end, int edit_plugins, int edit_autos);
virtual int select_translation(int cursor_x, int cursor_y) { return 0; }; // select video coordinates for frame
}
}
+void TrackCanvas::draw_hard_edges()
+{
+ int64_t x, y, w, h;
+
+// if(!mwindow->edl->session->show_assets) return;
+
+ for(Track *track = mwindow->edl->tracks->first; track; track = track->next) {
+ for(Edit *edit = track->edits->first; edit; edit = edit->next) {
+ if( !edit->hard_left && !edit->hard_right ) continue;
+ edit_dimensions(edit, x, y, w, h);
+ set_color(GREEN);
+ set_opaque(); int y1 = y+h-1;
+ if( edit->hard_left ) {
+ ArrayList<int> xpt, ypt;
+ xpt.append(x); ypt.append(y1);
+ xpt.append(x+HANDLE_W); ypt.append(y1);
+ xpt.append(x); ypt.append(y1-HANDLE_H);
+ fill_polygon(&xpt, &ypt);
+ }
+ if( edit->hard_right ) {
+ ArrayList<int> xpt, ypt; int x1 = x+w-1;
+ xpt.append(x1); ypt.append(y1);
+ xpt.append(x1-HANDLE_W); ypt.append(y1);
+ xpt.append(x1); ypt.append(y1-HANDLE_H);
+ fill_polygon(&xpt, &ypt);
+ }
+ }
+ }
+}
+
void TrackCanvas::draw_inout_points()
{
}
// Plugins
draw_plugins();
+ draw_hard_edges();
// Loop points
draw_loop_points();
int &rerender, int &update_overlay, int &new_cursor, int &update_cursor)
{
Edit *edit_result = 0;
- int handle_result = 0;
+ int handle_result = -1;
int result = 0;
- if(!mwindow->edl->session->show_assets) return 0;
+ if( !mwindow->edl->session->show_assets ) return 0;
- for(Track *track = mwindow->edl->tracks->first;
- track && !result;
- track = track->next) {
- for(Edit *edit = track->edits->first;
- edit && !result;
- edit = edit->next) {
+ for( Track *track=mwindow->edl->tracks->first; track && !result; track=track->next) {
+ for( Edit *edit=track->edits->first; edit && !result; edit=edit->next ) {
int64_t edit_x, edit_y, edit_w, edit_h;
edit_dimensions(edit, edit_x, edit_y, edit_w, edit_h);
- if(cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
- cursor_y >= edit_y && cursor_y < edit_y + edit_h) {
- if(cursor_x < edit_x + HANDLE_W) {
+ if( cursor_x >= edit_x && cursor_x <= edit_x + edit_w &&
+ cursor_y >= edit_y && cursor_y < edit_y + edit_h ) {
+ if( cursor_x < edit_x + HANDLE_W ) {
edit_result = edit;
handle_result = 0;
- result = 1;
+ if( cursor_y >= edit_y+edit_h - HANDLE_W ) {
+ new_cursor = DOWNLEFT_RESIZE;
+ if( button_press == LEFT_BUTTON )
+ result = -1;
+ }
+ else
+ result = 1;
}
- else if(cursor_x >= edit_x + edit_w - HANDLE_W) {
+ else if( cursor_x >= edit_x + edit_w - HANDLE_W ) {
edit_result = edit;
handle_result = 1;
- result = 1;
- }
- else {
- result = 0;
+ if( cursor_y >= edit_y+edit_h - HANDLE_W ) {
+ new_cursor = DOWNRIGHT_RESIZE;
+ if( button_press == LEFT_BUTTON )
+ result = -1;
+ }
+ else
+ result = 1;
}
}
}
}
update_cursor = 1;
- if(result) {
+ if( result > 0 ) {
double position = 0;
- if(handle_result == 0) {
+ if( handle_result == 0 ) {
position = edit_result->track->from_units(edit_result->startproject);
new_cursor = LEFT_CURSOR;
}
- else if(handle_result == 1) {
+ else if( handle_result == 1 ) {
position = edit_result->track->from_units(edit_result->startproject + edit_result->length);
new_cursor = RIGHT_CURSOR;
}
// Reposition cursor
- if(button_press) {
+ if( button_press ) {
mwindow->session->drag_edit = edit_result;
mwindow->session->drag_handle = handle_result;
mwindow->session->drag_button = get_buttonpress() - 1;
update_overlay = 1;
}
}
+ else if( result < 0) {
+ mwindow->undo->update_undo_before();
+ if( !shift_down() ) {
+ if( handle_result == 0 )
+ edit_result->hard_left = !edit_result->hard_left;
+ else if( handle_result == 1 )
+ edit_result->hard_right = !edit_result->hard_right;
+ }
+ else {
+ int status = handle_result == 0 ? edit_result->hard_left :
+ handle_result == 1 ? edit_result->hard_right : 0;
+ int new_status = !status;
+ int64_t edit_edge = edit_result->startproject;
+ if( handle_result == 1 ) edit_edge += edit_result->length;
+ double edge_position = edit_result->track->from_units(edit_edge);
+ for( Track *track=mwindow->edl->tracks->first; track!=0; track=track->next ) {
+ int64_t track_position = track->to_units(edge_position, 1);
+ Edit *left_edit = track->edits->editof(track_position, PLAY_FORWARD, 0);
+ if( left_edit ) {
+ int64_t left_edge = left_edit->startproject;
+ double left_position = track->from_units(left_edge);
+ if( EQUIV(edge_position, left_position) )
+ left_edit->hard_left = new_status;
+ }
+ Edit *right_edit = track->edits->editof(track_position, PLAY_REVERSE, 0);
+ if( right_edit ) {
+ int64_t right_edge = right_edit->startproject + right_edit->length;
+ double right_position = track->from_units(right_edge);
+ if( EQUIV(edge_position, right_position) )
+ right_edit->hard_right = new_status;
+ }
+ }
+ }
+ rerender = update_overlay = 1;
+ mwindow->undo->update_undo_after(_("hard_edge"), LOAD_EDITS);
+ result = 1;
+ }
return result;
}
int64_t edit_w,
int64_t edit_h);
void draw_automation();
+ void draw_hard_edges();
void draw_inout_points();
void draw_auto(Auto *current,
int x,
double start,
double end,
int all);
+ int blade(double position);
int clear(double start, double end, int clear_plugins, int edit_autos);
void clear_automation(double selectionstart,
double selectionend);
#include "vtrack.h"
#include <string.h>
+int Tracks::blade(double position)
+{
+ for( Track *track=first; track!=0; track=track->next ) {
+ if( !track->record ) continue;
+ track->blade(position);
+ }
+ return 0;
+}
+
int Tracks::clear(double start, double end, int clear_plugins, int edit_autos)
{
Track *current_track;
int64_t VTrack::to_units(double position, int round)
{
- if(round)
- {
- return Units::round(position * edl->session->frame_rate);
- }
- else
- {
-// Kludge for rounding errors, just on a smaller scale than formal rounding
- position *= edl->session->frame_rate;
- return Units::to_int64(position);
- }
+ return round ? Units::round(position * edl->session->frame_rate) :
+ Units::to_int64(position * edl->session->frame_rate + 1e-6);
}
double VTrack::to_doubleunits(double position)
}
}
-
-
-
+void VWindow::stop_playback()
+{
+ int locked = gui->get_window_lock();
+ if( locked ) gui->unlock_window();
+ playback_engine->interrupt_playback(1);
+ if( locked ) gui->lock_window("VWindow::stop_playback");
+}
int VWindow::update_position(double position)
{
void delete_source(int do_main_edl, int update_gui);
void goto_start();
void goto_end();
-
+ void stop_playback();
VTracking *playback_cursor;
}
}
+void ZWindow::stop_playback()
+{
+ int locked = zgui->get_window_lock();
+ if( locked ) zgui->unlock_window();
+ zgui->playback_engine->interrupt_playback(1);
+ if( locked ) zgui->lock_window("ZWindow::stop_playback");
+}
+
void ZWindow::issue_command(int command, int wait_tracking,
int use_inout, int update_refresh, int toggle_audio)
{
void handle_done_event(int result);
void handle_close_event(int result);
void change_source(EDL *edl);
+ void stop_playback();
void issue_command(int command, int wait_tracking,
int use_inout, int update_refresh, int toggle_audio);
void update_mixer_ids();
kernel.shmmax = 0x7fffffff
+kernel.shmmni = 0x4000
BC_Theme::BC_Theme()
{
- last_image = 0;
+ last_image_data = 0;
+ last_image_set = 0;
+ image_sets_start = -1;
}
BC_Theme::~BC_Theme()
void BC_Theme::dump()
{
- printf("BC_Theme::dump 1 image_sets=%d images=%d\n",
- image_sets.size(), images.size());
+ printf("BC_Theme::dump 1 images=%d\n", images.size());
for( int i=0; i<images.size(); ++i ) {
- image_item *item = images[i];
- printf(" %s %p\n", item->name, item->data);
+ BC_ImageData *image_data = images[i];
+ printf("%4d. %s %p\n", i, image_data->name, image_data->data);
+ }
+ printf("BC_Theme::dump 2 image_sets=%d\n", image_sets.size());
+ for( int i=0; i<image_sets.size(); ++i ) {
+ BC_ThemeSet *image_set = image_sets[i];
+ printf("%4d. %s %p\n", i, image_set->title, image_set->data[0]);
}
}
BC_ThemeSet *result = new BC_ThemeSet(1, 0, title);
result->data[0] = new VFramePng(get_image_data(path));
- image_sets.append(result);
+ add_image_set(result);
return result->data[0];
}
if( existing_image_set ) return existing_image_set;
BC_ThemeSet *result = new BC_ThemeSet(total, 1, title);
- image_sets.append(result);
+ add_image_set(result);
for( int i=0; i<total; ++i ) {
char *path = va_arg(*args, char*);
result->data[i] = new_image(path);
}
BC_ThemeSet *result = new BC_ThemeSet(total, 0, title);
- image_sets.append(result);
+ add_image_set(result);
for( int i=0; i<total; ++i ) {
result->data[i] = va_arg(list, VFrame*);
}
return result;
}
+void BC_Theme::add_image_set(BC_ThemeSet *image_set)
+{
+ image_sets.append(image_set);
+ if( image_sets_start >= 0 ) {
+ printf("BC_Theme::add_image_set image_sets unsorted, lookups degraded\n");
+ image_sets_start = -1;
+ }
+}
+
+int BC_Theme::image_set_cmpr(const void *ap, const void *bp)
+{
+ BC_ThemeSet*a = *(BC_ThemeSet**)ap, *b = *(BC_ThemeSet**)bp;
+ return strcmp(a->title, b->title);
+}
+
+void BC_Theme::sort_image_sets()
+{
+ if( image_sets_start >= 0 ) return;
+ qsort(&image_sets[0], image_sets.size(), sizeof(image_sets[0]), image_set_cmpr);
+// skip over un-titled image sets
+ int i = 0, n = image_sets.size();
+ while( i<n && !image_sets[i]->title[0] ) ++i;
+ image_sets_start = i;
+}
+
BC_ThemeSet* BC_Theme::get_image_set_object(const char *title)
{
+ if( last_image_set && !strcmp(title,last_image_set->title) )
+ return last_image_set;
+
+ if( image_sets_start >= 0 ) {
+// binary search for image set
+ int r = image_sets.size(), l = image_sets_start-1;
+ int m = 0, v = -1;
+ while( r-l > 1 ) {
+ m = (l + r) / 2;
+ BC_ThemeSet *image_set = image_sets[m];
+ if( !(v=strcmp(title, image_set->title)) )
+ return last_image_set = image_set;
+ if( v > 0 ) l = m; else r = m;
+ }
+ }
+ else {
// compare title[0],title[1] for faster prefix test
- const unsigned char *bp = (const unsigned char*)title;
- unsigned short tval = bp[0];
- if( tval ) tval |= (bp[1] << 8);
+ const unsigned char *tp = (const unsigned char*)title;
+ unsigned short tval = tp[0];
+ if( tval ) tval |= (tp[1] << 8);
- for( int i=0; i<image_sets.size(); ++i ) {
- const char *tp = image_sets[i]->title;
- bp = (const unsigned char *) tp;
- unsigned short val = bp[0];
- if( val ) val |= (bp[1] << 8);
- if( val != tval ) continue;
- if( !strcmp(tp, title) ) return image_sets[i];
+ for( int i=0; i<image_sets.size(); ++i ) {
+ tp = (const unsigned char *)image_sets[i]->title;
+ unsigned short val = tp[0];
+ if( val ) val |= (tp[1] << 8);
+ if( val != tval ) continue;
+ if( !strcmp((const char *)tp, title) )
+ return last_image_set = image_sets[i];
+ }
}
+
return 0;
}
{
VFramePng default_data(get_image_data(overlay_path));
BC_ThemeSet *result = new BC_ThemeSet(3, 1, title ? title : "");
- if( title ) image_sets.append(result);
+ if( title ) add_image_set(result);
result->data[0] = new_image(up_path);
result->data[1] = new_image(hi_path);
{
VFramePng default_data(get_image_data(overlay_path));
BC_ThemeSet *result = new BC_ThemeSet(4, 1, title ? title : "");
- if( title ) image_sets.append(result);
+ if( title ) add_image_set(result);
result->data[0] = new_image(up_path);
result->data[1] = new_image(hi_path);
{
VFramePng default_data(get_image_data(overlay_path));
BC_ThemeSet *result = new BC_ThemeSet(3, 0, title ? title : "");
- if( title ) image_sets.append(result);
+ if( title ) add_image_set(result);
result->data[0] = new VFrame(*up);
result->data[1] = new VFrame(*hi);
{
VFramePng default_data(get_image_data(overlay_path));
BC_ThemeSet *result = new BC_ThemeSet(5, 1, title ? title : "");
- if( title ) image_sets.append(result);
+ if( title ) add_image_set(result);
result->data[0] = new_image(up_path);
result->data[1] = new_image(hi_path);
{
VFramePng default_data(get_image_data(overlay_path));
BC_ThemeSet *result = new BC_ThemeSet(5, 0, title ? title : "");
- if( title ) image_sets.append(result);
+ if( title ) add_image_set(result);
result->data[0] = new VFrame(*up);
result->data[1] = new VFrame(*hi);
if( cp + sizeof(unsigned) > dp ) break;
unsigned ofs = 0;
for( int i=sizeof(unsigned); --i>=0; ofs|=cp[i] ) ofs <<= 8;
- images.append(new image_item(nm, dp+ofs));
+ images.append(new BC_ImageData(nm, dp+ofs));
cp += sizeof(unsigned);
}
int BC_Theme::images_cmpr(const void *ap, const void *bp)
{
- image_item *a = *(image_item**)ap, *b = *(image_item**)bp;
- return strcasecmp(a->name, b->name);
+ BC_ImageData *a = *(BC_ImageData**)ap, *b = *(BC_ImageData**)bp;
+ return strcmp(a->name, b->name);
}
unsigned char* BC_Theme::get_image_data(const char *name, int log_errs)
{
// Image is the same as the last one
- if( last_image && !strcasecmp(last_image->name, name) )
- return last_image->data;
+ if( last_image_data && !strcasecmp(last_image_data->name, name) )
+ return last_image_data->data;
// look forwards thru data sets for name
int start_item = 0;
int m = 0, v = -1;
while( r-l > 1 ) {
m = (l + r) / 2;
- image_item *item = images[m];
- if( !(v=strcasecmp(name, item->name)) ) {
- item->used = 1;
- last_image = item;
- return item->data;
+ BC_ImageData *image_data = images[m];
+ if( !(v=strcasecmp(name, image_data->name)) ) {
+ image_data->used = 1;
+ last_image_data = image_data;
+ return image_data->data;
}
if( v > 0 ) l = m; else r = m;
}
#include <stdarg.h>
class BC_ThemeSet;
+class BC_ImageData;
+class BC_ImageData {
+public:
+ char *name;
+ unsigned char *data;
+ int used;
+ BC_ImageData(char *nm, unsigned char *dp) {
+ name = nm; data = dp; used = 0;
+ }
+};
class BC_Theme
// Verify all images have been used after initialization.
void check_used();
+ void sort_image_sets();
void dump();
BC_Resources* get_resources();
// Decompressed image storage.
// Sets of images.
ArrayList<BC_ThemeSet*> image_sets;
+ BC_ThemeSet *last_image_set;
+ int image_sets_start;
+ static int image_set_cmpr(const void *ap, const void *bp);
+ void add_image_set(BC_ThemeSet *image_set);
// Compressed images are loaded in here.
- class image_item {
- public:
- char *name;
- unsigned char *data;
- int used;
-
- image_item(char *nm, unsigned char *dp) {
- name = nm; data = dp; used = 0;
- }
- } *last_image;
-
- ArrayList<image_item *> images;
ArrayList<int> data_items;
-
+ ArrayList<BC_ImageData *> images;
+ BC_ImageData *last_image_data;
static int images_cmpr(const void *ap, const void *bp);
};
lame.mak_params?= ; cd $(call bld_path,lame,include); ln -sf . lame
mjpegtools.cflags?="$(call inc_path,libjpeg) $(call ld_path,libjpeg,.libs)"
mjpegtools.mak_params?=; ln -s . $(call bld_path,mjpegtools,utils)/mjpegtools
-mjpegtools.cfg_params?= --enable-shared=no
+mjpegtools.cfg_params?= --enable-shared=no --without-libsdl
ladspa.cfg_vars?= CFLAGS+=' -Dinline="" '
ladspa.mak_params?=; $(MAKE) -C ladspa* install DESTDIR=$(call bld_path,ladspa)
libavc1394.cfg_vars?=PKG_CONFIG_PATH=$(call bld_path,libraw1394)