📄 trak.c
字号:
/******************************************************************************* trak.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include <stdlib.h>int quicktime_trak_init(quicktime_trak_t *trak, lqt_file_type_t type){ quicktime_tkhd_init(&(trak->tkhd), type); quicktime_edts_init(&(trak->edts)); quicktime_mdia_init(&(trak->mdia)); quicktime_tref_init(&(trak->tref)); trak->has_tref = 0; return 0;}int quicktime_trak_init_video(quicktime_t *file, quicktime_trak_t *trak, int frame_w, int frame_h, int frame_duration, int timescale, char *compressor){ quicktime_tkhd_init_video(file, &(trak->tkhd), frame_w, frame_h); quicktime_mdia_init_video(file, &(trak->mdia), frame_w, frame_h, frame_duration, timescale, compressor); if(!IS_MP4(file->file_type)) { quicktime_edts_init_table(&(trak->edts)); trak->has_edts = 1; } return 0;}int quicktime_trak_init_timecode(quicktime_t *file, quicktime_trak_t *trak, int time_scale, int frame_duration, int num_frames, int frame_w, int frame_h, uint32_t flags) { quicktime_tkhd_init_timecode(file, &(trak->tkhd), frame_w, frame_h); quicktime_mdia_init_timecode(file, &(trak->mdia), time_scale, frame_duration, num_frames, flags); quicktime_edts_init_table(&(trak->edts)); return 0; }int quicktime_trak_init_qtvr(quicktime_t *file, quicktime_trak_t *trak, int track_type, int width, int height, int frame_duration, int timescale){ quicktime_tkhd_init_video(file, &(trak->tkhd), height, width); quicktime_mdia_init_qtvr(file, &(trak->mdia), track_type, timescale, frame_duration); quicktime_edts_init_table(&(trak->edts)); trak->has_edts = 1; quicktime_tref_init_qtvr(&(trak->tref), track_type); trak->has_tref = 1; return 0;}int quicktime_trak_init_panorama(quicktime_t *file, quicktime_trak_t *trak, int width, int height, int frame_duration, int timescale){ quicktime_tkhd_init_video(file, &(trak->tkhd), height, height/2); quicktime_mdia_init_panorama(file, &(trak->mdia), width, height, timescale, frame_duration); quicktime_edts_init_table(&(trak->edts)); trak->has_edts = 1; return 0;}int quicktime_trak_init_audio(quicktime_t *file, quicktime_trak_t *trak, int channels, int sample_rate, int bits, char *compressor) { quicktime_mdia_init_audio(file, &(trak->mdia), channels, sample_rate, bits, compressor); if(!IS_MP4(file->file_type)) { quicktime_edts_init_table(&(trak->edts)); trak->has_edts = 1; } return 0; }int quicktime_trak_init_text(quicktime_t * file, quicktime_trak_t * trak, int timescale) { trak->tkhd.volume = 0; trak->tkhd.flags = 3; quicktime_mdia_init_text(file, &(trak->mdia), timescale); if(!IS_MP4(file->file_type)) { quicktime_edts_init_table(&(trak->edts)); trak->has_edts = 1; } return 0; }int quicktime_trak_init_tx3g(quicktime_t * file, quicktime_trak_t * trak, int timescale) { trak->tkhd.volume = 0; trak->tkhd.flags = 1; quicktime_mdia_init_tx3g(file, &(trak->mdia), timescale); return 0; } int quicktime_trak_delete(quicktime_trak_t *trak){ quicktime_mdia_delete(&(trak->mdia)); quicktime_edts_delete(&(trak->edts)); quicktime_tkhd_delete(&(trak->tkhd)); quicktime_tref_delete(&(trak->tref)); if(trak->chunk_sizes) free(trak->chunk_sizes); return 0;}int quicktime_trak_dump(quicktime_trak_t *trak){ lqt_dump(" track (trak)\n"); quicktime_tkhd_dump(&(trak->tkhd)); if(trak->has_edts) quicktime_edts_dump(&(trak->edts)); if (trak->has_tref) quicktime_tref_dump(&(trak->tref)); quicktime_mdia_dump(&(trak->mdia)); return 0;}// Used when reading a filequicktime_trak_t* quicktime_add_trak(quicktime_t *file){ quicktime_moov_t *moov = &(file->moov); if(moov->total_tracks < MAXTRACKS) { moov->trak[moov->total_tracks] = calloc(1, sizeof(quicktime_trak_t)); quicktime_trak_init(moov->trak[moov->total_tracks], file->file_type); moov->total_tracks++; } return moov->trak[moov->total_tracks - 1];}int quicktime_delete_trak(quicktime_moov_t *moov){ if(moov->total_tracks) { moov->total_tracks--; quicktime_trak_delete(moov->trak[moov->total_tracks]); free(moov->trak[moov->total_tracks]); } return 0;}int quicktime_read_trak(quicktime_t *file, quicktime_trak_t *trak, quicktime_atom_t *trak_atom) { quicktime_atom_t leaf_atom; do { quicktime_atom_read_header(file, &leaf_atom); /* mandatory */ if(quicktime_atom_is(&leaf_atom, "tkhd")) quicktime_read_tkhd(file, &(trak->tkhd)); else if(quicktime_atom_is(&leaf_atom, "mdia")) quicktime_read_mdia(file, trak, &(trak->mdia), &leaf_atom); /* optional */ else if(quicktime_atom_is(&leaf_atom, "clip")) quicktime_atom_skip(file, &leaf_atom); else if(quicktime_atom_is(&leaf_atom, "matt")) quicktime_atom_skip(file, &leaf_atom); else if(quicktime_atom_is(&leaf_atom, "edts")) { quicktime_read_edts(file, &(trak->edts), &leaf_atom); trak->has_edts = 1; } else if(quicktime_atom_is(&leaf_atom, "load")) quicktime_atom_skip(file, &leaf_atom); else if(quicktime_atom_is(&leaf_atom, "imap")) quicktime_atom_skip(file, &leaf_atom); else if(quicktime_atom_is(&leaf_atom, "udta")) quicktime_atom_skip(file, &leaf_atom); else if(quicktime_atom_is(&leaf_atom, "tref")) { trak->has_tref = 1; quicktime_read_tref(file, &(trak->tref), &leaf_atom); } else quicktime_atom_skip(file, &leaf_atom); } while(quicktime_position(file) < trak_atom->end); return 0; }int quicktime_write_trak(quicktime_t *file, quicktime_trak_t *trak) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "trak"); quicktime_write_tkhd(file, &(trak->tkhd)); if(trak->has_edts) quicktime_write_edts(file, &(trak->edts)); quicktime_write_mdia(file, &(trak->mdia)); if (trak->has_tref) quicktime_write_tref(file, &(trak->tref)); quicktime_atom_write_footer(file, &atom); return 0; }int64_t quicktime_track_samples(quicktime_t *file, quicktime_trak_t *trak) { quicktime_stts_t *stts = &(trak->mdia.minf.stbl.stts); int i; int64_t total = 0; if(trak->mdia.minf.is_audio) { for(i = 0; i < stts->total_entries; i++) { total += stts->table[i].sample_count * stts->table[i].sample_duration; } } else { for(i = 0; i < stts->total_entries; i++) { total += stts->table[i].sample_count; } } return total; }long quicktime_sample_of_chunk(quicktime_trak_t *trak, long chunk){ quicktime_stsc_table_t *table = trak->mdia.minf.stbl.stsc.table; long total_entries = trak->mdia.minf.stbl.stsc.total_entries; long chunk1entry, chunk2entry; long chunk1, chunk2, chunks, total = 0; for(chunk1entry = total_entries - 1, chunk2entry = total_entries; chunk1entry >= 0; chunk1entry--, chunk2entry--) { chunk1 = table[chunk1entry].chunk; if(chunk > chunk1) { if(chunk2entry < total_entries) { chunk2 = table[chunk2entry].chunk; if(chunk < chunk2) chunk2 = chunk; } else chunk2 = chunk; chunks = chunk2 - chunk1; total += chunks * table[chunk1entry].samples; } } return total;}// For AVIint quicktime_avg_chunk_samples(quicktime_t *file, quicktime_trak_t *trak){ int chunk = trak->mdia.minf.stbl.stco.total_entries - 1; long total_samples; if(chunk >= 0) { total_samples = quicktime_sample_of_chunk(trak, chunk);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -