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 + -
显示快捷键?