• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files

hvirtual/cinelerra/asset.C

Go to the documentation of this file.
00001 
00002 #include "asset.h"
00003 #include "assets.h"
00004 #include "bchash.h"
00005 #include "bcsignals.h"
00006 #include "clip.h"
00007 #include "edl.h"
00008 #include "file.h"
00009 #include "filesystem.h"
00010 #include "filexml.h"
00011 #include "quicktime.h"
00012 #include "interlacemodes.h"
00013 
00014 
00015 #include <stdio.h>
00016 #include <string.h>
00017 
00018 
00019 Asset::Asset()
00020  : ListItem<Asset>(), GarbageObject("Asset")
00021 {
00022         init_values();
00023 }
00024 
00025 Asset::Asset(Asset &asset)
00026  : ListItem<Asset>(), GarbageObject("Asset")
00027 {
00028         init_values();
00029         *this = asset;
00030 }
00031 
00032 Asset::Asset(const char *path)
00033  : ListItem<Asset>(), GarbageObject("Asset")
00034 {
00035         init_values();
00036         strcpy(this->path, path);
00037 }
00038 
00039 Asset::Asset(const int plugin_type, const char *plugin_title)
00040  : ListItem<Asset>(), GarbageObject("Asset")
00041 {
00042         init_values();
00043 }
00044 
00045 Asset::~Asset()
00046 {
00047         delete [] index_offsets;
00048         delete [] index_sizes;
00049 // Don't delete index buffer since it is shared with the index thread.
00050 }
00051 
00052 
00053 int Asset::init_values()
00054 {
00055         path[0] = 0;
00056         strcpy(folder, MEDIA_FOLDER);
00057 //      format = FILE_MOV;
00058 // Has to be unknown for file probing to succeed
00059         format = FILE_UNKNOWN;
00060         channels = 0;
00061         sample_rate = 0;
00062         bits = 0;
00063         byte_order = 0;
00064         signed_ = 0;
00065         header = 0;
00066         dither = 0;
00067         audio_data = 0;
00068         video_data = 0;
00069         audio_length = 0;
00070         video_length = 0;
00071 
00072         layers = 0;
00073         frame_rate = 0;
00074         width = 0;
00075         height = 0;
00076         strcpy(vcodec, QUICKTIME_YUV2);
00077         strcpy(acodec, QUICKTIME_TWOS);
00078         jpeg_quality = 100;
00079         aspect_ratio = -1;
00080         interlace_autofixoption = BC_ILACE_AUTOFIXOPTION_AUTO;
00081         interlace_mode = BC_ILACE_MODE_UNDETECTED;
00082         interlace_fixmethod = BC_ILACE_FIXMETHOD_NONE;
00083 
00084         ampeg_bitrate = 256;
00085         ampeg_derivative = 3;
00086 
00087         vorbis_vbr = 0;
00088         vorbis_min_bitrate = -1;
00089         vorbis_bitrate = 128000;
00090         vorbis_max_bitrate = -1;
00091 
00092         theora_fix_bitrate = 1;
00093         theora_bitrate = 860000;
00094         theora_quality = 16;
00095         theora_sharpness = 2;
00096         theora_keyframe_frequency = 64;
00097         theora_keyframe_force_frequency = 64;
00098 
00099         mp3_bitrate = 256000;
00100 
00101 
00102         mp4a_bitrate = 256000;
00103         mp4a_quantqual = 100;
00104 
00105 
00106 
00107 // mpeg parameters
00108         vmpeg_iframe_distance = 45;
00109         vmpeg_pframe_distance = 0;
00110         vmpeg_progressive = 0;
00111         vmpeg_denoise = 1;
00112         vmpeg_bitrate = 1000000;
00113         vmpeg_derivative = 1;
00114         vmpeg_quantization = 15;
00115         vmpeg_cmodel = 0;
00116         vmpeg_fix_bitrate = 0;
00117         vmpeg_seq_codes = 0;
00118         vmpeg_preset = 0;
00119         vmpeg_field_order = 0;
00120 
00121 // Divx parameters.  BC_Hash from encore2
00122         divx_bitrate = 2000000;
00123         divx_rc_period = 50;
00124         divx_rc_reaction_ratio = 45;
00125         divx_rc_reaction_period = 10;
00126         divx_max_key_interval = 250;
00127         divx_max_quantizer = 31;
00128         divx_min_quantizer = 1;
00129         divx_quantizer = 5;
00130         divx_quality = 5;
00131         divx_fix_bitrate = 1;
00132         divx_use_deblocking = 1;
00133 
00134         h264_bitrate = 2000000;
00135         h264_quantizer = 5;
00136         h264_fix_bitrate = 0;
00137 
00138         ms_bitrate = 1000000;
00139         ms_bitrate_tolerance = 500000;
00140         ms_quantization = 10;
00141         ms_interlaced = 0;
00142         ms_gop_size = 45;
00143         ms_fix_bitrate = 1;
00144 
00145         ac3_bitrate = 128;
00146 
00147         png_use_alpha = 0;
00148         exr_use_alpha = 0;
00149         exr_compression = 0;
00150 
00151         tiff_cmodel = 0;
00152         tiff_compression = 0;
00153 
00154         use_header = 1;
00155 
00156 
00157         reset_index();
00158         id = EDL::next_id();
00159 
00160         pipe[0] = 0;
00161         use_pipe = 0;
00162 
00163         reset_timecode();
00164 
00165         return 0;
00166 }
00167 
00168 int Asset::reset_index()
00169 {
00170         index_status = INDEX_NOTTESTED;
00171         index_start = old_index_end = index_end = 0;
00172         index_offsets = 0;
00173         index_sizes = 0;
00174         index_zoom = 0;
00175         index_bytes = 0;
00176         index_buffer = 0;
00177         return 0;
00178 }
00179 
00180 int Asset::reset_timecode()
00181 {
00182         strcpy(reel_name, "cin0000");
00183         reel_number = 0;
00184         tcstart = 0;
00185         tcend = 0;
00186         tcformat = 0;
00187         
00188         return 0;
00189 }
00190 
00191 void Asset::copy_from(Asset *asset, int do_index)
00192 {
00193         copy_location(asset);
00194         copy_format(asset, do_index);
00195 }
00196 
00197 void Asset::copy_location(Asset *asset)
00198 {
00199         strcpy(this->path, asset->path);
00200         strcpy(this->folder, asset->folder);
00201 }
00202 
00203 void Asset::copy_format(Asset *asset, int do_index)
00204 {
00205         if(do_index) update_index(asset);
00206 
00207         audio_data = asset->audio_data;
00208         format = asset->format;
00209         channels = asset->channels;
00210         sample_rate = asset->sample_rate;
00211         bits = asset->bits;
00212         byte_order = asset->byte_order;
00213         signed_ = asset->signed_;
00214         header = asset->header;
00215         dither = asset->dither;
00216         mp3_bitrate = asset->mp3_bitrate;
00217         mp4a_bitrate = asset->mp4a_bitrate;
00218         mp4a_quantqual = asset->mp4a_quantqual;
00219         use_header = asset->use_header;
00220         aspect_ratio = asset->aspect_ratio;
00221         interlace_autofixoption = asset->interlace_autofixoption;
00222         interlace_mode = asset->interlace_mode;
00223         interlace_fixmethod = asset->interlace_fixmethod;
00224 
00225         video_data = asset->video_data;
00226         layers = asset->layers;
00227         frame_rate = asset->frame_rate;
00228         width = asset->width;
00229         height = asset->height;
00230         strcpy(vcodec, asset->vcodec);
00231         strcpy(acodec, asset->acodec);
00232 
00233         this->audio_length = asset->audio_length;
00234         this->video_length = asset->video_length;
00235 
00236 
00237         ampeg_bitrate = asset->ampeg_bitrate;
00238         ampeg_derivative = asset->ampeg_derivative;
00239 
00240 
00241         vorbis_vbr = asset->vorbis_vbr;
00242         vorbis_min_bitrate = asset->vorbis_min_bitrate;
00243         vorbis_bitrate = asset->vorbis_bitrate;
00244         vorbis_max_bitrate = asset->vorbis_max_bitrate;
00245 
00246         
00247         theora_fix_bitrate = asset->theora_fix_bitrate;
00248         theora_bitrate = asset->theora_bitrate;
00249         theora_quality = asset->theora_quality;
00250         theora_sharpness = asset->theora_sharpness;
00251         theora_keyframe_frequency = asset->theora_keyframe_frequency;
00252         theora_keyframe_force_frequency = asset->theora_keyframe_frequency;
00253 
00254 
00255         jpeg_quality = asset->jpeg_quality;
00256 
00257 // mpeg parameters
00258         vmpeg_iframe_distance = asset->vmpeg_iframe_distance;
00259         vmpeg_pframe_distance = asset->vmpeg_pframe_distance;
00260         vmpeg_progressive = asset->vmpeg_progressive;
00261         vmpeg_denoise = asset->vmpeg_denoise;
00262         vmpeg_bitrate = asset->vmpeg_bitrate;
00263         vmpeg_derivative = asset->vmpeg_derivative;
00264         vmpeg_quantization = asset->vmpeg_quantization;
00265         vmpeg_cmodel = asset->vmpeg_cmodel;
00266         vmpeg_fix_bitrate = asset->vmpeg_fix_bitrate;
00267         vmpeg_seq_codes = asset->vmpeg_seq_codes;
00268         vmpeg_preset = asset->vmpeg_preset;
00269         vmpeg_field_order = asset->vmpeg_field_order;
00270 
00271 
00272         divx_bitrate = asset->divx_bitrate;
00273         divx_rc_period = asset->divx_rc_period;
00274         divx_rc_reaction_ratio = asset->divx_rc_reaction_ratio;
00275         divx_rc_reaction_period = asset->divx_rc_reaction_period;
00276         divx_max_key_interval = asset->divx_max_key_interval;
00277         divx_max_quantizer = asset->divx_max_quantizer;
00278         divx_min_quantizer = asset->divx_min_quantizer;
00279         divx_quantizer = asset->divx_quantizer;
00280         divx_quality = asset->divx_quality;
00281         divx_fix_bitrate = asset->divx_fix_bitrate;
00282         divx_use_deblocking = asset->divx_use_deblocking;
00283 
00284         h264_bitrate = asset->h264_bitrate;
00285         h264_quantizer = asset->h264_quantizer;
00286         h264_fix_bitrate = asset->h264_fix_bitrate;
00287 
00288 
00289         ms_bitrate = asset->ms_bitrate;
00290         ms_bitrate_tolerance = asset->ms_bitrate_tolerance;
00291         ms_interlaced = asset->ms_interlaced;
00292         ms_quantization = asset->ms_quantization;
00293         ms_gop_size = asset->ms_gop_size;
00294         ms_fix_bitrate = asset->ms_fix_bitrate;
00295 
00296         
00297         ac3_bitrate = asset->ac3_bitrate;
00298         
00299         png_use_alpha = asset->png_use_alpha;
00300         exr_use_alpha = asset->exr_use_alpha;
00301         exr_compression = asset->exr_compression;
00302 
00303         tiff_cmodel = asset->tiff_cmodel;
00304         tiff_compression = asset->tiff_compression;
00305 
00306         strcpy(pipe, asset->pipe);
00307         use_pipe = asset->use_pipe;
00308 
00309         strcpy(reel_name, asset->reel_name);
00310         reel_number = asset->reel_number;
00311         tcstart = asset->tcstart;
00312         tcend = asset->tcend;
00313         tcformat = asset->tcformat;
00314 }
00315 
00316 int64_t Asset::get_index_offset(int channel)
00317 {
00318         if(channel < channels && index_offsets)
00319                 return index_offsets[channel];
00320         else
00321                 return 0;
00322 }
00323 
00324 int64_t Asset::get_index_size(int channel)
00325 {
00326         if(channel < channels && index_sizes)
00327                 return index_sizes[channel];
00328         else
00329                 return 0;
00330 }
00331 
00332 
00333 char* Asset::get_compression_text(int audio, int video)
00334 {
00335         if(audio)
00336         {
00337                 switch(format)
00338                 {
00339                         case FILE_MOV:
00340                         case FILE_AVI:
00341                                 if(acodec[0])
00342                                         return quicktime_acodec_title(acodec);
00343                                 else
00344                                         return 0;
00345                                 break;
00346                 }
00347         }
00348         else
00349         if(video)
00350         {
00351                 switch(format)
00352                 {
00353                         case FILE_MOV:
00354                         case FILE_AVI:
00355                                 if(vcodec[0])
00356                                         return quicktime_vcodec_title(vcodec);
00357                                 else
00358                                         return 0;
00359                                 break;
00360                 }
00361         }
00362         return 0;
00363 }
00364 
00365 Asset& Asset::operator=(Asset &asset)
00366 {
00367         copy_location(&asset);
00368         copy_format(&asset, 1);
00369         return *this;
00370 }
00371 
00372 
00373 int Asset::equivalent(Asset &asset, 
00374         int test_audio, 
00375         int test_video)
00376 {
00377         int result = (!strcmp(asset.path, path) &&
00378                 format == asset.format);
00379 
00380         if(test_audio && result)
00381         {
00382                 result = (channels == asset.channels && 
00383                         sample_rate == asset.sample_rate && 
00384                         bits == asset.bits && 
00385                         byte_order == asset.byte_order && 
00386                         signed_ == asset.signed_ && 
00387                         header == asset.header && 
00388                         dither == asset.dither &&
00389                         !strcmp(acodec, asset.acodec));
00390         }
00391 
00392 
00393         if(test_video && result)
00394         {
00395                 result = (layers == asset.layers && 
00396                         frame_rate == asset.frame_rate &&
00397                         asset.interlace_autofixoption == interlace_autofixoption &&
00398                         asset.interlace_mode    == interlace_mode &&
00399                         interlace_fixmethod     == asset.interlace_fixmethod &&
00400                         width == asset.width &&
00401                         height == asset.height &&
00402                         !strcmp(vcodec, asset.vcodec) &&
00403                         strcmp(reel_name, asset.reel_name) == 0 &&
00404                         reel_number == asset.reel_number &&
00405                         tcstart == asset.tcstart &&
00406                         tcend == asset.tcend &&
00407                         tcformat == asset.tcformat);
00408         }
00409 
00410         return result;
00411 }
00412 
00413 int Asset::operator==(Asset &asset)
00414 {
00415 
00416         return equivalent(asset, 
00417                 1, 
00418                 1);
00419 }
00420 
00421 int Asset::operator!=(Asset &asset)
00422 {
00423         return !(*this == asset);
00424 }
00425 
00426 int Asset::test_path(const char *path)
00427 {
00428         if(!strcasecmp(this->path, path)) 
00429                 return 1; 
00430         else 
00431                 return 0;
00432 }
00433 
00434 int Asset::test_plugin_title(const char *path)
00435 {
00436 }
00437 
00438 int Asset::read(FileXML *file, 
00439         int expand_relative)
00440 {
00441         int result = 0;
00442 
00443 // Check for relative path.
00444         if(expand_relative)
00445         {
00446                 char new_path[BCTEXTLEN];
00447                 char asset_directory[BCTEXTLEN];
00448                 char input_directory[BCTEXTLEN];
00449                 FileSystem fs;
00450 
00451                 strcpy(new_path, path);
00452                 fs.set_current_dir("");
00453 
00454                 fs.extract_dir(asset_directory, path);
00455 
00456 // No path in asset.
00457 // Take path of XML file.
00458                 if(!asset_directory[0])
00459                 {
00460                         fs.extract_dir(input_directory, file->filename);
00461 
00462 // Input file has a path
00463                         if(input_directory[0])
00464                         {
00465                                 fs.join_names(path, input_directory, new_path);
00466                         }
00467                 }
00468         }
00469 
00470 
00471         while(!result)
00472         {
00473                 result = file->read_tag();
00474                 if(!result)
00475                 {
00476                         if(file->tag.title_is("/ASSET"))
00477                         {
00478                                 result = 1;
00479                         }
00480                         else
00481                         if(file->tag.title_is("AUDIO"))
00482                         {
00483                                 read_audio(file);
00484                         }
00485                         else
00486                         if(file->tag.title_is("AUDIO_OMIT"))
00487                         {
00488                                 read_audio(file);
00489                         }
00490                         else
00491                         if(file->tag.title_is("FORMAT"))
00492                         {
00493                                 char *string = file->tag.get_property("TYPE");
00494                                 format = File::strtoformat(string);
00495                                 use_header = 
00496                                         file->tag.get_property("USE_HEADER", use_header);
00497                         }
00498                         else
00499                         if(file->tag.title_is("FOLDER"))
00500                         {
00501                                 strcpy(folder, file->read_text());
00502                         }
00503                         else
00504                         if(file->tag.title_is("VIDEO"))
00505                         {
00506                                 read_video(file);
00507                         }
00508                         else
00509                         if(file->tag.title_is("VIDEO_OMIT"))
00510                         {
00511                                 read_video(file);
00512                         }
00513                         else
00514                         if(file->tag.title_is("INDEX"))
00515                         {
00516                                 read_index(file);
00517                         }
00518                 }
00519         }
00520 
00521 //printf("Asset::read 2\n");
00522         return 0;
00523 }
00524 
00525 int Asset::read_audio(FileXML *file)
00526 {
00527         if(file->tag.title_is("AUDIO")) audio_data = 1;
00528         channels = file->tag.get_property("CHANNELS", 2);
00529 // This is loaded from the index file after the EDL but this 
00530 // should be overridable in the EDL.
00531         if(!sample_rate) sample_rate = file->tag.get_property("RATE", 44100);
00532         bits = file->tag.get_property("BITS", 16);
00533         byte_order = file->tag.get_property("BYTE_ORDER", 1);
00534         signed_ = file->tag.get_property("SIGNED", 1);
00535         header = file->tag.get_property("HEADER", 0);
00536         dither = file->tag.get_property("DITHER", 0);
00537 
00538         audio_length = file->tag.get_property("AUDIO_LENGTH", 0);
00539         acodec[0] = 0;
00540         file->tag.get_property("ACODEC", acodec);
00541         
00542 
00543 
00544 //      ampeg_bitrate = file->tag.get_property("AMPEG_BITRATE", ampeg_bitrate);
00545 //      ampeg_derivative = file->tag.get_property("AMPEG_DERIVATIVE", ampeg_derivative);
00546 // 
00547 //      vorbis_vbr = file->tag.get_property("VORBIS_VBR", vorbis_vbr);
00548 //      vorbis_min_bitrate = file->tag.get_property("VORBIS_MIN_BITRATE", vorbis_min_bitrate);
00549 //      vorbis_bitrate = file->tag.get_property("VORBIS_BITRATE", vorbis_bitrate);
00550 //      vorbis_max_bitrate = file->tag.get_property("VORBIS_MAX_BITRATE", vorbis_max_bitrate);
00551 // 
00552 //      mp3_bitrate = file->tag.get_property("MP3_BITRATE", mp3_bitrate);
00553 
00554         if(!video_data)
00555         {
00556                 tcstart = 0;
00557                 tcend = audio_length;
00558                 tcformat = 0;
00559         }
00560 
00561         return 0;
00562 }
00563 
00564 int Asset::read_video(FileXML *file)
00565 {
00566         char string[BCTEXTLEN];
00567 
00568         if(file->tag.title_is("VIDEO")) video_data = 1;
00569         height = file->tag.get_property("HEIGHT", height);
00570         width = file->tag.get_property("WIDTH", width);
00571         layers = file->tag.get_property("LAYERS", layers);
00572 // This is loaded from the index file after the EDL but this 
00573 // should be overridable in the EDL.
00574         if(!frame_rate) frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
00575         vcodec[0] = 0;
00576         file->tag.get_property("VCODEC", vcodec);
00577 
00578         video_length = file->tag.get_property("VIDEO_LENGTH", 0);
00579 
00580         interlace_autofixoption = file->tag.get_property("INTERLACE_AUTOFIX",0);
00581 
00582         ilacemode_to_xmltext(string, BC_ILACE_MODE_NOTINTERLACED);
00583         interlace_mode = ilacemode_from_xmltext(file->tag.get_property("INTERLACE_MODE",string), BC_ILACE_MODE_NOTINTERLACED);
00584 
00585         ilacefixmethod_to_xmltext(string, BC_ILACE_FIXMETHOD_NONE);
00586         interlace_fixmethod = ilacefixmethod_from_xmltext(file->tag.get_property("INTERLACE_FIXMETHOD",string), BC_ILACE_FIXMETHOD_NONE);
00587 
00588         file->tag.get_property("REEL_NAME", reel_name);
00589         reel_number = file->tag.get_property("REEL_NUMBER", reel_number);
00590         tcstart = file->tag.get_property("TCSTART", tcstart);
00591         tcend = file->tag.get_property("TCEND", tcend);
00592         tcformat = file->tag.get_property("TCFORMAT", tcformat);
00593 
00594         return 0;
00595 }
00596 
00597 int Asset::read_index(FileXML *file)
00598 {
00599         delete [] index_offsets;
00600         index_offsets = new int64_t[channels];
00601         delete [] index_sizes;
00602         index_sizes = new int64_t[channels];
00603         for(int i = 0; i < channels; i++) 
00604         {
00605                 index_offsets[i] = 0;
00606                 index_sizes[i] = 0;
00607         }
00608 
00609         int current_offset = 0;
00610         int current_size = 0;
00611         int result = 0;
00612 
00613         index_zoom = file->tag.get_property("ZOOM", 1);
00614         index_bytes = file->tag.get_property("BYTES", (int64_t)0);
00615 
00616         while(!result)
00617         {
00618                 result = file->read_tag();
00619                 if(!result)
00620                 {
00621                         if(file->tag.title_is("/INDEX"))
00622                         {
00623                                 result = 1;
00624                         }
00625                         else
00626                         if(file->tag.title_is("OFFSET"))
00627                         {
00628                                 if(current_offset < channels)
00629                                 {
00630                                         index_offsets[current_offset++] = file->tag.get_property("FLOAT", 0);
00631 //printf("Asset::read_index %d %d\n", current_offset - 1, index_offsets[current_offset - 1]);
00632                                 }
00633                         }
00634                         else
00635                         if(file->tag.title_is("SIZE"))
00636                         {
00637                                 if(current_size < channels)
00638                                 {
00639                                         index_sizes[current_size++] = file->tag.get_property("FLOAT", 0);
00640                                 }
00641                         }
00642                 }
00643         }
00644         return 0;
00645 }
00646 
00647 int Asset::write_index(char *path, int data_bytes)
00648 {
00649         FILE *file;
00650         if(!(file = fopen(path, "wb")))
00651         {
00652 // failed to create it
00653                 printf(_("Asset::write_index Couldn't write index file %s to disk.\n"), path);
00654         }
00655         else
00656         {
00657                 FileXML xml;
00658 // Pad index start position
00659                 fwrite((char*)&(index_start), sizeof(int64_t), 1, file);
00660 
00661                 index_status = INDEX_READY;
00662 // Write encoding information
00663                 write(&xml, 
00664                         1, 
00665                         "");
00666                 xml.write_to_file(file);
00667                 index_start = ftell(file);
00668                 fseek(file, 0, SEEK_SET);
00669 // Write index start
00670                 fwrite((char*)&(index_start), sizeof(int64_t), 1, file);
00671                 fseek(file, index_start, SEEK_SET);
00672 
00673 // Write index data
00674                 fwrite(index_buffer, 
00675                         data_bytes, 
00676                         1, 
00677                         file);
00678                 fclose(file);
00679         }
00680 
00681 // Force reread of header
00682         index_status = INDEX_NOTTESTED;
00683 //      index_status = INDEX_READY;
00684         index_end = audio_length;
00685         old_index_end = 0;
00686         index_start = 0;
00687 }
00688 
00689 // Output path is the path of the output file if name truncation is desired.
00690 // It is a "" if complete names should be used.
00691 
00692 int Asset::write(FileXML *file, 
00693         int include_index, 
00694         char *output_path)
00695 {
00696         char new_path[BCTEXTLEN];
00697         char asset_directory[BCTEXTLEN];
00698         char output_directory[BCTEXTLEN];
00699         FileSystem fs;
00700 
00701 // Make path relative
00702         fs.extract_dir(asset_directory, path);
00703         if(output_path && output_path[0]) 
00704                 fs.extract_dir(output_directory, output_path);
00705         else
00706                 output_directory[0] = 0;
00707 
00708 // Asset and EDL are in same directory.  Extract just the name.
00709         if(!strcmp(asset_directory, output_directory))
00710         {
00711                 fs.extract_name(new_path, path);
00712         }
00713         else
00714         {
00715                 strcpy(new_path, path);
00716         }
00717 
00718         file->tag.set_title("ASSET");
00719         file->tag.set_property("SRC", new_path);
00720         file->append_tag();
00721         file->append_newline();
00722 
00723         file->tag.set_title("FOLDER");
00724         file->append_tag();
00725         file->append_text(folder);
00726         file->tag.set_title("/FOLDER");
00727         file->append_tag();
00728         file->append_newline();
00729 
00730 // Write the format information
00731         file->tag.set_title("FORMAT");
00732 
00733         file->tag.set_property("TYPE", 
00734                 File::formattostr(format));
00735         file->tag.set_property("USE_HEADER", use_header);
00736 
00737         file->append_tag();
00738         file->tag.set_title("/FORMAT");
00739         file->append_tag();
00740         file->append_newline();
00741 
00742 // Requiring data to exist caused batch render to lose settings.
00743 // But the only way to know if an asset doesn't have audio or video data 
00744 // is to not write the block.
00745 // So change the block name if the asset doesn't have the data.
00746         /* if(audio_data) */ write_audio(file);
00747         /* if(video_data) */ write_video(file);
00748         if(index_status == 0 && include_index) write_index(file);  // index goes after source
00749 
00750         file->tag.set_title("/ASSET");
00751         file->append_tag();
00752         file->append_newline();
00753         return 0;
00754 }
00755 
00756 int Asset::write_audio(FileXML *file)
00757 {
00758 // Let the reader know if the asset has the data by naming the block.
00759         if(audio_data)
00760                 file->tag.set_title("AUDIO");
00761         else
00762                 file->tag.set_title("AUDIO_OMIT");
00763 // Necessary for PCM audio
00764         file->tag.set_property("CHANNELS", channels);
00765         file->tag.set_property("RATE", sample_rate);
00766         file->tag.set_property("BITS", bits);
00767         file->tag.set_property("BYTE_ORDER", byte_order);
00768         file->tag.set_property("SIGNED", signed_);
00769         file->tag.set_property("HEADER", header);
00770         file->tag.set_property("DITHER", dither);
00771         if(acodec[0])
00772                 file->tag.set_property("ACODEC", acodec);
00773         
00774         file->tag.set_property("AUDIO_LENGTH", audio_length);
00775 
00776 
00777 
00778 // Rely on defaults operations for these.
00779 
00780 //      file->tag.set_property("AMPEG_BITRATE", ampeg_bitrate);
00781 //      file->tag.set_property("AMPEG_DERIVATIVE", ampeg_derivative);
00782 // 
00783 //      file->tag.set_property("VORBIS_VBR", vorbis_vbr);
00784 //      file->tag.set_property("VORBIS_MIN_BITRATE", vorbis_min_bitrate);
00785 //      file->tag.set_property("VORBIS_BITRATE", vorbis_bitrate);
00786 //      file->tag.set_property("VORBIS_MAX_BITRATE", vorbis_max_bitrate);
00787 // 
00788 //      file->tag.set_property("MP3_BITRATE", mp3_bitrate);
00789 // 
00790 
00791 
00792 
00793         file->append_tag();
00794         if(audio_data)
00795           file->tag.set_title("/AUDIO");
00796         else
00797           file->tag.set_title("/AUDIO_OMIT");
00798         file->append_tag();
00799         file->append_newline();
00800         return 0;
00801 }
00802 
00803 int Asset::write_video(FileXML *file)
00804 {
00805         char string[BCTEXTLEN];
00806 
00807         if(video_data)
00808                 file->tag.set_title("VIDEO");
00809         else
00810                 file->tag.set_title("VIDEO_OMIT");
00811         file->tag.set_property("HEIGHT", height);
00812         file->tag.set_property("WIDTH", width);
00813         file->tag.set_property("LAYERS", layers);
00814         file->tag.set_property("FRAMERATE", frame_rate);
00815         if(vcodec[0])
00816                 file->tag.set_property("VCODEC", vcodec);
00817 
00818         file->tag.set_property("VIDEO_LENGTH", video_length);
00819 
00820         file->tag.set_property("INTERLACE_AUTOFIX", interlace_autofixoption);
00821 
00822         ilacemode_to_xmltext(string, interlace_mode);
00823         file->tag.set_property("INTERLACE_MODE", string);
00824 
00825         ilacefixmethod_to_xmltext(string, interlace_fixmethod);
00826         file->tag.set_property("INTERLACE_FIXMETHOD", string);
00827 
00828 
00829         file->tag.set_property("REEL_NAME", reel_name);
00830         file->tag.set_property("REEL_NUMBER", reel_number);
00831         file->tag.set_property("TCSTART", tcstart);
00832         file->tag.set_property("TCEND", tcend);
00833         file->tag.set_property("TCFORMAT", tcformat);
00834 
00835         file->append_tag();
00836         if(video_data)
00837                 file->tag.set_title("/VIDEO");
00838         else
00839                 file->tag.set_title("/VIDEO_OMIT");
00840 
00841         file->append_tag();
00842         file->append_newline();
00843         return 0;
00844 }
00845 
00846 int Asset::write_index(FileXML *file)
00847 {
00848         file->tag.set_title("INDEX");
00849         file->tag.set_property("ZOOM", index_zoom);
00850         file->tag.set_property("BYTES", index_bytes);
00851         file->append_tag();
00852         file->append_newline();
00853 
00854         if(index_offsets)
00855         {
00856                 for(int i = 0; i < channels; i++)
00857                 {
00858                         file->tag.set_title("OFFSET");
00859                         file->tag.set_property("FLOAT", index_offsets[i]);
00860                         file->append_tag();
00861                         file->tag.set_title("/OFFSET");
00862                         file->append_tag();
00863                         file->tag.set_title("SIZE");
00864                         file->tag.set_property("FLOAT", index_sizes[i]);
00865                         file->append_tag();
00866                         file->tag.set_title("/SIZE");
00867                         file->append_tag();
00868                 }
00869         }
00870 
00871         file->append_newline();
00872         file->tag.set_title("/INDEX");
00873         file->append_tag();
00874         file->append_newline();
00875         return 0;
00876 }
00877 
00878 
00879 
00880 
00881 char* Asset::construct_param(char *param, char *prefix, char *return_value)
00882 {
00883         if(prefix)
00884                 sprintf(return_value, "%s%s", prefix, param);
00885         else
00886                 strcpy(return_value, param);
00887         return return_value;
00888 }
00889 
00890 #define UPDATE_DEFAULT(x, y) defaults->update(construct_param(x, prefix, string), y);
00891 #define GET_DEFAULT(x, y) defaults->get(construct_param(x, prefix, string), y);
00892 
00893 void Asset::load_defaults(BC_Hash *defaults, 
00894         char *prefix, 
00895         int do_format,
00896         int do_compression,
00897         int do_path,
00898         int do_data_types,
00899         int do_bits)
00900 {
00901         char string[BCTEXTLEN];
00902 
00903 // Can't save codec here because it's specific to render, record, and effect.
00904 // The codec has to be UNKNOWN for file probing to work.
00905 
00906         if(do_path)
00907         {
00908                 GET_DEFAULT("PATH", path);
00909         }
00910 
00911         if(do_compression)
00912         {
00913                 GET_DEFAULT("AUDIO_CODEC", acodec);
00914                 GET_DEFAULT("VIDEO_CODEC", vcodec);
00915         }
00916 
00917         if(do_format)
00918         {
00919                 format = GET_DEFAULT("FORMAT", format);