gif rework, C41 booby fix, add ext+s for list seq, features5
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / indexstate.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22
23 #ifndef INDEXSTATE_H
24 #define INDEXSTATE_H
25
26 #include "arraylist.h"
27 #include "asset.inc"
28 #include "filexml.inc"
29 #include "garbage.h"
30 #include "indexstate.inc"
31 #include "mutex.inc"
32
33 #include <stdio.h>
34 #include <stdint.h>
35
36 class IndexItem {
37 public:
38         float max, min;
39 };
40
41 class IndexMark {
42 public:
43         int64_t no, pos;
44         IndexMark() {}
45         IndexMark(int64_t n, int64_t p) { no = n;  pos = p; }
46
47         bool operator==(IndexMark &v) { return v.no == no; }
48         bool operator >(IndexMark &v) { return v.no > no; }
49 };
50
51 class IndexChannel : public IndexItem {
52 public:
53         IndexChannel(IndexState *state, int64_t length);
54         ~IndexChannel();
55
56         IndexState *state;
57         IndexItem *bfr, *inp;
58         int64_t length, size;
59         int zidx;
60
61         void alloc(int64_t sz) { bfr = inp = new IndexItem[(size=sz)+1]; }
62         int64_t used() { return inp - bfr; }
63         int64_t avail() { return size - used(); }
64         int64_t pos();
65         void put_sample(float v, int zoom) {
66                 if( v > max ) max = v;
67                 if( v < min ) min = v;
68                 if( ++zidx >= zoom )
69                         put_entry();
70         }
71         void put_entry();
72         void pad_data(int64_t pos);
73 };
74
75 class IndexChannels : public ArrayList<IndexChannel*> {
76 public:
77         IndexChannels() {}
78         ~IndexChannels() { remove_all_objects(); }
79 };
80
81
82 class IndexEntry {
83 public:
84         float *bfr;
85 // offsets / sizes of channels in index buffer in floats
86         int64_t offset, size;
87         IndexEntry(float *bp, int64_t ofs, int64_t sz) {
88                 bfr = bp;  offset = ofs;  size = sz;
89         }
90 };
91
92 class IndexEntries : public ArrayList<IndexEntry*> {
93 public:
94         IndexEntries() {}
95         ~IndexEntries() { remove_all_objects(); }
96 };
97
98 class IndexMarks : public ArrayList<IndexMark> {
99 public:
100         IndexMarks() {}
101         ~IndexMarks() {}
102         void add_mark(int64_t no, int64_t pos) { append(IndexMark(no, pos)); }
103         int find(int64_t no);
104 };
105
106 class IndexMarkers : public ArrayList<IndexMarks *> {
107 public:
108         IndexMarkers() {}
109         ~IndexMarkers() { remove_all_objects(); }
110 };
111
112 // Assets & nested EDLs store this information to have their indexes built
113 class IndexState : public Garbage
114 {
115 public:
116         IndexState();
117         ~IndexState();
118
119         void reset_index();
120         void reset_markers();
121         void init_scan(int64_t index_length);
122
123 // Supply asset to include encoding information in index file.
124         void write_xml(FileXML *file);
125         void read_xml(FileXML *file, int channels);
126         int write_index(const char *index_path, Asset *asset, int64_t zoom, int64_t file_bytes);
127         int create_index(const char *index_path, Asset *asset);
128         int read_markers(char *index_dir, char *file_path);
129         int read_marks(FILE *fp);
130         int write_markers(const char *index_path);
131         int64_t get_index_offset(int channel);
132         int64_t get_index_size(int channel);
133         float *get_channel_buffer(int channel);
134         int64_t get_channel_used(int channel);
135         void dump();
136
137 // index info
138         int index_status;       // Macro from assets.inc
139         int marker_status;
140         int64_t index_zoom;     // zoom factor of index data
141         int64_t index_start;    // byte start of index data in the index file
142 // Total bytes in the source file when the index was buillt
143         int64_t index_bytes;
144         IndexChannels index_channels;
145         IndexEntries index_entries;
146         Mutex *marker_lock;
147         IndexMarkers video_markers;
148         IndexMarkers audio_markers;
149
150         void add_audio_channel(int64_t length) {
151                 index_channels.append(new IndexChannel(this, length));
152         }
153         void add_audio_stream(int nch, int64_t length) {
154                 for( int ch=0; ch<nch; ++ch ) add_audio_channel(length);
155         }
156         void add_video_markers(int n) {
157                 while( --n >= 0 ) video_markers.append(new IndexMarks());
158         }
159         void add_audio_markers(int n) {
160                 while( --n >= 0 ) audio_markers.append(new IndexMarks());
161         }
162         void add_index_entry(float *bfr, int64_t offset, int64_t size) {
163                 index_entries.append(new IndexEntry(bfr, offset, size));
164         }
165
166         void put_data(int ch, int nch, float *data, int64_t len) {
167                 IndexChannel *chn = index_channels[ch];
168                 int64_t avl = chn->avail() * index_zoom - chn->zidx;
169                 if( len > avl ) len = avl;
170                 for( int64_t i=len; --i>=0; data+=nch )
171                         chn->put_sample(*data, index_zoom);
172         }
173         void put_data(int ch, double *data, int64_t len) {
174                 IndexChannel *chn = index_channels[ch];
175                 int64_t avl = chn->avail() * index_zoom - chn->zidx;
176                 if( len > avl ) len = avl;
177                 for( int64_t i=len; --i>=0; )
178                         chn->put_sample(*data++, index_zoom);
179         }
180         int64_t pos(int ch) { return index_channels[ch]->pos(); }
181         void pad_data(int ch, int nch, int64_t pos) {
182                 while( --nch >= 0 ) index_channels[ch++]->pad_data(pos);
183         }
184
185         void put_video_mark(int vidx, int64_t frm, int64_t pos) {
186                 if( vidx >= video_markers.size() ) return;
187                 IndexMarks &marks = *video_markers[vidx];
188                 if( marks.size()>0 && marks.last().no >= frm ) return;
189                 marks.add_mark(frm, pos);
190         }
191         void put_audio_mark(int aidx, int64_t smpl, int64_t pos) {
192                 if( aidx >= audio_markers.size() ) return;
193                 IndexMarks &marks = *audio_markers[aidx];
194                 if( marks.size()>0 && marks.last().no >= smpl ) return;
195                 marks.add_mark(smpl, pos);
196         }
197 };
198
199 #endif
200