1 #include "funcprotos.h"
6 void quicktime_delete_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
9 for(i = 0; i < file->moov.total_tracks; i++)
11 quicktime_delete_strl(hdrl->strl[i]);
16 void quicktime_read_hdrl(quicktime_t *file,
17 quicktime_hdrl_t *hdrl,
18 quicktime_atom_t *parent_atom)
20 quicktime_atom_t leaf_atom;
22 int current_track = 0;
24 //printf("quicktime_read_hdrl 1\n");
27 quicktime_atom_read_header(file, &leaf_atom);
30 if(quicktime_atom_is(&leaf_atom, "LIST"))
32 data[0] = data[1] = data[2] = data[3] = 0;
33 quicktime_read_data(file, data, 4);
36 if(quicktime_match_32(data, "strl"))
38 quicktime_strl_t *strl =
39 hdrl->strl[current_track++] =
41 quicktime_read_strl(file, strl, &leaf_atom);
45 quicktime_atom_skip(file, &leaf_atom);
46 }while(quicktime_position(file) < parent_atom->end);
48 quicktime_atom_skip(file, &leaf_atom);
51 void quicktime_init_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
54 quicktime_atom_t avih_atom;
58 quicktime_atom_write_header(file, &hdrl->atom, "LIST");
59 quicktime_write_char32(file, "hdrl");
63 quicktime_atom_write_header(file, &avih_atom, "avih");
65 if(file->total_vtracks) {
66 int d = quicktime_frame_rate_d(file, 0);
67 int n = quicktime_frame_rate_n(file, 0);
68 quicktime_write_int32_le(file, (uint32_t)(1000000. * d / n));
71 quicktime_write_int32_le(file, 0);
73 hdrl->bitrate_offset = quicktime_position(file);
74 quicktime_write_int32_le(file, 0); /* bitrate in bytes */
75 quicktime_write_int32_le(file, 0); /* padding */
76 quicktime_write_int32_le(file,
80 AVI_ISINTERLEAVED); /* flags */
81 hdrl->frames_offset = quicktime_position(file);
82 quicktime_write_int32_le(file, 0); /* nb frames, filled later */
83 quicktime_write_int32_le(file, 0); /* initial frame */
84 quicktime_write_int32_le(file, file->moov.total_tracks); /* nb streams */
85 quicktime_write_int32_le(file, 0); /* suggested buffer size */
87 if(file->total_vtracks)
89 quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_width);
90 quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_height);
94 quicktime_write_int32_le(file, 0);
95 quicktime_write_int32_le(file, 0);
97 quicktime_write_int32_le(file, 0); /* reserved */
98 quicktime_write_int32_le(file, 0); /* reserved */
99 quicktime_write_int32_le(file, 0); /* reserved */
100 quicktime_write_int32_le(file, 0); /* reserved */
102 quicktime_atom_write_footer(file, &avih_atom);
105 /* Write stream lists. */
106 /* Need the track maps to get the WAV ID for audio. */
108 for(i = 0; i < file->total_vtracks; i++)
110 quicktime_video_map_t *video_map = &file->vtracks[i];
111 quicktime_trak_t *trak = video_map->track;
112 quicktime_strl_t *strl =
113 hdrl->strl[current_track++] =
114 quicktime_new_strl();
115 quicktime_init_strl(file,
122 for(i = 0; i < file->total_atracks; i++)
124 quicktime_audio_map_t *audio_map = &file->atracks[i];
125 quicktime_trak_t *trak = audio_map->track;
126 quicktime_strl_t *strl =
127 hdrl->strl[current_track++] =
128 quicktime_new_strl();
129 quicktime_init_strl(file,
137 * for(i = 0; i < file->moov.total_tracks; i++)
139 * printf("quicktime_init_hdrl 10 %d %p\n", i, file->riff[0]->hdrl.strl[i]->tag);
144 quicktime_init_odml(file, hdrl);
145 quicktime_atom_write_footer(file, &hdrl->atom);
149 void quicktime_finalize_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
152 int64_t position = quicktime_position(file);
153 int64_t total_frames = 0;
154 double frame_rate = 0;
156 for(i = 0; i < file->moov.total_tracks; i++)
158 quicktime_trak_t *trak = file->moov.trak[i];
159 quicktime_strl_t *strl = hdrl->strl[i];
161 if(trak->mdia.minf.is_video)
164 quicktime_set_position(file, strl->length_offset);
165 total_frames = length = quicktime_track_samples(file, trak);
166 quicktime_write_int32_le(file, length);
167 frame_rate = (double)trak->mdia.mdhd.time_scale /
168 trak->mdia.minf.stbl.stts.table[0].sample_duration;
171 if(trak->mdia.minf.is_audio)
173 int length, samples_per_chunk, wav_id, sample_size, sample_rate;
174 quicktime_set_position(file, strl->length_offset);
175 length = quicktime_track_samples(file, trak);
176 quicktime_write_int32_le(file, length);
178 // dwScale and dwRate as per MSDN - // http://msdn.microsoft.com/library/default.asp?
179 // url=/library/en-us/wcemultimedia5/html/wce50conAVIStreamHeaders.asp
180 quicktime_set_position(file, strl->samples_per_chunk_offset);
181 wav_id = ((quicktime_codec_t*)(file->atracks[0].codec))->wav_id;
182 samples_per_chunk = wav_id == 1 ? 1 :
183 quicktime_avg_chunk_samples(file, trak);
184 quicktime_write_int32_le(file, samples_per_chunk);
185 sample_rate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
186 quicktime_write_int32_le(file, sample_rate);
187 quicktime_set_position(file, strl->sample_size_offset);
189 // dwSampleSize as per MSDN
190 // as per http://www.virtualdub.org/blog/pivot/entry.php?id=27, many programs ignore this value
191 // sample_size in quicktime is in bits... so we must divide by 8
192 // FIXME: This has to be zero for _all_ VBR encodings, and other values are used for specific encodings
193 sample_size = trak->mdia.minf.stbl.stsd.table[0].sample_size;
194 quicktime_write_int32_le(file, wav_id != 1 ? sample_size :
195 trak->mdia.minf.stbl.stsd.table[0].channels * sample_size / 8);
201 quicktime_set_position(file, hdrl->bitrate_offset);
202 quicktime_write_int32_le(file,
203 file->total_length / (total_frames / frame_rate));
204 quicktime_set_position(file, hdrl->frames_offset);
205 quicktime_write_int32_le(file, total_frames);
208 quicktime_set_position(file, position);