⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timecode.c

📁 这个库实现了录象功能
💻 C
字号:
/******************************************************************************* timecode.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 <stdlib.h>#include "lqt_private.h"#define TIMECODES_PER_CHUNK 16void lqt_add_timecode_track(quicktime_t * file, int track,                            uint32_t flags, int framerate)  {  quicktime_video_map_t * vm = file->vtracks + track;  int time_scale, frame_duration, constant;  int width, height;  double fps;  time_scale = lqt_video_time_scale(file, track);  width = quicktime_video_width(file, track);  height = quicktime_video_height(file, track);  frame_duration = lqt_frame_duration(file, track, &constant);  fps = (double)(time_scale) / (double)(frame_duration);    vm->timecode_track = quicktime_add_track(file);  quicktime_trak_init_timecode(file, vm->timecode_track, time_scale, frame_duration,                               framerate, width, height, flags);    /* reference timecode track */  quicktime_tref_init_tmcd(&vm->track->tref, vm->timecode_track->tkhd.track_id);  vm->track->has_tref = 1;  vm->timecodes = malloc(TIMECODES_PER_CHUNK * sizeof(*vm->timecodes));  vm->timecodes_alloc = TIMECODES_PER_CHUNK;  vm->current_timecode_chunk = 1;  }  void lqt_write_timecode(quicktime_t * file, int track,                        uint32_t timecode)  {  quicktime_video_map_t * vm = file->vtracks + track;  vm->encode_timecode = timecode;  vm->has_encode_timecode = 1;  /* Rest is done by lqt_flush_timecode (see below) */    }int lqt_has_timecode_track(quicktime_t * file, int track,                           uint32_t * flags, int * framerate)  {  quicktime_video_map_t * vm = file->vtracks + track;  if(vm->timecode_track)    {    if(flags)      *flags = vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.flags;    if(framerate)      *framerate = vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.numframes;        return 1;    }  else    return 0;  }static uint32_t * cache_timecodes(quicktime_t * file,                                  quicktime_trak_t * trak, int * total)  {  uint32_t * ret;  int i, j;  int num_read = 0, num;  int stsc_pos = 0;  *total = quicktime_track_samples(file, trak);  ret = malloc(*total * sizeof(*ret));    for(i = 0; i < trak->mdia.minf.stbl.stco.total_entries; i++)    {    if((stsc_pos < trak->mdia.minf.stbl.stsc.total_entries-1) &&       /* chunks start with 1 */       (i + 2 == trak->mdia.minf.stbl.stsc.table[stsc_pos+1].chunk))      {      stsc_pos++;      }    num = trak->mdia.minf.stbl.stsc.table[stsc_pos].samples;/*    fprintf(stderr, "Reading timecode chunk: num: %d off: %ld samples: %d\n",            i, trak->mdia.minf.stbl.stco.table[i].offset, num);*/        quicktime_set_position(file, trak->mdia.minf.stbl.stco.table[i].offset);    for(j = 0; j < num; j++)      {      ret[num_read + j] = quicktime_read_int32(file);      // quicktime_read_data(file, (uint8_t*)(ret + num_read), num * sizeof(*ret));      }        num_read += num;    }    return ret;  }int lqt_read_timecode(quicktime_t * file, int track,                      uint32_t * timecode)  {  int64_t sample;  int64_t time;  int64_t stts_index;  int64_t stts_count;    quicktime_video_map_t * vm = file->vtracks + track;  if(!vm->timecode_track)    return 0;  /* Read all timecodes at once */  if(!vm->timecodes)    {    vm->timecodes = cache_timecodes(file,                                    vm->timecode_track,                                    &vm->num_timecodes);    }  time = vm->timestamp;  sample =    quicktime_time_to_sample(&vm->timecode_track->mdia.minf.stbl.stts,                             &time, &stts_index, &stts_count);  /* Got a timecode */  if(time == vm->timestamp)    {    *timecode = vm->timecodes[sample];    return 1;    }  return 0;  }/* private to lqt */void lqt_flush_timecode(quicktime_t * file, int track, int64_t time,                        int force)  {  int i;  quicktime_video_map_t * vm = file->vtracks + track;  quicktime_stts_t * stts;  if(!force)    {    if(!vm->has_encode_timecode)      return;        /* Append to array */      vm->timecodes[vm->num_timecodes] = vm->encode_timecode;    vm->has_encode_timecode = 0;    vm->num_timecodes++;    /* Update stts */    if(vm->timecodes_written)      {      stts = &vm->timecode_track->mdia.minf.stbl.stts;      quicktime_update_stts(stts, vm->timecodes_written-1,                            time - vm->timecode_timestamp);      vm->timecode_timestamp = time;      }            vm->timecodes_written++;    }  else    {    if(vm->timecodes_written)      {      stts = &vm->timecode_track->mdia.minf.stbl.stts;      quicktime_update_stts(stts, vm->timecodes_written-1,                            time - vm->timecode_timestamp);      vm->timecode_timestamp = time;      }    }    /* Write chunk */  if(vm->num_timecodes &&     ((vm->num_timecodes >= vm->timecodes_alloc) || force))    {    quicktime_atom_t chunk_atom;    quicktime_write_chunk_header(file, vm->timecode_track, &chunk_atom);    for(i = 0; i < vm->num_timecodes; i++)      quicktime_write_int32(file, vm->timecodes[i]);        quicktime_write_chunk_footer(file, vm->timecode_track, vm->current_timecode_chunk,                                 &chunk_atom, vm->num_timecodes);    vm->current_timecode_chunk++;    vm->num_timecodes = 0;    }  }const char * lqt_get_timecode_tape_name(quicktime_t * file, int track)  {    quicktime_video_map_t * vm = file->vtracks + track;    return vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.name;  }void lqt_set_timecode_tape_name(quicktime_t * file, int track,				const char * tapename)  {  quicktime_video_map_t * vm = file->vtracks + track;  if(vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.name)    free(vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.name);  vm->timecode_track->mdia.minf.stbl.stsd.table[0].tmcd.name = strdup(tapename);  }int lqt_get_timecode_track_enabled(quicktime_t * file, int track)  {    quicktime_video_map_t * vm = file->vtracks + track;    return vm->timecode_track->tkhd.flags & 1;  }void lqt_set_timecode_track_enabled(quicktime_t * file, int track,				    int enabled)  {    quicktime_video_map_t * vm = file->vtracks + track;    if(enabled)      vm->timecode_track->tkhd.flags |= 1;    else      vm->timecode_track->tkhd.flags &= ~1;  }

⌨️ 快捷键说明

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