r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / avi_strl.c
blob25a3cd409b29025fa98265137ed04e403ebc393d
1 #include "funcprotos.h"
2 #include "quicktime.h"
5 // Update during close:
6 // length
7 // samples per chunk
8 #define JUNK_SIZE 0x1018
12 quicktime_strl_t* quicktime_new_strl()
14 quicktime_strl_t *strl = calloc(1, sizeof(quicktime_strl_t));
15 return strl;
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;
27 int i;
29 /* Construct tag */
30 if(vtrack)
32 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
33 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
34 strl->tag[2] = 'd';
35 strl->tag[3] = 'c';
37 else
38 if(atrack)
40 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
41 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
42 strl->tag[2] = 'w';
43 strl->tag[3] = 'b';
47 /* LIST 'strl' */
48 quicktime_atom_write_header(file, &list_atom, "LIST");
49 quicktime_write_char32(file, "strl");
51 /* 'strh' */
52 quicktime_atom_write_header(file, &strh_atom, "strh");
56 /* vids */
57 if(vtrack)
59 quicktime_write_char32(file, "vids");
60 quicktime_write_char32(file,
61 trak->mdia.minf.stbl.stsd.table[0].format);
62 /* flags */
63 quicktime_write_int32_le(file, 0);
64 /* priority */
65 quicktime_write_int16_le(file, 0);
66 /* language */
67 quicktime_write_int16_le(file, 0);
68 /* initial frame */
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);
78 /* start */
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);
85 /* quality */
86 quicktime_write_int32_le(file, -1);
87 /* sample size */
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);
94 else
95 /* auds */
96 if(atrack)
98 quicktime_write_char32(file, "auds");
99 quicktime_write_int32_le(file, 0);
100 /* flags */
101 quicktime_write_int32_le(file, 0);
102 /* priority */
103 quicktime_write_int16_le(file, 0);
104 /* language */
105 quicktime_write_int16_le(file, 0);
106 /* initial frame */
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);
114 /* start */
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);
121 /* quality */
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);
137 /* strf */
138 quicktime_atom_write_header(file, &strf_atom, "strf");
140 if(vtrack)
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);
146 /* planes */
147 quicktime_write_int16_le(file, 1);
148 /* depth */
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);
159 else
160 if(atrack)
162 /* By now the codec is instantiated so the WAV ID is available. */
163 int wav_id = 0x0;
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,
169 wav_id);
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);
176 /* block align */
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);
214 free(strl);
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];
224 int denominator;
225 int numerator;
226 double frame_rate;
227 int width;
228 int height;
229 int depth;
230 int frames;
231 int bytes_per_sample;
232 int sample_size;
233 int samples;
234 int samples_per_chunk;
235 int channels;
236 int sample_rate;
237 int compression_id;
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: */
246 /* vids -> trak */
247 /* auds -> trak */
248 /* Only one track is in each strl object */
251 quicktime_atom_t leaf_atom;
252 quicktime_atom_read_header(file, &leaf_atom);
254 // strh
255 if(quicktime_atom_is(&leaf_atom, "strh"))
257 // stream type
258 quicktime_read_data(file, data, 4);
260 if(quicktime_match_32(data, "vids"))
262 trak = quicktime_add_trak(file);
263 width = 0;
264 height = 0;
265 depth = 24;
266 frames = 0;
267 strl->is_video = 1;
270 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
271 file->moov.mvhd.next_track_id++;
274 /* Codec */
275 quicktime_read_data(file,
276 codec,
278 //printf("quicktime_read_strl 1 %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
279 /* Blank */
280 quicktime_set_position(file, quicktime_position(file) + 12);
281 denominator = quicktime_read_int32_le(file);
282 numerator = quicktime_read_int32_le(file);
283 if(denominator != 0)
284 frame_rate = (double)numerator / denominator;
285 else
286 frame_rate = numerator;
288 /* Blank */
289 quicktime_set_position(file, quicktime_position(file) + 4);
290 frames = quicktime_read_int32_le(file);
292 else
293 if(quicktime_match_32(data, "auds"))
295 trak = quicktime_add_trak(file);
296 sample_size = 16;
297 channels = 2;
298 sample_rate = 0;
299 compression_id = 0;
300 strl->is_audio = 1;
302 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
303 file->moov.mvhd.next_track_id++;
304 quicktime_read_data(file,
305 codec,
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);
311 /* start */
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);
325 // strf
326 else
327 if(quicktime_atom_is(&leaf_atom, "strf"))
329 if(strl->is_video)
331 /* atom size repeated */
332 quicktime_read_int32_le(file);
333 width = quicktime_read_int32_le(file);
334 height = quicktime_read_int32_le(file);
335 /* Panes */
336 quicktime_read_int16_le(file);
337 /* Depth in bits */
338 depth = quicktime_read_int16_le(file);
339 quicktime_read_data(file,
340 codec,
343 else
344 if(strl->is_audio)
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);
354 else
355 // Super index.
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);
361 strl->have_indx = 1;
364 //printf("quicktime_read_strl 60\n");
367 // Next object
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);
373 if(strl->is_video)
375 /* Generate quicktime structures */
376 quicktime_trak_init_video(file,
377 trak,
378 width,
379 height,
380 frame_rate,
381 codec);
382 quicktime_mhvd_init_video(file,
383 &file->moov.mvhd,
384 frame_rate);
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;
390 else
391 if(strl->is_audio)
393 /* Generate quicktime structures */
394 //printf("quicktime_read_strl 70 %d\n", sample_size);
395 quicktime_trak_init_audio(file,
396 trak,
397 channels,
398 sample_rate,
399 sample_size,
400 codec);
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
406 // is nonzero.
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");