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 // Acutally use the proper data and formula for calculating period of one frame, previous was wrong
66 if(file
->total_vtracks
)
67 quicktime_write_int32_le(file
,
68 (uint32_t)((double)1000000 * quicktime_frame_rate_d(file
, 0) / quicktime_frame_rate_n(file
,0)));
70 quicktime_write_int32_le(file
, 0);
72 hdrl
->bitrate_offset
= quicktime_position(file
);
73 quicktime_write_int32_le(file
, 0); /* bitrate in bytes */
74 quicktime_write_int32_le(file
, 0); /* padding */
75 quicktime_write_int32_le(file
,
79 AVI_ISINTERLEAVED
); /* flags */
80 hdrl
->frames_offset
= quicktime_position(file
);
81 quicktime_write_int32_le(file
, 0); /* nb frames, filled later */
82 quicktime_write_int32_le(file
, 0); /* initial frame */
83 quicktime_write_int32_le(file
, file
->moov
.total_tracks
); /* nb streams */
84 quicktime_write_int32_le(file
, 0); /* suggested buffer size */
86 if(file
->total_vtracks
)
88 quicktime_write_int32_le(file
, file
->vtracks
[0].track
->tkhd
.track_width
);
89 quicktime_write_int32_le(file
, file
->vtracks
[0].track
->tkhd
.track_height
);
93 quicktime_write_int32_le(file
, 0);
94 quicktime_write_int32_le(file
, 0);
96 quicktime_write_int32_le(file
, 0); /* reserved */
97 quicktime_write_int32_le(file
, 0); /* reserved */
98 quicktime_write_int32_le(file
, 0); /* reserved */
99 quicktime_write_int32_le(file
, 0); /* reserved */
101 quicktime_atom_write_footer(file
, &avih_atom
);
104 /* Write stream lists. */
105 /* Need the track maps to get the WAV ID for audio. */
107 for(i
= 0; i
< file
->total_vtracks
; i
++)
109 quicktime_video_map_t
*video_map
= &file
->vtracks
[i
];
110 quicktime_trak_t
*trak
= video_map
->track
;
111 quicktime_strl_t
*strl
=
112 hdrl
->strl
[current_track
++] =
113 quicktime_new_strl();
114 quicktime_init_strl(file
,
121 for(i
= 0; i
< file
->total_atracks
; i
++)
123 quicktime_audio_map_t
*audio_map
= &file
->atracks
[i
];
124 quicktime_trak_t
*trak
= audio_map
->track
;
125 quicktime_strl_t
*strl
=
126 hdrl
->strl
[current_track
++] =
127 quicktime_new_strl();
128 quicktime_init_strl(file
,
136 * for(i = 0; i < file->moov.total_tracks; i++)
138 * printf("quicktime_init_hdrl 10 %d %p\n", i, file->riff[0]->hdrl.strl[i]->tag);
143 quicktime_init_odml(file
, hdrl
);
144 quicktime_atom_write_footer(file
, &hdrl
->atom
);
148 void quicktime_finalize_hdrl(quicktime_t
*file
, quicktime_hdrl_t
*hdrl
)
151 int64_t position
= quicktime_position(file
);
152 int64_t total_frames
= 0;
153 double frame_rate
= 0;
155 for(i
= 0; i
< file
->moov
.total_tracks
; i
++)
157 quicktime_trak_t
*trak
= file
->moov
.trak
[i
];
158 quicktime_strl_t
*strl
= hdrl
->strl
[i
];
160 if(trak
->mdia
.minf
.is_video
)
163 quicktime_set_position(file
, strl
->length_offset
);
164 total_frames
= length
= quicktime_track_samples(file
, trak
);
165 quicktime_write_int32_le(file
, length
);
166 frame_rate
= (double)trak
->mdia
.mdhd
.time_scale
/
167 trak
->mdia
.minf
.stbl
.stts
.table
[0].sample_duration
;
170 if(trak
->mdia
.minf
.is_audio
)
172 int length
, samples_per_chunk
;
173 quicktime_set_position(file
, strl
->length_offset
);
174 length
= quicktime_track_samples(file
, trak
);
175 quicktime_write_int32_le(file
, length
);
177 // dwScale and dwRate as per MSDN - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemultimedia5/html/wce50conAVIStreamHeaders.asp
178 quicktime_set_position(file
, strl
->samples_per_chunk_offset
);
179 int wav_id
= ((quicktime_codec_t
*)(file
->atracks
[0].codec
))->wav_id
;
180 samples_per_chunk
= quicktime_avg_chunk_samples(file
, trak
);
182 { // for uncompressed - as per avi_strl.c, which has accurate comment that we should tread compressed and uncompressed differently
183 // we could also multiply both by samples_per_chunk... but then we would be screwed because of overflow!
184 quicktime_write_int32_le(file
,
186 quicktime_write_int32_le(file
,
187 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
190 quicktime_write_int32_le(file
,
192 quicktime_write_int32_le(file
,
193 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
);
195 quicktime_set_position(file
, strl
->sample_size_offset
);
197 // dwSampleSize as per MSDN
200 // as per http://www.virtualdub.org/blog/pivot/entry.php?id=27, many programs ignore this value
201 // sample_size in quicktime is in bytes... so we must divide by 8
202 quicktime_write_int32_le(file
,
203 trak
->mdia
.minf
.stbl
.stsd
.table
[0].channels
* trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
/ 8);
207 // This can be codec specific...
208 // FIXME: This has to be zero for _all_ VBR encodings, and other values are used for specific encodings
209 quicktime_write_int32_le(file
,
210 trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_size
);
217 quicktime_set_position(file
, hdrl
->bitrate_offset
);
218 quicktime_write_int32_le(file
,
219 file
->total_length
/ (total_frames
/ frame_rate
));
220 quicktime_set_position(file
, hdrl
->frames_offset
);
221 quicktime_write_int32_le(file
, total_frames
);
224 quicktime_set_position(file
, position
);