long quicktime_video_length(quicktime_t *file, int track) { /*printf("quicktime_video_length %d %d\n", quicktime_track_samples(file, file->vtracks[track].track), track); */ if(file->total_vtracks > 0) return quicktime_track_samples(file, file->vtracks[track].track); return 0; }
long quicktime_audio_length(quicktime_t *file, int track) { if(file->total_atracks > 0) return quicktime_track_samples(file, file->atracks[track].track); return 0; }
int quicktime_trak_fix_counts(quicktime_t *file, quicktime_trak_t *trak) { long samples = quicktime_track_samples(file, trak); if (trak->mdia.minf.stbl.stts.total_entries == 1) { trak->mdia.minf.stbl.stts.table[0].sample_count = samples; } if(trak->mdia.minf.stbl.stsz.sample_size) trak->mdia.minf.stbl.stsz.total_entries = samples; return 0; }
long quicktime_frame_size(quicktime_t *file, long frame, int track) { long bytes = 0; quicktime_trak_t *trak = file->vtracks[track].track; if(trak->mdia.minf.stbl.stsz.sample_size) { bytes = trak->mdia.minf.stbl.stsz.sample_size; } else { long total_frames = quicktime_track_samples(file, trak); if(frame < 0) frame = 0; else if(frame > total_frames - 1) frame = total_frames - 1; bytes = trak->mdia.minf.stbl.stsz.table[frame].size; } return bytes; }
void quicktime_finalize_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl) { int i; int64_t position = quicktime_position(file); int64_t total_frames = 0; double frame_rate = 0; for(i = 0; i < file->moov.total_tracks; i++) { quicktime_trak_t *trak = file->moov.trak[i]; quicktime_strl_t *strl = hdrl->strl[i]; if(trak->mdia.minf.is_video) { int length; quicktime_set_position(file, strl->length_offset); total_frames = length = quicktime_track_samples(file, trak); quicktime_write_int32_le(file, length); frame_rate = (double)trak->mdia.mdhd.time_scale / trak->mdia.minf.stbl.stts.table[0].sample_duration; } else if(trak->mdia.minf.is_audio) { int length, samples_per_chunk, wav_id, sample_size, sample_rate; quicktime_set_position(file, strl->length_offset); length = quicktime_track_samples(file, trak); quicktime_write_int32_le(file, length); // dwScale and dwRate as per MSDN - // http://msdn.microsoft.com/library/default.asp? // url=/library/en-us/wcemultimedia5/html/wce50conAVIStreamHeaders.asp quicktime_set_position(file, strl->samples_per_chunk_offset); wav_id = ((quicktime_codec_t*)(file->atracks[0].codec))->wav_id; samples_per_chunk = wav_id == 1 ? 1 : quicktime_avg_chunk_samples(file, trak); quicktime_write_int32_le(file, samples_per_chunk); sample_rate = trak->mdia.minf.stbl.stsd.table[0].sample_rate; quicktime_write_int32_le(file, sample_rate); quicktime_set_position(file, strl->sample_size_offset); // dwSampleSize as per MSDN // as per http://www.virtualdub.org/blog/pivot/entry.php?id=27, many programs ignore this value // sample_size in quicktime is in bits... so we must divide by 8 // FIXME: This has to be zero for _all_ VBR encodings, and other values are used for specific encodings sample_size = trak->mdia.minf.stbl.stsd.table[0].sample_size; quicktime_write_int32_le(file, wav_id != 1 ? sample_size : trak->mdia.minf.stbl.stsd.table[0].channels * sample_size / 8); } } if(total_frames) { quicktime_set_position(file, hdrl->bitrate_offset); quicktime_write_int32_le(file, file->total_length / (total_frames / frame_rate)); quicktime_set_position(file, hdrl->frames_offset); quicktime_write_int32_le(file, total_frames); } quicktime_set_position(file, position); }