... attaching the correct file... :)
bye andraz
diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/batchrender.C hvirtual-2/cinelerra/batchrender.C --- hvirtual-cvs/cinelerra/batchrender.C 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/batchrender.C 2006-05-29 00:19:23.000000000 +0200 @@ -459,11 +459,7 @@ 0); // Append output paths allocated to total - for(int j = 0; j < packages->get_total_packages(); j++) - { - RenderPackage *package = packages->get_package(j); - paths->append(strdup(package->path)); - } + packages->get_package_paths(paths); // Delete package harness delete packages; @@ -504,6 +500,8 @@ plugindb); int result = ConfirmSave::test_files(0, &paths); + paths.remove_all_objects(); + // Abort on any existing file because it's so hard to set this up. if(result) return; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/fileogg.C hvirtual-2/cinelerra/fileogg.C --- hvirtual-cvs/cinelerra/fileogg.C 2006-05-30 02:04:25.000000000 +0200 +++ hvirtual-2/cinelerra/fileogg.C 2006-05-31 00:55:19.000000000 +0200 @@ -35,6 +35,7 @@ asset->format = FILE_OGG; asset->byte_order = 0; reset_parameters(); + final_write = 1; } FileOGG::~FileOGG() @@ -153,7 +154,8 @@ // need more data for page if (read_buffer(in, sw, READ_SIZE) == 0) { - printf("FileOGG: There is no more data in the file we are reading from\n"); +// FIXME We should report that just in some situations... sometimes we go to the end +// printf("FileOGG: There is no more data in the file we are reading from\n"); return 0; // No more data } } @@ -545,7 +547,7 @@ break; } - if (vorbis_p == 3 && theora_p == 3) + if ((!vorbis_p || vorbis_p == 3) && (!theora_p || theora_p == 3)) break; /* The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec */ @@ -919,6 +921,15 @@ return (ogg_get_next_page(sw, serialno, og)); } +int FileOGG::ogg_seek_to_databegin(sync_window_t *sw, long serialno) +{ + +// printf("FileOGG:: Seeking to first page at %lli\n", filedata_begin); + read_buffer_at(stream, sw, READ_SIZE, filedata_begin); +// we don't even need to sync since we _know_ it is right + return (0); +} + int FileOGG::ogg_get_next_page(sync_window_t *sw, long serialno, ogg_page *og) { while (take_page_out_autoadvance(stream, sw, og) > 0) @@ -1058,6 +1069,8 @@ current_comming_sample += vorbis_synthesis_pcmout(&tf->vd, NULL); if (current_comming_sample > sample) { + if (previous_comming_sample > sample) + printf("Ogg decoding error while seeking sample\n"); vorbis_synthesis_read(&tf->vd, (sample - previous_comming_sample)); // printf("WE GOT IT, samples already decoded: %li\n", vorbis_synthesis_pcmout(&tf->vd,NULL)); return 1; // YAY next sample read is going to be ours, sexy! @@ -1267,7 +1280,7 @@ data[3] == 'S') { fclose(fd); - printf("Yay, we have an ogg file\n"); +// printf("Yay, we have an ogg file\n"); return 1; } fclose(fd); @@ -1280,11 +1293,13 @@ if (wr) { - if (asset->audio_data) - write_samples_vorbis(0, 0, 1); // set eos - if (asset->video_data) - write_frames_theora(0, 1, 1); // set eos - + if (final_write) + { + if (asset->audio_data) + write_samples_vorbis(0, 0, 1); // set eos + if (asset->video_data) + write_frames_theora(0, 1, 1); // set eos + } flush_ogg(1); // flush all if (asset->audio_data) diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/fileogg.h hvirtual-2/cinelerra/fileogg.h --- hvirtual-cvs/cinelerra/fileogg.h 2006-03-27 01:56:09.000000000 +0200 +++ hvirtual-2/cinelerra/fileogg.h 2006-05-31 00:49:18.000000000 +0200 @@ -74,6 +74,7 @@ class FileOGG : public FileBase { +friend class PackagingEngineOgg; public: FileOGG(Asset *asset, File *file); ~FileOGG(); @@ -128,6 +129,7 @@ int ogg_get_page_of_frame(sync_window_t *sw, long serialno, ogg_page *og, int64_t frame); int ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *keyframe_number); + int ogg_seek_to_databegin(sync_window_t *sw, long serialno); int64_t start_sample; // first and last sample inside this file @@ -152,6 +154,7 @@ int64_t ogg_frame_position; // LAST decoded frame position int64_t next_frame_position; // what is the next sample read_frames must deliver char theora_keyframe_granule_shift; + int final_write; }; class OGGConfigAudio; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/packagedispatcher.C hvirtual-2/cinelerra/packagedispatcher.C --- hvirtual-cvs/cinelerra/packagedispatcher.C 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/packagedispatcher.C 2006-05-31 00:52:40.000000000 +0200 @@ -13,11 +13,15 @@ +#include "file.h" +#include <ogg/ogg.h> +#include "fileogg.h" PackageDispatcher::PackageDispatcher() { packages = 0; package_lock = new Mutex("PackageDispatcher::package_lock"); + packaging_engine = 0; } PackageDispatcher::~PackageDispatcher() @@ -78,38 +82,23 @@ packages[0]->audio_end = audio_end; packages[0]->video_start = video_position; packages[0]->video_end = video_end; + packages[0]->audio_do = default_asset->audio_data; + packages[0]->video_do = default_asset->video_data; strcpy(packages[0]->path, default_asset->path); } else if(strategy == SINGLE_PASS_FARM) - { - total_len = this->total_end - this->total_start; - total_packages = preferences->renderfarm_job_count; - total_allocated = total_packages + nodes; - packages = new RenderPackage*[total_allocated]; - package_len = total_len / total_packages; - min_package_len = 2.0 / edl->session->frame_rate; - - -//printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len); - Render::get_starting_number(default_asset->path, - current_number, - number_start, - total_digits, - 3); - - for(int i = 0; i < total_allocated; i++) - { - RenderPackage *package = packages[i] = new RenderPackage; - -// Create file number differently if image file sequence - Render::create_filename(package->path, - default_asset->path, - current_number, - total_digits, - number_start); - current_number++; - } + { + if (default_asset->format == FILE_OGG) + packaging_engine = new PackagingEngineOgg(); + else + packaging_engine = new PackagingEngineDefault(); + packaging_engine->create_packages_single_farm( + edl, + preferences, + default_asset, + total_start, + total_end); } else if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM) @@ -131,6 +120,8 @@ new RenderPackage; package->audio_start = audio_position; package->video_start = video_position; + package->audio_do = default_asset->audio_data; + package->video_do = default_asset->video_data; while(label && @@ -213,16 +204,26 @@ mwindow) { ArrayList<char*> paths; - for(int i = 0; i < total_allocated; i++) - { - paths.append(packages[i]->path); - } + get_package_paths(&paths); result = ConfirmSave::test_files(mwindow, &paths); + paths.remove_all_objects(); } return result; } +void PackageDispatcher::get_package_paths(ArrayList<char*> *path_list) +{ + if (strategy == SINGLE_PASS_FARM) + packaging_engine->get_package_paths(path_list); + else + for(int i = 0; i < total_allocated; i++) + { + path_list->append(strdup(packages[i]->path)); + } + +} + RenderPackage* PackageDispatcher::get_package(double frames_per_second, int client_number, int use_local_rate) @@ -250,9 +251,210 @@ else if(strategy == SINGLE_PASS_FARM) { + result = packaging_engine->get_package_single_farm(frames_per_second, + client_number, + use_local_rate); + } + else + if(strategy == BRENDER_FARM) + { +//printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end); + if(video_position < video_end) + { +// Allocate new packages + if(total_packages == 0) + { + total_allocated = 256; + packages = new RenderPackage*[total_allocated]; + } + else + if(total_packages >= total_allocated) + { + RenderPackage **old_packages = packages; + total_allocated *= 2; + packages = new RenderPackage*[total_allocated]; + memcpy(packages, + old_packages, + total_packages * sizeof(RenderPackage*)); + delete [] old_packages; + } + +// Calculate package. + result = packages[total_packages] = new RenderPackage; + double scaled_len; + +// No load balancing data exists + if(EQUIV(frames_per_second, 0) || + EQUIV(avg_frames_per_second, 0)) + { + scaled_len = package_len; + } + else +// Load balancing data exists + { + scaled_len = package_len * + frames_per_second / + avg_frames_per_second; + } + + scaled_len = MAX(scaled_len, min_package_len); + +// Always an image file sequence + result->audio_start = audio_position; + result->video_start = video_position; + result->audio_end = result->audio_start + + Units::to_int64(scaled_len * default_asset->sample_rate); + result->video_end = result->video_start + + Units::to_int64(scaled_len * default_asset->frame_rate); + if(result->video_end == result->video_start) result->video_end++; + audio_position = result->audio_end; + video_position = result->video_end; + result->audio_do = default_asset->audio_data; + result->video_do = default_asset->video_data; + + +// The frame numbers are read from the vframe objects themselves. + Render::create_filename(result->path, + default_asset->path, + 0, + total_digits, + number_start); +//printf("PackageDispatcher::get_package 2 %s\n", result->path); + + current_number++; + total_packages++; + current_package++; + } + } + + package_lock->unlock(); + +//printf("PackageDispatcher::get_package %p\n", result); + return result; +} + + +ArrayList<Asset*>* PackageDispatcher::get_asset_list() +{ + ArrayList<Asset*> *assets = new ArrayList<Asset*>; + + for(int i = 0; i < current_package; i++) + { + Asset *asset = new Asset; + *asset = *default_asset; + strcpy(asset->path, packages[i]->path); + asset->video_length = packages[i]->video_end - packages[i]->video_start; + asset->audio_length = packages[i]->audio_end - packages[i]->audio_start; + assets->append(asset); + } + + return assets; +} + +int64_t PackageDispatcher::get_progress_max() +{ + if (strategy == SINGLE_PASS_FARM) + return packaging_engine->get_progress_max(); + else + return Units::to_int64(default_asset->sample_rate * + (total_end - total_start)) + + Units::to_int64(preferences->render_preroll * + total_allocated * + default_asset->sample_rate); +} + + +int PackageDispatcher::get_total_packages() +{ + return total_allocated; +} + +int PackageDispatcher::packages_are_done() +{ + if (packaging_engine) + return packaging_engine->packages_are_done(); + return 0; +} + + +PackagingEngineDefault::PackagingEngineDefault() +{ + packages = 0; +} + +PackagingEngineDefault::~PackagingEngineDefault() +{ + if(packages) + { + for(int i = 0; i < total_packages; i++) + delete packages[i]; + delete [] packages; + } +} + + +int PackagingEngineDefault::create_packages_single_farm( + EDL *edl, + Preferences *preferences, + Asset *default_asset, + double total_start, + double total_end) +{ + this->total_start = total_start; + this->total_end = total_end; + + this->preferences = preferences; + this->default_asset = default_asset; + audio_position = Units::to_int64(total_start * default_asset->sample_rate); + video_position = Units::to_int64(total_start * default_asset->frame_rate); + audio_end = Units::to_int64(total_end * default_asset->sample_rate); + video_end = Units::to_int64(total_end * default_asset->frame_rate); + current_package = 0; + + double total_len = total_end - total_start; + total_packages = preferences->renderfarm_job_count; + total_allocated = total_packages + preferences->get_enabled_nodes(); + packages = new RenderPackage*[total_allocated]; + package_len = total_len / total_packages; + min_package_len = 2.0 / edl->session->frame_rate; + + +//printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len); + int current_number; // The number being injected into the filename. + int number_start; // Character in the filename path at which the number begins + int total_digits; // Total number of digits including padding the user specified. + + Render::get_starting_number(default_asset->path, + current_number, + number_start, + total_digits, + 3); + + for(int i = 0; i < total_allocated; i++) + { + RenderPackage *package = packages[i] = new RenderPackage; + +// Create file number differently if image file sequence + Render::create_filename(package->path, + default_asset->path, + current_number, + total_digits, + number_start); + current_number++; + } + +} + +RenderPackage* PackagingEngineDefault::get_package_single_farm(double frames_per_second, + int client_number, + int use_local_rate) +{ //printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end); + RenderPackage *result = 0; + float avg_frames_per_second = preferences->get_avg_rate(use_local_rate); + if(audio_position < audio_end || video_position < video_end) { @@ -261,12 +463,14 @@ result = packages[current_package]; result->audio_start = audio_position; result->video_start = video_position; + result->video_do = default_asset->video_data; + result->audio_do = default_asset->audio_data; if(current_package >= total_allocated - 1) { result->audio_end = audio_end; result->video_end = video_end; - audio_position = result->audio_end; + audio_position = result->audio_end; video_position = result->video_end; } else @@ -334,106 +538,382 @@ //result->audio_end, //result->video_end); } + return result; + +} + +void PackagingEngineDefault::get_package_paths(ArrayList<char*> *path_list) +{ + for(int i = 0; i < total_allocated; i++) + { + path_list->append(strdup(packages[i]->path)); } - else - if(strategy == BRENDER_FARM) +} + +int64_t PackagingEngineDefault::get_progress_max() +{ + return Units::to_int64(default_asset->sample_rate * + (total_end - total_start)) + + Units::to_int64(preferences->render_preroll * + 2 * + default_asset->sample_rate); +} + +int PackagingEngineDefault::packages_are_done() +{ + return 0; +} + +PackagingEngineOgg::PackagingEngineOgg() +{ + packages = 0; + default_asset = 0; +} + +PackagingEngineOgg::~PackagingEngineOgg() +{ + if(packages) { -//printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end); - if(video_position < video_end) - { -// Allocate new packages - if(total_packages == 0) - { - total_allocated = 256; - packages = new RenderPackage*[total_allocated]; - } - else - if(total_packages >= total_allocated) - { - RenderPackage **old_packages = packages; - total_allocated *= 2; - packages = new RenderPackage*[total_allocated]; - memcpy(packages, - old_packages, - total_packages * sizeof(RenderPackage*)); - delete [] old_packages; - } + for(int i = 0; i < total_packages; i++) + delete packages[i]; + delete [] packages; + } + if (default_asset) + delete default_asset; +} -// Calculate package. - result = packages[total_packages] = new RenderPackage; - double scaled_len; -// No load balancing data exists - if(EQUIV(frames_per_second, 0) || - EQUIV(avg_frames_per_second, 0)) - { - scaled_len = package_len; - } - else -// Load balancing data exists - { - scaled_len = package_len * - frames_per_second / - avg_frames_per_second; - } - scaled_len = MAX(scaled_len, min_package_len); +int PackagingEngineOgg::create_packages_single_farm( + EDL *edl, + Preferences *preferences, + Asset *default_asset, + double total_start, + double total_end) +{ + this->total_start = total_start; + this->total_end = total_end; + this->edl = edl; -// Always an image file sequence - result->audio_start = audio_position; - result->video_start = video_position; - result->audio_end = result->audio_start + - Units::to_int64(scaled_len * default_asset->sample_rate); - result->video_end = result->video_start + - Units::to_int64(scaled_len * default_asset->frame_rate); - if(result->video_end == result->video_start) result->video_end++; - audio_position = result->audio_end; - video_position = result->video_end; -// The frame numbers are read from the vframe objects themselves. - Render::create_filename(result->path, - default_asset->path, - 0, + this->preferences = preferences; + +// We make A COPY of the asset, because we set audio_data = 0 on local asset which is the same copy as default_asset... +// Should be taken care of somewhere else actually + this->default_asset = new Asset(*default_asset); + + audio_start = Units::to_int64(total_start * default_asset->sample_rate); + video_start = Units::to_int64(total_start * default_asset->frame_rate); + audio_position = audio_start; + video_position = video_start; + audio_end = Units::to_int64(total_end * default_asset->sample_rate); + video_end = Units::to_int64(total_end * default_asset->frame_rate); + current_package = 0; + + double total_len = total_end - total_start; +//printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len); + + total_packages = 0; + if (default_asset->audio_data) + total_packages++; + if (default_asset->video_data) + total_packages += preferences->renderfarm_job_count; + + packages = new RenderPackage*[total_packages]; + + int local_current_package = 0; + if (default_asset->audio_data) + { + packages[local_current_package] = new RenderPackage; + sprintf(packages[current_package]->path, "%s.audio", default_asset->path); + local_current_package++; + } + + if (default_asset->video_data) + { + video_package_len = (total_len) / preferences->renderfarm_job_count; + int current_number; // The number being injected into the filename. + int number_start; // Character in the filename path at which the number begins + int total_digits; // Total number of digits including padding the user specified. + + Render::get_starting_number(default_asset->path, + current_number, + number_start, + total_digits, + 3); + + for(int i = 0; i < preferences->renderfarm_job_count; i++) + { + RenderPackage *package = packages[local_current_package] = new RenderPackage; + Render::create_filename(package->path, + default_asset->path, + current_number, total_digits, number_start); -//printf("PackageDispatcher::get_package 2 %s\n", result->path); - current_number++; - total_packages++; - current_package++; + local_current_package++; } } +} - package_lock->unlock(); +RenderPackage* PackagingEngineOgg::get_package_single_farm(double frames_per_second, + int client_number, + int use_local_rate) +{ -//printf("PackageDispatcher::get_package %p\n", result); +//printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end); + if (current_package == total_packages) + return 0; + + RenderPackage *result = 0; + if (current_package == 0 && default_asset->audio_data) + { + result = packages[0]; + result->audio_start = audio_start; + result->video_start = video_start; + result->audio_end = audio_end; + result->video_end = video_end; + result->audio_do = 1; + result->video_do = 0; + } else if (default_asset->video_data) + { + // Do not do any scaling according to node speed, so we know we can get evenly distributed 'forced' keyframes + result = packages[current_package]; + result->audio_do = 0; + result->video_do = 1; + + result->audio_start = audio_position; + result->video_start = video_position; + result->audio_end = audio_position + + Units::round(video_package_len * default_asset->sample_rate); + result->video_end = video_position + + Units::round(video_package_len * default_asset->frame_rate); + +// Last package... take it all! + if (current_package == total_packages -1 ) + { + result->audio_end = audio_end; + result->video_end = video_end; + } + + audio_position = result->audio_end; + video_position = result->video_end; + + } + + current_package ++; return result; -} +} -ArrayList<Asset*>* PackageDispatcher::get_asset_list() +void PackagingEngineOgg::get_package_paths(ArrayList<char*> *path_list) { - ArrayList<Asset*> *assets = new ArrayList<Asset*>; - - for(int i = 0; i < current_package; i++) + for(int i = 0; i < total_packages; i++) { - Asset *asset = new Asset; - *asset = *default_asset; - strcpy(asset->path, packages[i]->path); - asset->video_length = packages[i]->video_end - packages[i]->video_start; - asset->audio_length = packages[i]->audio_end - packages[i]->audio_start; - assets->append(asset); + path_list->append(strdup(packages[i]->path)); } - - return assets; +// We will mux to the the final file at the end! + path_list->append(strdup(default_asset->path)); } -RenderPackage* PackageDispatcher::get_package(int number) +int64_t PackagingEngineOgg::get_progress_max() { - return packages[number]; + return Units::to_int64(default_asset->sample_rate * + (total_end - total_start)) * 2+ + Units::to_int64(preferences->render_preroll * + total_packages * + default_asset->sample_rate); } -int PackageDispatcher::get_total_packages() +int PackagingEngineOgg::packages_are_done() { - return total_allocated; + + +// Mux audio and video into one file + +// First fix our asset... have to workaround the bug of corruption of local asset +// Render::check_asset(edl, *default_asset); + + Asset *video_asset, *audio_asset; + File *audio_file_gen, *video_file_gen; + FileOGG *video_file, *audio_file; + ogg_stream_state audio_in_stream, video_in_stream; + + int local_current_package = 0; + if (default_asset->audio_data) + { + audio_asset = new Asset(packages[local_current_package]->path); + local_current_package++; + + audio_file_gen = new File(); + audio_file_gen->open_file(preferences, + audio_asset, + 1, //rd + 0, //wr + 0, //base sample rate + 0); // base_frame rate + audio_file = (FileOGG*) audio_file_gen->file; + ogg_stream_init(&audio_in_stream, audio_file->tf->vo.serialno); + audio_file->ogg_seek_to_databegin(audio_file->tf->audiosync, audio_file->tf->vo.serialno); + } + + if (default_asset->video_data) + { + video_asset = new Asset(packages[local_current_package]->path); + local_current_package++; + + video_file_gen = new File(); + video_file_gen->open_file(preferences, + video_asset, + 1, //rd + 0, //wr + 0, //base sample rate + 0); // base_frame rate + video_file = (FileOGG*) video_file_gen->file; + ogg_stream_init(&video_in_stream, video_file->tf->to.serialno); + video_file->ogg_seek_to_databegin(video_file->tf->videosync, video_file->tf->to.serialno); + } + +// Output file + File *output_file_gen = new File(); + output_file_gen->open_file(preferences, + default_asset, + 0, + 1, + default_asset->sample_rate, + default_asset->frame_rate); + FileOGG *output_file = (FileOGG*) output_file_gen->file; + + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + + int audio_ready = default_asset->audio_data; + int video_ready = default_asset->video_data; + int64_t video_packetno = 1; + int64_t audio_packetno = 1; + int64_t frame_offset = 0; + int64_t current_frame = 0; + while ((default_asset->audio_data && audio_ready) || (default_asset->video_data && video_ready)) + { + if (video_ready) + { + while (ogg_stream_packetpeek(&video_in_stream, NULL) != 1) // get as many pages as needed for one package + { + if (!video_file->ogg_get_next_page(video_file->tf->videosync, video_file->tf->to.serialno, &video_file->tf->videopage)) + { + // We are at the end of our file, see if it is more and open more if there is + if (local_current_package < total_packages) + { + frame_offset = current_frame +1; + ogg_stream_clear(&video_in_stream); + video_file_gen->close_file(); + delete video_file_gen; + delete video_asset; + video_asset = new Asset(packages[local_current_package]->path); + local_current_package++; + + video_file_gen = new File(); + video_file_gen->open_file(preferences, + video_asset, + 1, //rd + 0, //wr + 0, //base sample rate + 0); // base_frame rate + video_file = (FileOGG*) video_file_gen->file; + ogg_stream_init(&video_in_stream, video_file->tf->to.serialno); + int64_t fp = 0; + video_file->ogg_seek_to_databegin(video_file->tf->videosync, video_file->tf->to.serialno); + + } else + video_ready = 0; + break; + } + ogg_stream_pagein(&video_in_stream, &video_file->tf->videopage); + } + while (ogg_stream_packetpeek(&video_in_stream, NULL) == 1) // get all packets out of the page + { + ogg_stream_packetout(&video_in_stream, &op); + if (local_current_package != total_packages) // keep it from closing the stream + op.e_o_s = 0; + if (video_packetno != 1) // if this is not the first video package do not start with b_o_s + op.b_o_s = 0; + else + op.b_o_s = 1; + op.packetno = video_packetno; + video_packetno ++; + int64_t granulepos = op.granulepos; + if (granulepos != -1) + { + // Fix granulepos! + int64_t rel_iframe = granulepos >> video_file->theora_keyframe_granule_shift; + int64_t rel_pframe = granulepos - (rel_iframe << video_file->theora_keyframe_granule_shift); + int64_t rel_current_frame = rel_iframe + rel_pframe; + current_frame = frame_offset + rel_current_frame; + int64_t abs_iframe = current_frame - rel_pframe; + + op.granulepos = (abs_iframe << video_file->theora_keyframe_granule_shift) + rel_pframe; + +// printf("iframe: %i, pframe: %i, granulepos: %i, op.packetno %lli, abs_iframe: %i\n", rel_iframe, rel_pframe, granulepos, op.packetno, abs_iframe); + + } + ogg_stream_packetin (&output_file->tf->to, &op); + output_file->tf->v_pkg++; + } + } + if (audio_ready) + { + while (ogg_stream_packetpeek(&audio_in_stream, NULL) != 1) // get as many pages as needed for one package + { + if (!audio_file->ogg_get_next_page(audio_file->tf->audiosync, audio_file->tf->vo.serialno, &audio_file->tf->audiopage)) + { + audio_ready = 0; + break; + } + ogg_stream_pagein(&audio_in_stream, &audio_file->tf->audiopage); + } + while (ogg_stream_packetpeek(&audio_in_stream, NULL) == 1) // get all packets out of the page + { + ogg_stream_packetout(&audio_in_stream, &op); + ogg_stream_packetin (&output_file->tf->vo, &op); + audio_packetno++; + output_file->tf->a_pkg++; + } + } + + output_file->flush_ogg(0); + + + } + +// flush_ogg(1) is called on file closing time... +// output_file->flush_ogg(1); + +// Just prevent thet write_samples and write_frames are called + output_file->final_write = 0; + + if (default_asset->audio_data) + { + ogg_stream_clear(&audio_in_stream); + audio_file_gen->close_file(); + delete audio_file_gen; + delete audio_asset; + } + if (default_asset->video_data) + { + ogg_stream_clear(&video_in_stream); + video_file_gen->close_file(); + delete video_file_gen; + delete video_asset; + } + + output_file_gen->close_file(); + delete output_file_gen; + +// Now delete the temp files + for(int i = 0; i < total_packages; i++) + unlink(packages[i]->path); + + return 0; } + diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/packagedispatcher.h hvirtual-2/cinelerra/packagedispatcher.h --- hvirtual-cvs/cinelerra/packagedispatcher.h 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/packagedispatcher.h 2006-05-30 19:35:23.000000000 +0200 @@ -11,6 +11,7 @@ #include "preferences.inc" +class PackagingEngine; // Allocates fragments given a total start and total end. // Checks the existence of every file. @@ -35,9 +36,13 @@ int client_number, int use_local_rate); ArrayList<Asset*>* get_asset_list(); - RenderPackage* get_package(int number); - int get_total_packages(); + void get_package_paths(ArrayList<char*> *path_list); + int get_total_packages(); + int64_t get_progress_max(); + int packages_are_done(); + +private: EDL *edl; int64_t audio_position; int64_t video_position; @@ -61,6 +66,105 @@ RenderPackage **packages; int current_package; Mutex *package_lock; + + PackagingEngine *packaging_engine; +}; + + +// Classes used for different packaging strategies, which allow for customary splitting of packages +// Used for renderfarm jobs + +class PackagingEngine +{ +public: + virtual int create_packages_single_farm( + EDL *edl, + Preferences *preferences, + Asset *default_asset, + double total_start, + double total_end) = 0; + virtual RenderPackage* get_package_single_farm(double frames_per_second, + int client_number, + int use_local_rate) = 0; + virtual int64_t get_progress_max() = 0; + virtual void get_package_paths(ArrayList<char*> *path_list) = 0; + virtual int packages_are_done() = 0; +}; + +class PackagingEngineDefault : public PackagingEngine +{ +public: + PackagingEngineDefault(); + ~PackagingEngineDefault(); + int create_packages_single_farm( + EDL *edl, + Preferences *preferences, + Asset *default_asset, + double total_start, + double total_end); + RenderPackage* get_package_single_farm(double frames_per_second, + int client_number, + int use_local_rate); + int64_t get_progress_max(); + void get_package_paths(ArrayList<char*> *path_list); + int packages_are_done(); +private: + RenderPackage **packages; + int64_t total_allocated; // Total packages to test the existence of + int current_number; // The number being injected into the filename. + int number_start; // Character in the filename path at which the number begins + int total_digits; // Total number of digits including padding the user specified. + double package_len; // Target length of a single package + double min_package_len; // Minimum package length after load balancing + int64_t total_packages; // Total packages to base calculations on + int64_t audio_position; + int64_t video_position; + int64_t audio_end; + int64_t video_end; + int current_package; + Asset *default_asset; + Preferences *preferences; + double total_start; + double total_end; +}; + +class PackagingEngineOgg : public PackagingEngine +{ +public: + PackagingEngineOgg(); + ~PackagingEngineOgg(); + int create_packages_single_farm( + EDL *edl, + Preferences *preferences, + Asset *default_asset, + double total_start, + double total_end); + RenderPackage* get_package_single_farm(double frames_per_second, + int client_number, + int use_local_rate); + int64_t get_progress_max(); + void get_package_paths(ArrayList<char*> *path_list); + int packages_are_done(); + +private: + EDL *edl; + + RenderPackage **packages; + int total_packages; + double video_package_len; // Target length of a single package + + Asset *default_asset; + Preferences *preferences; + int current_package; + double total_start; + double total_end; + int64_t audio_position; + int64_t video_position; + int64_t audio_start; + int64_t video_start; + int64_t audio_end; + int64_t video_end; + }; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/packagerenderer.C hvirtual-2/cinelerra/packagerenderer.C --- hvirtual-cvs/cinelerra/packagerenderer.C 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/packagerenderer.C 2006-05-31 00:58:07.000000000 +0200 @@ -79,6 +79,9 @@ delete vconfig; } +// PackageRenderer::initialize happens only once for every node when doing rendering session +// This is not called for each package! + int PackageRenderer::initialize(MWindow *mwindow, EDL *edl, Preferences *preferences, @@ -520,6 +523,11 @@ // package->video_end - package->video_start); +// FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek + default_asset->video_data = package->video_do; + default_asset->audio_data = package->audio_do; + Render::check_asset(edl, *default_asset); + create_output(); if(!asset->video_data) video_done = 1; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/packagerenderer.h hvirtual-2/cinelerra/packagerenderer.h --- hvirtual-cvs/cinelerra/packagerenderer.h 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/packagerenderer.h 2006-05-28 01:56:50.000000000 +0200 @@ -39,6 +39,8 @@ int64_t video_end; int done; int use_brender; + int video_do; + int audio_do; }; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/render.C hvirtual-2/cinelerra/render.C --- hvirtual-cvs/cinelerra/render.C 2006-04-02 11:13:17.000000000 +0200 +++ hvirtual-2/cinelerra/render.C 2006-05-31 00:56:38.000000000 +0200 @@ -504,11 +504,8 @@ char string[BCTEXTLEN]; FileSystem fs; - progress_max = Units::to_int64(default_asset->sample_rate * - (total_end - total_start)) + - Units::to_int64(preferences->render_preroll * - packages->total_allocated * - default_asset->sample_rate); + progress_max = packages->get_progress_max(); + progress_timer->update(); last_eta = 0; if(mwindow) @@ -790,6 +787,7 @@ if(strategy == SINGLE_PASS_FARM || strategy == FILE_PER_LABEL_FARM) { farm_server->wait_clients(); + result |= packages->packages_are_done(); } //printf("Render::render 90\n"); diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/renderfarm.C hvirtual-2/cinelerra/renderfarm.C --- hvirtual-cvs/cinelerra/renderfarm.C 2005-11-12 12:12:47.000000000 +0100 +++ hvirtual-2/cinelerra/renderfarm.C 2006-05-31 00:56:06.000000000 +0200 @@ -543,6 +543,8 @@ STORE_INT32(package->video_end); int use_brender = (server->brender ? 1 : 0); STORE_INT32(use_brender); + STORE_INT32(package->audio_do); + STORE_INT32(package->video_do); int len = i; i = 0; diff -ru --exclude-from exclude hvirtual-cvs/cinelerra/renderfarmclient.C hvirtual-2/cinelerra/renderfarmclient.C --- hvirtual-cvs/cinelerra/renderfarmclient.C 2005-11-12 12:12:48.000000000 +0100 +++ hvirtual-2/cinelerra/renderfarmclient.C 2006-05-28 02:06:12.000000000 +0200 @@ -454,6 +454,10 @@ package->video_end = READ_INT32(data_ptr); data_ptr += 4; package->use_brender = READ_INT32(data_ptr); + data_ptr += 4; + package->audio_do = READ_INT32(data_ptr); + data_ptr += 4; + package->video_do = READ_INT32(data_ptr); delete [] data;