1 #include "funcprotos.h"
5 void quicktime_read_riff(quicktime_t
*file
, quicktime_atom_t
*parent_atom
)
7 quicktime_riff_t
*riff
= quicktime_new_riff(file
);
8 quicktime_atom_t leaf_atom
;
13 riff
->atom
= *parent_atom
;
16 quicktime_read_data(file
, data
, 4);
17 //printf("quicktime_read_riff 1 %llx\n", quicktime_position(file));
19 // Certain AVI parameters must be copied over to quicktime objects:
25 result
= quicktime_atom_read_header(file
, &leaf_atom
);
28 * printf("quicktime_read_riff 1 %llx %llx %c%c%c%c\n",
38 if(quicktime_atom_is(&leaf_atom
, "LIST"))
43 result
= !quicktime_read_data(file
, data
, 4);
49 if(quicktime_match_32(data
, "hdrl"))
53 //printf("quicktime_read_riff 10 %llx\n", quicktime_position(file));
54 quicktime_read_hdrl(file
, &riff
->hdrl
, &leaf_atom
);
55 //printf("quicktime_read_riff 20 %llx\n", quicktime_position(file));
59 if(quicktime_match_32(data
, "movi"))
61 //printf("quicktime_read_riff 30 %llx\n", quicktime_position(file));
62 quicktime_read_movi(file
, &leaf_atom
, &riff
->movi
);
63 //printf("quicktime_read_riff 40 %llx\n", quicktime_position(file));
68 quicktime_atom_skip(file
, &leaf_atom
);
73 if(quicktime_atom_is(&leaf_atom
, "movi"))
75 quicktime_read_movi(file
, &leaf_atom
, &riff
->movi
);
79 // Got 'idx1' original index
80 if(quicktime_atom_is(&leaf_atom
, "idx1"))
83 //printf("quicktime_read_riff 50 %llx\n", quicktime_position(file));
85 int64_t start_position
= quicktime_position(file
);
86 long temp_size
= leaf_atom
.end
- start_position
;
87 unsigned char *temp
= malloc(temp_size
);
88 quicktime_set_preload(file
,
89 (temp_size
< 0x100000) ? 0x100000 : temp_size
);
90 quicktime_read_data(file
, temp
, temp_size
);
91 quicktime_set_position(file
, start_position
);
95 quicktime_read_idx1(file
, riff
, &leaf_atom
);
96 //printf("quicktime_read_riff 60 %llx\n", quicktime_position(file));
103 quicktime_atom_skip(file
, &leaf_atom
);
107 }while(!result
&& quicktime_position(file
) < parent_atom
->end
);
109 //printf("quicktime_read_riff 10\n");
115 quicktime_riff_t
* quicktime_new_riff(quicktime_t
*file
)
117 if(file
->total_riffs
>= MAX_RIFFS
)
119 fprintf(stderr
, "quicktime_new_riff file->total_riffs >= MAX_RIFFS\n");
124 quicktime_riff_t
*riff
= calloc(1, sizeof(quicktime_riff_t
));
125 file
->riff
[file
->total_riffs
++] = riff
;
132 void quicktime_delete_riff(quicktime_t
*file
, quicktime_riff_t
*riff
)
135 quicktime_delete_hdrl(file
, &riff
->hdrl
);
136 quicktime_delete_movi(file
, &riff
->movi
);
137 quicktime_delete_idx1(&riff
->idx1
);
141 void quicktime_init_riff(quicktime_t
*file
)
145 quicktime_riff_t
*riff
= quicktime_new_riff(file
);
149 quicktime_atom_write_header(file
, &riff
->atom
, "RIFF");
150 quicktime_write_char32(file
, "AVI ");
152 // Write header list in first RIFF only
153 if(file
->total_riffs
< 2)
155 quicktime_init_hdrl(file
, &riff
->hdrl
);
159 quicktime_init_movi(file
, riff
);
162 void quicktime_finalize_riff(quicktime_t
*file
, quicktime_riff_t
*riff
)
164 // Write partial indexes
165 quicktime_finalize_movi(file
, &riff
->movi
);
168 printf("quicktime_finalize_riff 1\n");
169 quicktime_finalize_hdrl(file
, &riff
->hdrl
);
170 printf("quicktime_finalize_riff 10\n");
171 // Write original index for first RIFF
172 quicktime_write_idx1(file
, &riff
->idx1
);
173 printf("quicktime_finalize_riff 100\n");
175 quicktime_atom_write_footer(file
, &riff
->atom
);
181 void quicktime_import_avi(quicktime_t
*file
)
184 quicktime_riff_t
*first_riff
= file
->riff
[0];
185 quicktime_idx1_t
*idx1
= &first_riff
->idx1
;
186 quicktime_hdrl_t
*hdrl
= &first_riff
->hdrl
;
190 /* Determine whether to use idx1 or indx indexes for offsets. */
191 /* idx1 must always be used for keyframes but it also must be */
192 /* ignored for offsets if indx exists. */
195 //printf("quicktime_import_avi 1\n");
196 /* Convert idx1 to keyframes and load offsets and sizes */
197 for(i
= 0; i
< idx1
->table_size
; i
++)
199 quicktime_idx1table_t
*idx1table
= idx1
->table
+ i
;
200 char *tag
= idx1table
->tag
;
201 int track_number
= (tag
[0] - '0') * 10 + (tag
[1] - '0');
202 if(track_number
< file
->moov
.total_tracks
)
204 quicktime_trak_t
*trak
= file
->moov
.trak
[track_number
];
205 int is_audio
= trak
->mdia
.minf
.is_audio
;
206 int is_video
= trak
->mdia
.minf
.is_video
;
210 quicktime_stco_t
*stco
= &trak
->mdia
.minf
.stbl
.stco
;
212 quicktime_stsz_t
*stsz
= &trak
->mdia
.minf
.stbl
.stsz
;
213 /* Samples per chunk */
214 quicktime_stsc_t
*stsc
= &trak
->mdia
.minf
.stbl
.stsc
;
215 /* Sample description */
216 quicktime_stsd_t
*stsd
= &trak
->mdia
.minf
.stbl
.stsd
;
219 /* Enter the offset and size no matter what so the sample counts */
220 /* can be used to set keyframes */
221 quicktime_update_stco(stco
,
222 stco
->total_entries
+ 1,
223 idx1table
->offset
+ first_riff
->movi
.atom
.start
);
227 /* Just get the keyframe flag. don't call quicktime_insert_keyframe because */
228 /* that updates idx1 and we don't have a track map. */
229 int is_keyframe
= (idx1table
->flags
& AVI_KEYFRAME
) == AVI_KEYFRAME
;
232 quicktime_stss_t
*stss
= &trak
->mdia
.minf
.stbl
.stss
;
233 /* This is done before the image size table so this value is right */
234 int frame
= stsz
->total_entries
;
237 if(stss
->entries_allocated
<= stss
->total_entries
)
239 stss
->entries_allocated
*= 2;
240 stss
->table
= realloc(stss
->table
,
241 sizeof(quicktime_stss_table_t
) * stss
->entries_allocated
);
243 stss
->table
[stss
->total_entries
++].sample
= frame
;
247 quicktime_update_stsz(stsz
,
254 /* Set samples per chunk if PCM */
255 if(stsd
->table
[0].sample_size
> 0)
257 quicktime_update_stsc(stsc
,
258 stsc
->total_entries
+ 1,
261 stsd
->table
[0].sample_size
/
262 stsd
->table
[0].channels
);
268 //printf("quicktime_import_avi 10\n");
271 /* Convert super indexes into Quicktime indexes. */
272 /* Append to existing entries if idx1 exists. */
273 /* No keyframes here. */
274 for(i
= 0; i
< file
->moov
.total_tracks
; i
++)
276 quicktime_strl_t
*strl
= first_riff
->hdrl
.strl
[i
];
280 quicktime_indx_t
*indx
= &strl
->indx
;
281 quicktime_trak_t
*trak
= file
->moov
.trak
[i
];
282 quicktime_stco_t
*stco
= &trak
->mdia
.minf
.stbl
.stco
;
283 quicktime_stsz_t
*stsz
= &trak
->mdia
.minf
.stbl
.stsz
;
284 quicktime_stsc_t
*stsc
= &trak
->mdia
.minf
.stbl
.stsc
;
285 quicktime_stsd_t
*stsd
= &trak
->mdia
.minf
.stbl
.stsd
;
286 /* Get existing chunk count from the idx1 */
287 int existing_chunks
= stco
->total_entries
;
289 /* Read each indx entry */
290 for(j
= 0; j
< indx
->table_size
; j
++)
292 quicktime_indxtable_t
*indx_table
= &indx
->table
[j
];
293 quicktime_ix_t
*ix
= indx_table
->ix
;
295 for(k
= 0; k
< ix
->table_size
; k
++)
297 /* Copy from existing chunk count to end of ix table */
298 if(existing_chunks
<= 0)
300 quicktime_ixtable_t
*ixtable
= &ix
->table
[k
];
302 /* Do the same things that idx1 did to the chunk tables */
303 /* Subtract the super indexes by size of the header. McRoweSoft seems to */
304 /* want the header before the ix offset but after the idx1 offset. */
305 quicktime_update_stco(stco
,
306 stco
->total_entries
+ 1,
307 ixtable
->relative_offset
+ ix
->base_offset
- 8);
310 quicktime_update_stsz(stsz
,
317 if(stsd
->table
[0].sample_size
> 0)
319 quicktime_update_stsc(stsc
,
320 stsc
->total_entries
+ 1,
323 stsd
->table
[0].sample_size
/
324 stsd
->table
[0].channels
);
336 //printf("quicktime_import_avi 20\n");
341 /* Set total samples, time to sample, for audio */
342 for(i
= 0; i
< file
->moov
.total_tracks
; i
++)
344 quicktime_trak_t
*trak
= file
->moov
.trak
[i
];
345 quicktime_stsz_t
*stsz
= &trak
->mdia
.minf
.stbl
.stsz
;
346 quicktime_stsc_t
*stsc
= &trak
->mdia
.minf
.stbl
.stsc
;
347 quicktime_stco_t
*stco
= &trak
->mdia
.minf
.stbl
.stco
;
348 quicktime_stts_t
*stts
= &trak
->mdia
.minf
.stbl
.stts
;
350 if(trak
->mdia
.minf
.is_audio
)
352 quicktime_stsc_table_t
*stsc_table
= stsc
->table
;
353 long total_entries
= stsc
->total_entries
;
354 long chunk
= stco
->total_entries
;
359 sample
= quicktime_sample_of_chunk(trak
, chunk
) +
360 stsc_table
[total_entries
- 1].samples
;
363 stsz
->sample_size
= 1;
364 stsz
->total_entries
= sample
;
365 stts
->table
[0].sample_count
= sample
;
368 if(trak
->mdia
.minf
.is_video
)
370 stsc
->total_entries
= 1;
371 /* stts has 1 allocation by default */
372 stts
->table
[0].sample_count
= stco
->total_entries
;
376 //printf("quicktime_import_avi 30\n");