X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Findexstate.C;h=6de431985f1a828955e30f8153a954c46652f541;hb=fa7f91658c01ba88aab006beff8b167a4bbb7085;hp=52eb0c8a802ae0e0888e4a8c9eeb60969b8b7026;hpb=5aad2133f228b736f033d6c48e1629078b858286;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/indexstate.C b/cinelerra-5.0/cinelerra/indexstate.C index 52eb0c8a..6de43198 100644 --- a/cinelerra-5.0/cinelerra/indexstate.C +++ b/cinelerra-5.0/cinelerra/indexstate.C @@ -20,90 +20,131 @@ */ +#include "arraylist.h" #include "asset.h" +#include "clip.h" #include "filexml.h" #include "format.inc" +#include "indexfile.h" #include "indexstate.h" -#include "indexstate.inc" #include "language.h" +#include "mainerror.h" +#include "mutex.h" #include +#include +int IndexMarks::find(int64_t no) +{ + int l = -1, r = size(); + while( (r - l) > 1 ) { + int i = (l+r) >> 1; + if( no > values[i].no ) l = i; else r = i; + } + return l; +} -IndexState::IndexState() +IndexChannel::IndexChannel(IndexState *state, int64_t length) { - reset(); + this->state = state; + this->length = length; + min = max = 0; + bfr = inp = 0; + size = 0; + zidx = 0; } -IndexState::~IndexState() +IndexChannel::~IndexChannel() { - delete [] index_offsets; - delete [] index_sizes; -// Don't delete index buffer since it is shared with the index thread. + delete [] bfr; } -void IndexState::reset() +void IndexChannel::put_entry() +{ + inp->min = min; + inp->max = max; + ++inp; + max = -1; min = 1; + zidx = 0; +} + +int64_t IndexChannel::pos() +{ + return used() * state->index_zoom + zidx; +} + +void IndexChannel::pad_data(int64_t pos) +{ + CLAMP(pos, 0, length); + while( this->pos() < pos ) put_entry(); + inp = bfr + pos / state->index_zoom; + zidx = pos % state->index_zoom; +} + +void IndexState::reset_index() { index_status = INDEX_NOTTESTED; - index_start = old_index_end = index_end = 0; - index_offsets = 0; - index_sizes = 0; + index_start = 0; index_zoom = 0; index_bytes = 0; - index_buffer = 0; - channels = 0; + index_entries.remove_all_objects(); + index_channels.remove_all_objects(); } -void IndexState::dump() +void IndexState::reset_markers() { - printf("IndexState::dump this=%p\n", this); - printf(" channels=%d index_status=%d index_zoom=" _LD - " index_bytes=" _LD " index_offsets=%p\n", - channels, index_status, index_zoom, - index_bytes, index_offsets); - if(index_sizes) - { - printf(" index_sizes="); - for(int i = 0; i < channels; i++) - printf(_LD " ", index_sizes[i]); - printf("\n"); - } + marker_status = MARKERS_NOTTESTED; + video_markers.remove_all_objects(); + audio_markers.remove_all_objects(); } -void IndexState::copy_from(IndexState *src) +IndexState::IndexState() + : Garbage("IndexState") { - if(this == src) return; - - delete [] index_offsets; - delete [] index_sizes; - index_offsets = 0; - index_sizes = 0; - -//printf("Asset::update_index 1 %d\n", index_status); - index_status = src->index_status; - index_zoom = src->index_zoom; // zoom factor of index data - index_start = src->index_start; // byte start of index data in the index file - index_bytes = src->index_bytes; // Total bytes in source file for comparison before rebuilding the index - index_end = src->index_end; - old_index_end = src->old_index_end; // values for index build - channels = src->channels; - - if(src->index_offsets) - { - index_offsets = new int64_t[channels]; - index_sizes = new int64_t[channels]; - - int i; - for(i = 0; i < channels; i++) - { -// offsets of channels in index file in floats - index_offsets[i] = src->index_offsets[i]; - index_sizes[i] = src->index_sizes[i]; - } + marker_lock = new Mutex("IndexState::marker_lock"); + reset_index(); + reset_markers(); +} + +IndexState::~IndexState() +{ + reset_index(); + reset_markers(); + delete marker_lock; +} + +void IndexState::init_scan(int64_t index_length) +{ + index_zoom = 1; + int channels = index_channels.size(); + if( !channels ) return; + int64_t max_samples = 0; + for( int ch=0; chlength; + if( max_samples < len ) max_samples = len; + } + int64_t items = index_length / sizeof(IndexItem); + int64_t count = (items - channels) / channels + 1; + while( count*index_zoom < max_samples ) index_zoom *= 2; + for( int ch=0; chlength / index_zoom + 1; + chn->alloc(len); + chn->put_entry(); } + reset_markers(); +} -// pointer - index_buffer = src->index_buffer; +void IndexState::dump() +{ + printf("IndexState::dump this=%p\n", this); + printf(" index_status=%d index_zoom=" _LD " index_bytes=" _LD "\n", + index_status, index_zoom, index_bytes); + printf(" index entries=%d\n", index_entries.size()); + for( int i=0; ioffset, index_entries[i]->size); + printf("\n"); } void IndexState::write_xml(FileXML *file) @@ -114,17 +155,13 @@ void IndexState::write_xml(FileXML *file) file->append_tag(); file->append_newline(); - if(index_offsets) - { - for(int i = 0; i < channels; i++) - { - file->tag.set_title("OFFSET"); - file->tag.set_property("FLOAT", index_offsets[i]); - file->append_tag(); - file->tag.set_title("SIZE"); - file->tag.set_property("FLOAT", index_sizes[i]); - file->append_tag(); - } + for( int i=0; itag.set_title("OFFSET"); + file->tag.set_property("FLOAT", index_entries[i]->offset); + file->append_tag(); + file->tag.set_title("SIZE"); + file->tag.set_property("FLOAT", index_entries[i]->size); + file->append_tag(); } file->append_newline(); @@ -135,18 +172,8 @@ void IndexState::write_xml(FileXML *file) void IndexState::read_xml(FileXML *file, int channels) { - this->channels = channels; - - delete [] index_offsets; - delete [] index_sizes; - index_offsets = new int64_t[channels]; - index_sizes = new int64_t[channels]; - - for(int i = 0; i < channels; i++) - { - index_offsets[i] = 0; - index_sizes[i] = 0; - } + index_entries.remove_all_objects(); + for( int i=0; itag.get_property("ZOOM", 1); index_bytes = file->tag.get_property("BYTES", (int64_t)0); - while(!result) - { + while(!result) { result = file->read_tag(); - if(!result) - { - if(file->tag.title_is("/INDEX")) - { + if(!result) { + if(file->tag.title_is("/INDEX")) { result = 1; } - else - if(file->tag.title_is("OFFSET")) - { - if(current_offset < channels) - { - index_offsets[current_offset++] = file->tag.get_property("FLOAT", 0); + else if(file->tag.title_is("OFFSET")) { + if(current_offset < channels) { + int64_t offset = file->tag.get_property("FLOAT", (int64_t)0); + index_entries[current_offset++]->offset = offset; //printf("Asset::read_index %d %d\n", current_offset - 1, index_offsets[current_offset - 1]); } } - else - if(file->tag.title_is("SIZE")) - { - if(current_size < channels) - { - index_sizes[current_size++] = file->tag.get_property("FLOAT", 0); + else if(file->tag.title_is("SIZE")) { + if(current_size < channels) { + int64_t size = file->tag.get_property("FLOAT", (int64_t)0); + index_entries[current_size++]->size = size; } } } } } -int IndexState::write_index(const char *path, - int data_bytes, - Asset *asset, - int64_t length_source) +int IndexState::write_index(const char *index_path, Asset *asset, int64_t zoom, int64_t file_bytes) { - - FILE *file; - if(!(file = fopen(path, "wb"))) - { -// failed to create it - printf(_("IndexState::write_index Couldn't write index file %s to disk.\n"), - path); + FILE *fp = fopen(index_path, "wb"); + if( !fp ) { + eprintf(_("IndexState::write_index Couldn't write index file %s to disk.\n"), + index_path); + return 1; } + index_zoom = zoom; + index_bytes = file_bytes; + index_status = INDEX_READY; + + FileXML xml; +// write index_state as asset or directly. + if( asset ) + asset->write(&xml, 1, ""); else - { - FileXML xml; -// Pad index start position - fwrite((char*)&(index_start), sizeof(int64_t), 1, file); - - index_status = INDEX_READY; - -// Write asset encoding information in index file. -// This also calls back into index_state to write it. - if(asset) - { - asset->write(&xml, - 1, - ""); - } - else - { -// Must write index_state directly. - write_xml(&xml); - } + write_xml(&xml); + int64_t len = xml.length() + FileXML::xml_header_size; + index_start = sizeof(index_start) + len; + fwrite(&index_start, sizeof(index_start), 1, fp); + xml.write_to_file(fp); + + int channels = index_entries.size(); + int64_t max_size = 0; + for( int ch=0; chbfr; + int64_t size = ent->size; + if( max_size < size ) max_size = size; + fwrite(bfr, sizeof(float), size, fp); + } + + fclose(fp); + reset_index(); + return 0; +} - xml.write_to_file(file); - index_start = ftell(file); - fseek(file, 0, SEEK_SET); -// Write index start - fwrite((char*)&(index_start), sizeof(int64_t), 1, file); - fseek(file, index_start, SEEK_SET); - -// Write index data - fwrite(index_buffer, - data_bytes, - 1, - file); - fclose(file); +int IndexState::write_markers(const char *index_path) +{ + int vid_size = video_markers.size(); + int aud_size = audio_markers.size(); + if( !vid_size && !aud_size ) return 0; + + FILE *fp = 0; + char marker_path[BCTEXTLEN]; + strcpy(marker_path, index_path); + char *basename = strrchr(marker_path,'/'); + if( !basename ) basename = marker_path; + char *ext = strrchr(basename, '.'); + if( ext ) { + strcpy(ext, ".mkr"); + fp = fopen(marker_path, "wb"); } -// Force reread of header - index_status = INDEX_NOTTESTED; - index_end = length_source; - old_index_end = 0; - index_start = 0; + char version[] = MARKER_MAGIC_VERSION; + if( !fp || !fwrite(version, strlen(version), 1, fp) ) { + eprintf(_("IndexState::write_markers Couldn't write marker file %s to disk.\n"), + marker_path); + return 1; + } + + fwrite(&vid_size, sizeof(vid_size), 1, fp); + for( int vidx=0; vidxlock("IndexState::read_markers"); + if( marker_status == MARKERS_NOTTESTED ) { + char src_path[BCTEXTLEN], marker_path[BCTEXTLEN]; + IndexFile::get_index_filename(src_path, index_dir, marker_path, file_path, ".mkr"); + FILE *fp = fopen(marker_path, "rb"); + int vsz = strlen(MARKER_MAGIC_VERSION); + char version[vsz]; + if( fp && fread(version, vsz, 1, fp) ) { + if( memcmp(version, MARKER_MAGIC_VERSION, vsz) ) { + eprintf(_("IndexState::read_markers marker file version mismatched\n: %s\n"), + marker_path); + return 1; + } + ret = read_marks(fp); + if( !ret ) marker_status = MARKERS_READY; + fclose(fp); + } + } + marker_lock->unlock(); + return ret; +} + +int IndexState::read_marks(FILE *fp) +{ + reset_markers(); + int vid_size = 0; + if( !fread(&vid_size, sizeof(vid_size), 1, fp) ) return 1; + add_video_markers(vid_size); + for( int vidx=0; vidxbfr; + int64_t size = 2 * chn->used(); + add_index_entry(bfr, offset, size); + offset += size; + } + + write_markers(index_path); + return write_index(index_path, asset, index_zoom, index_bytes); +} + int64_t IndexState::get_index_offset(int channel) { - return channel < channels && index_offsets ? index_offsets[channel] : 0; + return channel >= index_entries.size() ? 0 : + index_entries[channel]->offset; } int64_t IndexState::get_index_size(int channel) { - return channel < channels && index_sizes ? index_sizes[channel] : 0; + return channel >= index_entries.size() ? 0 : + index_entries[channel]->size; } +float *IndexState::get_channel_buffer(int channel) +{ + return channel >= index_channels.size() ? 0 : + (float *)index_channels[channel]->bfr; +} + +int64_t IndexState::get_channel_used(int channel) +{ + return channel >= index_channels.size() ? 0 : + index_channels[channel]->used(); +}