6 #include "interlacemodes.h"
10 #include "renderfarmfsserver.inc"
12 #include "mainerror.h"
22 FileList::FileList(Asset *asset,
28 : FileBase(asset, file)
31 asset->video_data = 1;
32 this->list_prefix = list_prefix;
33 this->file_extension = file_extension;
34 this->frame_type = frame_type;
35 this->list_type = list_type;
36 table_lock = new Mutex("FileList::table_lock");
45 int FileList::reset_parameters_derived()
53 int FileList::open_file(int rd, int wr)
59 // skip header for write
62 // Frame files are created in write_frame and list index is created when
64 // Look for the starting number in the path but ignore the starting character
65 // and total digits since these are used by the header.
66 Render::get_starting_number(asset->path,
70 path_list.remove_all_objects();
71 writer = new FrameWriter(this,
72 asset->format == list_type ? file->cpus : 1);
77 // Determine type of file.
78 // Header isn't used for background rendering, in which case everything known
79 // by the file encoder is known by the decoder.
80 //printf("FileList::open_file 1 %d\n", asset->use_header);
83 FILE *stream = fopen(asset->path, "rb");
86 char string[BCTEXTLEN];
87 fread(string, strlen(list_prefix), 1, stream);
90 if(!strncasecmp(string, list_prefix, strlen(list_prefix)))
93 asset->format = list_type;
95 // Open index here or get frame size from file.
96 result = read_list_header();
97 if(!result) result = read_frame_header(path_list.values[0]);
101 //printf("FileList::open_file 2\n", asset->use_header);
102 asset->format = frame_type;
103 result = read_frame_header(asset->path);
105 if(!asset->frame_rate)
106 asset->frame_rate = 1;
107 asset->video_length = -1;
113 Render::get_starting_number(asset->path,
121 file->current_frame = 0;
122 // Compressed data storage
129 int FileList::close_file()
131 // path_list.total, asset->format, list_type, wr);
132 if(asset->format == list_type && path_list.total)
134 if(wr && asset->use_header) write_list_header();
135 path_list.remove_all_objects();
137 if(data) delete data;
138 if(writer) delete writer;
139 if(temp) delete temp;
142 FileBase::close_file();
146 int FileList::write_list_header()
148 FILE *stream = fopen(asset->path, "w");
149 // Use sprintf instead of fprintf for VFS.
150 char string[BCTEXTLEN];
151 sprintf(string, "%s\n", list_prefix);
152 fwrite(string, strlen(string), 1, stream);
153 sprintf(string, "# First line is always %s\n", list_prefix);
154 fwrite(string, strlen(string), 1, stream);
155 sprintf(string, "# Frame rate:\n");
156 fwrite(string, strlen(string), 1, stream);
157 sprintf(string, "%f\n", asset->frame_rate);
158 fwrite(string, strlen(string), 1, stream);
159 sprintf(string, "# Width:\n");
160 fwrite(string, strlen(string), 1, stream);
161 sprintf(string, "%d\n", asset->width);
162 fwrite(string, strlen(string), 1, stream);
163 sprintf(string, "# Height:\n");
164 fwrite(string, strlen(string), 1, stream);
165 sprintf(string, "%d\n", asset->height);
166 fwrite(string, strlen(string), 1, stream);
167 sprintf(string, "# List of image files follows\n");
168 fwrite(string, strlen(string), 1, stream);
170 for(int i = 0; i < path_list.total; i++)
172 // Fix path for VFS but leave leading slash
173 if(!strncmp(path_list.values[i], RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
174 sprintf(string, "%s\n", path_list.values[i] + strlen(RENDERFARM_FS_PREFIX));
176 sprintf(string, "%s\n", path_list.values[i]);
177 fwrite(string, strlen(string), 1, stream);
183 int FileList::read_list_header()
185 char string[BCTEXTLEN], *new_entry;
187 FILE *stream = fopen(asset->path, "r");
192 // Get information about the frames
195 fgets(string, BCTEXTLEN, stream);
196 }while(!feof(stream) && (string[0] == '#' || string[0] == ' ' || isalpha(string[0])));
198 // Don't want a user configured frame rate to get destroyed
199 if(asset->frame_rate == 0)
200 asset->frame_rate = atof(string);
204 fgets(string, BCTEXTLEN, stream);
205 }while(!feof(stream) && (string[0] == '#' || string[0] == ' '));
206 asset->width = atol(string);
210 fgets(string, BCTEXTLEN, stream);
211 }while(!feof(stream) && (string[0] == '#' || string[0] == ' '));
212 asset->height = atol(string);
214 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // May be good to store the info in the list?
216 asset->audio_data = 0;
217 asset->video_data = 1;
222 fgets(string, BCTEXTLEN, stream);
223 if(strlen(string) && string[0] != '#' && string[0] != ' ' && !feof(stream))
225 string[strlen(string) - 1] = 0;
226 path_list.append(new_entry = new char[strlen(string) + 1]);
227 strcpy(new_entry, string);
231 //for(int i = 0; i < path_list.total; i++) printf("%s\n", path_list.values[i]);
233 asset->video_length = path_list.total;
241 int FileList::read_frame(VFrame *frame)
244 if(file->current_frame < 0 ||
245 (asset->use_header && file->current_frame >= path_list.total &&
246 asset->format == list_type))
249 if(asset->format == list_type)
251 char string[BCTEXTLEN];
253 if(asset->use_header)
255 path = path_list.values[file->current_frame];
259 path = calculate_path(file->current_frame, string);
265 if(!strncmp(asset->path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
266 sprintf(string, "%s%s", RENDERFARM_FS_PREFIX, path);
268 strcpy(string, path);
270 if(!(in = fopen(string, "rb")))
272 eprintf("Error while opening \"%s\" for reading. \n%m\n", string);
277 stat(string, &ostat);
279 switch(frame->get_color_model())
282 frame->allocate_compressed_data(ostat.st_size);
283 frame->set_compressed_size(ostat.st_size);
284 fread(frame->get_data(), ostat.st_size, 1, in);
287 data->allocate_compressed_data(ostat.st_size);
288 data->set_compressed_size(ostat.st_size);
289 fread(data->get_data(), ostat.st_size, 1, in);
290 result = read_frame(frame, data);
300 // Allocate and decompress once into temporary
301 //printf("FileList::read_frame %d\n", frame->get_color_model());
302 if(!temp || temp->get_color_model() != frame->get_color_model())
304 if(temp) delete temp;
307 FILE *fd = fopen(asset->path, "rb");
311 stat(asset->path, &ostat);
313 switch(frame->get_color_model())
316 frame->allocate_compressed_data(ostat.st_size);
317 frame->set_compressed_size(ostat.st_size);
318 fread(frame->get_data(), ostat.st_size, 1, fd);
321 data->allocate_compressed_data(ostat.st_size);
322 data->set_compressed_size(ostat.st_size);
323 fread(data->get_data(), ostat.st_size, 1, fd);
327 frame->get_color_model());
328 read_frame(temp, data);
336 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
341 if(!temp) return result;
343 // printf("FileList::read_frame frame=%d temp=%d\n",
344 // frame->get_color_model(),
345 // temp->get_color_model());
346 if(frame->get_color_model() == temp->get_color_model())
348 frame->copy_from(temp);
353 cmodel_transfer(frame->get_rows(), /* Leave NULL if non existent */
355 frame->get_y(), /* Leave NULL if non existent */
358 temp->get_y(), /* Leave NULL if non existent */
361 0, /* Dimensions to capture from input frame */
365 0, /* Dimensions to project on output frame */
369 temp->get_color_model(),
370 frame->get_color_model(),
371 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
372 temp->get_w(), /* For planar use the luma rowspan */
378 //printf("FileList::read_frame 5 %d\n", result);
384 int FileList::write_frames(VFrame ***frames, int len)
388 //printf("FileList::write_frames 1\n");
389 if(frames[0][0]->get_color_model() == BC_COMPRESSED)
391 for(int i = 0; i < asset->layers && !return_value; i++)
393 for(int j = 0; j < len && !return_value; j++)
395 VFrame *frame = frames[i][j];
396 char *path = create_path(frame->get_number());
398 FILE *fd = fopen(path, "wb");
401 return_value = !fwrite(frames[i][j]->get_data(),
402 frames[i][j]->get_compressed_size(),
410 eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
418 //printf("FileList::write_frames 2\n");
419 writer->write_frames(frames, len);
420 //printf("FileList::write_frames 100\n");
433 void FileList::add_return_value(int amount)
435 table_lock->lock("FileList::add_return_value");
436 return_value += amount;
437 table_lock->unlock();
440 char* FileList::calculate_path(int number, char *string)
442 // Synthesize filename.
443 // If a header is used, the filename number must be in a different location.
444 if(asset->use_header)
447 strcpy(string, asset->path);
448 for(k = strlen(string) - 1; k > 0 && string[k] != '.'; k--)
450 if(k <= 0) k = strlen(string);
452 sprintf(&string[k], "%06d%s",
457 // Without a header, the original filename can be altered.
459 Render::create_filename(string,
469 char* FileList::create_path(int number_override)
471 if(asset->format != list_type) return asset->path;
473 table_lock->lock("FileList::create_path");
478 char output[BCTEXTLEN];
479 if(file->current_frame >= path_list.total || !asset->use_header)
482 if(number_override < 0)
483 number = file->current_frame++;
486 number = number_override;
487 file->current_frame++;
490 if(!asset->use_header)
492 number += first_number;
495 calculate_path(number, output);
497 path = new char[strlen(output) + 1];
498 strcpy(path, output);
499 path_list.append(path);
503 // Overwrite an old path
504 path = path_list.values[file->current_frame];
508 table_lock->unlock();
513 FrameWriterUnit* FileList::new_writer_unit(FrameWriter *writer)
515 return new FrameWriterUnit(writer);
518 int64_t FileList::get_memory_usage()
521 if(data) result += data->get_compressed_allocated();
522 if(temp) result += temp->get_data_size();
526 int FileList::get_units()
528 if(writer) return writer->get_total_clients();
532 FrameWriterUnit* FileList::get_unit(int number)
534 if(writer) return (FrameWriterUnit*)writer->get_client(number);
543 FrameWriterPackage::FrameWriterPackage()
547 FrameWriterPackage::~FrameWriterPackage()
561 FrameWriterUnit::FrameWriterUnit(FrameWriter *server)
564 // Don't use server here since subclasses call this with no server.
565 this->server = server;
569 FrameWriterUnit::~FrameWriterUnit()
574 void FrameWriterUnit::process_package(LoadPackage *package)
576 //printf("FrameWriterUnit::process_package 1\n");
577 FrameWriterPackage *ptr = (FrameWriterPackage*)package;
581 //printf("FrameWriterUnit::process_package 2 %s\n", ptr->path);
582 if(!(file = fopen(ptr->path, "wb")))
584 eprintf("Error while opening \"%s\" for writing. \n%m\n", ptr->path);
587 //printf("FrameWriterUnit::process_package 3");
590 int result = server->file->write_frame(ptr->input, output, this);
592 //printf("FrameWriterUnit::process_package 4 %s %d\n", ptr->path, output->get_compressed_size());
593 if(!result) result = !fwrite(output->get_data(), output->get_compressed_size(), 1, file);
594 //TRACE("FrameWriterUnit::process_package 4");
596 //TRACE("FrameWriterUnit::process_package 5");
598 server->file->add_return_value(result);
599 //TRACE("FrameWriterUnit::process_package 6");
612 FrameWriter::FrameWriter(FileList *file, int cpus)
613 : LoadServer(cpus, 0)
619 FrameWriter::~FrameWriter()
623 void FrameWriter::init_packages()
625 for(int i = 0, layer = 0, number = 0;
626 i < get_total_packages();
629 FrameWriterPackage *package = (FrameWriterPackage*)get_package(i);
630 package->input = frames[layer][number];
631 package->path = file->create_path(package->input->get_number());
632 // printf("FrameWriter::init_packages 1 %p %d %s\n",
634 // package->input->get_number(),
645 void FrameWriter::write_frames(VFrame ***frames, int len)
647 this->frames = frames;
649 set_package_count(len * file->asset->layers);
654 LoadClient* FrameWriter::new_client()
656 return file->new_writer_unit(this);
659 LoadPackage* FrameWriter::new_package()
661 return new FrameWriterPackage;