00001 #include "funcprotos.h"
00002 #include "quicktime.h"
00003 #include <string.h>
00004
00005
00006
00007
00008
00009 #define JUNK_SIZE 0x1018
00010
00011
00012
00013 quicktime_strl_t* quicktime_new_strl()
00014 {
00015 quicktime_strl_t *strl = calloc(1, sizeof(quicktime_strl_t));
00016 return strl;
00017 }
00018
00019
00020 void quicktime_init_strl(quicktime_t *file,
00021 quicktime_audio_map_t *atrack,
00022 quicktime_video_map_t *vtrack,
00023 quicktime_trak_t *trak,
00024 quicktime_strl_t *strl)
00025 {
00026 quicktime_atom_t list_atom, strh_atom, strf_atom;
00027 quicktime_atom_t junk_atom;
00028 int i;
00029
00030
00031 if(vtrack)
00032 {
00033 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
00034 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
00035 strl->tag[2] = 'd';
00036 strl->tag[3] = 'c';
00037 }
00038 else
00039 if(atrack)
00040 {
00041 strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;
00042 strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;
00043 strl->tag[2] = 'w';
00044 strl->tag[3] = 'b';
00045 }
00046
00047
00048
00049 quicktime_atom_write_header(file, &list_atom, "LIST");
00050 quicktime_write_char32(file, "strl");
00051
00052
00053 quicktime_atom_write_header(file, &strh_atom, "strh");
00054
00055
00056
00057
00058 if(vtrack)
00059 {
00060 quicktime_write_char32(file, "vids");
00061 quicktime_write_char32(file,
00062 trak->mdia.minf.stbl.stsd.table[0].format);
00063
00064 quicktime_write_int32_le(file, 0);
00065
00066 quicktime_write_int16_le(file, 0);
00067
00068 quicktime_write_int16_le(file, 0);
00069
00070 quicktime_write_int32_le(file, 0);
00071
00072
00073 quicktime_write_int32_le(file,
00074 trak->mdia.minf.stbl.stts.table[0].sample_duration);
00075
00076 quicktime_write_int32_le(file,
00077 trak->mdia.mdhd.time_scale);
00078
00079
00080 quicktime_write_int32_le(file, 0);
00081 strl->length_offset = quicktime_position(file);
00082
00083 quicktime_write_int32_le(file, 0);
00084
00085 quicktime_write_int32_le(file, 0);
00086
00087 quicktime_write_int32_le(file, -1);
00088
00089 quicktime_write_int32_le(file, 0);
00090 quicktime_write_int16_le(file, 0);
00091 quicktime_write_int16_le(file, 0);
00092 quicktime_write_int16_le(file, trak->tkhd.track_width);
00093 quicktime_write_int16_le(file, trak->tkhd.track_height);
00094 }
00095 else
00096
00097 if(atrack)
00098 {
00099 quicktime_write_char32(file, "auds");
00100 quicktime_write_int32_le(file, 0);
00101
00102 quicktime_write_int32_le(file, 0);
00103
00104 quicktime_write_int16_le(file, 0);
00105
00106 quicktime_write_int16_le(file, 0);
00107
00108 quicktime_write_int32_le(file, 0);
00109 strl->samples_per_chunk_offset = quicktime_position(file);
00110
00111 quicktime_write_int32_le(file, 0);
00112
00113
00114 quicktime_write_int32_le(file, 0);
00115
00116 quicktime_write_int32_le(file, 0);
00117 strl->length_offset = quicktime_position(file);
00118
00119 quicktime_write_int32_le(file, 0);
00120
00121 quicktime_write_int32_le(file, 0);
00122
00123 quicktime_write_int32_le(file, -1);
00124
00125 strl->sample_size_offset = quicktime_position(file);
00126 quicktime_write_int32_le(file, 0);
00127 quicktime_write_int32_le(file, 0);
00128 quicktime_write_int32_le(file, 0);
00129 }
00130 quicktime_atom_write_footer(file, &strh_atom);
00131
00132
00133
00134
00135
00136
00137
00138
00139 quicktime_atom_write_header(file, &strf_atom, "strf");
00140
00141 if(vtrack)
00142 {
00143
00144 quicktime_write_int32_le(file, 40);
00145 quicktime_write_int32_le(file, trak->tkhd.track_width);
00146 quicktime_write_int32_le(file, trak->tkhd.track_height);
00147
00148 quicktime_write_int16_le(file, 1);
00149
00150 quicktime_write_int16_le(file, 24);
00151 quicktime_write_char32(file,
00152 trak->mdia.minf.stbl.stsd.table[0].format);
00153 quicktime_write_int32_le(file,
00154 trak->tkhd.track_width * trak->tkhd.track_height * 3);
00155 quicktime_write_int32_le(file, 0);
00156 quicktime_write_int32_le(file, 0);
00157 quicktime_write_int32_le(file, 0);
00158 quicktime_write_int32_le(file, 0);
00159 }
00160 else
00161 if(atrack)
00162 {
00163
00164 quicktime_codec_t *codec_base = atrack->codec;
00165 int wav_id = codec_base->wav_id;
00166
00167 quicktime_write_int16_le(file,
00168 wav_id);
00169 quicktime_write_int16_le(file,
00170 trak->mdia.minf.stbl.stsd.table[0].channels);
00171
00172 quicktime_write_int32_le(file,
00173 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
00174 if (wav_id == 0x01)
00175 {
00176
00177 quicktime_write_int32_le(file, trak->mdia.minf.stbl.stsd.table[0].sample_rate * trak->mdia.minf.stbl.stsd.table[0].sample_size * trak->mdia.minf.stbl.stsd.table[0].channels / 8);
00178
00179
00180
00181
00182 quicktime_write_int16_le(file, trak->mdia.minf.stbl.stsd.table[0].sample_size * trak->mdia.minf.stbl.stsd.table[0].channels / 8);
00183 }
00184 else
00185 {
00186
00187 quicktime_write_int32_le(file, 256000 / 8);
00188 quicktime_write_int16_le(file, 1);
00189 }
00190
00191
00192 quicktime_write_int16_le(file,
00193 trak->mdia.minf.stbl.stsd.table[0].sample_size);
00194 quicktime_write_int16_le(file, 0);
00195 }
00196
00197 quicktime_atom_write_footer(file, &strf_atom);
00198
00199
00200
00201
00202
00203
00204 strl->indx_offset = quicktime_position(file);
00205 strl->padding_size = JUNK_SIZE;
00206
00207
00208
00209 quicktime_atom_write_header(file, &junk_atom, "JUNK");
00210 for(i = 0; i < strl->padding_size; i += 4)
00211 quicktime_write_int32_le(file, 0);
00212 quicktime_atom_write_footer(file, &junk_atom);
00213
00214
00215
00216 quicktime_init_indx(file, &strl->indx, strl);
00217
00218
00219 quicktime_atom_write_footer(file, &list_atom);
00220 }
00221
00222
00223
00224 void quicktime_delete_strl(quicktime_strl_t *strl)
00225 {
00226 quicktime_delete_indx(&strl->indx);
00227 free(strl);
00228 }
00229
00230 void quicktime_read_strl(quicktime_t *file,
00231 quicktime_strl_t *strl,
00232 quicktime_atom_t *parent_atom)
00233 {
00234
00235
00236 char data[4], codec[4];
00237 int denominator;
00238 int numerator;
00239 double frame_rate;
00240 int width;
00241 int height;
00242 int depth;
00243 int frames;
00244 int bytes_per_sample;
00245 int sample_size;
00246 int samples;
00247 int samples_per_chunk;
00248 int channels;
00249 int sample_rate;
00250 int compression_id;
00251 int bytes_per_second;
00252 quicktime_trak_t *trak = 0;
00253 quicktime_riff_t *first_riff = file->riff[0];
00254
00255
00256 codec[0] = codec[1] = codec[2] = codec[3] = 0;
00257
00258
00259
00260
00261
00262 do
00263 {
00264 quicktime_atom_t leaf_atom;
00265 quicktime_atom_read_header(file, &leaf_atom);
00266
00267
00268 if(quicktime_atom_is(&leaf_atom, "strh"))
00269 {
00270
00271 quicktime_read_data(file, data, 4);
00272
00273 if(quicktime_match_32(data, "vids"))
00274 {
00275 trak = quicktime_add_trak(file);
00276 width = 0;
00277 height = 0;
00278 depth = 24;
00279 frames = 0;
00280 strl->is_video = 1;
00281
00282
00283 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
00284 file->moov.mvhd.next_track_id++;
00285
00286
00287
00288 quicktime_read_data(file,
00289 codec,
00290 4);
00291
00292
00293 quicktime_set_position(file, quicktime_position(file) + 12);
00294 denominator = quicktime_read_int32_le(file);
00295 numerator = quicktime_read_int32_le(file);
00296 if(denominator != 0)
00297 frame_rate = (double)numerator / denominator;
00298 else
00299 frame_rate = numerator;
00300
00301
00302 quicktime_set_position(file, quicktime_position(file) + 4);
00303 frames = quicktime_read_int32_le(file);
00304 }
00305 else
00306 if(quicktime_match_32(data, "auds"))
00307 {
00308 trak = quicktime_add_trak(file);
00309 sample_size = 16;
00310 channels = 2;
00311 sample_rate = 0;
00312 compression_id = 0;
00313 strl->is_audio = 1;
00314
00315 trak->tkhd.track_id = file->moov.mvhd.next_track_id;
00316 file->moov.mvhd.next_track_id++;
00317 quicktime_read_data(file,
00318 codec,
00319 4);
00320
00321 quicktime_set_position(file, quicktime_position(file) + 12);
00322 samples_per_chunk = quicktime_read_int32_le(file);
00323 bytes_per_second = quicktime_read_int32_le(file);
00324
00325 quicktime_set_position(file, quicktime_position(file) + 4);
00326
00327 samples = quicktime_read_int32_le(file);
00328
00329 quicktime_set_position(file, quicktime_position(file) + 8);
00330
00331
00332
00333
00334 bytes_per_sample = quicktime_read_int32_le(file);
00335
00336 }
00337 }
00338
00339 else
00340 if(quicktime_atom_is(&leaf_atom, "strf"))
00341 {
00342 if(strl->is_video)
00343 {
00344
00345 quicktime_read_int32_le(file);
00346 width = quicktime_read_int32_le(file);
00347 height = quicktime_read_int32_le(file);
00348
00349 quicktime_read_int16_le(file);
00350
00351 depth = quicktime_read_int16_le(file);
00352 quicktime_read_data(file,
00353 codec,
00354 4);
00355 }
00356 else
00357 if(strl->is_audio)
00358 {
00359 compression_id = quicktime_read_int16_le(file);
00360 channels = quicktime_read_int16_le(file);
00361 sample_rate = quicktime_read_int32_le(file);
00362 quicktime_set_position(file, quicktime_position(file) + 6);
00363 sample_size = quicktime_read_int16_le(file);
00364
00365 }
00366 }
00367 else
00368
00369
00370 if(quicktime_atom_is(&leaf_atom, "indx"))
00371 {
00372
00373 quicktime_read_indx(file, strl, &leaf_atom);
00374 strl->have_indx = 1;
00375 }
00376
00377
00378
00379
00380
00381 quicktime_atom_skip(file, &leaf_atom);
00382 }while(quicktime_position(file) < parent_atom->end);
00383
00384
00385
00386 if(strl->is_video)
00387 {
00388
00389 quicktime_trak_init_video(file,
00390 trak,
00391 width,
00392 height,
00393 frame_rate,
00394 codec);
00395 quicktime_mhvd_init_video(file,
00396 &file->moov.mvhd,
00397 frame_rate);
00398 trak->mdia.mdhd.duration = frames;
00399
00400 memcpy(trak->mdia.minf.stbl.stsd.table[0].format, codec, 4);
00401 trak->mdia.minf.stbl.stsd.table[0].depth = depth;
00402 }
00403 else
00404 if(strl->is_audio)
00405 {
00406
00407
00408 quicktime_trak_init_audio(file,
00409 trak,
00410 channels,
00411 sample_rate,
00412 sample_size,
00413 codec);
00414
00415
00416
00417
00418
00419
00420
00421 trak->mdia.minf.stbl.stsd.table[0].compression_id = compression_id;
00422
00423
00424 if(!bytes_per_sample)
00425 {
00426
00427 trak->mdia.minf.stbl.stsc.table[0].samples = samples_per_chunk;
00428 trak->mdia.minf.stbl.stsc.total_entries = 1;
00429 }
00430 }
00431
00432
00433
00434 }
00435
00436
00437
00438