$(OBJDIR)/filedv.o \
$(OBJDIR)/fileexr.o \
$(OBJDIR)/fileflac.o \
- $(OBJDIR)/filefork.o \
$(OBJDIR)/fileformat.o \
$(OBJDIR)/filegif.o \
$(OBJDIR)/filelist.o \
$(OBJDIR)/fileogg.o \
$(OBJDIR)/filepng.o \
$(OBJDIR)/filescene.o \
- $(OBJDIR)/fileserver.o \
$(OBJDIR)/filesndfile.o \
$(OBJDIR)/filetga.o \
$(OBJDIR)/filethread.o \
$(OBJDIR)/filexml.o \
$(OBJDIR)/floatauto.o \
$(OBJDIR)/floatautos.o \
- $(OBJDIR)/forkwrapper.o \
$(OBJDIR)/formatcheck.o \
$(OBJDIR)/formatpresets.o \
$(OBJDIR)/formatpopup.o \
$(OBJDIR)/theme.o \
$(OBJDIR)/threadexec.o \
$(OBJDIR)/threadloader.o \
- $(OBJDIR)/threadfork.o \
$(OBJDIR)/timelinepane.o \
$(OBJDIR)/timebar.o \
$(OBJDIR)/timeentry.o \
@echo g++ -o $@ $(BDWOBJS)
@g++ $(CFLAGS) -pthread -o $@ $(BDWOBJS) $(LIBS)
-$(OBJDIR)/test:
- $(CC) -shared -o $(OBJDIR)/test.so \
- $(OBJDIR)/threadfork.o \
- ../guicast/$(OBJDIR)/thread.o \
- ../guicast/$(OBJDIR)/mutex.o
- $(CC) -o $(OBJDIR)/test test.C \
- `cat $(OBJDIR)/c_flags` \
- $(OBJDIR)/test.so \
- $(LIBS)
-
clean:
rm -rf $(OBJDIR)
find \( -name core \
-// Used by filefork
channels = GET_DEFAULT("CHANNELS", 2);
if(!sample_rate) sample_rate = GET_DEFAULT("RATE", 44100);
header = GET_DEFAULT("HEADER", 0);
-// Used by filefork
UPDATE_DEFAULT("CHANNELS", channels);
UPDATE_DEFAULT("RATE", sample_rate);
UPDATE_DEFAULT("HEADER", header);
strcat(font_path, "/fonts");
BC_Resources::init_fontconfig(font_path);
BC_WindowBase::get_resources()->vframe_shm = 1;
- MWindow::init_fileserver(preferences);
//PRINT_TRACE
load_jobs(batch_path, preferences);
#include "fileexr.h"
#include "fileffmpeg.h"
#include "fileflac.h"
-#include "filefork.h"
#include "filegif.h"
#include "file.h"
#include "filejpeg.h"
#include "fileogg.h"
#include "filepng.h"
#include "filescene.h"
-#include "fileserver.h"
#include "filesndfile.h"
#include "filetga.h"
#include "filethread.h"
format_completion = new Condition(1, "File::format_completion");
write_lock = new Condition(1, "File::write_lock");
frame_cache = new FrameCache;
-#ifdef USE_FILEFORK
- forked = new Mutex("File::forked",0);
-#endif
reset_parameters();
}
asset->Garbage::remove_user();
delete format_completion;
delete write_lock;
-#ifdef USE_FILEFORK
- delete forked;
-#endif
delete frame_cache;
}
void File::reset_parameters()
{
-#ifdef USE_FILEFORK
- file_fork = 0;
- is_fork = 0;
-#endif
-
file = 0;
audio_thread = 0;
video_thread = 0;
{
if( cpus > 8 ) // mpegvideo max_threads = 16, more causes errs
cpus = 8; // 8 cpus ought to decode just about anything
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_PROCESSORS, (unsigned char*)&cpus, sizeof(cpus));
- file_fork->read_result();
- }
-#endif
-
// Set all instances so gets work.
this->cpus = cpus;
int File::set_preload(int64_t size)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_PRELOAD, (unsigned char*)&size, sizeof(size));
- file_fork->read_result();
- }
-
-#endif
-
this->playback_preload = size;
return 0;
}
void File::set_subtitle(int value)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_SUBTITLE, (unsigned char*)&value, sizeof(value));
- file_fork->read_result();
- }
-
-#endif
this->playback_subtitle = value;
if( file ) file->set_subtitle(value);
}
void File::set_interpolate_raw(int value)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_INTERPOLATE_RAW, (unsigned char*)&value, sizeof(value));
- file_fork->read_result();
- }
-
-#endif
-
this->interpolate_raw = value;
}
void File::set_white_balance_raw(int value)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_WHITE_BALANCE_RAW, (unsigned char*)&value, sizeof(value));
- file_fork->read_result();
- }
-#endif
-
this->white_balance_raw = value;
}
int rd,
int wr)
{
- int result = 0;
const int debug = 0;
this->preferences = preferences;
if(debug) printf("File::open_file %d\n", __LINE__);
-#ifdef USE_FILEFORK
- if( !is_fork && MWindow::file_server && (rd || wr) ) {
- FileForker this_is(*forked);
-// printf("File::open_file %d file_server=%p rd=%d wr=%d %d\n",
-// __LINE__,
-// MWindow::file_server,
-// rd,
-// wr,
-// asset->ms_quantization);
- file_fork = MWindow::file_server->new_filefork();
-//printf("File::open_file %d\n", __LINE__);
-
-// Send the asset
-// Convert to hash table
- BC_Hash table;
- asset->save_defaults(&table, "", 1, 1, 1, 1, 1);
-// Convert to string
- char *string = 0;
- table.save_string(string);
- int buffer_size = sizeof(int) * 7 + strlen(string) + 1;
- unsigned char *buffer = new unsigned char[buffer_size];
- int offset = 0;
- *(int*)(buffer + offset) = rd;
- offset += sizeof(int);
- *(int*)(buffer + offset) = wr;
- offset += sizeof(int);
- *(int*)(buffer + offset) = cpus;
- offset += sizeof(int);
- *(int*)(buffer + offset) = white_balance_raw;
- offset += sizeof(int);
- *(int*)(buffer + offset) = interpolate_raw;
- offset += sizeof(int);
- *(int*)(buffer + offset) = playback_subtitle;
- offset += sizeof(int);
- *(int*)(buffer + offset) = current_program;
- offset += sizeof(int);
- memcpy(buffer + offset, string, strlen(string) + 1);
-//printf("File::open_file %d\n", __LINE__);
- file_fork->send_command(FileFork::OPEN_FILE,
- buffer,
- buffer_size);
- delete [] buffer;
- free(string);
-//printf("File::open_file %d\n", __LINE__);
-
-// Get the updated asset from the fork
- result = file_fork->read_result();
-//printf("File::open_file %d\n", __LINE__);
- if(!result)
- {
- table.load_string((char*)file_fork->result_data);
-
- asset->load_defaults(&table, "", 1, 1, 1, 1, 1);
- this->asset->load_defaults(&table, "", 1, 1, 1, 1, 1);
-//this->asset->dump();
- }
-//printf("File::open_file %d\n", __LINE__);
-
-
-// If it's a scene renderer, close it & reopen it locally to get the
-// full OpenGL support.
-// Just doing 2D for now. Should be forked in case Festival crashes.
-// if(rd && this->asset->format == FILE_SCENE)
-// {
-// //printf("File::open_file %p %d\n", this, __LINE__);
-// close_file(0);
-// // Lie to get it to work properly
-// is_fork = 1;
-// }
-// else
- {
- return result;
- }
- }
-#endif
-
-
if(debug) printf("File::open_file %p %d\n", this, __LINE__);
switch(this->asset->format)
return 1;
}
- char test[16];
- result = fread(test, 16, 1, stream);
+ char test[16]; memset(test,0,sizeof(test)); // int result =
+ fread(test, 16, 1, stream);
if(FileScene::check_sig(this->asset, test)) {
// libsndfile
{
const int debug = 0;
-#ifdef USE_FILEFORK
- if(debug) printf("File::close_file file=%p file_fork=%p %d\n", file, file_fork, __LINE__);
-
- if(file_fork) {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::CLOSE_FILE, 0, 0);
- file_fork->read_result();
-
- if(asset && wr) {
- asset->audio_length = current_sample = *(int64_t*)file_fork->result_data;
- asset->video_length = current_frame = *(int64_t*)(file_fork->result_data + sizeof(int64_t));
- }
-
- if(debug) printf("File::close_file:%d current_sample=" _LD " current_frame=" _LD "\n",
- __LINE__,
- current_sample,
- current_frame);
-
- delete file_fork;
- file_fork = 0;
- }
-#endif
-
if(debug) printf("File::close_file file=%p %d\n", file, __LINE__);
if(!ignore_thread) {
int File::get_index(char *index_path)
{
-#ifdef USE_FILEFORK
- if(file_fork) {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_INDEX, (unsigned char*)index_path, strlen(index_path) + 1);
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
if(file) {
return file->get_index(index_path);
}
{
this->audio_ring_buffers = ring_buffers;
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- unsigned char buffer[sizeof(int) * 2];
- int *ibfr = (int *)buffer;
- ibfr[0] = buffer_size;
- ibfr[1] = audio_ring_buffers;
- file_fork->send_command(FileFork::START_AUDIO_THREAD, buffer, sizeof(buffer));
- int result = file_fork->read_result();
-
-
-//printf("File::start_audio_thread %d file_fork->result_data=%p\n", __LINE__, file_fork->result_data);
-// Create server copy of buffer
- delete_temp_samples_buffer();
-//printf("File::start_audio_thread %d\n", __LINE__);
- temp_samples_buffer = new Samples**[audio_ring_buffers];
-//printf("File::start_audio_thread %d\n", __LINE__);
- for(int i = 0; i < audio_ring_buffers; i++)
- {
-//printf("File::start_audio_thread %d\n", __LINE__);
- temp_samples_buffer[i] = new Samples*[asset->channels];
-//printf("File::start_audio_thread %d\n", __LINE__);
- for(int j = 0; j < asset->channels; j++)
- {
- int offset = i * Samples::filefork_size() * asset->channels +
- j * Samples::filefork_size();
-//printf("File::start_audio_thread %d j=%d offset=%d\n", __LINE__, j, offset);
- temp_samples_buffer[i][j] = new Samples;
- temp_samples_buffer[i][j]->from_filefork(
- file_fork->result_data +
- offset);
-//printf("File::start_audio_thread %d\n", __LINE__);
- }
- }
-
- return result;
- }
-#endif
-
if(!audio_thread)
{
this->video_ring_buffers = ring_buffers;
this->video_buffer_size = buffer_size;
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
-// This resets variables
- delete_temp_frame_buffer();
-
- this->video_ring_buffers = ring_buffers;
- this->video_buffer_size = buffer_size;
-
- unsigned char buffer[sizeof(int) * 4];
- int *ibfr = (int *)buffer;
- ibfr[0] = buffer_size;
- ibfr[1] = color_model;
- ibfr[2] = video_ring_buffers;
- ibfr[3] = compressed;
-// Buffers are allocated
- file_fork->send_command(FileFork::START_VIDEO_THREAD,
- buffer,
- sizeof(buffer));
- int result = file_fork->read_result();
-
-
-// Create server copy of buffer
-//printf("File::start_video_thread %d %d\n", __LINE__, video_ring_buffers);
- temp_frame_buffer = new VFrame***[video_ring_buffers];
- for(int i = 0; i < video_ring_buffers; i++)
- {
- temp_frame_buffer[i] = new VFrame**[asset->layers];
- for(int j = 0; j < asset->layers; j++)
- {
- temp_frame_buffer[i][j] = new VFrame*[video_buffer_size];
-//printf("File::start_video_thread %d %p\n", __LINE__, temp_frame_buffer[i][j]);
- for(int k = 0; k < video_buffer_size; k++)
- {
- temp_frame_buffer[i][j][k] = new VFrame;
- temp_frame_buffer[i][j][k]->from_filefork(file_fork->result_data +
- i * asset->layers * video_buffer_size * VFrame::filefork_size() +
- j * video_buffer_size * VFrame::filefork_size() +
- k * VFrame::filefork_size());
- }
- }
- }
-
-
- return result;
- }
-#endif
-
-
-
if(!video_thread)
{
video_thread = new FileThread(this, 0, 1);
int File::start_video_decode_thread()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::START_VIDEO_DECODE_THREAD, 0, 0);
- file_fork->read_result();
- return 0;
- }
-#endif
-
-
// Currently, CR2 is the only one which won't work asynchronously, so
// we're not using a virtual function yet.
if(!video_thread /* && asset->format != FILE_CR2 */)
int File::stop_audio_thread()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- file_fork->send_command(FileFork::STOP_AUDIO_THREAD, 0, 0);
- file_fork->read_result();
- return 0;
- }
-#endif
-
if(audio_thread)
{
audio_thread->stop_writing();
int File::stop_video_thread()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::STOP_VIDEO_THREAD, 0, 0);
- file_fork->read_result();
- return 0;
- }
-#endif
-
if(video_thread)
{
video_thread->stop_reading();
int File::set_channel(int channel)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
-// Set it locally for get_channel
- current_channel = channel;
- file_fork->send_command(FileFork::SET_CHANNEL, (unsigned char*)&channel, sizeof(channel));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
if(file && channel < asset->channels)
{
current_channel = channel;
// returns current program
int File::set_program(int no)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_PROGRAM, (unsigned char*)&no, sizeof(no));
- int result = file_fork->read_result();
- current_program = no < 0 ? result : no;
- return result;
- }
-#endif
int result = file ? file->set_program(no) : current_program;
current_program = no < 0 ? result : no;
return result;
int File::get_cell_time(int no, double &time)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_CELL_TIME, (unsigned char*)&no, sizeof(no));
- int result = file_fork->read_result();
- time = *(double *)file_fork->result_data;
- return result;
- }
-#endif
-
return file ? file->get_cell_time(no, time) : -1;
}
int File::get_system_time(int64_t &tm)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_STT_TIME, 0, 0);
- int result = file_fork->read_result();
- tm = *(int64_t *)file_fork->result_data;
- return result;
- }
-#endif
-
return file ? file->get_system_time(tm) : -1;
}
int File::get_audio_for_video(int vstream, int astream, int64_t &channel_mask)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- unsigned char buffer[2*sizeof(int)];
- int offset = 0;
- *(int*)(buffer + offset) = vstream;
- offset += sizeof(int);
- *(int*)(buffer + offset) = astream;
- file_fork->send_command(FileFork::GET_AUDIO4VIDEO, buffer, sizeof(buffer));
- int result = file_fork->read_result();
- channel_mask = *(int64_t *)file_fork->result_data;
- return result;
- }
-#endif
-
return file ? file->get_audio_for_video(vstream, astream, channel_mask) : -1;
}
int File::get_video_pid(int track)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_VIDEO_PID,
- (unsigned char*)&track, sizeof(track));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
return file ? file->get_video_pid(track) : -1;
}
int File::get_video_info(int track, int &pid, double &framerate,
int &width, int &height, char *title)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_VIDEO_INFO,
- (unsigned char*)&track, sizeof(track));
- int result = file_fork->read_result();
- if( !result ) {
- unsigned char *bp = file_fork->result_data;
- framerate = *(double*)bp; bp += sizeof(framerate);
- pid = *(int *) bp; bp += sizeof(pid);
- width = *(int *) bp; bp += sizeof(width);
- height = *(int *) bp; bp += sizeof(height);
- strcpy(title, (char *)bp);
- }
- return result;
- }
-#endif
-
return !file ? -1 :
file->get_video_info(track, pid, framerate, width, height, title);
}
int File::select_video_stream(Asset *asset, int vstream)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SELECT_VIDEO_STREAM,
- (unsigned char*)&vstream, sizeof(vstream));
- int result = file_fork->read_result();
- if( !result ) {
- unsigned char *bp = file_fork->result_data;
- asset->frame_rate = *(double*) bp; bp += sizeof(asset->frame_rate);
- asset->video_length = *(int64_t *) bp; bp += sizeof(asset->video_length);
- asset->width = *(int *) bp; bp += sizeof(asset->width);
- asset->height = *(int *) bp; bp += sizeof(asset->height);
- }
- }
-#endif
return !file ? -1 :
file->select_video_stream(asset, vstream);
}
int File::select_audio_stream(Asset *asset, int astream)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SELECT_AUDIO_STREAM,
- (unsigned char*)&astream, sizeof(astream));
- int result = file_fork->read_result();
- if( !result ) {
- unsigned char *bp = file_fork->result_data;
- asset->audio_length = *(int64_t *) bp; bp += sizeof(asset->audio_length);
- asset->sample_rate = *(int *) bp; bp += sizeof(asset->sample_rate);
- }
- }
-#endif
return !file ? -1 :
file->select_audio_stream(asset, astream);
}
int File::set_layer(int layer, int is_thread)
{
-#ifdef USE_FILEFORK
-// thread should only call in the fork
- if(file_fork && !is_fork && !is_thread)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_LAYER, (unsigned char*)&layer, sizeof(layer));
- int result = file_fork->read_result();
- current_layer = layer;
- return result;
- }
-#endif
-
if(file && layer < asset->layers)
{
if(!is_thread && video_thread)
int64_t File::get_audio_length()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_AUDIO_LENGTH, 0, 0);
- int64_t result = file_fork->read_result();
- return result;
- }
-#endif
-
int64_t result = asset->audio_length;
int64_t base_samplerate = -1;
if(result > 0)
int64_t File::get_video_length()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_VIDEO_LENGTH, 0, 0);
- int64_t result = file_fork->read_result();
- return result;
- }
-#endif
-
-
int64_t result = asset->video_length;
float base_framerate = -1;
if(result > 0)
int64_t File::get_video_position()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_VIDEO_POSITION, 0, 0);
- int64_t result = file_fork->read_result();
- return result;
- }
-#endif
-
float base_framerate = -1;
if(base_framerate > 0)
return (int64_t)((double)current_frame / asset->frame_rate * base_framerate + 0.5);
int64_t File::get_audio_position()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_AUDIO_POSITION, 0, 0);
- int64_t result = file_fork->read_result();
- return result;
- }
-#endif
-
-
// int64_t base_samplerate = -1;
// if(base_samplerate > 0)
// {
int File::set_audio_position(int64_t position)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::SET_AUDIO_POSITION,
- (unsigned char*)&position,
- sizeof(position));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
int result = 0;
if(!file) return 1;
int File::set_video_position(int64_t position,
int is_thread)
{
-#ifdef USE_FILEFORK
-// Thread should only call in the fork
- if(file_fork && !is_fork && !is_thread)
- {
- FileForker this_is(*forked);
-//printf("File::set_video_position %d %lld\n", __LINE__, position);
- file_fork->send_command(FileFork::SET_VIDEO_POSITION, (unsigned char*)&position, sizeof(position));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
int result = 0;
if(!file) return 0;
// No resampling here.
int File::write_samples(Samples **buffer, int64_t len)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- int entry_size = Samples::filefork_size();
- int buffer_size = entry_size * asset->channels + sizeof(int64_t);
- unsigned char fork_buffer[buffer_size];
- for(int i = 0; i < asset->channels; i++)
- {
- buffer[i]->to_filefork(fork_buffer + entry_size * i);
- }
-
- *(int64_t*)(fork_buffer +
- entry_size * asset->channels) = len;
-
- file_fork->send_command(FileFork::WRITE_SAMPLES,
- fork_buffer,
- buffer_size);
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
-
-
-
int result = 1;
if(file)
int File::write_frames(VFrame ***frames, int len)
{
//printf("File::write_frames %d\n", __LINE__);
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
-//printf("File::write_frames %d\n", __LINE__);
- int entry_size = frames[0][0]->filefork_size();
- unsigned char fork_buffer[entry_size * asset->layers * len + sizeof(int)];
- for(int i = 0; i < asset->layers; i++)
- {
- for(int j = 0; j < len; j++)
- {
-// printf("File::write_frames %d " _LD " %d\n",
-// __LINE__,
-// frames[i][j]->get_number(),
-// frames[i][j]->get_keyframe());
- frames[i][j]->to_filefork(fork_buffer +
- sizeof(int) +
- entry_size * len * i +
- entry_size * j);
- }
- }
-
-
-//PRINT_TRACE
-// Frames per layer
- int *fbfr = (int *)fork_buffer;
- fbfr[0] = len;
-//PRINT_TRACE
-
- file_fork->send_command(FileFork::WRITE_FRAMES,
- fork_buffer,
- sizeof(fork_buffer));
-//PRINT_TRACE
- int result = file_fork->read_result();
-
-
-//printf("File::write_frames %d\n", __LINE__);
- return result;
- }
-
-
-#endif // USE_FILEFORK
-
-
//PRINT_TRACE
// Store the counters in temps so the filebase can choose to overwrite them.
int result;
int File::write_audio_buffer(int64_t len)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::WRITE_AUDIO_BUFFER, (unsigned char*)&len, sizeof(len));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
int result = 0;
if(audio_thread)
{
int File::write_video_buffer(int64_t len)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
-// Copy over sequence numbers for background rendering
-// frame sizes for direct copy
-//printf("File::write_video_buffer %d\n", __LINE__);
- int fork_buffer_size = sizeof(int64_t) +
- VFrame::filefork_size() * asset->layers * len;
- unsigned char fork_buffer[fork_buffer_size];
- int64_t *fbfr = (int64_t *)fork_buffer;
- fbfr[0] = len;
-
- for(int i = 0; i < asset->layers; i++)
- {
- for(int j = 0; j < len; j++)
- {
-// Send memory state
- current_frame_buffer[i][j]->to_filefork(fork_buffer +
- sizeof(int64_t) +
- VFrame::filefork_size() * (len * i + j));
-// printf("File::write_video_buffer %d size=%d %d %02x %02x %02x %02x %02x %02x %02x %02x\n",
-// __LINE__,
-// current_frame_buffer[i][j]->get_shmid(),
-// current_frame_buffer[i][j]->get_compressed_size(),
-// current_frame_buffer[i][j]->get_data()[0],
-// current_frame_buffer[i][j]->get_data()[1],
-// current_frame_buffer[i][j]->get_data()[2],
-// current_frame_buffer[i][j]->get_data()[3],
-// current_frame_buffer[i][j]->get_data()[4],
-// current_frame_buffer[i][j]->get_data()[5],
-// current_frame_buffer[i][j]->get_data()[6],
-// current_frame_buffer[i][j]->get_data()[7]);
- }
- }
-
-//printf("File::write_video_buffer %d\n", __LINE__);
- file_fork->send_command(FileFork::WRITE_VIDEO_BUFFER,
- fork_buffer,
- fork_buffer_size);
-//printf("File::write_video_buffer %d\n", __LINE__);
- int result = file_fork->read_result();
-//printf("File::write_video_buffer %d\n", __LINE__);
- return result;
- }
-#endif
-
int result = 0;
if(video_thread)
{
Samples** File::get_audio_buffer()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::GET_AUDIO_BUFFER, 0, 0);
- int result = file_fork->read_result();
-
-// Read parameters for a Samples buffer & create it in File
-// delete_temp_samples_buffer();
-// if(!temp_samples_buffer)
-// {
-// temp_samples_buffer = new Samples**[ring_buffers];
-// for(int i = 0; i < ring_buffers; i++) temp_samples_buffer[i] = 0;
-// }
-//
-//
-// temp_samples_buffer = new Samples*[asset->channels];
-// for(int i = 0; i < asset->channels; i++)
-// {
-// temp_samples_buffer[i] = new Samples;
-// temp_samples_buffer[i]->from_filefork(file_fork->result_data +
-// i * Samples::filefork_size());
-// }
-
- return temp_samples_buffer[result];
- }
-#endif
-
if(audio_thread) return audio_thread->get_audio_buffer();
return 0;
}
VFrame*** File::get_video_buffer()
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
-
- file_fork->send_command(FileFork::GET_VIDEO_BUFFER, 0, 0);
- int result = file_fork->read_result();
-
-// Read parameters for a VFrame buffer & create it in File
-// delete_temp_frame_buffer();
-
-
-// temp_frame_size = *(int*)(file_fork->result_data +
-// file_fork->result_bytes -
-// sizeof(int));
-//
-// //printf("File::get_video_buffer %d %p %d\n", __LINE__, this, asset->layers);
-// temp_frame_buffer = new VFrame**[asset->layers];
-//
-// for(int i = 0; i < asset->layers; i++)
-// {
-//
-// temp_frame_buffer[i] = new VFrame*[temp_frame_size];
-//
-// for(int j = 0; j < temp_frame_size; j++)
-// {
-//
-// temp_frame_buffer[i][j] = new VFrame;
-// printf("File::get_video_buffer %d %p\n", __LINE__, temp_frame_buffer[i][j]);
-//
-// temp_frame_buffer[i][j]->from_filefork(file_fork->result_data +
-// i * temp_frame_size * VFrame::filefork_size() +
-// j * VFrame::filefork_size());
-//
-// }
-// }
-//
-
- current_frame_buffer = temp_frame_buffer[result];
-
- return current_frame_buffer;
- }
-#endif
-
if(video_thread)
{
VFrame*** result = video_thread->get_video_buffer();
const int debug = 0;
if(debug) PRINT_TRACE
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- int buffer_bytes = Samples::filefork_size() + sizeof(int64_t);
- unsigned char buffer[buffer_bytes];
- samples->to_filefork(buffer);
- *(int64_t*)(buffer + Samples::filefork_size()) = len;
- if(debug) PRINT_TRACE
- file_fork->send_command(FileFork::READ_SAMPLES,
- buffer,
- buffer_bytes);
- if(debug) PRINT_TRACE
- int result = file_fork->read_result();
-
-// Crashed
- if(result && !file_fork->child_running())
- {
- delete file_fork;
- result = open_file(preferences, asset, rd, wr);
- }
-
- return result;
- }
-#endif
-
if(debug) PRINT_TRACE
double *buffer = samples->get_data();
if(debug) PRINT_TRACE
-#ifdef USE_FILEFORK
-// is_thread is only true in the fork
- if(file_fork && !is_fork && !is_thread)
- {
- FileForker this_is(*forked);
- unsigned char fork_buffer[VFrame::filefork_size()];
- if(debug) PRINT_TRACE
-
- frame->to_filefork(fork_buffer);
- file_fork->send_command(FileFork::READ_FRAME,
- fork_buffer,
- VFrame::filefork_size());
-
- int result = file_fork->read_result();
-
-
-// Crashed
- if(result && !file_fork->child_running())
- {
- delete file_fork;
- result = open_file(preferences, asset, rd, wr);
- }
- else
- if(!result &&
- frame->get_color_model() == BC_COMPRESSED)
- {
-// Get compressed data from socket
-//printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
- int header_size = sizeof(int) * 2;
- if(file_fork->result_bytes > header_size)
- {
-//printf("File::read_frame %d %d\n", __LINE__, file_fork->result_bytes);
- frame->allocate_compressed_data(file_fork->result_bytes - header_size);
- frame->set_compressed_size(file_fork->result_bytes - header_size);
- frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
- memcpy(frame->get_data(),
- file_fork->result_data + header_size,
- file_fork->result_bytes - header_size);
- }
- else
-// Get compressed data size
- {
- frame->set_compressed_size(*(int*)file_fork->result_data);
- frame->set_keyframe(*(int*)(file_fork->result_data + sizeof(int)));
-//printf("File::read_frame %d %d\n", __LINE__, *(int*)(file_fork->result_data + sizeof(int)));
- }
- }
-
- return result;
- }
-#endif
-
-
//printf("File::read_frame %d\n", __LINE__);
if(video_thread && !is_thread) return video_thread->read_frame(frame);
int advance_position = 1;
// Test cache
- if(use_cache && !is_fork &&
+ if(use_cache &&
frame_cache->get_frame(frame,
current_frame,
current_layer,
}
//printf("File::read_frame %d use_cache=%d\n", __LINE__, use_cache);
- if(use_cache && !is_fork)
+ if(use_cache)
frame_cache->put_frame(frame,
current_frame, current_layer,
asset->frame_rate, 1, 0);
{
if(!asset) return 0;
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- FileXML xml;
- asset->write(&xml, 1, "");
- xml.terminate_string();
- const char *xml_string = xml.string();
- long xml_length = strlen(xml_string);
- int buffer_size = xml_length + 1 +
- sizeof(int64_t) +
- sizeof(int) +
- sizeof(int);
- unsigned char *buffer = new unsigned char[buffer_size];
- *(int64_t*)(buffer) = position;
- *(int*)(buffer + sizeof(int64_t)) = output_w;
- *(int*)(buffer + sizeof(int64_t) + sizeof(int)) = output_h;
- memcpy(buffer +
- sizeof(int64_t) +
- sizeof(int) +
- sizeof(int),
- xml_string,
- xml_length + 1);
-
- file_fork->send_command(FileFork::CAN_COPY_FROM,
- buffer,
- buffer_size);
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
-
if(file)
{
return asset->width == output_w &&
int File::colormodel_supported(int colormodel)
{
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- unsigned char buffer[sizeof(int)];
- int *ibfr = (int *)buffer;
- ibfr[0] = colormodel;
-
- file_fork->send_command(FileFork::COLORMODEL_SUPPORTED,
- buffer,
- sizeof(int));
- int result = file_fork->read_result();
- return result;
- }
-#endif
-
-
if(file)
return file->colormodel_supported(colormodel);
{
int64_t result = 0;
-#ifdef USE_FILEFORK
- if(file_fork)
- {
- FileForker this_is(*forked);
- file_fork->send_command(FileFork::FILE_MEMORY_USAGE, 0, 0);
- result = file_fork->read_result();
- }
- else
-#endif
result += file_memory_usage();
if(temp_frame) result += temp_frame->get_data_size();
result += frame_cache->get_memory_usage();
#include "filebase.inc"
#include "file.inc"
-#ifdef USE_FILEFORK
-#include "filefork.inc"
-#endif
-
#include "filethread.inc"
#include "filexml.inc"
#include "formattools.inc"
File();
~File();
- friend class FileFork;
-
// Get attributes for various file formats.
// The dither parameter is carried over from recording, where dither is done at the device.
int get_options(FormatTools *format,
// Copy read frames to the cache
int use_cache;
-#ifdef USE_FILEFORK
-// Pointer to the fork object. 0 if this instance of File is the fork.
- FileFork *file_fork;
-// If this instance is the fork.
- int is_fork;
-// result_data must be locked during sync transaction
- Mutex *forked;
-
- class FileForker {
- Mutex &m;
- public:
- FileForker(Mutex &lk) : m(lk) { m.lock("FileForker::FileForker"); }
- ~FileForker() { m.unlock(); }
- };
-#endif
-
};
#endif
#include "language.h"
-#define USE_FILEFORK
-
// Return values for open_file
#define FILE_OK 0
#define FILE_NOT_FOUND 1
+++ /dev/null
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "bchash.h"
-#include "bcsignals.h"
-#include "file.h"
-#include "filefork.h"
-#include "fileserver.h"
-#include "filesystem.h"
-#include "filethread.h"
-#include "filexml.h"
-#include "format.inc"
-#include "mutex.h"
-#include "mwindow.h"
-#include "samples.h"
-#include "string.h"
-#include "vframe.h"
-
-
-#include <unistd.h>
-
-
-#ifdef USE_FILEFORK
-
-
-FileFork::FileFork(FileServer *server) : ForkWrapper()
-{
- file = 0;
- real_fork = 0;
- this->server = server;
-//printf("FileFork::FileFork %d\n", __LINE__);
-}
-
-FileFork::~FileFork()
-{
- if(real_fork)
- {
- MWindow::file_server->delete_filefork(real_fork);
- }
-}
-
-void FileFork::init_child()
-{
-//printf("FileFork::init_child %d\n", __LINE__);
-}
-
-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;
-}
-
-
-#endif // USE_FILEFORK
-
-
-
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-
-#ifndef FILEFORK_H
-#define FILEFORK_H
-
-#include "file.inc"
-#include "fileserver.inc"
-#include "forkwrapper.h"
-
-// This is an object created by File which runs in a separate process to
-// actually interface the data. File functions redirect to this process.
-// This is to isolate file format crashes.
-
-
-
-#ifdef USE_FILEFORK
-class FileFork : public ForkWrapper
-{
-public:
- FileFork(FileServer *server);
- virtual ~FileFork();
-
- void init_child();
- int handle_command();
-
-// Instance of file that does the actual work.
- File *file;
-// If this is a dummy filefork, the pointer of the real filefork in the fileserver
-// memory space.
- FileFork *real_fork;
- FileServer *server;
-
-// Command tokens
- enum
- {
- NO_COMMAND,
- OPEN_FILE,
- SET_PROCESSORS,
- SET_PRELOAD,
- SET_SUBTITLE,
- SET_INTERPOLATE_RAW,
- SET_WHITE_BALANCE_RAW,
- CLOSE_FILE,
- GET_INDEX,
- START_VIDEO_THREAD,
- START_AUDIO_THREAD, // 10
- START_VIDEO_DECODE_THREAD,
- STOP_AUDIO_THREAD,
- STOP_VIDEO_THREAD,
- SET_CHANNEL,
- SET_LAYER,
- GET_AUDIO_LENGTH,
- GET_VIDEO_LENGTH,
- GET_AUDIO_POSITION,
- GET_VIDEO_POSITION,
- SET_AUDIO_POSITION, // 20
- SET_VIDEO_POSITION,
- WRITE_SAMPLES,
- WRITE_FRAMES,
- WRITE_AUDIO_BUFFER,
- WRITE_VIDEO_BUFFER,
- GET_AUDIO_BUFFER,
- GET_VIDEO_BUFFER,
- READ_SAMPLES,
- READ_COMPRESSED_FRAME,
- COMPRESSED_FRAME_SIZE, // 30
- READ_FRAME,
- CAN_COPY_FROM,
- COLORMODEL_SUPPORTED,
- FILE_MEMORY_USAGE,
- SET_PROGRAM,
- GET_CELL_TIME,
- GET_STT_TIME,
- GET_AUDIO4VIDEO,
- GET_VIDEO_PID,
- GET_VIDEO_INFO, // 40
- SELECT_VIDEO_STREAM,
- SELECT_AUDIO_STREAM,
- };
-};
-
-#endif // USE_FILEFORK
-
-
-#endif
-
-
-
+++ /dev/null
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-
-
-
-#ifndef FILEFORK_INC
-#define FILEFORK_INC
-
-class FileFork;
-
-
-#endif
-
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "file.inc"
-
-#ifdef USE_FILEFORK
-
-#include "bcresources.h"
-#include "bcsignals.h"
-#include "filefork.h"
-#include "fileserver.h"
-#include "mutex.h"
-
-
-#include <unistd.h>
-
-
-FileServer::FileServer(Preferences *preferences) : ForkWrapper()
-{
- this->preferences = preferences;
- lock = new Mutex("FileServer::lock");
-}
-
-FileServer::~FileServer()
-{
- stop();
- delete lock;
-}
-
-void FileServer::init_child()
-{
- BC_WindowBase::get_resources()->vframe_shm = 1;
-//printf("FileServer::init_child %d %d\n", __LINE__, getpid());
-}
-
-int FileServer::handle_command()
-{
- const int debug = 0;
- switch(command_token)
- {
- case NEW_FILEFORK:
- {
- FileFork *file_fork = new FileFork(this);
- file_fork->start();
- unsigned char buffer[sizeof(FileFork*) + sizeof(int)];
- FileFork **ffbfr = (FileFork **)buffer;
- *ffbfr = file_fork;
- int *ibfr = (int *)&ffbfr[1];
- *ibfr = file_fork->pid;
-
- if(debug) printf("FileServer::handle_command NEW_FILEFORK %d parent_fd=%d file_fork=%p\n",
- __LINE__,
- file_fork->parent_fd,
- file_fork);
- send_fd(file_fork->parent_fd);
- send_result(0, buffer, sizeof(FileFork*) + sizeof(int));
- break;
- }
-
- case DELETE_FILEFORK:
- {
- FileFork **ffbfr = (FileFork **)command_data;
- FileFork *file_fork = *ffbfr;
- if(debug) printf("FileServer::handle_command DELETE_FILEFORK %d file_fork=%p\n",
- __LINE__,
- file_fork);
- delete file_fork;
- break;
- }
- }
-
- return 0;
-}
-
-FileFork* FileServer::new_filefork()
-{
- lock->lock("FileServer::open_file");
- FileFork *dummy_fork = new FileFork(this);
-// Create real file fork on the server
- send_command(FileServer::NEW_FILEFORK, 0, 0);
-
- int parent_fd = get_fd();
- read_result();
-
-// Transfer fd to dummy file fork
- dummy_fork->start_dummy(parent_fd, *(int*)(result_data + sizeof(FileFork*)));
- dummy_fork->real_fork = *(FileFork**)result_data;
-// printf("FileServer::new_filefork %d parent_fd=%d real_fork=%p\n",
-// __LINE__,
-// parent_fd,
-// dummy_fork->real_fork);
- lock->unlock();
- return dummy_fork;
-}
-
-void FileServer::delete_filefork(FileFork *file_fork)
-{
- lock->lock("FileServer::close_file");
-// Delete filefork on server
- unsigned char buffer[sizeof(FileFork*)];
- FileFork **ffbfr = (FileFork **)buffer;
- *ffbfr = file_fork;
- send_command(FileServer::DELETE_FILEFORK, buffer, sizeof(FileFork*));
- lock->unlock();
-}
-
-#endif // USE_FILEFORK
-
-
-
-
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-
-// This creates all the FileFork objects in a fork of its own so we don't
-// duplicate open file descriptors & keep memory from getting freed.
-
-
-
-#include "file.inc"
-#include "filefork.inc"
-#include "forkwrapper.h"
-#include "mutex.inc"
-#include "preferences.inc"
-
-
-class FileServer : public ForkWrapper
-{
-public:
- FileServer(Preferences *preferences);
- virtual ~FileServer();
-
-// Creates a dummy filefork pointer & commands the server to start a real filefork.
-// The real filefork's socket is copied & transferred to the dummy.
- FileFork* new_filefork();
-
-// Called by the dummy filefork's destructor.
-// Commands the server to delete the real filefork
- void delete_filefork(FileFork *file_fork);
-
- void init_child();
-
- int handle_command();
-
- enum
- {
- NEW_FILEFORK,
- DELETE_FILEFORK
- };
-
-// Only allow 1 call at a time
- Mutex *lock;
- Preferences *preferences;
-};
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-#ifndef FILESERVER_INC
-#define FILESERVER_INC
-
-
-
-
-class FileServer;
-
-
-
-
-#endif
-
-
-
-
-
-
-
-
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "bcsignals.h"
-#include "bcwindowbase.inc"
-#include "forkwrapper.h"
-#include "format.inc"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#define EXIT_CODE 0x7fff
-
-
-ForkWrapper::ForkWrapper()
-{
- done = 0;
- command_data = 0;
- command_allocated = 0;
- result_data = 0;
- result_allocated = 0;
- parent_fd = 0;
- child_fd = 0;
- pid = 0;
- is_dummy = 0;
-}
-
-ForkWrapper::~ForkWrapper()
-{
- int status;
- if(!is_dummy && pid)
- {
- waitpid(pid, &status, 0);
- }
-
- delete [] command_data;
- if(parent_fd) close(parent_fd);
- if(child_fd) close(child_fd);
-}
-
-void ForkWrapper::start()
-{
-// Create the process & socket pair.
- int sockets[2];
- socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
- parent_fd = sockets[0];
- child_fd = sockets[1];
-
- pid = fork();
-
-// Child process
- if(!pid)
- {
-//printf("ForkWrapper::start %d %d\n", __LINE__, getpid());
- BC_Signals::reset_locks();
- BC_Signals::set_sighup_exit(1);
- init_child();
- run();
- _exit(0);
- }
-}
-
-void ForkWrapper::stop()
-{
- send_command(EXIT_CODE,
- 0,
- 0);
-}
-
-void ForkWrapper::start_dummy(int parent_fd, int pid)
-{
- this->parent_fd = parent_fd;
- this->pid = pid;
- is_dummy = 1;
-}
-
-void ForkWrapper::init_child()
-{
- printf("ForkWrapper::init_child %d\n", __LINE__);
-}
-
-int ForkWrapper::handle_command()
-{
- printf("ForkWrapper::handle_command %d\n", __LINE__);
- return 0;
-}
-
-void ForkWrapper::run()
-{
- int result = 0;
- const int debug = 0;
-
- while(!done)
- {
- if(debug) printf("ForkWrapper::run %d this=%p parent_fd=%d child_fd=%d\n",
- __LINE__, this, parent_fd, child_fd);
-
- result = read_command();
-
-
-
- if(debug) printf("ForkWrapper::run %d this=%p result=%d command_token=%d\n",
- __LINE__, this, result, command_token);
-
- if(!result && command_token == EXIT_CODE)
- done = 1;
- else
- if(!result)
- {
- handle_command();
- }
- }
-}
-
-
-int ForkWrapper::send_command(int token,
- unsigned char *data,
- int bytes)
-{
- unsigned char buffer[sizeof(int) * 2];
- this->command_token = token;
- this->command_bytes = bytes;
-// printf("ForkWrapper::send_command %d parent_fd=%d token=%d data=%p bytes=%d\n",
-// __LINE__,
-// parent_fd,
-// token,
-// data,
-// bytes);
- int *ibfr = (int *)buffer;
- ibfr[0] = token;
- ibfr[1] = bytes;
- (void)write(parent_fd, buffer, sizeof(buffer));
- if(data && bytes) (void)write(parent_fd, data, bytes);
- return 0;
-}
-
-int ForkWrapper::read_command()
-{
- unsigned char buffer[sizeof(int) * 2];
-//printf("ForkWrapper::read_command %d child_fd=%d\n", __LINE__, child_fd);
- (void)read(child_fd, buffer, sizeof(buffer));
-//printf("ForkWrapper::read_command %d child_fd=%d\n", __LINE__, child_fd);
- int *ibfr = (int *)buffer;
- command_token = ibfr[0];
- command_bytes = ibfr[1];
-
-// printf("ForkWrapper::read_command %d command_token=%d command_bytes=%d\n",
-// __LINE__,
-// command_token,
-// command_bytes);
- if(command_bytes && command_allocated < command_bytes)
- {
- delete [] command_data;
- command_data = new unsigned char[command_bytes];
- command_allocated = command_bytes;
- }
- if(command_bytes) (void)read(child_fd, command_data, command_bytes);
- return 0;
-}
-
-int ForkWrapper::send_result(int64_t value, unsigned char *data, int data_size)
-{
- unsigned char buffer[sizeof(int64_t) + sizeof(int)];
- int64_t *lbfr = (int64_t *)buffer;
- lbfr[0] = value;
- int *ibfr = (int *)&lbfr[1];
- ibfr[0] = data_size;
- (void)write(child_fd, buffer, sizeof(buffer));
- if(data && data_size) (void)write(child_fd, data, data_size);
- return 0;
-}
-
-// Return 1 if the child is dead
-int ForkWrapper::read_timeout(unsigned char *data, int size)
-{
- fd_set rfds;
- struct timeval timeout_struct;
- int bytes_read = 0;
-
-// Poll child status while doing timed reads
- while(bytes_read < size)
- {
- timeout_struct.tv_sec = 1;
- timeout_struct.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_SET(parent_fd, &rfds);
- int result = select(parent_fd + 1, &rfds, 0, 0, &timeout_struct);
-
- if(result <= 0 && !child_running()) return 1;
-
-
- if(result > 0)
- {
- int fragment = read(parent_fd, data + bytes_read, size - bytes_read);
- if(fragment > 0) bytes_read += fragment;
- }
- }
-
- return 0;
-}
-
-int64_t ForkWrapper::read_result()
-{
- unsigned char buffer[sizeof(int64_t) + sizeof(int)];
-//printf("ForkWrapper::read_result %d parent_fd=%d\n", __LINE__, parent_fd);
-
- if(read_timeout(buffer, sizeof(buffer))) return 1;
-//printf("ForkWrapper::read_result %d parent_fd=%d\n", __LINE__, parent_fd);
- int64_t *lbfr = (int64_t *)buffer;
- int64_t result = lbfr[0];
- int *ibfr = (int *)&lbfr[1];
- result_bytes = ibfr[0];
-
- if(result_bytes && result_allocated < result_bytes)
- {
- delete [] result_data;
- result_data = new unsigned char[result_bytes];
- result_allocated = result_bytes;
- }
-//printf("ForkWrapper::read_result %d parent_fd=%d result=" _LD " result_bytes=%d\n",
-//__LINE__,
-//parent_fd,
-//result,
-//result_bytes);
-
- if(result_bytes)
- if(read_timeout(result_data, result_bytes)) return 1;
-//printf("ForkWrapper::read_result %d parent_fd=%d\n", __LINE__, parent_fd);
-
- return result;
-}
-
-// return 1 if the child is running
-int ForkWrapper::child_running()
-{
- char string[BCTEXTLEN];
- sprintf(string, "/proc/%d/stat", pid);
- FILE *fd = fopen(string, "r");
- if(fd)
- {
- while(!feof(fd) && fgetc(fd) != ')')
- ;
-
- fgetc(fd);
- int status = fgetc(fd);
-
-//printf("ForkWrapper::child_running '%c'\n", status);
- fclose(fd);
- if(status == 'Z')
- {
- printf("ForkWrapper::child_running %d: process %d dead\n", __LINE__, pid);
- return 0;
- }
- else
- return 1;
- }
- else
- {
- printf("ForkWrapper::child_running %d: process %d not found\n", __LINE__, pid);
- return 0;
- }
-}
-
-
-// From libancillary
-#define ANCIL_FD_BUFFER(n) \
-struct { \
- struct cmsghdr h; \
- int fd[n]; \
-}
-
-void ForkWrapper::send_fd(int fd)
-{
- ANCIL_FD_BUFFER(1) buffer;
- struct msghdr msghdr;
- char nothing = '!';
- struct iovec nothing_ptr;
- struct cmsghdr *cmsg;
-
- nothing_ptr.iov_base = ¬hing;
- nothing_ptr.iov_len = 1;
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = ¬hing_ptr;
- msghdr.msg_iovlen = 1;
- msghdr.msg_flags = 0;
- msghdr.msg_control = &buffer;
- msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
- cmsg = CMSG_FIRSTHDR(&msghdr);
- cmsg->cmsg_len = msghdr.msg_controllen;
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- int *ifd = (int *)CMSG_DATA(cmsg);
- *ifd = fd;
- sendmsg(child_fd, &msghdr, 0);
-}
-
-int ForkWrapper::get_fd()
-{
- ANCIL_FD_BUFFER(1) buffer;
- struct msghdr msghdr;
- char nothing;
- struct iovec nothing_ptr;
- struct cmsghdr *cmsg;
-
- nothing_ptr.iov_base = ¬hing;
- nothing_ptr.iov_len = 1;
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = ¬hing_ptr;
- msghdr.msg_iovlen = 1;
- msghdr.msg_flags = 0;
- msghdr.msg_control = &buffer;
- msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
- cmsg = CMSG_FIRSTHDR(&msghdr);
- cmsg->cmsg_len = msghdr.msg_controllen;
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- int *ifd = (int *)CMSG_DATA(cmsg);
- *ifd = -1;
-
- if(recvmsg(parent_fd, &msghdr, 0) < 0) return(-1);
- return *ifd;
-}
-
-
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-#ifndef FORKWRAPPER_H
-#define FORKWRAPPER_H
-
-// Utility functions for all the forking classes
-
-
-#include <stdint.h>
-
-
-class ForkWrapper
-{
-public:
- ForkWrapper();
- virtual ~ForkWrapper();
-
-// Can't start in the constructor because it'll erase the subclass constructor.
- void start();
-// Called by subclass to send a command to exit the loop
- void stop();
-// Use the fd of another fork already in progress.
-// Used to transfer a parent ForkWrapper from 1 process to another.
- void start_dummy(int parent_fd, int pid);
- void run();
- virtual void init_child();
- virtual int handle_command();
-// return 1 if the child is running
- int child_running();
-// Return 1 if the child is dead
- int read_timeout(unsigned char *data, int size);
-
- int done;
-
-// Called by parent to send commands
- int send_command(int token,
- unsigned char *data,
- int bytes);
-// Called by child to get commands
- int read_command();
-// Called by parent to read result
- int64_t read_result();
-// Called by child to send result
- int send_result(int64_t value, unsigned char *data, int data_size);
-// Called by child to send a file descriptor
- void send_fd(int fd);
-// Called by parent to get a file descriptor
- int get_fd();
-
- int pid;
- int parent_fd;
- int child_fd;
- int is_dummy;
-
- int command_token;
- unsigned char *command_data;
- int command_bytes;
- int command_allocated;
-
-
- unsigned char *result_data;
- int result_bytes;
- int result_allocated;
-};
-
-
-
-#endif
-
-
-
#include "edl.h"
#include "file.inc"
#include "filexml.h"
-#include "fileserver.h"
#include "filesystem.h"
#include "language.h"
#include "langinfo.h"
BatchRenderThread *thread = new BatchRenderThread;
thread->start_rendering(config_path,
batch_path);
- delete MWindow::file_server;
break;
}
#include "errorbox.h"
#include "fileformat.h"
#include "file.h"
-#include "fileserver.h"
#include "filesystem.h"
#include "filexml.h"
#include "format.inc"
ArrayList<PluginServer*>* MWindow::plugindb = 0;
-FileServer* MWindow::file_server = 0;
Commercials* MWindow::commercials = 0;
}
-void MWindow::init_fileserver(Preferences *preferences)
-{
-#ifdef USE_FILEFORK
- if( !file_server && preferences->file_forking ) {
- file_server = new FileServer(preferences);
- file_server->start();
- }
-#endif
-}
-
void MWindow::create_objects(int want_gui,
int want_new,
char *config_path)
// Initialize before too much else is running
// Preferences & theme are required for building MPEG table of contents
- init_fileserver(preferences);
// Default project created here
init_edl();
#include "dvdcreate.inc"
#include "edit.inc"
#include "edl.inc"
-#include "fileserver.inc"
#include "filesystem.inc"
#include "filexml.inc"
#include "framecache.inc"
ChannelDB *channeldb_buz;
ChannelDB *channeldb_v4l2jpeg;
- static FileServer *file_server;
-
// ====================================== plugins ==============================
// Contains file descriptors for all the dlopens
// Initialize shared memory
void init_shm();
- static void init_fileserver(Preferences *preferences);
// Initialize channel DB's for playback
void init_channeldb();
add_subwindow(new BC_Title(x2, y1, _("(must be root)"), MEDIUMFONT, RED));
y += 30;
- file_forking = new PrefsFileForking(this, x, y);
- add_subwindow(file_forking);
- file_forking->check_enable();
- y += 30;
-
ffmpeg_early_probe = new PrefsFFMPEGEarlyProbe(this, x, y);
add_subwindow(ffmpeg_early_probe);
x1 = x + ffmpeg_early_probe->get_w() + 24;
int PrefsTrapSigSEGV::handle_event()
{
perf_prefs->pwindow->thread->preferences->trap_sigsegv = get_value();
- perf_prefs->file_forking->check_enable();
return 1;
}
int PrefsTrapSigINTR::handle_event()
{
perf_prefs->pwindow->thread->preferences->trap_sigintr = get_value();
- perf_prefs->file_forking->check_enable();
- return 1;
-}
-
-
-PrefsFileForking::PrefsFileForking(PerformancePrefs *perf_prefs, int x, int y)
- : BC_CheckBox(x, y,
- perf_prefs->pwindow->thread->preferences->file_forking,
- _("enable/disable file fork"))
-{
- this->perf_prefs = perf_prefs;
-}
-PrefsFileForking::~PrefsFileForking()
-{
-}
-int PrefsFileForking::handle_event()
-{
- perf_prefs->pwindow->thread->preferences->file_forking = get_value();
return 1;
}
-void PrefsFileForking::check_enable()
-{
- Preferences *preferences = perf_prefs->pwindow->thread->preferences;
- if( preferences->trap_sigsegv || preferences->trap_sigintr ) {
- preferences->file_forking = 0;
- update(0, 0);
- disable();
- }
- else if( !preferences->trap_sigsegv && !preferences->trap_sigintr ) {
- enable();
- }
-}
-
PrefsFFMPEGEarlyProbe::PrefsFFMPEGEarlyProbe(PerformancePrefs *perf_prefs, int x, int y)
: BC_CheckBox(x, y,
PrefsRenderFarmNodes *node_list;
FormatTools *brender_tools;
BC_Title *master_rate;
- PrefsFileForking *file_forking;
PrefsFFMPEGEarlyProbe *ffmpeg_early_probe;
PrefsFFMPEGMarkerIndecies *ffmpeg_marker_indecies;
};
PerformancePrefs *perf_prefs;
};
-class PrefsFileForking : public BC_CheckBox
-{
-public:
- PrefsFileForking(PerformancePrefs *perf_prefs, int x, int y);
- ~PrefsFileForking();
-
- int handle_event();
- void check_enable();
-
- PerformancePrefs *perf_prefs;
-};
-
class PrefsFFMPEGEarlyProbe : public BC_CheckBox
{
public:
class PrefsTrapSigINTR;
class PrefsFFMPEGEarlyProbe;
class PrefsFFMPEGMarkerIndecies;
-class PrefsFileForking;
class PrefsRenderFarm;
class PrefsRenderFarmConsolidate;
class PrefsRenderFarmPort;
renderfarm_job_count = 20;
processors = calculate_processors(0);
real_processors = calculate_processors(1);
- file_forking = 0;
ffmpeg_early_probe = 0;
ffmpeg_marker_indecies = 1;
warn_indecies = 1;
trap_sigintr = that->trap_sigintr;
processors = that->processors;
real_processors = that->real_processors;
- file_forking = that->file_forking;
ffmpeg_early_probe = that->ffmpeg_early_probe;
ffmpeg_marker_indecies = that->ffmpeg_marker_indecies;
warn_indecies = that->warn_indecies;
force_uniprocessor = defaults->get("FORCE_UNIPROCESSOR", force_uniprocessor);
- file_forking = defaults->get("FILE_FORKING", file_forking);
ffmpeg_early_probe = defaults->get("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
ffmpeg_marker_indecies = defaults->get("FFMPEG_MARKER_INDECIES", ffmpeg_marker_indecies);
warn_indecies = defaults->get("WARN_INDECIES", warn_indecies);
}
defaults->update("FORCE_UNIPROCESSOR", force_uniprocessor);
- defaults->update("FILE_FORKING", file_forking);
defaults->update("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
defaults->update("FFMPEG_MARKER_INDECIES", ffmpeg_marker_indecies);
defaults->update("WARN_INDECIES", warn_indecies);
int processors;
// Number of processors for interactive operations.
int real_processors;
-// enable/disable filefork
- int file_forking;
// ffmpeg probes early/late during File::open_file read
int ffmpeg_early_probe;
// ffmpeg builds marker indecies as it builds idx files
(*this_aconfig != *aconfig) || (*this_vconfig != *vconfig) ||
!preferences->brender_asset->equivalent(*mwindow->preferences->brender_asset, 0, 1);
- if( preferences->file_forking != mwindow->preferences->file_forking ) {
- MainError::show_error(
- _("Reseting file forking requires restarting cinelerra"));
- }
mwindow->edl->copy_session(edl, 1);
mwindow->preferences->copy_from(preferences);
mwindow->init_brender();
boot_preferences = new Preferences;
boot_preferences->load_defaults(boot_defaults);
MWindow::init_plugins(0, boot_preferences);
- MWindow::init_fileserver(boot_preferences);
}
make $OBJDIR/timebar.o
make $OBJDIR/threadloader.o
make $OBJDIR/threadindexer.o
-make $OBJDIR/threadfork.o
make $OBJDIR/threadexec.o
make $OBJDIR/theme.o
make $OBJDIR/statusbar.o
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "threadfork.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-
-
-int main()
-{
- ThreadFork *test;
- test = new ThreadFork;
- test->start_command("ls", 0);
- delete test;
-}
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "threadfork.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#define MAX_ARGS 32
-
-
-
-
-ThreadFork::ThreadFork()
-{
- pid = 0;
- tid = 0;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutex_init(&start_lock, &attr);
-
-
-
- arguments = new char*[MAX_ARGS];
- total_arguments = 0;
- stdin_fd = 0;
- pipe_stdin = 0;
- command_line = "";
-}
-
-ThreadFork::~ThreadFork()
-{
-// if(pipe_stdin)
-// {
- pclose(stdin_fd);
-// if(stdin_fd) fclose(stdin_fd);
-// close(filedes[0]);
-// close(filedes[1]);
-// }
-
-// pthread_join(tid, 0);
-
- for(int i = 0; i < total_arguments; i++)
- delete [] arguments[i];
-
- pthread_mutex_destroy(&start_lock);
- delete [] arguments;
-}
-
-void* ThreadFork::entrypoint(void *ptr)
-{
- ThreadFork *threadfork = (ThreadFork*)ptr;
- threadfork->run();
- return 0;
-}
-
-void ThreadFork::start_command(const char *command_line, int pipe_stdin)
-{
- this->command_line = command_line;
- this->pipe_stdin = pipe_stdin;
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
-
-
- stdin_fd = popen(command_line, "w");
-
-// pthread_mutex_lock(&start_lock);
-
-
-// pthread_create(&tid, &attr, entrypoint, this);
-// pthread_mutex_lock(&start_lock);
-// pthread_mutex_unlock(&start_lock);
-}
-
-
-void ThreadFork::run()
-{
- char *path_ptr;
- char *ptr;
- char *argument_ptr;
- char argument[BCTEXTLEN];
- char command_line[BCTEXTLEN];
- int new_pid;
-
- strcpy(command_line, this->command_line);
-
-
-
-// Set up arguments for exec
- ptr = command_line;
- path_ptr = path;
- while(*ptr != ' ' && *ptr != 0)
- {
- *path_ptr++ = *ptr++;
- }
- *path_ptr = 0;
-
- arguments[total_arguments] = new char[strlen(path) + 1];
- strcpy(arguments[total_arguments], path);
-
- total_arguments++;
- arguments[total_arguments] = 0;
-
- while(*ptr != 0)
- {
- ptr++;
- argument_ptr = argument;
- while(*ptr != ' ' && *ptr != 0)
- {
- *argument_ptr++ = *ptr++;
- }
- *argument_ptr = 0;
-
- arguments[total_arguments] = new char[strlen(argument) + 1];
- strcpy(arguments[total_arguments], argument);
- total_arguments++;
- arguments[total_arguments] = 0;
- }
-
-
-
-
-
-
-
-
-
-
- if(pipe_stdin)
- {
- (void)pipe(filedes);
- stdin_fd = fdopen(filedes[1], "w");
- }
-
- pthread_mutex_unlock(&start_lock);
-
-
-
- new_pid = vfork();
-
-// Redirect stdin
- if(new_pid == 0)
- {
- if(pipe_stdin) dup2(filedes[0], fileno(stdin));
-
-
-
- execvp(path, arguments);
-
-
-
- perror("execvp");
- _exit(0);
- }
- else
- {
- pid = new_pid;
- pthread_mutex_unlock(&start_lock);
-
- int return_value;
- if(waitpid(pid, &return_value, WUNTRACED) == -1)
- {
- perror("ThreadFork::run: waitpid");
- }
- }
-
-
-}
-
-
-FILE* ThreadFork::get_stdin()
-{
- return stdin_fd;
-}
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-#ifndef THREADFORK_H
-#define THREADFORK_H
-
-
-// Construct command arguments, fork a background process and wait for it.
-
-#include <stdio.h>
-#include <stdint.h>
-#include <pthread.h>
-
-#include "bcwindowbase.inc"
-
-class ThreadFork
-{
-public:
- ThreadFork();
- ~ThreadFork();
-
- FILE* get_stdin();
- void run();
- void start_command(const char *command_line, int pipe_stdin);
-
- static void* entrypoint(void *ptr);
-
-private:
- int filedes[2];
- int pid;
- pthread_t tid;
- char **arguments;
- char path[BCTEXTLEN];
- int total_arguments;
- FILE *stdin_fd;
- pthread_mutex_t start_lock;
- const char *command_line;
- int pipe_stdin;
-};
-
-
-
-
-#endif
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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
- *
- */
-
-#ifndef THREADFORK_INC
-#define THREADFORK_INC
-
-
-
-
-
-class ThreadFork;
-
-
-
-#endif