Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

filethread.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "bcsignals.h"
00003 #include "condition.h"
00004 #include "file.h"
00005 #include "filethread.h"
00006 #include "mutex.h"
00007 #include "vframe.h"
00008 
00009 #include <unistd.h>
00010 
00011 FileThread::FileThread(File *file, int do_audio, int do_video)
00012  : Thread(1, 0, 0)
00013 {
00014         reset();
00015         create_objects(file,
00016                 do_audio,
00017                 do_video);
00018 }
00019 
00020 FileThread::~FileThread()
00021 {
00022         delete_objects();
00023 
00024 
00025 
00026         delete file_lock;
00027 }
00028 
00029 void FileThread::reset()
00030 {
00031         audio_buffer = 0;
00032         video_buffer = 0;
00033         output_size = 0;
00034         input_lock = 0;
00035         output_lock = 0;
00036         last_buffer = 0;
00037 }
00038 
00039 
00040 void FileThread::create_objects(File *file, 
00041                 int do_audio, 
00042                 int do_video)
00043 {
00044         this->file = file;
00045         this->do_audio = do_audio;
00046         this->do_video = do_video;
00047         file_lock = new Mutex("FileThread::file_lock");
00048 }
00049 
00050 
00051 void FileThread::delete_objects()
00052 {
00053         if(output_lock)
00054         {
00055                 for(int i = 0; i < ring_buffers; i++)
00056                 {
00057                         delete output_lock[i];
00058                 }
00059                 delete [] output_lock;
00060         }
00061 
00062         if(input_lock)
00063         {
00064                 for(int i = 0; i < ring_buffers; i++)
00065                 {
00066                         delete input_lock[i];
00067                 }
00068                 delete [] input_lock;
00069         }
00070 
00071 
00072         if(last_buffer)
00073                 delete [] last_buffer;
00074 
00075 
00076         delete [] output_size;
00077 
00078         reset();
00079 }
00080 
00081 void FileThread::run()
00082 {
00083         int done = 0;
00084         int i, j, result;
00085 
00086         while(!done)
00087         {
00088                 output_lock[local_buffer]->lock("FileThread::run 1");
00089                 return_value = 0;
00090 
00091 
00092 // Timer timer;
00093 // timer.update();
00094                 if(!last_buffer[local_buffer])
00095                 {
00096                         if(output_size[local_buffer])
00097                         {
00098                                 file_lock->lock("FileThread::run 2");
00099                                 if(do_audio)
00100                                 {
00101 TRACE("FileThread::run 4");
00102                                         result = file->write_samples(audio_buffer[local_buffer], 
00103                                                 output_size[local_buffer]);
00104 TRACE("FileThread::run 5");
00105                                 }
00106                                 else
00107                                 if(do_video)
00108                                 {
00109                                         result = 0;
00110                                         if(compressed)
00111                                         {
00112                                                 for(j = 0; j < file->asset->layers && !result; j++)
00113                                                         for(i = 0; i < output_size[local_buffer] && !result; i++)
00114                                                                 result = file->write_compressed_frame(video_buffer[local_buffer][j][i]);
00115                                         }
00116                                         else
00117                                         {
00118                                                 result = file->write_frames(video_buffer[local_buffer], 
00119                                                         output_size[local_buffer]);
00120                                         }
00121                                 }
00122 
00123                                 file_lock->unlock();
00124                                 return_value = result;
00125                         }
00126                         else
00127                                 return_value = 0;
00128 
00129                         output_size[local_buffer] = 0;
00130                 }
00131                 else
00132                         done = 1;
00133 
00134                 input_lock[local_buffer]->unlock();
00135                 local_buffer++;
00136                 if(local_buffer >= ring_buffers) local_buffer = 0;
00137         }
00138 }
00139 
00140 
00141 
00142 int FileThread::stop_writing()
00143 {
00144 
00145         int i, buffer, layer, frame;
00146 
00147         swap_buffer();
00148         input_lock[current_buffer]->lock("FileThread::stop_writing 1");
00149 
00150         last_buffer[current_buffer] = 1;
00151 
00152         for(i = 0; i < ring_buffers; i++)
00153                 output_lock[i]->unlock();
00154 
00155         swap_buffer();
00156 
00157 // wait for thread to finish
00158         Thread::join();
00159 
00160 // delete buffers
00161         file_lock->lock("FileThread::stop_writing 2");
00162         if(do_audio)
00163         {
00164                 for(buffer = 0; buffer < ring_buffers; buffer++)
00165                 {
00166                         for(i = 0; i < file->asset->channels; i++)
00167                                 delete [] audio_buffer[buffer][i];
00168                         delete [] audio_buffer[buffer];
00169                 }
00170                 delete [] audio_buffer;
00171                 audio_buffer = 0;
00172         }
00173 
00174 // printf("FileThread::stop_writing %d %d %d %d\n", 
00175 // do_video,
00176 // ring_buffers,
00177 // file->asset->layers,
00178 // buffer_size);
00179         if(do_video)
00180         {
00181                 for(buffer = 0; buffer < ring_buffers; buffer++)
00182                 {
00183                         for(layer = 0; layer < file->asset->layers; layer++)
00184                         {
00185                                 for(frame = 0; frame < buffer_size; frame++)
00186                                 {
00187                                         delete video_buffer[buffer][layer][frame];
00188                                 }
00189                                 delete [] video_buffer[buffer][layer];
00190                         }
00191                         delete [] video_buffer[buffer];
00192                 }
00193                 delete [] video_buffer;
00194                 video_buffer = 0;
00195         }
00196 
00197         file_lock->unlock();
00198         return 0;
00199 }
00200 
00201 int FileThread::start_writing(long buffer_size, 
00202                 int color_model, 
00203                 int ring_buffers, 
00204                 int compressed)
00205 {
00206 // allocate buffers
00207         int buffer, layer, frame;
00208         long bytes_per_frame;
00209 
00210         this->ring_buffers = ring_buffers;
00211         this->buffer_size = buffer_size;
00212         this->color_model = color_model;
00213         this->compressed = compressed;
00214         this->current_buffer = ring_buffers - 1;
00215         return_value = 0;
00216         local_buffer = 0;
00217 
00218         file_lock->lock("FileThread::start_writing 1");
00219 
00220 
00221 
00222 
00223 // Buffer is swapped before first get
00224         last_buffer = new int[ring_buffers];
00225         output_size = new long[ring_buffers];
00226 
00227 
00228         output_lock = new Condition*[ring_buffers];
00229         input_lock = new Condition*[ring_buffers];
00230         for(int i = 0; i < ring_buffers; i++)
00231         {
00232                 output_lock[i] = new Condition(0, "FileThread::output_lock");
00233                 input_lock[i] = new Condition(1, "FileThread::input_lock");
00234                 last_buffer[i] = 0;
00235                 output_size[i] = 0;
00236         }
00237 
00238 
00239 
00240         if(do_audio)
00241         {
00242                 audio_buffer = new double**[ring_buffers];
00243                 for(buffer = 0; buffer < ring_buffers; buffer++)
00244                 {
00245                         audio_buffer[buffer] = new double*[file->asset->channels];
00246 
00247                         for(int channel = 0; channel < file->asset->channels; channel++)
00248                         {
00249                                 audio_buffer[buffer][channel] = new double[buffer_size];
00250                         }
00251                 }
00252         }
00253 
00254         if(do_video)
00255         {
00256                 this->color_model = color_model;
00257                 bytes_per_frame = VFrame::calculate_data_size(file->asset->width,
00258                         file->asset->height,
00259                         -1,
00260                         color_model);
00261 
00262                 video_buffer = new VFrame***[ring_buffers];
00263 // printf("FileThread::start_writing 1 %d %d %d %p\n", 
00264 // ring_buffers,
00265 // file->asset->layers,
00266 // buffer_size,
00267 // video_buffer);
00268                 for(buffer = 0; buffer < ring_buffers; buffer++)
00269                 {
00270                         video_buffer[buffer] = new VFrame**[file->asset->layers];
00271                         for(layer = 0; layer < file->asset->layers; layer++)
00272                         {
00273                                 video_buffer[buffer][layer] = new VFrame*[buffer_size];
00274                                 for(frame = 0; frame < buffer_size; frame++)
00275                                 {
00276                                         if(compressed)
00277                                                 video_buffer[buffer][layer][frame] = new VFrame;
00278                                         else
00279                                         {
00280                                                 video_buffer[buffer][layer][frame] = 
00281                                                         new VFrame(0, 
00282                                                                 file->asset->width, 
00283                                                                 file->asset->height, 
00284                                                                 color_model);
00285 // printf("FileThread::start_writing 4 %d %d %d %p\n", 
00286 // buffer, 
00287 // layer, 
00288 // frame, 
00289 // video_buffer[buffer][layer]);
00290                                         }
00291                                 }
00292                         }
00293                 }
00294         }
00295         file_lock->unlock();
00296 
00297         for(int i = 0; i < ring_buffers; i++)
00298         {
00299                 last_buffer[i] = 0;
00300         }
00301 
00302 
00303         start();
00304         return 0;
00305 }
00306 
00307 double** FileThread::get_audio_buffer()
00308 {
00309         swap_buffer();
00310 
00311         input_lock[current_buffer]->lock("FileThread::get_audio_buffer");
00312         return audio_buffer[current_buffer];
00313 }
00314 
00315 VFrame*** FileThread::get_video_buffer()
00316 {
00317         swap_buffer();
00318 
00319         input_lock[current_buffer]->lock("FileThread::get_video_buffer");
00320         return video_buffer[current_buffer];
00321 }
00322 
00323 int FileThread::write_buffer(long size)
00324 {
00325         output_size[current_buffer] = size;
00326 
00327 // unlock the output lock
00328         output_lock[current_buffer]->unlock();
00329 
00330         return return_value;
00331 }
00332 
00333 int FileThread::swap_buffer()
00334 {
00335         current_buffer++;
00336         if(current_buffer >= ring_buffers) current_buffer = 0;
00337 }

Generated on Sun Jan 8 13:38:55 2006 for Cinelerra-svn by  doxygen 1.4.4