texttrack.c

来自「这个库实现了录象功能」· C语言 代码 · 共 537 行 · 第 1/2 页

C
537
字号
/******************************************************************************* texttrack.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 "charset.h"#include <stdlib.h>#include <string.h>#define LOG_DOMAIN "texttrack"/* Common functions */void lqt_init_text_map(quicktime_t * file,                       quicktime_text_map_t * map, quicktime_trak_t * trak,                       int encode)  {  const char * charset;  const char * charset_fallback;  map->track = trak;  map->current_chunk = 1;  if(!encode)    {    charset          = lqt_get_charset(trak->mdia.mdhd.language, file->file_type);    charset_fallback = lqt_get_charset_fallback(trak->mdia.mdhd.language, file->file_type);        if(!charset && !charset_fallback)      {      lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN,              "Cannot determine character set of text track, will copy the strings verbatim");      return;      }    else      {      if(charset)        map->cnv = lqt_charset_converter_create(file, charset, "UTF-8");      if(!map->cnv && charset_fallback)        map->cnv = lqt_charset_converter_create(file, charset_fallback, "UTF-8");      }    if(!map->cnv)      lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN,              "Unsupported charset in text track, will copy the strings verbatim");    }  }void lqt_delete_text_map(quicktime_t * file,                         quicktime_text_map_t * map)  {  if(map->text_buffer) free(map->text_buffer);  if(map->cnv) lqt_charset_converter_destroy(map->cnv);  }/* Decoding */int lqt_text_tracks(quicktime_t * file)  {  int i, result = 0;  quicktime_minf_t *minf;  for(i = 0; i < file->moov.total_tracks; i++)    {    minf = &(file->moov.trak[i]->mdia.minf);    if(minf->is_text)      result++;    }  return result;  }int lqt_text_time_scale(quicktime_t * file, int track)  {  return file->ttracks[track].track->mdia.mdhd.time_scale;  }  int lqt_read_text(quicktime_t * file, int track, char ** text, int * text_alloc,                  int64_t * timestamp, int64_t * duration)  {  int64_t file_position, stts_index = 0, stts_count = 0;  char * ptr;    int string_length;    quicktime_text_map_t * ttrack = &file->ttracks[track];  quicktime_trak_t * trak = ttrack->track;  quicktime_stts_t * stts = &trak->mdia.minf.stbl.stts;    if(ttrack->current_position >= quicktime_track_samples(file, trak))    return 0; // EOF    /* Get the file position */  file_position = quicktime_sample_to_offset(file, trak, ttrack->current_position);  quicktime_set_position(file, file_position);  string_length = quicktime_read_int16(file);  if(string_length)    {        /* Read whole sample */    if(ttrack->text_buffer_alloc < string_length)      {      ttrack->text_buffer_alloc = string_length + 128;      ttrack->text_buffer = realloc(ttrack->text_buffer, ttrack->text_buffer_alloc);      }    quicktime_read_data(file, (uint8_t*)ttrack->text_buffer, string_length);    if(ttrack->cnv)      {      /* Convert character set */      lqt_charset_convert_realloc(ttrack->cnv,                                  ttrack->text_buffer, string_length,                                  text, text_alloc, (int*)0);      }    else /* Copy verbatim */      {      if(*text_alloc < string_length)        {        *text_alloc = string_length + 64;        *text = realloc(*text, *text_alloc);        memcpy(*text, ttrack->text_buffer, string_length);        }      }    }  else /* Empty string */    {    if(*text_alloc < 1)      {      *text_alloc = 1;      *text = realloc(*text, 1);      }    (*text)[0] = '\0';    }    *timestamp = quicktime_sample_to_time(stts, ttrack->current_position,                                        &stts_index, &stts_count);  *duration = stts->table[stts_index].sample_duration;  /* de-macify linebreaks */  ptr = *text;  while(*ptr != '\0')    {    if(*ptr == '\r')      *ptr = '\n';    ptr++;    }  ttrack->current_position++;  return 1;  }  int lqt_is_chapter_track(quicktime_t * file, int track)  {  int i, j, k;  quicktime_trak_t * trak =  file->ttracks[track].track;    for(i = 0; i < file->moov.total_tracks; i++)    {    if(file->moov.trak[i] == trak)      continue;    /* Track reference present */    if(file->moov.trak[i]->has_tref)      {      for(j = 0; j < file->moov.trak[i]->tref.num_references; j++)        {        /* Track reference has type chap */        if(quicktime_match_32(file->moov.trak[i]->tref.references[j].type, "chap"))          {          for(k = 0; k < file->moov.trak[i]->tref.references[j].num_tracks; k++)            {            /* Track reference points to us */            if(file->moov.trak[i]->tref.references[j].tracks[k] == trak->tkhd.track_id)              return 1;            }          }        }      }    }  return 0;  }int64_t lqt_text_samples(quicktime_t * file, int track)  {  return quicktime_track_samples(file, file->ttracks[track].track);  }void lqt_set_text_position(quicktime_t * file, int track, int64_t position)  {  file->ttracks[track].current_position = position;  }void lqt_set_text_time(quicktime_t * file, int track, int64_t time)  {  int64_t stts_index, stts_count;  quicktime_text_map_t * ttrack = &file->ttracks[track];  quicktime_trak_t * trak = ttrack->track;      file->ttracks[track].current_position =    quicktime_time_to_sample(&(trak->mdia.minf.stbl.stts),                             &(time),                             &(stts_index),                             &(stts_count));    }/* Encoding */int lqt_add_text_track(quicktime_t * file, int timescale)  {  quicktime_trak_t * trak;  file->ttracks =    realloc(file->ttracks, (file->total_ttracks+1)*sizeof(quicktime_text_map_t));  memset(&(file->ttracks[file->total_ttracks]), 0, sizeof(quicktime_text_map_t));    trak = quicktime_add_track(file);  if(IS_MP4(file->file_type))    quicktime_trak_init_tx3g(file, trak, timescale);  else if(file->file_type & (LQT_FILE_QT | LQT_FILE_QT_OLD))    quicktime_trak_init_text(file, trak, timescale);  else    lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN,            "Text track not supported for this file");  lqt_init_text_map(file, &(file->ttracks[file->total_ttracks]),                    trak, 1);  file->total_ttracks++;  return 0;  }void lqt_set_chapter_track(quicktime_t * file, int track)  {  file->ttracks[track].is_chapter_track = 1;  }static void make_chapter_track(quicktime_t * file,                               quicktime_trak_t * trak)  {  quicktime_trak_t * ref_track;    /* We create one "chap" reference in one other track. Choose the first     video track if possible */  if(file->total_vtracks)    ref_track = file->vtracks[0].track;  else if(file->total_atracks)

⌨️ 快捷键说明

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