X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcommonrender.C;fp=cinelerra-5.1%2Fcinelerra%2Fcommonrender.C;h=18239788c8d73a45cfc79665b5896aecabaef595;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/commonrender.C b/cinelerra-5.1/cinelerra/commonrender.C new file mode 100644 index 00000000..18239788 --- /dev/null +++ b/cinelerra-5.1/cinelerra/commonrender.C @@ -0,0 +1,331 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "auto.h" +#include "cache.h" +#include "commonrender.h" +#include "condition.h" +#include "edl.h" +#include "edlsession.h" +#include "intautos.h" +#include "localsession.h" +#include "mainsession.h" +#include "module.h" +#include "mwindow.h" +#include "patchbay.h" +#include "patch.h" +#include "playabletracks.h" +#include "preferences.h" +#include "renderengine.h" +#include "track.h" +#include "tracks.h" +#include "transportque.h" +#include "virtualconsole.h" + +CommonRender::CommonRender(RenderEngine *renderengine) + : Thread(1, 0, 0) +{ + this->renderengine = renderengine; + reset_parameters(); + start_lock = new Condition(0, "CommonRender::start_lock"); +} + +CommonRender::~CommonRender() +{ + delete_vconsole(); + if(modules) + { + for(int i = 0; i < total_modules; i++) + delete modules[i]; + delete [] modules; + } + delete start_lock; +} + +void CommonRender::reset_parameters() +{ + total_modules = 0; + modules = 0; + vconsole = 0; + done = 0; + interrupt = 0; + asynchronous = 0; + restart_plugins = 0; +} + +void CommonRender::arm_command() +{ + int64_t temp_length = 1; + + current_position = tounits(renderengine->command->playbackstart, 0); + if(renderengine->command->realtime) init_output_buffers(); + + if(test_reconfigure(current_position, temp_length)) + { + restart_playback(); + } + else + { + vconsole->start_playback(); + } + + done = 0; + interrupt = 0; + restart_plugins = 0; +} + + + +void CommonRender::create_modules() +{ +// Create a module for every track, playable or not + Track *current = renderengine->get_edl()->tracks->first; + int module = 0; +// printf("CommonRender::create_modules %d modules=%p total_modules=%d\n", +// __LINE__, +// modules, +// total_modules); + + if(!modules) + { + total_modules = get_total_tracks(); + modules = new Module*[total_modules]; + +// printf("CommonRender::create_modules %d total_modules=%d\n", +// __LINE__, +// total_modules); + for(module = 0; module < total_modules && current; current = NEXT) + { + if(current->data_type == data_type) + { + modules[module] = new_module(current); + modules[module]->create_objects(); + module++; + } + } + } + else +// Update changes in plugins for existing modules + { + for(module = 0; module < total_modules; module++) + { + modules[module]->create_objects(); + } + } +} + +void CommonRender::start_plugins() +{ +// Only start if virtual console was created + if(restart_plugins) + { + for(int i = 0; i < total_modules; i++) + { + modules[i]->render_init(); + } + } +} + +void CommonRender::stop_plugins() +{ + for(int i = 0; i < total_modules; i++) + { + modules[i]->render_stop(); + } +} + +int CommonRender::test_reconfigure(int64_t position, int64_t &length) +{ + if(!vconsole) return 1; + if(!modules) return 1; + + return vconsole->test_reconfigure(position, length); +} + + +void CommonRender::build_virtual_console() +{ +// Create new virtual console object + if(!vconsole) + { + vconsole = new_vconsole_object(); + } + +// Create nodes + vconsole->create_objects(); +} + +void CommonRender::start_command() +{ + if(renderengine->command->realtime) + { + Thread::set_realtime(renderengine->get_edl()->session->real_time_playback && + data_type == TRACK_AUDIO); + Thread::start(); + start_lock->lock("CommonRender::start_command"); + } +} + +void CommonRender::interrupt_playback() +{ + interrupt = 1; +} + +int CommonRender::restart_playback() +{ +//printf("CommonRender::restart_playback %d\n", __LINE__); + delete_vconsole(); + create_modules(); + build_virtual_console(); +//vconsole->dump(); + start_plugins(); +//printf("CommonRender::restart_playback %d\n", __LINE__); + + done = 0; + interrupt = 0; + restart_plugins = 0; + return 0; +} + +void CommonRender::delete_vconsole() +{ + if(vconsole) delete vconsole; + vconsole = 0; +} + +int CommonRender::get_boundaries(int64_t ¤t_render_length) +{ + int64_t loop_end = tounits(renderengine->get_edl()->local_session->loop_end, 1); + int64_t loop_start = tounits(renderengine->get_edl()->local_session->loop_start, 0); + int64_t start_position = tounits(renderengine->command->start_position, 0); + int64_t end_position = tounits(renderengine->command->end_position, 1); + + +// test absolute boundaries if no loop and not infinite + if(renderengine->command->single_frame() || + (!renderengine->get_edl()->local_session->loop_playback && + !renderengine->command->infinite)) + { + if(renderengine->command->get_direction() == PLAY_FORWARD) + { + if(current_position + current_render_length >= end_position) + { + current_render_length = end_position - current_position; + if(current_render_length <= 0) done = 1; + } + } +// reverse playback + else + { + if(current_position - current_render_length <= start_position) + { + current_render_length = current_position - start_position; + if(current_render_length <= 0) done = 1; + } + } + } + +// test against loop boundaries + if(!renderengine->command->single_frame() && + renderengine->get_edl()->local_session->loop_playback && + !renderengine->command->infinite) + { + if(renderengine->command->get_direction() == PLAY_FORWARD) + { + int64_t segment_end = current_position + current_render_length; + if(segment_end > loop_end) + { + current_render_length = loop_end - current_position; + } + } + else + { + int64_t segment_end = current_position - current_render_length; + if(segment_end < loop_start) + { + current_render_length = current_position - loop_start; + } + } + } + + if(renderengine->command->single_frame()) + current_render_length = 1; + + if(current_render_length < 0) current_render_length = 0; + return 0; +} + +void CommonRender::run() +{ + start_lock->unlock(); +} + +int64_t CommonRender::tounits(double position, int round) +{ + return (int64_t)position; +} + +double CommonRender::fromunits(int64_t position) +{ + return (double)position; +} + +int CommonRender::advance_position(int64_t current_render_length) +{ + int64_t loop_end = tounits(renderengine->get_edl()->local_session->loop_end, 1); + int64_t loop_start = tounits(renderengine->get_edl()->local_session->loop_start, 0); + int64_t start_position = tounits(renderengine->command->start_position, 0); + int64_t end_position = tounits(renderengine->command->end_position, 1); + int direction = renderengine->command->get_direction(); + +// advance the playback position + if(direction == PLAY_REVERSE) + current_position -= current_render_length; + else + current_position += current_render_length; + +// test loop again + if(renderengine->get_edl()->local_session->loop_playback && + !renderengine->command->infinite) + { + if(direction == PLAY_REVERSE) + { + if(current_position <= loop_start) + current_position = loop_end; + } + else + { + if(current_position >= loop_end) + current_position = loop_start + (current_position - loop_end); + } + } + else +// test end of file again + { + if( (direction == PLAY_FORWARD && current_position >= end_position) || + (direction == PLAY_REVERSE && current_position <= start_position) ) + done = 1; + } + + return 0; +} + +