initial commit
[goodguy/history.git] / cinelerra-5.0 / quicktime / avi_idx1.c
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include <string.h>
4
5
6
7 typedef struct
8 {
9         char tag[4];
10         int32_t flags;
11         int32_t offset;
12         int32_t size;
13 } avi_tag_t;
14
15
16 #if 0
17 static int is_keyframe(quicktime_trak_t *trak, int frame)
18 {
19         int i;
20         quicktime_stss_t *stss = &trak->mdia.minf.stbl.stss;
21         frame++;
22         for(i = 0; i < stss->total_entries; i++)
23         {
24                 if(stss->table[i].sample == frame) return 1;
25         }
26         return 0;
27 }
28 #endif
29
30 void quicktime_delete_idx1(quicktime_idx1_t *idx1)
31 {
32         if(idx1->table) free(idx1->table);
33 }
34
35 void quicktime_read_idx1(quicktime_t *file, 
36         quicktime_riff_t *riff,
37         quicktime_atom_t *parent_atom)
38 {
39         int i;
40         quicktime_idx1_t *idx1 = &riff->idx1;
41
42 //printf("quicktime_read_idx1 1 %llx\n", quicktime_position(file));
43
44 // Allocate table.
45         idx1->table_size = (parent_atom->end - quicktime_position(file)) / 16;
46         idx1->table_allocation = idx1->table_size;
47         idx1->table = calloc(sizeof(quicktime_idx1table_t), idx1->table_size);
48 //printf("quicktime_read_idx1 10\n");
49
50 // Store it in idx1 table now.
51 // Wait for full ix table discovery before converting to stco.
52         for(i = 0; i < idx1->table_size; i++)
53         {
54                 quicktime_idx1table_t *idx1table = idx1->table + i;
55
56                 quicktime_read_data(file, idx1table->tag, 4);
57                 idx1table->flags = quicktime_read_int32_le(file);
58                 idx1table->offset = quicktime_read_int32_le(file);
59                 idx1table->size = quicktime_read_int32_le(file);
60         }
61
62 //printf("quicktime_read_idx1 100\n");
63 }
64
65 void quicktime_write_idx1(quicktime_t *file, 
66         quicktime_idx1_t *idx1)
67 {
68         int i;
69         quicktime_idx1table_t *table = idx1->table;
70         int table_size = idx1->table_size;
71
72
73
74 // Write table
75         quicktime_atom_write_header(file, &idx1->atom, "idx1");
76
77         for(i = 0; i < table_size; i++)
78         {
79                 quicktime_idx1table_t *entry = &table[i];
80                 quicktime_write_char32(file, entry->tag);
81                 quicktime_write_int32_le(file, entry->flags);
82                 quicktime_write_int32_le(file, entry->offset);
83                 quicktime_write_int32_le(file, entry->size);
84         }
85
86
87         quicktime_atom_write_footer(file, &idx1->atom);
88 }
89
90 void quicktime_set_idx1_keyframe(quicktime_t *file, 
91         quicktime_trak_t *trak,
92         int new_keyframe)
93 {
94         quicktime_riff_t *riff = file->riff[0];
95         quicktime_hdrl_t *hdrl = &riff->hdrl;
96         quicktime_strl_t *strl = hdrl->strl[trak->tkhd.track_id - 1];
97         char *tag = strl->tag;
98         quicktime_idx1_t *idx1 = &riff->idx1;
99         int i;
100         int counter = -1;
101
102 // Search through entire index for right numbered tag.
103 // Since all the tracks are combined in the same index, this is unavoidable.
104         for(i = 0; i < idx1->table_size; i++)
105         {
106                 quicktime_idx1table_t *idx1_table = &idx1->table[i];
107                 if(!memcmp(idx1_table->tag, tag, 4))
108                 {
109                         counter++;
110                         if(counter == new_keyframe)
111                         {
112                                 idx1_table->flags |= AVI_KEYFRAME;
113                                 break;
114                         }
115                 }
116         }
117 }
118
119 void quicktime_update_idx1table(quicktime_t *file, 
120         quicktime_trak_t *trak, 
121         int offset,
122         int size)
123 {
124         quicktime_riff_t *riff = file->riff[0];
125         quicktime_hdrl_t *hdrl = &riff->hdrl;
126         quicktime_strl_t *strl = hdrl->strl[trak->tkhd.track_id - 1];
127         char *tag = strl->tag;
128         quicktime_idx1_t *idx1 = &riff->idx1;
129         quicktime_movi_t *movi = &riff->movi;
130         quicktime_idx1table_t *idx1_table;
131         quicktime_stss_t *stss = &trak->mdia.minf.stbl.stss;
132         uint32_t flags = 0;
133         int i;
134         int keyframe_frame = idx1->table_size + 1;
135
136 // Set flag for keyframe
137         for(i = stss->total_entries - 1; i >= 0; i--)
138         {
139                 if(stss->table[i].sample == keyframe_frame)
140                 {
141                         flags |= AVI_KEYFRAME;
142                         break;
143                 }
144                 else
145                 if(stss->table[i].sample < keyframe_frame)
146                 {
147                         break;
148                 }
149         }
150
151
152 // Allocation
153         if(idx1->table_size >= idx1->table_allocation)
154         {
155                 quicktime_idx1table_t *old_table = idx1->table;
156                 int new_allocation = idx1->table_allocation * 2;
157                 if(new_allocation < 1) new_allocation = 1;
158                 idx1->table = calloc(1, sizeof(quicktime_idx1table_t) * new_allocation);
159                 if(old_table)
160                 {
161                         memcpy(idx1->table, old_table, sizeof(quicktime_idx1table_t) * idx1->table_size);
162                         free(old_table);
163                 }
164                 idx1->table_allocation = new_allocation;
165         }
166
167
168 // Appendage
169         idx1_table = &idx1->table[idx1->table_size];
170         memcpy(idx1_table->tag, tag, 4);
171         idx1_table->flags = flags;
172         idx1_table->offset = offset - 8 - movi->atom.start;
173         idx1_table->size = size;
174         idx1->table_size++;
175 }
176
177
178
179