Make FloatAutos::get_values() always use a PLAY_FORWARD direction.
[cinelerra_cv/pmdumuid.git] / quicktime / avi_strl.c
blob320295b84e590a860a5f083ac6e001257e2c8ac7
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include <string.h>
6 // Update during close:
7 // length
8 // samples per chunk
9 #define JUNK_SIZE 0x1018
13 quicktime_strl_t* quicktime_new_strl()
15 quicktime_strl_t *strl = calloc(1, sizeof(quicktime_strl_t));
16 return strl;
20 void quicktime_init_strl(quicktime_t *file,
21 quicktime_audio_map_t *atrack,
22 quicktime_video_map_t *vtrack,
23 quicktime_trak_t *trak,
24 quicktime_strl_t *strl)
26 quicktime_atom_t list_atom, strh_atom, strf_atom;
27 quicktime_atom_t junk_atom;
28 int i;
30 /* Construct tag */
31 if(vtrack)
33 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
34 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
35 strl->tag[2] = 'd';
36 strl->tag[3] = 'c';
38 else
39 if(atrack)
41 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
42 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
43 strl->tag[2] = 'w';
44 strl->tag[3] = 'b';
48 /* LIST 'strl' */
49 quicktime_atom_write_header(file, &list_atom, "LIST");
50 quicktime_write_char32(file, "strl");
52 /* 'strh' */
53 quicktime_atom_write_header(file, &strh_atom, "strh");
57 /* vids */
58 if(vtrack)
60 quicktime_write_char32(file, "vids");
61 quicktime_write_char32(file,
62 trak->mdia.minf.stbl.stsd.table[0].format);
63 /* flags */
64 quicktime_write_int32_le(file, 0);
65 /* priority */
66 quicktime_write_int16_le(file, 0);
67 /* language */
68 quicktime_write_int16_le(file, 0);
69 /* initial frame */
70 quicktime_write_int32_le(file, 0);
72 /* framerate denominator */
73 quicktime_write_int32_le(file,
74 trak->mdia.minf.stbl.stts.table[0].sample_duration);
75 /* framerate numerator */
76 quicktime_write_int32_le(file,
77 trak->mdia.mdhd.time_scale);
79 /* start */
80 quicktime_write_int32_le(file, 0);
81 strl->length_offset = quicktime_position(file);
82 /* length: fill later */
83 quicktime_write_int32_le(file, 0);
84 /* suggested buffer size */
85 quicktime_write_int32_le(file, 0);
86 /* quality */
87 quicktime_write_int32_le(file, -1);
88 /* sample size */
89 quicktime_write_int32_le(file, 0);
90 quicktime_write_int16_le(file, 0);
91 quicktime_write_int16_le(file, 0);
92 quicktime_write_int16_le(file, trak->tkhd.track_width);
93 quicktime_write_int16_le(file, trak->tkhd.track_height);
95 else
96 /* auds */
97 if(atrack)
99 quicktime_write_char32(file, "auds");
100 quicktime_write_int32_le(file, 0);
101 /* flags */
102 quicktime_write_int32_le(file, 0);
103 /* priority */
104 quicktime_write_int16_le(file, 0);
105 /* language */
106 quicktime_write_int16_le(file, 0);
107 /* initial frame */
108 quicktime_write_int32_le(file, 0);
109 strl->samples_per_chunk_offset = quicktime_position(file);
110 /* samples per chunk */
111 quicktime_write_int32_le(file, 0);
112 /* sample rate * samples per chunk if uncompressed */
113 /* sample rate if compressed */
114 quicktime_write_int32_le(file, 0);
115 /* start */
116 quicktime_write_int32_le(file, 0);
117 strl->length_offset = quicktime_position(file);
118 /* length, XXX: filled later */
119 quicktime_write_int32_le(file, 0);
120 /* suggested buffer size */
121 quicktime_write_int32_le(file, 0);
122 /* quality */
123 quicktime_write_int32_le(file, -1);
124 /* sample size: 0 for compressed and number of bytes for uncompressed */
125 strl->sample_size_offset = quicktime_position(file);
126 quicktime_write_int32_le(file, 0);
127 quicktime_write_int32_le(file, 0);
128 quicktime_write_int32_le(file, 0);
130 quicktime_atom_write_footer(file, &strh_atom);
138 /* strf */
139 quicktime_atom_write_header(file, &strf_atom, "strf");
141 if(vtrack)
143 /* atom size repeated */
144 quicktime_write_int32_le(file, 40);
145 quicktime_write_int32_le(file, trak->tkhd.track_width);
146 quicktime_write_int32_le(file, trak->tkhd.track_height);
147 /* planes */
148 quicktime_write_int16_le(file, 1);
149 /* depth */
150 quicktime_write_int16_le(file, 24);
151 quicktime_write_char32(file,
152 trak->mdia.minf.stbl.stsd.table[0].format);
153 quicktime_write_int32_le(file,
154 trak->tkhd.track_width * trak->tkhd.track_height * 3);
155 quicktime_write_int32_le(file, 0);
156 quicktime_write_int32_le(file, 0);
157 quicktime_write_int32_le(file, 0);
158 quicktime_write_int32_le(file, 0);
160 else
161 if(atrack)
163 /* By now the codec is instantiated so the WAV ID is available. */
164 int wav_id = 0x0;
165 quicktime_codec_t *codec_base = atrack->codec;
167 if(codec_base->wav_id)
168 wav_id = codec_base->wav_id;
169 quicktime_write_int16_le(file,
170 wav_id);
171 quicktime_write_int16_le(file,
172 trak->mdia.minf.stbl.stsd.table[0].channels);
173 quicktime_write_int32_le(file,
174 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
175 /* bitrate in bytes */
176 quicktime_write_int32_le(file, 256000 / 8);
177 /* block align */
178 quicktime_write_int16_le(file, 1);
179 /* bits per sample */
180 quicktime_write_int16_le(file,
181 trak->mdia.minf.stbl.stsd.table[0].sample_size);
182 quicktime_write_int16_le(file, 0);
185 quicktime_atom_write_footer(file, &strf_atom);
190 /* Junk is required in Windows. */
191 /* In Heroine Kernel it's padding for the super index */
192 strl->indx_offset = quicktime_position(file);
193 strl->padding_size = JUNK_SIZE;
197 quicktime_atom_write_header(file, &junk_atom, "JUNK");
198 for(i = 0; i < JUNK_SIZE; i += 4)
199 quicktime_write_int32_le(file, 0);
200 quicktime_atom_write_footer(file, &junk_atom);
203 /* Initialize super index */
204 quicktime_init_indx(file, &strl->indx, strl);
207 quicktime_atom_write_footer(file, &list_atom);
212 void quicktime_delete_strl(quicktime_strl_t *strl)
214 quicktime_delete_indx(&strl->indx);
215 free(strl);
218 void quicktime_read_strl(quicktime_t *file,
219 quicktime_strl_t *strl,
220 quicktime_atom_t *parent_atom)
222 // These are 0 if no track is currently being processed.
223 // Set to 1 if audio or video track is being processed.
224 char data[4], codec[4];
225 int denominator;
226 int numerator;
227 double frame_rate;
228 int width;
229 int height;
230 int depth;
231 int frames;
232 int bytes_per_sample;
233 int sample_size;
234 int samples;
235 int samples_per_chunk;
236 int channels;
237 int sample_rate;
238 int compression_id;
239 int bytes_per_second;
240 quicktime_trak_t *trak = 0;
241 quicktime_riff_t *first_riff = file->riff[0];
244 codec[0] = codec[1] = codec[2] = codec[3] = 0;
246 /* AVI translation: */
247 /* vids -> trak */
248 /* auds -> trak */
249 /* Only one track is in each strl object */
252 quicktime_atom_t leaf_atom;
253 quicktime_atom_read_header(file, &leaf_atom);
255 // strh
256 if(quicktime_atom_is(&leaf_atom, "strh"))
258 // stream type
259 quicktime_read_data(file, data, 4);
261 if(quicktime_match_32(data, "vids"))
263 trak = quicktime_add_trak(file);
264 width = 0;
265 height = 0;
266 depth = 24;
267 frames = 0;
268 strl->is_video = 1;
271 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
272 file->moov.mvhd.next_track_id++;
275 /* Codec */
276 quicktime_read_data(file,
277 codec,
279 //printf("quicktime_read_strl 1 %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
280 /* Blank */
281 quicktime_set_position(file, quicktime_position(file) + 12);
282 denominator = quicktime_read_int32_le(file);
283 numerator = quicktime_read_int32_le(file);
284 if(denominator != 0)
285 frame_rate = (double)numerator / denominator;
286 else
287 frame_rate = numerator;
289 /* Blank */
290 quicktime_set_position(file, quicktime_position(file) + 4);
291 frames = quicktime_read_int32_le(file);
293 else
294 if(quicktime_match_32(data, "auds"))
296 trak = quicktime_add_trak(file);
297 sample_size = 16;
298 channels = 2;
299 sample_rate = 0;
300 compression_id = 0;
301 strl->is_audio = 1;
303 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
304 file->moov.mvhd.next_track_id++;
305 quicktime_read_data(file,
306 codec,
308 //printf("quicktime_read_strl 2 %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
309 quicktime_set_position(file, quicktime_position(file) + 12);
310 samples_per_chunk = quicktime_read_int32_le(file);
311 bytes_per_second = quicktime_read_int32_le(file);
312 /* start */
313 quicktime_set_position(file, quicktime_position(file) + 4);
314 /* length of track */
315 samples = quicktime_read_int32_le(file);
316 /* suggested buffer size, quality */
317 quicktime_set_position(file, quicktime_position(file) + 8);
319 // If this is 0 use constant samples_per_chunk to guess locations.
320 // If it isn't 0 synthesize samples per chunk table to get locations.
321 // McRowesoft doesn't really obey this rule so we may need to base it on codec ID.
322 bytes_per_sample = quicktime_read_int32_le(file);
323 //printf("quicktime_read_strl 20 %d\n", samples_per_chunk);
326 // strf
327 else
328 if(quicktime_atom_is(&leaf_atom, "strf"))
330 if(strl->is_video)
332 /* atom size repeated */
333 quicktime_read_int32_le(file);
334 width = quicktime_read_int32_le(file);
335 height = quicktime_read_int32_le(file);
336 /* Panes */
337 quicktime_read_int16_le(file);
338 /* Depth in bits */
339 depth = quicktime_read_int16_le(file);
340 quicktime_read_data(file,
341 codec,
344 else
345 if(strl->is_audio)
347 compression_id = quicktime_read_int16_le(file);
348 channels = quicktime_read_int16_le(file);
349 sample_rate = quicktime_read_int32_le(file);
350 quicktime_set_position(file, quicktime_position(file) + 6);
351 sample_size = quicktime_read_int16_le(file);
352 //printf("quicktime_read_strl 40 %d %d %d\n", channels, sample_rate, sample_size);
355 else
356 // Super index.
357 // Read the super index + all the partial indexes now
358 if(quicktime_atom_is(&leaf_atom, "indx"))
360 //printf("quicktime_read_strl 50\n");
361 quicktime_read_indx(file, strl, &leaf_atom);
362 strl->have_indx = 1;
365 //printf("quicktime_read_strl 60\n");
368 // Next object
369 quicktime_atom_skip(file, &leaf_atom);
370 }while(quicktime_position(file) < parent_atom->end);
371 //printf("quicktime_read_strl 70 %d %d\n", strl->is_audio, strl->is_video);
374 if(strl->is_video)
376 /* Generate quicktime structures */
377 quicktime_trak_init_video(file,
378 trak,
379 width,
380 height,
381 frame_rate,
382 codec);
383 quicktime_mhvd_init_video(file,
384 &file->moov.mvhd,
385 frame_rate);
386 trak->mdia.mdhd.duration = frames;
387 // trak->mdia.mdhd.time_scale = 1;
388 memcpy(trak->mdia.minf.stbl.stsd.table[0].format, codec, 4);
389 trak->mdia.minf.stbl.stsd.table[0].depth = depth;
391 else
392 if(strl->is_audio)
394 /* Generate quicktime structures */
395 //printf("quicktime_read_strl 70 %d\n", sample_size);
396 quicktime_trak_init_audio(file,
397 trak,
398 channels,
399 sample_rate,
400 sample_size,
401 codec);
404 // We store a constant samples per chunk based on the
405 // packet size if sample_size zero
406 // and calculate the samples per chunk based on the chunk size if sample_size
407 // is nonzero.
408 // trak->mdia.minf.stbl.stsd.table[0].sample_size = bytes_per_sample;
409 trak->mdia.minf.stbl.stsd.table[0].compression_id = compression_id;
411 /* Synthesize stsc table for constant samples per chunk */
412 if(!bytes_per_sample)
414 /* Should be enough entries allocated in quicktime_stsc_init_table */
415 trak->mdia.minf.stbl.stsc.table[0].samples = samples_per_chunk;
416 trak->mdia.minf.stbl.stsc.total_entries = 1;
421 //printf("quicktime_read_strl 100\n");