1 #include "funcprotos.h"
5 // Update during close:
8 #define JUNK_SIZE 0x1018
12 quicktime_strl_t
* quicktime_new_strl()
14 quicktime_strl_t
*strl
= calloc(1, sizeof(quicktime_strl_t
));
19 void quicktime_init_strl(quicktime_t
*file
,
20 quicktime_audio_map_t
*atrack
,
21 quicktime_video_map_t
*vtrack
,
22 quicktime_trak_t
*trak
,
23 quicktime_strl_t
*strl
)
25 quicktime_atom_t list_atom
, strh_atom
, strf_atom
;
26 quicktime_atom_t junk_atom
;
32 strl
->tag
[0] = '0' + (trak
->tkhd
.track_id
- 1) / 10;
33 strl
->tag
[1] = '0' + (trak
->tkhd
.track_id
- 1) % 10;
40 strl
->tag
[0] = '0' + (trak
->tkhd
.track_id
- 1) / 10;
41 strl
->tag
[1] = '0' + (trak
->tkhd
.track_id
- 1) % 10;
48 quicktime_atom_write_header(file
, &list_atom
, "LIST");
49 quicktime_write_char32(file
, "strl");
52 quicktime_atom_write_header(file
, &strh_atom
, "strh");
59 quicktime_write_char32(file
, "vids");
60 quicktime_write_char32(file
,
61 trak
->mdia
.minf
.stbl
.stsd
.table
[0].format
);
63 quicktime_write_int32_le(file
, 0);
65 quicktime_write_int16_le(file
, 0);
67 quicktime_write_int16_le(file
, 0);
69 quicktime_write_int32_le(file
, 0);
71 /* framerate denominator */
72 quicktime_write_int32_le(file
,
73 trak
->mdia
.minf
.stbl
.stts
.table
[0].sample_duration
);
74 /* framerate numerator */
75 quicktime_write_int32_le(file
,
76 trak
->mdia
.mdhd
.time_scale
);
79 quicktime_write_int32_le(file
, 0);
80 strl
->length_offset
= quicktime_position(file
);
81 /* length: fill later */
82 quicktime_write_int32_le(file
, 0);
83 /* suggested buffer size */
84 quicktime_write_int32_le(file
, 0);
86 quicktime_write_int32_le(file
, -1);
88 quicktime_write_int32_le(file
, 0);
89 quicktime_write_int16_le(file
, 0);
90 quicktime_write_int16_le(file
, 0);
91 quicktime_write_int16_le(file
, trak
->tkhd
.track_width
);
92 quicktime_write_int16_le(file
, trak
->tkhd
.track_height
);
98 quicktime_write_char32(file
, "auds");
99 quicktime_write_int32_le(file
, 0);
101 quicktime_write_int32_le(file
, 0);
103 quicktime_write_int16_le(file
, 0);
105 quicktime_write_int16_le(file
, 0);
107 quicktime_write_int32_le(file
, 0);
108 strl
->samples_per_chunk_offset
= quicktime_position(file
);
109 /* samples per chunk */
110 quicktime_write_int32_le(file
, 0);
111 /* sample rate * samples per chunk if uncompressed */
112 /* sample rate if compressed */
113 quicktime_write_int32_le(file
, 0);
115 quicktime_write_int32_le(file
, 0);
116 strl
->length_offset
= quicktime_position(file
);
117 /* length, XXX: filled later */
118 quicktime_write_int32_le(file
, 0);
119 /* suggested buffer size */
120 quicktime_write_int32_le(file
, 0);
122 quicktime_write_int32_le(file
, -1);
123 /* sample size: 0 for compressed and number of bytes for uncompressed */
124 strl
->sample_size_offset
= quicktime_position(file
);
125 quicktime_write_int32_le(file
, 0);
126 quicktime_write_int32_le(file
, 0);
127 quicktime_write_int32_le(file
, 0);
129 quicktime_atom_write_footer(file
, &strh_atom
);
138 quicktime_atom_write_header(file
, &strf_atom
, "strf");
142 /* atom size repeated */
143 quicktime_write_int32_le(file
, 40);
144 quicktime_write_int32_le(file
, trak
->tkhd
.track_width
);
145 quicktime_write_int32_le(file
, trak
->tkhd
.track_height
);
147 quicktime_write_int16_le(file
, 1);
149 quicktime_write_int16_le(file
, 24);
150 quicktime_write_char32(file
,
151 trak
->mdia
.minf
.stbl
.stsd
.table
[0].format
);
152 quicktime_write_int32_le(file
,
153 trak
->tkhd
.track_width
* trak
->tkhd
.track_height
* 3);
154 quicktime_write_int32_le(file
, 0);
155 quicktime_write_int32_le(file
, 0);
156 quicktime_write_int32_le(file
, 0);
157 quicktime_write_int32_le(file
, 0);
162 /* By now the codec is instantiated so the WAV ID is available. */
164 quicktime_codec_t
*codec_base
= atrack
->codec
;
166 if(codec_base
->wav_id
)
167 wav_id
= codec_base
->wav_id
;
168 quicktime_write_int16_le(file
,
170 quicktime_write_int16_le(file
,
171 trak
->mdia
.minf
.stbl
.stsd
.table
[0].channels
);
172 quicktime_write_int32_le(file
,
173 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
174 /* bitrate in bytes */
175 quicktime_write_int32_le(file
, 256000 / 8);
177 quicktime_write_int16_le(file
, 1);
178 /* bits per sample */
179 quicktime_write_int16_le(file
,
180 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
);
181 quicktime_write_int16_le(file
, 0);
184 quicktime_atom_write_footer(file
, &strf_atom
);
189 /* Junk is required in Windows. */
190 /* In Heroine Kernel it's padding for the super index */
191 strl
->indx_offset
= quicktime_position(file
);
192 strl
->padding_size
= JUNK_SIZE
;
196 quicktime_atom_write_header(file
, &junk_atom
, "JUNK");
197 for(i
= 0; i
< JUNK_SIZE
; i
+= 4)
198 quicktime_write_int32_le(file
, 0);
199 quicktime_atom_write_footer(file
, &junk_atom
);
202 /* Initialize super index */
203 quicktime_init_indx(file
, &strl
->indx
, strl
);
206 quicktime_atom_write_footer(file
, &list_atom
);
211 void quicktime_delete_strl(quicktime_strl_t
*strl
)
213 quicktime_delete_indx(&strl
->indx
);
217 void quicktime_read_strl(quicktime_t
*file
,
218 quicktime_strl_t
*strl
,
219 quicktime_atom_t
*parent_atom
)
221 // These are 0 if no track is currently being processed.
222 // Set to 1 if audio or video track is being processed.
223 char data
[4], codec
[4];
231 int bytes_per_sample
;
234 int samples_per_chunk
;
238 int bytes_per_second
;
239 quicktime_trak_t
*trak
= 0;
240 quicktime_riff_t
*first_riff
= file
->riff
[0];
243 codec
[0] = codec
[1] = codec
[2] = codec
[3] = 0;
245 /* AVI translation: */
248 /* Only one track is in each strl object */
251 quicktime_atom_t leaf_atom
;
252 quicktime_atom_read_header(file
, &leaf_atom
);
255 if(quicktime_atom_is(&leaf_atom
, "strh"))
258 quicktime_read_data(file
, data
, 4);
260 if(quicktime_match_32(data
, "vids"))
262 trak
= quicktime_add_trak(file
);
270 trak
->tkhd
.track_id
= file
->moov
.mvhd
.next_track_id
;
271 file
->moov
.mvhd
.next_track_id
++;
275 quicktime_read_data(file
,
278 //printf("quicktime_read_strl 1 %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
280 quicktime_set_position(file
, quicktime_position(file
) + 12);
281 denominator
= quicktime_read_int32_le(file
);
282 numerator
= quicktime_read_int32_le(file
);
284 frame_rate
= (double)numerator
/ denominator
;
286 frame_rate
= numerator
;
289 quicktime_set_position(file
, quicktime_position(file
) + 4);
290 frames
= quicktime_read_int32_le(file
);
293 if(quicktime_match_32(data
, "auds"))
295 trak
= quicktime_add_trak(file
);
302 trak
->tkhd
.track_id
= file
->moov
.mvhd
.next_track_id
;
303 file
->moov
.mvhd
.next_track_id
++;
304 quicktime_read_data(file
,
307 //printf("quicktime_read_strl 2 %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
308 quicktime_set_position(file
, quicktime_position(file
) + 12);
309 samples_per_chunk
= quicktime_read_int32_le(file
);
310 bytes_per_second
= quicktime_read_int32_le(file
);
312 quicktime_set_position(file
, quicktime_position(file
) + 4);
313 /* length of track */
314 samples
= quicktime_read_int32_le(file
);
315 /* suggested buffer size, quality */
316 quicktime_set_position(file
, quicktime_position(file
) + 8);
318 // If this is 0 use constant samples_per_chunk to guess locations.
319 // If it isn't 0 synthesize samples per chunk table to get locations.
320 // McRowesoft doesn't really obey this rule so we may need to base it on codec ID.
321 bytes_per_sample
= quicktime_read_int32_le(file
);
322 //printf("quicktime_read_strl 20 %d\n", samples_per_chunk);
327 if(quicktime_atom_is(&leaf_atom
, "strf"))
331 /* atom size repeated */
332 quicktime_read_int32_le(file
);
333 width
= quicktime_read_int32_le(file
);
334 height
= quicktime_read_int32_le(file
);
336 quicktime_read_int16_le(file
);
338 depth
= quicktime_read_int16_le(file
);
339 quicktime_read_data(file
,
346 compression_id
= quicktime_read_int16_le(file
);
347 channels
= quicktime_read_int16_le(file
);
348 sample_rate
= quicktime_read_int32_le(file
);
349 quicktime_set_position(file
, quicktime_position(file
) + 6);
350 sample_size
= quicktime_read_int16_le(file
);
351 //printf("quicktime_read_strl 40 %d %d %d\n", channels, sample_rate, sample_size);
356 // Read the super index + all the partial indexes now
357 if(quicktime_atom_is(&leaf_atom
, "indx"))
359 //printf("quicktime_read_strl 50\n");
360 quicktime_read_indx(file
, strl
, &leaf_atom
);
364 //printf("quicktime_read_strl 60\n");
368 quicktime_atom_skip(file
, &leaf_atom
);
369 }while(quicktime_position(file
) < parent_atom
->end
);
370 //printf("quicktime_read_strl 70 %d %d\n", strl->is_audio, strl->is_video);
375 /* Generate quicktime structures */
376 quicktime_trak_init_video(file
,
382 quicktime_mhvd_init_video(file
,
385 trak
->mdia
.mdhd
.duration
= frames
;
386 // trak->mdia.mdhd.time_scale = 1;
387 memcpy(trak
->mdia
.minf
.stbl
.stsd
.table
[0].format
, codec
, 4);
388 trak
->mdia
.minf
.stbl
.stsd
.table
[0].depth
= depth
;
393 /* Generate quicktime structures */
394 //printf("quicktime_read_strl 70 %d\n", sample_size);
395 quicktime_trak_init_audio(file
,
403 // We store a constant samples per chunk based on the
404 // packet size if sample_size zero
405 // and calculate the samples per chunk based on the chunk size if sample_size
407 // trak->mdia.minf.stbl.stsd.table[0].sample_size = bytes_per_sample;
408 trak
->mdia
.minf
.stbl
.stsd
.table
[0].compression_id
= compression_id
;
410 /* Synthesize stsc table for constant samples per chunk */
411 if(!bytes_per_sample
)
413 /* Should be enough entries allocated in quicktime_stsc_init_table */
414 trak
->mdia
.minf
.stbl
.stsc
.table
[0].samples
= samples_per_chunk
;
415 trak
->mdia
.minf
.stbl
.stsc
.total_entries
= 1;
420 //printf("quicktime_read_strl 100\n");