... 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;
 

Reply via email to