00001 #include "funcprotos.h"
00002 #include "quicktime.h"
00003
00004
00005
00006 void quicktime_delete_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
00007 {
00008 int i;
00009 for(i = 0; i < file->moov.total_tracks; i++)
00010 {
00011 quicktime_delete_strl(hdrl->strl[i]);
00012 }
00013 }
00014
00015
00016 void quicktime_read_hdrl(quicktime_t *file,
00017 quicktime_hdrl_t *hdrl,
00018 quicktime_atom_t *parent_atom)
00019 {
00020 quicktime_atom_t leaf_atom;
00021 char data[4];
00022 int current_track = 0;
00023
00024
00025 do
00026 {
00027 quicktime_atom_read_header(file, &leaf_atom);
00028
00029
00030 if(quicktime_atom_is(&leaf_atom, "LIST"))
00031 {
00032 data[0] = data[1] = data[2] = data[3] = 0;
00033 quicktime_read_data(file, data, 4);
00034
00035
00036 if(quicktime_match_32(data, "strl"))
00037 {
00038 quicktime_strl_t *strl =
00039 hdrl->strl[current_track++] =
00040 quicktime_new_strl();
00041 quicktime_read_strl(file, strl, &leaf_atom);
00042 }
00043 }
00044
00045 quicktime_atom_skip(file, &leaf_atom);
00046 }while(quicktime_position(file) < parent_atom->end);
00047
00048 quicktime_atom_skip(file, &leaf_atom);
00049 }
00050
00051 void quicktime_init_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
00052 {
00053 int i;
00054 quicktime_atom_t avih_atom;
00055 int current_track;
00056
00057
00058 quicktime_atom_write_header(file, &hdrl->atom, "LIST");
00059 quicktime_write_char32(file, "hdrl");
00060
00061
00062
00063 quicktime_atom_write_header(file, &avih_atom, "avih");
00064
00065
00066 if(file->total_vtracks)
00067 quicktime_write_int32_le(file,
00068 (uint32_t)((double)1000000 * quicktime_frame_rate_d(file, 0) / quicktime_frame_rate_n(file,0)));
00069 else
00070 quicktime_write_int32_le(file, 0);
00071
00072 hdrl->bitrate_offset = quicktime_position(file);
00073 quicktime_write_int32_le(file, 0);
00074 quicktime_write_int32_le(file, 0);
00075 quicktime_write_int32_le(file,
00076 AVI_TRUSTCKTYPE |
00077 AVI_HASINDEX |
00078 AVI_MUSTUSEINDEX |
00079 AVI_ISINTERLEAVED);
00080 hdrl->frames_offset = quicktime_position(file);
00081 quicktime_write_int32_le(file, 0);
00082 quicktime_write_int32_le(file, 0);
00083 quicktime_write_int32_le(file, file->moov.total_tracks);
00084 quicktime_write_int32_le(file, 0);
00085
00086 if(file->total_vtracks)
00087 {
00088 quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_width);
00089 quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_height);
00090 }
00091 else
00092 {
00093 quicktime_write_int32_le(file, 0);
00094 quicktime_write_int32_le(file, 0);
00095 }
00096 quicktime_write_int32_le(file, 0);
00097 quicktime_write_int32_le(file, 0);
00098 quicktime_write_int32_le(file, 0);
00099 quicktime_write_int32_le(file, 0);
00100
00101 quicktime_atom_write_footer(file, &avih_atom);
00102
00103
00104
00105
00106 current_track = 0;
00107 for(i = 0; i < file->total_vtracks; i++)
00108 {
00109 quicktime_video_map_t *video_map = &file->vtracks[i];
00110 quicktime_trak_t *trak = video_map->track;
00111 quicktime_strl_t *strl =
00112 hdrl->strl[current_track++] =
00113 quicktime_new_strl();
00114 quicktime_init_strl(file,
00115 0,
00116 video_map,
00117 trak,
00118 strl);
00119 }
00120
00121 for(i = 0; i < file->total_atracks; i++)
00122 {
00123 quicktime_audio_map_t *audio_map = &file->atracks[i];
00124 quicktime_trak_t *trak = audio_map->track;
00125 quicktime_strl_t *strl =
00126 hdrl->strl[current_track++] =
00127 quicktime_new_strl();
00128 quicktime_init_strl(file,
00129 audio_map,
00130 0,
00131 trak,
00132 strl);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 quicktime_init_odml(file, hdrl);
00144 quicktime_atom_write_footer(file, &hdrl->atom);
00145 }
00146
00147
00148 void quicktime_finalize_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl)
00149 {
00150 int i;
00151 int64_t position = quicktime_position(file);
00152 int64_t total_frames = 0;
00153 double frame_rate = 0;
00154
00155 for(i = 0; i < file->moov.total_tracks; i++)
00156 {
00157 quicktime_trak_t *trak = file->moov.trak[i];
00158 quicktime_strl_t *strl = hdrl->strl[i];
00159
00160 if(trak->mdia.minf.is_video)
00161 {
00162 int length;
00163 quicktime_set_position(file, strl->length_offset);
00164 total_frames = length = quicktime_track_samples(file, trak);
00165 quicktime_write_int32_le(file, length);
00166 frame_rate = (double)trak->mdia.mdhd.time_scale /
00167 trak->mdia.minf.stbl.stts.table[0].sample_duration;
00168 }
00169 else
00170 if(trak->mdia.minf.is_audio)
00171 {
00172 int length, samples_per_chunk;
00173 quicktime_set_position(file, strl->length_offset);
00174 length = quicktime_track_samples(file, trak);
00175 quicktime_write_int32_le(file, length);
00176
00177
00178 quicktime_set_position(file, strl->samples_per_chunk_offset);
00179 int wav_id = ((quicktime_codec_t*)(file->atracks[0].codec))->wav_id;
00180 samples_per_chunk = quicktime_avg_chunk_samples(file, trak);
00181 if (wav_id = 0x01)
00182 {
00183
00184 quicktime_write_int32_le(file,
00185 1);
00186 quicktime_write_int32_le(file,
00187 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
00188 } else
00189 {
00190 quicktime_write_int32_le(file,
00191 samples_per_chunk);
00192 quicktime_write_int32_le(file,
00193 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
00194 }
00195 quicktime_set_position(file, strl->sample_size_offset);
00196
00197
00198 if (wav_id == 0x1)
00199 {
00200
00201
00202 quicktime_write_int32_le(file,
00203 trak->mdia.minf.stbl.stsd.table[0].channels * trak->mdia.minf.stbl.stsd.table[0].sample_size / 8);
00204 }
00205 else
00206 {
00207
00208
00209 quicktime_write_int32_le(file,
00210 trak->mdia.minf.stbl.stsd.table[0].sample_size);
00211 }
00212 }
00213 }
00214
00215 if(total_frames)
00216 {
00217 quicktime_set_position(file, hdrl->bitrate_offset);
00218 quicktime_write_int32_le(file,
00219 file->total_length / (total_frames / frame_rate));
00220 quicktime_set_position(file, hdrl->frames_offset);
00221 quicktime_write_int32_le(file, total_frames);
00222 }
00223
00224 quicktime_set_position(file, position);
00225 }
00226
00227
00228
00229
00230
00231
00232