1 /*******************************************************************************
2 avi_indx.c
3
4 libquicktime - A library for reading and writing quicktime/avi/mp4 files.
5 http://libquicktime.sourceforge.net
6
7 Copyright (C) 2002 Heroine Virtual Ltd.
8 Copyright (C) 2002-2011 Members of the libquicktime project.
9
10 This library is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free
12 Software Foundation; either version 2.1 of the License, or (at your option)
13 any later version.
14
15 This library is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 details.
19
20 You should have received a copy of the GNU Lesser General Public License along
21 with this library; if not, write to the Free Software Foundation, Inc., 51
22 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *******************************************************************************/
24
25 #include "lqt_private.h"
26 #include <stdlib.h>
27 #include <string.h>
28
quicktime_delete_indx(quicktime_indx_t * indx)29 void quicktime_delete_indx(quicktime_indx_t *indx)
30 {
31 int i;
32 if(indx->table)
33 {
34 for(i = 0; i < indx->table_size; i++)
35 {
36 quicktime_indxtable_t *indx_table = &indx->table[i];
37 if(indx_table->ix) quicktime_delete_ix(indx_table->ix);
38 }
39 free(indx->table);
40 }
41 }
42
quicktime_init_indx(quicktime_t * file,quicktime_indx_t * indx,quicktime_strl_t * strl)43 void quicktime_init_indx(quicktime_t *file,
44 quicktime_indx_t *indx,
45 quicktime_strl_t *strl)
46 {
47 indx->longs_per_entry = 4;
48 indx->index_subtype = 0;
49 indx->index_type = AVI_INDEX_OF_INDEXES;
50 memcpy(indx->chunk_id, strl->tag, 4);
51 }
52
quicktime_indx_init_riff(quicktime_t * file,quicktime_trak_t * trak)53 void quicktime_indx_init_riff(quicktime_t *file, quicktime_trak_t * trak)
54 {
55 quicktime_strl_t * strl;
56 quicktime_indx_t * indx;
57 quicktime_indxtable_t *indx_table;
58
59 strl = trak->strl;
60 indx = &strl->indx;
61
62
63 if(indx->table_size >= indx->table_allocation)
64 {
65 int new_allocation = indx->table_allocation * 2;
66 if(new_allocation < 1) new_allocation = 1;
67
68 indx->table = realloc(indx->table, new_allocation * sizeof(quicktime_indxtable_t));
69 memset(indx->table + indx->table_size, 0, new_allocation - indx->table_size);
70 indx->table_allocation = new_allocation;
71 }
72
73 /* Append */
74 indx_table = &indx->table[indx->table_size++];
75 indx_table->ix = quicktime_new_ix(file, trak, strl);
76
77 }
78
quicktime_indx_finalize_riff(quicktime_t * file,quicktime_trak_t * trak)79 void quicktime_indx_finalize_riff(quicktime_t *file, quicktime_trak_t * trak)
80 {
81 quicktime_strl_t * strl;
82 quicktime_indx_t * indx;
83 quicktime_indxtable_t *indx_table;
84
85 strl = trak->strl;
86 indx = &strl->indx;
87
88 indx_table = &indx->table[indx->table_size-1];
89
90 quicktime_write_ix(file, trak);
91
92 indx_table->index_offset = indx_table->ix->atom.start - 8;
93 indx_table->index_size = indx_table->ix->atom.size;
94 indx_table->duration = indx_table->ix->table_size;
95 }
96
97
quicktime_finalize_indx(quicktime_t * file,quicktime_indx_t * indx)98 void quicktime_finalize_indx(quicktime_t *file, quicktime_indx_t * indx)
99 {
100 int j;
101 quicktime_atom_t junk_atom;
102
103 quicktime_set_position(file, indx->offset);
104
105 /* Write indx */
106 // quicktime_set_position(file, strl->indx_offset);
107 quicktime_atom_write_header(file, &indx->atom, "indx");
108 /* longs per entry */
109 quicktime_write_int16_le(file, indx->longs_per_entry);
110 /* index sub type */
111 quicktime_write_char(file, indx->index_subtype);
112 /* index type */
113 quicktime_write_char(file, indx->index_type);
114 /* entries in use */
115 quicktime_write_int32_le(file, indx->table_size);
116 /* chunk ID */
117 quicktime_write_char32(file, indx->chunk_id);
118 /* reserved */
119 quicktime_write_int32_le(file, 0);
120 quicktime_write_int32_le(file, 0);
121 quicktime_write_int32_le(file, 0);
122
123 /* table */
124 for(j = 0; j < indx->table_size; j++)
125 {
126 quicktime_indxtable_t *indx_table = &indx->table[j];
127 quicktime_write_int64_le(file, indx_table->index_offset);
128 quicktime_write_int32_le(file, indx_table->index_size);
129 quicktime_write_int32_le(file, indx_table->duration);
130 }
131
132 quicktime_atom_write_footer(file, &indx->atom);
133
134 quicktime_atom_write_header(file, &junk_atom, "JUNK");
135
136 while(quicktime_position(file) < indx->offset + indx->size)
137 quicktime_write_char(file, 0);
138 quicktime_atom_write_footer(file, &junk_atom);
139 }
140
quicktime_read_indx(quicktime_t * file,quicktime_strl_t * strl,quicktime_atom_t * parent_atom)141 void quicktime_read_indx(quicktime_t *file,
142 quicktime_strl_t *strl,
143 quicktime_atom_t *parent_atom)
144 {
145 quicktime_indx_t *indx = &strl->indx;
146 quicktime_indxtable_t *indx_table;
147 quicktime_ix_t *ix;
148 int i;
149 int64_t offset;
150
151 file->file_type = LQT_FILE_AVI_ODML;
152
153 indx->longs_per_entry = quicktime_read_int16_le(file);
154 indx->index_subtype = quicktime_read_char(file);
155 indx->index_type = quicktime_read_char(file);
156 indx->table_size = quicktime_read_int32_le(file);
157 quicktime_read_char32(file, indx->chunk_id);
158 quicktime_read_int32_le(file);
159 quicktime_read_int32_le(file);
160 quicktime_read_int32_le(file);
161
162 /* Read indx entries */
163 indx->table = calloc(indx->table_size, sizeof(quicktime_indxtable_t));
164 for(i = 0; i < indx->table_size; i++)
165 {
166 indx_table = &indx->table[i];
167 indx_table->index_offset = quicktime_read_int64_le(file);
168 indx_table->index_size = quicktime_read_int32_le(file);
169 indx_table->duration = quicktime_read_int32_le(file);
170 offset = quicktime_position(file);
171
172 /* Now read the partial index */
173 ix = indx_table->ix = calloc(1, sizeof(quicktime_ix_t));
174 quicktime_set_position(file, indx_table->index_offset);
175 quicktime_read_ix(file, ix);
176 quicktime_set_position(file, offset);
177 }
178
179 }
180
quicktime_set_indx_keyframe(quicktime_t * file,quicktime_trak_t * trak,long new_keyframe)181 void quicktime_set_indx_keyframe(quicktime_t *file,
182 quicktime_trak_t *trak,
183 long new_keyframe)
184 {
185 long frame_count;
186 int i;
187 quicktime_indx_t *indx = &trak->strl->indx;
188
189 /* Get the right ix table */
190 frame_count = 0;
191 i = 0;
192
193
194 while(frame_count + indx->table[i].ix->table_size < new_keyframe)
195 {
196 frame_count+= indx->table[i].ix->table_size;
197 i++;
198 }
199 indx->table[i].ix->table[new_keyframe - frame_count].size &= 0x7fffffff;
200 }
201
quicktime_indx_dump(quicktime_indx_t * indx)202 void quicktime_indx_dump(quicktime_indx_t *indx)
203 {
204 int i;
205 lqt_dump(" indx");
206 lqt_dump(" longs_per_entry: %d\n", indx->longs_per_entry);
207 lqt_dump(" index_subtype: %d\n", indx->index_subtype);
208 lqt_dump(" index_type: %d\n", indx->index_type);
209 lqt_dump(" chunk_id: %s\n", indx->chunk_id);
210 lqt_dump(" table_size: %d\n", indx->table_size);
211
212 for(i = 0; i < indx->table_size; i++)
213 {
214 lqt_dump(" index_offset: %"PRId64"\n", indx->table[i].index_offset);
215 lqt_dump(" index_size: %d\n", indx->table[i].index_size);
216 lqt_dump(" duration: %d\n", indx->table[i].duration);
217 quicktime_ix_dump(indx->table[i].ix);
218 }
219
220 }
221
222