1 /*******************************************************************************
2 avi_idx1.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
29 typedef struct
30 {
31 char tag[4];
32 int32_t flags;
33 int32_t offset;
34 int32_t size;
35 } avi_tag_t;
36
37
38
quicktime_delete_idx1(quicktime_idx1_t * idx1)39 void quicktime_delete_idx1(quicktime_idx1_t *idx1)
40 {
41 if(idx1->table) free(idx1->table);
42 }
43
quicktime_idx1_dump(quicktime_idx1_t * idx1)44 void quicktime_idx1_dump(quicktime_idx1_t *idx1)
45 {
46 int i;
47 lqt_dump("idx1\n");
48 for(i = 0; i < idx1->table_size; i++)
49 {
50 quicktime_idx1table_t *idx1table = idx1->table + i;
51 lqt_dump(" T: %c%c%c%c, F: %08x, O: %d, S: %d\n",
52 idx1table->tag[0],
53 idx1table->tag[1],
54 idx1table->tag[2],
55 idx1table->tag[3],
56 idx1table->flags,
57 idx1table->offset,
58 idx1table->size);
59 }
60
61 }
62
63
quicktime_read_idx1(quicktime_t * file,quicktime_riff_t * riff,quicktime_atom_t * parent_atom)64 void quicktime_read_idx1(quicktime_t *file,
65 quicktime_riff_t *riff,
66 quicktime_atom_t *parent_atom)
67 {
68 int i;
69 quicktime_idx1_t *idx1 = &riff->idx1;
70
71
72 // Allocate table.
73 idx1->table_size = (parent_atom->end - quicktime_position(file)) / 16;
74
75 if(idx1->table_size <= 0)
76 {
77 idx1->table_size = 0;
78 return;
79 }
80 idx1->table_allocation = idx1->table_size;
81 idx1->table = calloc(sizeof(quicktime_idx1table_t), idx1->table_size);
82
83 // Store it in idx1 table now.
84 // Wait for full ix table discovery before converting to stco.
85 for(i = 0; i < idx1->table_size; i++)
86 {
87 quicktime_idx1table_t *idx1table = idx1->table + i;
88
89 quicktime_read_data(file, (uint8_t*)(idx1table->tag), 4);
90 idx1table->flags = quicktime_read_int32_le(file);
91 idx1table->offset = quicktime_read_int32_le(file);
92 idx1table->size = quicktime_read_int32_le(file);
93 }
94
95
96
97 }
98
quicktime_write_idx1(quicktime_t * file,quicktime_idx1_t * idx1)99 void quicktime_write_idx1(quicktime_t *file,
100 quicktime_idx1_t *idx1)
101 {
102 int i;
103 quicktime_idx1table_t *table = idx1->table;
104 int table_size = idx1->table_size;
105
106
107 // Write table
108 quicktime_atom_write_header(file, &idx1->atom, "idx1");
109
110 for(i = 0; i < table_size; i++)
111 {
112 quicktime_idx1table_t *entry = &table[i];
113 quicktime_write_char32(file, entry->tag);
114 quicktime_write_int32_le(file, entry->flags);
115 quicktime_write_int32_le(file, entry->offset);
116 quicktime_write_int32_le(file, entry->size);
117 }
118
119
120 quicktime_atom_write_footer(file, &idx1->atom);
121 }
122
quicktime_set_idx1_keyframe(quicktime_t * file,quicktime_trak_t * trak,int new_keyframe)123 void quicktime_set_idx1_keyframe(quicktime_t *file,
124 quicktime_trak_t *trak,
125 int new_keyframe)
126 {
127 quicktime_riff_t *riff = file->riff[0];
128 quicktime_hdrl_t *hdrl = &riff->hdrl;
129 quicktime_strl_t *strl = hdrl->strl[trak->tkhd.track_id - 1];
130 char *tag = strl->tag;
131 quicktime_idx1_t *idx1 = &riff->idx1;
132 int i;
133 int counter = -1;
134 // Search through entire index for right numbered tag.
135 // Since all the tracks are combined in the same index, this is unavoidable.
136 for(i = 0; i < idx1->table_size; i++)
137 {
138 quicktime_idx1table_t *idx1_table = &idx1->table[i];
139 if(!memcmp(idx1_table->tag, tag, 4))
140 {
141 counter++;
142 if(counter == new_keyframe)
143 {
144 idx1_table->flags |= AVI_KEYFRAME;
145 break;
146 }
147 }
148 }
149 }
150
quicktime_update_idx1table(quicktime_t * file,quicktime_trak_t * trak,int offset,int size)151 void quicktime_update_idx1table(quicktime_t *file,
152 quicktime_trak_t *trak,
153 int offset,
154 int size)
155 {
156 quicktime_riff_t *riff = file->riff[0];
157 quicktime_strl_t *strl = trak->strl;
158 char *tag = strl->tag;
159 quicktime_idx1_t *idx1 = &riff->idx1;
160 quicktime_movi_t *movi = &riff->movi;
161 quicktime_idx1table_t *idx1_table;
162 #if 0
163 int keyframe_frame = idx1->table_size + 1;
164
165 // Set flag for keyframe
166 for(i = stss->total_entries - 1; i >= 0; i--)
167 {
168 if(stss->table[i].sample == keyframe_frame)
169 {
170 flags |= AVI_KEYFRAME;
171 break;
172 }
173 else
174 if(stss->table[i].sample < keyframe_frame)
175 {
176 break;
177 }
178 }
179 #endif
180
181 // Allocation
182 if(idx1->table_size >= idx1->table_allocation)
183 {
184 idx1->table_allocation += 1024;
185
186 idx1->table = realloc(idx1->table, sizeof(*idx1->table) * idx1->table_allocation);
187 memset(idx1->table + idx1->table_size, 0,
188 sizeof(*idx1->table) * (idx1->table_allocation - idx1->table_size));
189 }
190
191 // Appendage
192 idx1_table = &idx1->table[idx1->table_size];
193 memcpy(idx1_table->tag, tag, 4);
194
195 if(trak->mdia.minf.is_audio ||
196 !trak->mdia.minf.stbl.stss.total_entries)
197 idx1_table->flags = AVI_KEYFRAME;
198 else
199 idx1_table->flags = 0;
200
201 idx1_table->offset = offset - 8 - movi->atom.start;
202 idx1_table->size = size;
203 idx1->table_size++;
204 }
205
206
207
208
209