📄 stsc.c
字号:
/******************************************************************************* stsc.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>void quicktime_stsc_init(quicktime_stsc_t *stsc){ stsc->version = 0; stsc->flags = 0; stsc->total_entries = 0; stsc->entries_allocated = 0;}void quicktime_stsc_init_table(quicktime_t *file, quicktime_stsc_t *stsc){ if(!stsc->entries_allocated) { stsc->total_entries = 1; stsc->entries_allocated = 2048; stsc->table = (quicktime_stsc_table_t*)calloc(1, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated); }}void quicktime_stsc_init_video(quicktime_t *file, quicktime_stsc_t *stsc){ quicktime_stsc_table_t *table; quicktime_stsc_init_table(file, stsc); table = &(stsc->table[0]); table->chunk = 1; table->samples = 1; table->id = 1;}void quicktime_stsc_init_audio(quicktime_t *file, quicktime_stsc_t *stsc, int sample_rate){ quicktime_stsc_table_t *table; quicktime_stsc_init_table(file, stsc); table = &(stsc->table[0]); table->chunk = 1; table->samples = 0; /* set this after completion or after every audio chunk is written */ table->id = 1;}void quicktime_stsc_delete(quicktime_stsc_t *stsc){ if(stsc->total_entries) free(stsc->table); stsc->total_entries = 0;}void quicktime_stsc_dump(quicktime_stsc_t *stsc){ int i; lqt_dump(" sample to chunk (stsc)\n"); lqt_dump(" version %d\n", stsc->version); lqt_dump(" flags %ld\n", stsc->flags); lqt_dump(" total_entries %ld\n", stsc->total_entries); for(i = 0; i < stsc->total_entries; i++) { lqt_dump(" chunk %ld samples %lx id %ld\n", stsc->table[i].chunk, stsc->table[i].samples, stsc->table[i].id); }}void quicktime_read_stsc(quicktime_t *file, quicktime_stsc_t *stsc){ int i; stsc->version = quicktime_read_char(file); stsc->flags = quicktime_read_int24(file); stsc->total_entries = quicktime_read_int32(file); stsc->entries_allocated = stsc->total_entries; stsc->table = (quicktime_stsc_table_t*)malloc(sizeof(quicktime_stsc_table_t) * stsc->total_entries); for(i = 0; i < stsc->total_entries; i++) { stsc->table[i].chunk = quicktime_read_int32(file); stsc->table[i].samples = quicktime_read_int32(file); stsc->table[i].id = quicktime_read_int32(file); }}void quicktime_compress_stsc(quicktime_stsc_t *stsc) { int i, last_same; /* This can happen, if a stream was created, but no samples have been written. The resulting file will be invalid anyway, just don't let us crash */ if(!stsc->table) return; for(i = 1, last_same = 0; i < stsc->total_entries; i++) { if(stsc->table[i].samples != stsc->table[last_same].samples) { /* An entry has a different sample count. */ last_same++; if(last_same < i) { /* Move it up the list. */ stsc->table[last_same] = stsc->table[i]; } } } last_same++; stsc->total_entries = last_same; }void quicktime_write_stsc(quicktime_t *file, quicktime_stsc_t *stsc) { int i; quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "stsc"); quicktime_write_char(file, stsc->version); quicktime_write_int24(file, stsc->flags); quicktime_write_int32(file, stsc->total_entries); for(i = 0; i < stsc->total_entries; i++) { quicktime_write_int32(file, stsc->table[i].chunk); quicktime_write_int32(file, stsc->table[i].samples); quicktime_write_int32(file, stsc->table[i].id); } quicktime_atom_write_footer(file, &atom); }int quicktime_update_stsc(quicktime_stsc_t *stsc, long chunk, long samples){ if(chunk > stsc->entries_allocated) { stsc->entries_allocated = chunk * 2; stsc->table =(quicktime_stsc_table_t*)realloc(stsc->table, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated); } stsc->table[chunk - 1].samples = samples; stsc->table[chunk - 1].chunk = chunk; stsc->table[chunk - 1].id = 1; if(chunk > stsc->total_entries) stsc->total_entries = chunk; return 0;}/* Optimizing while writing doesn't allow seeks during recording so *//* entries are created for every chunk and only optimized during *//* writeout. Unfortunately there's no way to keep audio synchronized *//* after overwriting a recording as the fractional audio chunk in the *//* middle always overwrites the previous location of a larger chunk. On *//* writing, the table must be optimized. RealProducer requires an *//* optimized table. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -