Пример #1
0
int IndexFile::read_info(Asset *test_asset)
{
	if(!test_asset) test_asset = asset;
	if(test_asset->index_status == INDEX_NOTTESTED)
	{
// read start of index data
		fread((char*)&(test_asset->index_start), sizeof(int64_t), 1, file);

// read test_asset info from index
		char *data;
		
		data = new char[test_asset->index_start];
		fread(data, test_asset->index_start - sizeof(int64_t), 1, file);
		data[test_asset->index_start - sizeof(int64_t)] = 0;
		FileXML xml;
		xml.read_from_string(data);
		test_asset->read(&xml);

		delete [] data;
		if(test_asset->format == FILE_UNKNOWN)
		{
			return 1;
		}
	}
	return 0;
}
Пример #2
0
int MainUndo::redo()
{
	UndoStackItem *current = undo_stack->current;
//printf("MainUndo::redo 1\n");
//undo_stack->dump();

// Get 1st entry
	if(!current) current = undo_stack->first;

// Advance to a before entry
	if(current && (undo_stack->number_of(current) % 2))
	{
		current = NEXT;
	}

// Advance to an after entry
	if(current && !(undo_stack->number_of(current) % 2))
	{
		current = NEXT;
	}

	if(current)
	{
		FileXML file;
		char *current_data = current->get_data();
		undo_stack->current = current;

		if(current_data)
		{
			mwindow->set_filename(current->get_filename());
			file.read_from_string(current_data);
			load_from_undo(&file, current->get_flags());
			delete [] current_data;

			if(mwindow->gui)
			{
// Update menu
				mwindow->gui->mainmenu->undo->update_caption(current->get_description());

// Get next after entry
				current = NEXT;			
				if(current)
					current = NEXT;

				if(current)
					mwindow->gui->mainmenu->redo->update_caption(current->get_description());
				else
					mwindow->gui->mainmenu->redo->update_caption("");
			}
		}
	}
	reset_creators();
//undo_stack->dump();
	return 0;
}
Пример #3
0
int FileFork::handle_command()
{
	int64_t result = 0;
	const int debug = 0;

	if(debug) printf("FileFork::handle_command %d (pid=%d) this=%p command=%d\n", 
		__LINE__, getpid(), this, command_token);
// to grab this task in the debugger
	//static int zbug = 1;  volatile int bug = zbug;
	//while( bug ) usleep(10000);

	switch(command_token)
	{
		case OPEN_FILE:
		{
			file = new File;
			file->is_fork = 1;


// Read file modes
			int offset = 0;
			int rd = *(int*)(command_data + offset);
			offset += sizeof(int);
			int wr = *(int*)(command_data + offset);
			offset += sizeof(int);
			file->cpus = *(int*)(command_data + offset);
			offset += sizeof(int);
			file->white_balance_raw = *(int*)(command_data + offset);
			offset += sizeof(int);
			file->interpolate_raw = *(int*)(command_data + offset);
			offset += sizeof(int);
			file->playback_subtitle = *(int*)(command_data + offset);
			offset += sizeof(int);
			file->current_program = *(int*)(command_data + offset);
			offset += sizeof(int);

// Read asset from socket
			BC_Hash table;
			table.load_string((char*)command_data + offset);
			Asset *new_asset = new Asset;
			new_asset->load_defaults(&table, "", 1, 1, 1, 1, 1);
			if(debug)
			{
				printf("FileFork::handle_command %d\n%s\n", 
				__LINE__, 
				command_data + offset);
				new_asset->dump();
			}


// printf("FileFork::handle_command %d\n", __LINE__);
// table.dump();
//printf("FileFork::handle_command %d server=%p\n", __LINE__, server);
//printf("FileFork::handle_command %d server->preferences=%p\n", __LINE__, server->preferences);
			result = file->open_file(
				server->preferences, 
				new_asset, 
				rd, 
				wr);
			new_asset->Garbage::remove_user();
			if(debug) printf("FileFork::handle_command %d result=" _LD "\n", 
				__LINE__, result);



// Send updated asset
			file->asset->save_defaults(&table, "", 1, 1, 1, 1, 1);
			char *string = 0;
			table.save_string(string);
			int buffer_size = strlen(string) + 1;
			send_result(result, (unsigned char*)string, buffer_size);
			free(string);
			break;
		}

		case SET_PROCESSORS:
			file->set_processors(*(int*)command_data);
			send_result(0, 0, 0);
			break;


		case SET_PRELOAD:
			file->set_preload(*(int64_t*)command_data);
			send_result(0, 0, 0);
			break;

		case SET_SUBTITLE:
			file->set_subtitle(*(int*)command_data);
			send_result(0, 0, 0);
			break;

		case SET_INTERPOLATE_RAW:
			file->set_interpolate_raw(*(int*)command_data);
			send_result(0, 0, 0);
			break;

		case SET_WHITE_BALANCE_RAW:
			file->set_white_balance_raw(*(int*)command_data);
			send_result(0, 0, 0);
			break;

		case CLOSE_FILE:
		{
			unsigned char result_buffer[sizeof(int64_t) * 2];
			int64_t *rbfr = (int64_t *)result_buffer;
			file->close_file(0);
			rbfr[0] = file->asset->audio_length;
			rbfr[1] = file->asset->video_length;
// printf("FileFork::handle_command %d " _LD " " _LD "\n", 
// __LINE__, 
// file->asset->audio_length, 
// file->asset->video_length);
			send_result(0, result_buffer, sizeof(int64_t) * 2);
			done = 1;
			break;
		}

		case GET_INDEX:
			result = file->get_index((char*)command_data);
			send_result(result, 0, 0);
			break;


		case START_AUDIO_THREAD:
		{
			int buffer_size = *(int*)command_data;
			int ring_buffers = *(int*)(command_data + sizeof(int));
			result = file->start_audio_thread(buffer_size, ring_buffers);
// Send buffer information back to server here
			int result_bytes = ring_buffers * 
				Samples::filefork_size() * 
				file->asset->channels;
			unsigned char result_buffer[result_bytes];
			for(int i = 0; i < ring_buffers; i++)
			{
				Samples **samples = file->audio_thread->audio_buffer[i];
				for(int j = 0; j < file->asset->channels; j++)
				{
					samples[j]->to_filefork(result_buffer +
						i * Samples::filefork_size() * file->asset->channels +
						j * Samples::filefork_size());
				}
			}

			send_result(result, result_buffer, result_bytes);
			break;
		}

		case START_VIDEO_THREAD:
		{
			int buffer_size = *(int*)command_data;
			int color_model = *(int*)(command_data + sizeof(int));
			int ring_buffers = *(int*)(command_data + sizeof(int) * 2);
			int compressed = *(int*)(command_data + sizeof(int) * 3);
// allocate buffers here
			result = file->start_video_thread(buffer_size, 
				color_model,
				ring_buffers,
				compressed);

// Send buffer information back to server here
			int result_bytes = ring_buffers *
				file->asset->layers *
				buffer_size *
				VFrame::filefork_size();
			unsigned char result_buffer[result_bytes];

			for(int i = 0; i < ring_buffers; i++)
			{
				VFrame ***frames = file->video_thread->video_buffer[i];
				for(int j = 0; j < file->asset->layers; j++)
				{
					for(int k = 0; k < buffer_size; k++)
					{
//printf("FileFork::handle_command %d j=%d k=%d %p %p\n", __LINE__, j, k, frames[j][k], frames[j][k]->get_shmid()));
						frames[j][k]->to_filefork(result_buffer +
							i * file->asset->layers *
								buffer_size *
								VFrame::filefork_size() +
							j * buffer_size *
								VFrame::filefork_size() +
							k * VFrame::filefork_size());
					}
				}
			}

			send_result(result, result_buffer, result_bytes);
			break;
		}


		case START_VIDEO_DECODE_THREAD:
			result = file->start_video_decode_thread();
			send_result(result, 0, 0);
			break;


		case STOP_AUDIO_THREAD:
			result = file->stop_audio_thread();
			send_result(result, 0, 0);
			break;

		case STOP_VIDEO_THREAD:
			result = file->stop_video_thread();
			send_result(result, 0, 0);
			break;

		case SET_CHANNEL:
			result = file->set_channel(*(int*)command_data);
			send_result(result, 0, 0);
			break;

		case SET_LAYER:
			result = file->set_layer(*(int*)command_data, 0);
			send_result(result, 0, 0);
			break;

		case GET_AUDIO_LENGTH:
			result = file->get_audio_length();
			send_result(result, 0, 0);
			break;

		case GET_VIDEO_LENGTH:
			result = file->get_video_length();
			send_result(result, 0, 0);
			break;

		case GET_VIDEO_POSITION:
			result = file->get_video_position();
			send_result(result, 0, 0);
			break;

		case GET_AUDIO_POSITION:
			result = file->get_audio_position();
			send_result(result, 0, 0);
			break;

		case SET_AUDIO_POSITION:
			result = file->set_audio_position(*(int64_t*)command_data);
			send_result(result, 0, 0);
			break;

		case SET_VIDEO_POSITION:
			result = file->set_video_position(*(int64_t*)command_data, 0);
			send_result(result, 0, 0);
			break;

		case WRITE_SAMPLES:
		{
			int entry_size = Samples::filefork_size();
			Samples **samples = new Samples*[file->asset->channels];
			for(int i = 0; i < file->asset->channels; i++)
			{
				samples[i] = new Samples;
				samples[i]->from_filefork(
					command_data + entry_size * i);
			}
			int64_t len = *(int64_t*)(command_data + 
				entry_size * file->asset->channels);

			result = file->write_samples(samples, len);
			send_result(result, 0, 0);

			for(int i = 0; i < file->asset->channels; i++)
			{
				delete samples[i];
			}
			delete [] samples;
			break;
		}

		case WRITE_FRAMES:
		{
//PRINT_TRACE
			int entry_size = VFrame::filefork_size();
//PRINT_TRACE
			VFrame ***frames = new VFrame**[file->asset->layers];
//printf("FileFork::handle_command %d %d\n", __LINE__, file->asset->layers);
			int len = *(int*)command_data;
//printf("FileFork::handle_command %d %d %d\n", __LINE__, file->asset->layers, len);

			for(int i = 0; i < file->asset->layers; i++)
			{
				frames[i] = new VFrame*[len];
				for(int j = 0; j < len; j++)
				{
					frames[i][j] = new VFrame;
//PRINT_TRACE
					frames[i][j]->from_filefork(command_data +
						sizeof(int) + 
						entry_size * len * i +
						entry_size * j);
// printf("FileFork::handle_command %d color_model=%d\n", 
// __LINE__, 
// frames[i][j]->get_color_model(),
// frames[i][j]->get_compressed_size());

//PRINT_TRACE
				}
			}

//PRINT_TRACE
			result = file->write_frames(frames, len);
//PRINT_TRACE

			send_result(result, 0, 0);
			for(int i = 0; i < file->asset->layers; i++)
			{
				for(int j = 0; j < len; j++)
				{
					delete frames[i][j];
				}
				delete [] frames[i];
			}
			delete [] frames;
			break;
		}


		case WRITE_AUDIO_BUFFER:
			result = file->write_audio_buffer(*(int64_t*)command_data);
			send_result(result, 0, 0);
			break;

		case WRITE_VIDEO_BUFFER:
		{
//printf("FileFork::handle_command %d\n", __LINE__);
			int len = *(int64_t*)command_data;
			VFrame ***video_buffer = file->video_thread->get_last_video_buffer();
			for(int i = 0; i < file->asset->layers; i++)
			{
				for(int j = 0; j < len; j++)
				{
// Copy memory state
//printf("FileFork::handle_command %d i=%d j=%d %p %p\n", __LINE__, i, j, video_buffer[i][j], video_buffer[i][j]->get_shmid());
					video_buffer[i][j]->from_filefork(command_data +
						sizeof(int64_t) +
						VFrame::filefork_size() * (len * i + j));
//printf("FileFork::handle_command %d %p " _LD "\n", __LINE__, video_buffer[i][j]->get_shmid(), video_buffer[i][j]->get_number());

				}
			}
		
			result = file->write_video_buffer(len);
			send_result(result, 0, 0);
//printf("FileFork::handle_command %d\n", __LINE__);
			break;
		}

		case GET_AUDIO_BUFFER:
		{
// 			int entry_size = Samples::filefork_size();
// 			int result_bytes = entry_size * file->asset->channels;
// 			unsigned char result_buffer[sizeof(int)];
// 			
// Make it swap buffers
//			Samples **samples = file->get_audio_buffer();
// 			for(int i = 0; i < file->asset->channels; i++)
// 			{
// 				samples[i]->to_filefork(result_buffer + 
// 					i * Samples::filefork_size());
// 			}

			file->get_audio_buffer();
			send_result(file->audio_thread->current_buffer, 0, 0);
			break;
		}

		case GET_VIDEO_BUFFER:
		{
// 			int entry_size = VFrame::filefork_size();
// 			int layers = file->asset->layers;
// 			int buffer_size = file->video_thread->buffer_size;
// 			int result_size = entry_size * 
// 				layers *
// 				buffer_size +
// 				sizeof(int);
// 			unsigned char result_buffer[result_size];
// 			*(int*)(result_buffer + entry_size * 
// 				layers *
// 				buffer_size) = buffer_size;
//printf("FileFork::handle_command %d layers=%d\n", __LINE__, layers);

//			VFrame ***frames = file->get_video_buffer();
// 			for(int i = 0; i < layers; i++)
// 			{
// 				for(int j = 0; j < buffer_size; j++)
// 				{
// 					frames[i][j]->to_filefork(result_buffer +
// 						entry_size * i * buffer_size +
// 						entry_size * j);
// 				}
// 			}

			file->get_video_buffer();
			send_result(file->video_thread->current_buffer, 0, 0);
//printf("FileFork::handle_command %d\n", __LINE__);
			break;
		}

		case READ_SAMPLES:
		{
			if(debug) PRINT_TRACE
			int len = *(int64_t*)(command_data + Samples::filefork_size());
			if(debug) PRINT_TRACE
			Samples *samples = new Samples;
			samples->from_filefork(command_data);
			if(debug) PRINT_TRACE

			result = file->read_samples(samples, len);
			if(debug) PRINT_TRACE
			send_result(result, 0, 0);
			if(debug) PRINT_TRACE

			delete samples;
			if(debug) PRINT_TRACE
			break;
		}

		case READ_FRAME:
		{
			VFrame *frame = new VFrame;
			frame->from_filefork(command_data);
			int allocated_data = frame->get_compressed_allocated();
			
			
// printf("FileFork::handle_command %d file=%p\n", 
// __LINE__, 
// file);
// frame->dump();
			result = file->read_frame(frame, 0);


// printf("FileFork::handle_command %d size=%d\n", 
// __LINE__, 
// frame->get_compressed_size());


// Send compressed data through socket only if data allocation changed.
			if(frame->get_color_model() == BC_COMPRESSED &&
				allocated_data != frame->get_compressed_allocated())
			{
				int result_size = sizeof(int) * 2 + frame->get_compressed_size();
				unsigned char *result_data = new unsigned char[result_size];
				*(int*)result_data = frame->get_compressed_size();
				*(int*)(result_data + sizeof(int)) = frame->get_keyframe();
				memcpy(result_data + sizeof(int) * 2, 
					frame->get_data(), 
					frame->get_compressed_size());
				send_result(result, 
					result_data, 
					result_size);
				delete [] result_data;
			}
			else
			{
				int result_size = sizeof(int) * 2;
				unsigned char *result_data = new unsigned char[result_size];
				*(int*)result_data = frame->get_compressed_size();
				*(int*)(result_data + sizeof(int)) = frame->get_keyframe();
				send_result(result, result_data, result_size);
				delete [] result_data;
			}


// printf("FileFork::handle_command %d size=%d\n", 
// __LINE__, 
// frame->get_compressed_size());
			delete frame;

// printf("FileFork::handle_command %d size=%d\n", 
// __LINE__, 
// frame->get_compressed_size());
			break;
		}

		case CAN_COPY_FROM:
		{
			FileXML xml;
			int64_t position = *(int64_t*)(command_data);
			int output_w = *(int*)(command_data + sizeof(int64_t));
			int output_h = *(int*)(command_data + sizeof(int64_t) + sizeof(int));
			xml.read_from_string((char*)command_data + 
				sizeof(int64_t) + 
				sizeof(int) * 2);
			xml.read_tag();
// Asset doesn't read the XML path.
			Asset *new_asset = new Asset(xml.tag.get_property("SRC"));
			new_asset->read(&xml, 1);
			result = file->can_copy_from(new_asset, 
				position, 
				output_w, 
				output_h);
			send_result(result, 0, 0);
			new_asset->Garbage::remove_user();
			break;
		}

		case COLORMODEL_SUPPORTED:
		{
			int colormodel = *(int*)command_data;
			result = file->colormodel_supported(colormodel);
			send_result(result, 0, 0);
			break;
		}

		case FILE_MEMORY_USAGE:
			result = file->file_memory_usage();
			send_result(result, 0, 0);
			break;

		case SET_PROGRAM:
		{
			int no = *(int*)command_data;
			result = file->set_program(no);
			send_result(result, 0, 0);
			break;
		}

		case GET_CELL_TIME:
		{
			double time;
			int no = *(int*)command_data;
			result = file->get_cell_time(no, time);
			send_result(result, (unsigned char *)&time, sizeof(time));
			break;
		}

		case GET_STT_TIME:
		{
			int64_t tm;
			result = file->get_system_time(tm);
			send_result(result, (unsigned char *)&tm, sizeof(tm));
			break;
		}

		case GET_AUDIO4VIDEO:
		{
			int64_t channel_mask = 0;
			int vstream = *(int*)command_data;
			int astream = *(int*)(command_data + sizeof(int));
			result = file->get_audio_for_video(vstream, astream, channel_mask);
			send_result(result, (unsigned char *)&channel_mask, sizeof(channel_mask));
			break;
		}

		case GET_VIDEO_PID:
		{
			int track = *(int*)command_data;
			result = file->get_video_pid(track);
			send_result(result, 0, 0);
			break;
		}

		case GET_VIDEO_INFO:
		{
			int width=0, height=0;  double framerate=0;
			char title[BCTEXTLEN];  title[0]=0;
			int track = *(int*)command_data;
			result = file->get_video_info(track, pid,
				framerate, width, height, title);
			unsigned char data[sizeof(framerate)+sizeof(pid)+
				sizeof(width)+sizeof(height)+sizeof(title)];
			unsigned char *bp = data;
			*(double *)bp = framerate;  bp += sizeof(framerate);
			*(int *)bp = pid;     bp += sizeof(pid);
			*(int *)bp = width;   bp += sizeof(width);
			*(int *)bp = height;  bp += sizeof(height);
			for( char *cp=title; (*bp++=*cp)!=0; ++cp );
			send_result(result, data, bp-data);
			break;
		}
		case SELECT_VIDEO_STREAM:
		{
			Asset *asset = new Asset;
			int vstream = *(int*)command_data;
			result = file->select_video_stream(asset, vstream);
			unsigned char data[sizeof(asset->frame_rate)+sizeof(asset->video_length)+
				sizeof(asset->width)+sizeof(asset->height)];
			unsigned char *bp = data;
			*(double *)bp = asset->frame_rate; bp += sizeof(asset->frame_rate);
			*(int *)bp = asset->video_length;  bp += sizeof(asset->video_length);
			*(int *)bp = asset->width;         bp += sizeof(asset->width);
			*(int *)bp = asset->height;        bp += sizeof(asset->height);
			delete asset;
			send_result(result, data, bp-data);
			break;
		}
		case SELECT_AUDIO_STREAM:
		{
			Asset *asset = new Asset;
			int astream = *(int*)command_data;
			result = file->select_audio_stream(asset, astream);
			unsigned char data[sizeof(asset->channels)+sizeof(asset->sample_rate)+
				sizeof(asset->audio_length)];
			unsigned char *bp = data;
			*(int *)bp = asset->channels;      bp += sizeof(asset->channels);
			*(int *)bp = asset->sample_rate;   bp += sizeof(asset->sample_rate);
			*(int *)bp = asset->audio_length;  bp += sizeof(asset->audio_length);
			delete asset;
			send_result(result, data, bp-data);
			break;
		}
	}

	return result;
}
Пример #4
0
int MainUndo::undo()
{
	UndoStackItem *current = undo_stack->current;
	char after_description[BCTEXTLEN];
	after_description[0] = 0;

//printf("MainUndo::undo 1\n");
//undo_stack->dump();

// Rewind to an after entry
	if(current && !(undo_stack->number_of(current) % 2))
	{
		current = PREVIOUS;
	}

// Rewind to a before entry
	if(current && (undo_stack->number_of(current) % 2))
	{
		strcpy(after_description, current->get_description());
		current = PREVIOUS;
	}

// Now have an even number
	if(current)
	{
		undo_stack->current = current;
// Set the redo text to the current description
		if(mwindow->gui) 
			mwindow->gui->mainmenu->redo->update_caption(
				after_description);

		FileXML file;
		char *current_data = current->get_data();
		if(current_data)
		{
			file.read_from_string(current_data);
			load_from_undo(&file, current->get_flags());
//printf("MainUndo::undo %d %s\n", __LINE__, current->get_filename());
			mwindow->set_filename(current->get_filename());
			delete [] current_data;

// move current entry back one step
			undo_stack->pull();    


			if(mwindow->gui)
			{
// Now update the menu with the after entry
				current = PREVIOUS;
// Must be a previous entry to perform undo
				if(current)
					mwindow->gui->mainmenu->undo->update_caption(
						current->get_description());
				else
					mwindow->gui->mainmenu->undo->update_caption("");
			}
		}
	}


//undo_stack->dump();
	reset_creators();
	return 0;
}