X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Fvrender.C;fp=cinelerra-5.0%2Fcinelerra%2Fvrender.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=8c5e7e2206753737cc0e4a44a97ec7cf7fb57ac5;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/vrender.C b/cinelerra-5.0/cinelerra/vrender.C deleted file mode 100644 index 8c5e7e22..00000000 --- a/cinelerra-5.0/cinelerra/vrender.C +++ /dev/null @@ -1,547 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2009 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 "asset.h" -#include "bcsignals.h" -#include "cache.h" -#include "condition.h" -#include "datatype.h" -#include "edits.h" -#include "edl.h" -#include "edlsession.h" -#include "file.h" -#include "format.inc" -#include "localsession.h" -#include "mainsession.h" -#include "mwindow.h" -#include "overlayframe.h" -#include "playabletracks.h" -#include "playbackengine.h" -#include "preferences.h" -#include "preferencesthread.h" -#include "renderengine.h" -#include "strategies.inc" -#include "tracks.h" -#include "transportque.h" -#include "units.h" -#include "vedit.h" -#include "vframe.h" -#include "videoconfig.h" -#include "videodevice.h" -#include "virtualconsole.h" -#include "virtualvconsole.h" -#include "vmodule.h" -#include "vrender.h" -#include "vtrack.h" - - - - - -VRender::VRender(RenderEngine *renderengine) - : CommonRender(renderengine) -{ - data_type = TRACK_VIDEO; - transition_temp = 0; - overlayer = new OverlayFrame(renderengine->preferences->processors); - input_temp = 0; - vmodule_render_fragment = 0; - playback_buffer = 0; - session_frame = 0; - asynchronous = 0; // render 1 frame at a time - framerate_counter = 0; - video_out = 0; - render_strategy = -1; -} - -VRender::~VRender() -{ - if(input_temp) delete input_temp; - if(transition_temp) delete transition_temp; - if(overlayer) delete overlayer; -} - - -VirtualConsole* VRender::new_vconsole_object() -{ - return new VirtualVConsole(renderengine, this); -} - -int VRender::get_total_tracks() -{ - return renderengine->get_edl()->tracks->total_video_tracks(); -} - -Module* VRender::new_module(Track *track) -{ - return new VModule(renderengine, this, 0, track); -} - -int VRender::flash_output() -{ - if(video_out) - return renderengine->video->write_buffer(video_out, renderengine->get_edl()); - else - return 0; -} - -int VRender::process_buffer(VFrame *video_out, - int64_t input_position, - int use_opengl) -{ -// process buffer for non realtime - int64_t render_len = 1; - int reconfigure = 0; - - - this->video_out = video_out; - - current_position = input_position; - - reconfigure = vconsole->test_reconfigure(input_position, - render_len); - - if(reconfigure) restart_playback(); - return process_buffer(input_position, use_opengl); -} - - -int VRender::process_buffer(int64_t input_position, - int use_opengl) -{ - VEdit *playable_edit = 0; - int colormodel; - int use_vconsole = 1; - int use_brender = 0; - int result = 0; - int use_cache = renderengine->command->single_frame(); - int use_asynchronous = - renderengine->command->realtime && - renderengine->get_edl()->session->video_every_frame && - renderengine->get_edl()->session->video_asynchronous; - const int debug = 0; - -// Determine the rendering strategy for this frame. - use_vconsole = get_use_vconsole(&playable_edit, - input_position, - use_brender); - if(debug) printf("VRender::process_buffer %d use_vconsole=%d\n", __LINE__, use_vconsole); - -// Negotiate color model - colormodel = get_colormodel(playable_edit, use_vconsole, use_brender); - if(debug) printf("VRender::process_buffer %d\n", __LINE__); - - - - -// Get output buffer from device - if(renderengine->command->realtime && - !renderengine->is_nested) - { - renderengine->video->new_output_buffer(&video_out, colormodel); - } - - if(debug) printf("VRender::process_buffer %d video_out=%p\n", __LINE__, video_out); - -// printf("VRender::process_buffer use_vconsole=%d colormodel=%d video_out=%p\n", -// use_vconsole, -// colormodel, -// video_out); -// Read directly from file to video_out - if(!use_vconsole) - { - - if(use_brender) - { - Asset *asset = renderengine->preferences->brender_asset; - File *file = renderengine->get_vcache()->check_out(asset, - renderengine->get_edl()); - - if(file) - { - int64_t corrected_position = current_position; - if(renderengine->command->get_direction() == PLAY_REVERSE) - corrected_position--; - -// Cache single frames only - if(use_asynchronous) - file->start_video_decode_thread(); - else - file->stop_video_thread(); - if(use_cache) file->set_cache_frames(1); - int64_t normalized_position = (int64_t)(corrected_position * - asset->frame_rate / - renderengine->get_edl()->session->frame_rate); - - file->set_video_position(normalized_position, - 0); - file->read_frame(video_out); - - - if(use_cache) file->set_cache_frames(0); - renderengine->get_vcache()->check_in(asset); - } - - } - else - if(playable_edit) - { - if(debug) printf("VRender::process_buffer %d\n", __LINE__); - result = ((VEdit*)playable_edit)->read_frame(video_out, - current_position, - renderengine->command->get_direction(), - renderengine->get_vcache(), - 1, - use_cache, - use_asynchronous); - if(debug) printf("VRender::process_buffer %d\n", __LINE__); - } - - - - video_out->set_opengl_state(VFrame::RAM); - } - else -// Read into virtual console - { - -// process this buffer now in the virtual console - result = ((VirtualVConsole*)vconsole)->process_buffer(input_position, - use_opengl); - } - - return result; -} - -// Determine if virtual console is needed -int VRender::get_use_vconsole(VEdit* *playable_edit, - int64_t position, int &use_brender) -{ - *playable_edit = 0; - -// Background rendering completed - if((use_brender = renderengine->brender_available(position, - renderengine->command->get_direction())) != 0) - return 0; - -// Descend into EDL nest - return renderengine->get_edl()->get_use_vconsole(playable_edit, - position, - renderengine->command->get_direction(), - vconsole->playable_tracks); -} - -int VRender::get_colormodel(VEdit *playable_edit, - int use_vconsole, int use_brender) -{ - int colormodel = renderengine->get_edl()->session->color_model; - - if(!use_vconsole && !renderengine->command->single_frame()) - { -// Get best colormodel supported by the file - int driver = renderengine->config->vconfig->driver; - File *file; - Asset *asset; - - if(use_brender) - { - asset = renderengine->preferences->brender_asset; - } - else - { - int64_t source_position = 0; - asset = playable_edit->get_nested_asset(&source_position, - current_position, - renderengine->command->get_direction()); - } - - if(asset) - { - file = renderengine->get_vcache()->check_out(asset, - renderengine->get_edl()); - - if(file) - { - colormodel = file->get_best_colormodel(driver); - renderengine->get_vcache()->check_in(asset); - } - } - } - - return colormodel; -} - - - - - - - -void VRender::run() -{ - int reconfigure; - const int debug = 0; - -// Want to know how many samples rendering each frame takes. -// Then use this number to predict the next frame that should be rendered. -// Be suspicious of frames that render late so have a countdown -// before we start dropping. - int64_t current_sample, start_sample, end_sample; // Absolute counts. - int64_t skip_countdown = VRENDER_THRESHOLD; // frames remaining until drop - int64_t delay_countdown = VRENDER_THRESHOLD; // Frames remaining until delay -// Number of frames before next reconfigure - int64_t current_input_length; -// Number of frames to skip. - int64_t frame_step = 1; - int use_opengl = (renderengine->video && - renderengine->video->out_config->driver == PLAYBACK_X11_GL); - - first_frame = 1; - -// Number of frames since start of rendering - session_frame = 0; - framerate_counter = 0; - framerate_timer.update(); - - start_lock->unlock(); - if(debug) printf("VRender::run %d\n", __LINE__); - - - while(!done && !interrupt ) - { -// Perform the most time consuming part of frame decompression now. -// Want the condition before, since only 1 frame is rendered -// and the number of frames skipped after this frame varies. - current_input_length = 1; - - reconfigure = vconsole->test_reconfigure(current_position, - current_input_length); - - - if(debug) printf("VRender::run %d\n", __LINE__); - if(reconfigure) restart_playback(); - - if(debug) printf("VRender::run %d\n", __LINE__); - process_buffer(current_position, use_opengl); - - - if(debug) printf("VRender::run %d\n", __LINE__); - - if(renderengine->command->single_frame()) - { - if(debug) printf("VRender::run %d\n", __LINE__); - flash_output(); - frame_step = 1; - done = 1; - } - else -// Perform synchronization - { -// Determine the delay until the frame needs to be shown. - current_sample = (int64_t)(renderengine->sync_position() * - renderengine->command->get_speed()); -// latest sample at which the frame can be shown. - end_sample = Units::tosamples(session_frame, - renderengine->get_edl()->session->sample_rate, - renderengine->get_edl()->session->frame_rate); -// earliest sample by which the frame needs to be shown. - start_sample = Units::tosamples(session_frame - 1, - renderengine->get_edl()->session->sample_rate, - renderengine->get_edl()->session->frame_rate); - - if(first_frame || end_sample < current_sample) - { -// Frame rendered late or this is the first frame. Flash it now. -//printf("VRender::run %d\n", __LINE__); - flash_output(); - - if(renderengine->get_edl()->session->video_every_frame) - { -// User wants every frame. - frame_step = 1; - } - else - if(skip_countdown > 0) - { -// Maybe just a freak. - frame_step = 1; - skip_countdown--; - } - else - { -// Get the frames to skip. - delay_countdown = VRENDER_THRESHOLD; - frame_step = 1; - frame_step += (int64_t)Units::toframes(current_sample, - renderengine->get_edl()->session->sample_rate, - renderengine->get_edl()->session->frame_rate); - frame_step -= (int64_t)Units::toframes(end_sample, - renderengine->get_edl()->session->sample_rate, - renderengine->get_edl()->session->frame_rate); - } - } - else - { -// Frame rendered early or just in time. - frame_step = 1; - - if(delay_countdown > 0) - { -// Maybe just a freak - delay_countdown--; - } - else - { - skip_countdown = VRENDER_THRESHOLD; - if(start_sample > current_sample) - { - int64_t delay_time = (int64_t)((float)(start_sample - current_sample) * - 1000 / renderengine->get_edl()->session->sample_rate); - if( delay_time > 1000 ) delay_time = 1000; - timer.delay(delay_time); - } - else - { -// Came after the earliest sample so keep going - } - } - -// Flash frame now. -//printf("VRender::run %d " _LD "\n", __LINE__, current_input_length); - flash_output(); - } - } - if(debug) printf("VRender::run %d\n", __LINE__); - -// Trigger audio to start - if(first_frame) - { - renderengine->first_frame_lock->unlock(); - first_frame = 0; - renderengine->reset_sync_position(); - } - if(debug) printf("VRender::run %d\n", __LINE__); - - session_frame += frame_step; - -// advance position in project - current_input_length = frame_step; - - -// Subtract frame_step in a loop to allow looped playback to drain -// printf("VRender::run %d %d %d %d\n", -// __LINE__, -// done, -// frame_step, -// current_input_length); - while(frame_step && current_input_length) - { -// trim current_input_length to range - get_boundaries(current_input_length); -// advance 1 frame - advance_position(current_input_length); - frame_step -= current_input_length; - current_input_length = frame_step; - if(done) break; -// printf("VRender::run %d %d %d %d\n", -// __LINE__, -// done, -// frame_step, -// current_input_length); - } - - if(debug) printf("VRender::run %d current_position=" _LD " done=%d\n", - __LINE__, current_position, done); - -// Update tracking. - if(renderengine->command->realtime && - renderengine->playback_engine && - renderengine->command->command != CURRENT_FRAME) - { - renderengine->playback_engine->update_tracking(fromunits(current_position)); - } - if(debug) printf("VRender::run %d\n", __LINE__); - -// Calculate the framerate counter - framerate_counter++; - if(framerate_counter >= renderengine->get_edl()->session->frame_rate && - renderengine->command->realtime) - { - renderengine->update_framerate((float)framerate_counter / - ((float)framerate_timer.get_difference() / 1000)); - framerate_counter = 0; - framerate_timer.update(); - } - if(debug) printf("VRender::run %d done=%d\n", __LINE__, done); - if( !interrupt ) - interrupt = renderengine->video->interrupt; - } - - -// In case we were interrupted before the first loop - renderengine->first_frame_lock->unlock(); - stop_plugins(); - if(debug) printf("VRender::run %d done=%d\n", __LINE__, done); -} - -int VRender::start_playback() -{ -// start reading input and sending to vrenderthread -// use a thread only if there's a video device - if(renderengine->command->realtime) - { - start(); - } - return 0; -} - -int64_t VRender::tounits(double position, int round) -{ - if(round) - return Units::round(position * renderengine->get_edl()->session->frame_rate); - else - return Units::to_int64(position * renderengine->get_edl()->session->frame_rate); -} - -double VRender::fromunits(int64_t position) -{ - return (double)position / renderengine->get_edl()->session->frame_rate; -} - - - - - - - - - - - - - - - - - - - -