stts.c

来自「这个库实现了录象功能」· C语言 代码 · 共 275 行

C
275
字号
/******************************************************************************* stts.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>#include <string.h>void quicktime_stts_init(quicktime_stts_t *stts)  {  stts->version = 0;  stts->flags = 0;  stts->total_entries = 0;  }void quicktime_stts_init_table(quicktime_stts_t *stts)  {  if(!stts->total_entries)    {    stts->total_entries = 1;    stts->entries_allocated = 1;    stts->table = calloc(stts->total_entries, sizeof(*stts->table));    }  }void quicktime_stts_init_qtvr(quicktime_t *file,                              quicktime_stts_t *stts, int frame_duration)  {  quicktime_stts_table_t *table;  quicktime_stts_init_table(stts);  table = &(stts->table[0]);  table->sample_duration = frame_duration;  }void quicktime_stts_init_panorama(quicktime_t *file,                                  quicktime_stts_t *stts, int frame_duration)  {  quicktime_stts_table_t *table;  quicktime_stts_init_table(stts);  table = &(stts->table[0]);  table->sample_duration = frame_duration;  }void quicktime_stts_init_video(quicktime_t *file, quicktime_stts_t *stts,                               int frame_duration)  {  quicktime_stts_table_t *table;  quicktime_stts_init_table(stts);  table = &(stts->table[0]);  table->sample_duration = frame_duration;  stts->default_duration = frame_duration;  }void quicktime_stts_init_audio(quicktime_t *file, quicktime_stts_t *stts,                               int sample_rate)  {  quicktime_stts_table_t *table;  quicktime_stts_init_table(stts);  table = &(stts->table[0]);  table->sample_duration = 1;  }void quicktime_stts_init_timecode(quicktime_t *file, quicktime_stts_t *stts)  {  quicktime_stts_init_table(stts);  }void quicktime_stts_delete(quicktime_stts_t *stts)  {  if(stts->total_entries) free(stts->table);  stts->total_entries = 0;  }void quicktime_stts_dump(quicktime_stts_t *stts)  {  int i;  lqt_dump("     time to sample (stts)\n");  lqt_dump("      version %d\n", stts->version);  lqt_dump("      flags %ld\n", stts->flags);  lqt_dump("      total_entries %ld\n", stts->total_entries);  for(i = 0; i < stts->total_entries; i++)    {    lqt_dump("       count %ld duration %ld\n",             stts->table[i].sample_count, stts->table[i].sample_duration);    }  }void quicktime_read_stts(quicktime_t *file, quicktime_stts_t *stts)  {  int i;  stts->version = quicktime_read_char(file);  stts->flags = quicktime_read_int24(file);  stts->total_entries = quicktime_read_int32(file);  stts->table = malloc(sizeof(*stts->table) * stts->total_entries);  for(i = 0; i < stts->total_entries; i++)    {    stts->table[i].sample_count = quicktime_read_int32(file);    stts->table[i].sample_duration = quicktime_read_int32(file);    }  }void quicktime_write_stts(quicktime_t *file, quicktime_stts_t *stts)  {  int i;  quicktime_atom_t atom;  quicktime_atom_write_header(file, &atom, "stts");  quicktime_write_char(file, stts->version);  quicktime_write_int24(file, stts->flags);  quicktime_write_int32(file, stts->total_entries);  for(i = 0; i < stts->total_entries; i++)    {    quicktime_write_int32(file, stts->table[i].sample_count);    quicktime_write_int32(file, stts->table[i].sample_duration);    }  quicktime_atom_write_footer(file, &atom);  }int64_t quicktime_time_to_sample(quicktime_stts_t *stts, int64_t * time,                                 int64_t * stts_index, int64_t * stts_count)  {  int64_t ret = 0;  int64_t time_count = 0;  *stts_index = 0;  while(1)    {    if(time_count + stts->table[*stts_index].sample_duration *       stts->table[*stts_index].sample_count >= *time)      {      *stts_count = (*time - time_count) / stts->table[*stts_index].sample_duration;      time_count += *stts_count * stts->table[*stts_index].sample_duration;      ret += *stts_count;      break;      }    else      {      time_count += stts->table[*stts_index].sample_duration *        stts->table[*stts_index].sample_count;      ret += stts->table[*stts_index].sample_count;      (*stts_index)++;      }    if(*stts_index >= stts->total_entries)      break;    }  *time = time_count;  return ret;  }/* sample = -1 returns the total duration */int64_t quicktime_sample_to_time(quicktime_stts_t *stts, int64_t sample,                                 int64_t * stts_index, int64_t * stts_count)  {  int64_t ret = 0;  int64_t sample_count;  if(sample < 0)    {    for(*stts_index = 0; *stts_index < stts->total_entries; (*stts_index)++)      {      ret += stts->table[*stts_index].sample_duration *        stts->table[*stts_index].sample_count;      }    return ret;    }  *stts_index = 0;  //  *stts_count = 0;  sample_count = 0;    while(1)    {    if(sample_count + stts->table[*stts_index].sample_count > sample)      {      *stts_count = (sample - sample_count);      ret += *stts_count * stts->table[*stts_index].sample_duration;      break;      }    else      {      sample_count += stts->table[*stts_index].sample_count;      ret += stts->table[*stts_index].sample_count * stts->table[*stts_index].sample_duration;      (*stts_index)++;      }    }  return ret;  }/* If one calls quicktime_update_stts(), the table is set up with one entry per sample.   Before writing, call quicktime_compress_stts() to kick out redundant entries */void quicktime_update_stts(quicktime_stts_t *stts, long sample, long duration)  {  if(sample >= stts->entries_allocated)    {    stts->entries_allocated = sample + 1024;    stts->table = realloc(stts->table,                          stts->entries_allocated * sizeof(*(stts->table)));    }  stts->table[sample].sample_count = 1;  if(duration)    stts->table[sample].sample_duration = duration;  else    stts->table[sample].sample_duration = stts->default_duration;    if(sample >= stts->total_entries)    stts->total_entries = sample + 1;  }void quicktime_compress_stts(quicktime_stts_t *stts)  {  long sample = 0;  long i;  if(stts->total_entries <= 1)    return;      while(sample < stts->total_entries)    {    i = 1;    while(sample + i < stts->total_entries)      {      if(stts->table[sample + i].sample_duration ==  stts->table[sample].sample_duration)        {        stts->table[sample].sample_count++;        }      else        {        break;        }      i++;      }    if(stts->table[sample].sample_count > 1)      {      /* Compress */      if(stts->total_entries - sample - i)        memmove(&stts->table[sample + 1], &stts->table[sample + i],                sizeof(stts->table[sample + i]) * (stts->total_entries - sample - i));      stts->total_entries -= stts->table[sample].sample_count-1;      }    sample++;    }  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?