📄 tx3g.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / ISO Media File Format sub-project * * GPAC 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, or (at your option) * any later version. * * GPAC 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/internal/isomedia_dev.h>#include <gpac/constants.h>#ifndef GPAC_READ_ONLYGF_Err gf_isom_update_text_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, GF_TextSampleDescriptor *desc){ GF_TrackBox *trak; GF_Err e; u32 i; GF_TextSampleEntryBox *txt; if (!descriptionIndex || !desc) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM; txt = (GF_TextSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex - 1); if (!txt) return GF_BAD_PARAM; if (txt->type != GF_ISOM_BOX_TYPE_TX3G) return GF_BAD_PARAM; trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); txt->back_color = desc->back_color; txt->default_box = desc->default_pos; txt->default_style = desc->default_style; txt->displayFlags = desc->displayFlags; txt->vertical_justification = desc->vert_justif; txt->horizontal_justification = desc->horiz_justif; if (txt->font_table) gf_isom_box_del((GF_Box*)txt->font_table); txt->font_table = (GF_FontTableBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_FTAB); txt->font_table->entry_count = desc->font_count; txt->font_table->fonts = (GF_FontRecord *) malloc(sizeof(GF_FontRecord) * desc->font_count); for (i=0; i<desc->font_count; i++) { txt->font_table->fonts[i].fontID = desc->fonts[i].fontID; if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = strdup(desc->fonts[i].fontName); } return e;}GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextSampleDescriptor *desc, char *URLname, char *URNname, u32 *outDescriptionIndex){ GF_TrackBox *trak; GF_Err e; u32 dataRefIndex, i; GF_TextSampleEntryBox *txt; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM; //get or create the data ref e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; if (!dataRefIndex) { e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; } trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); txt = (GF_TextSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TX3G); txt->dataReferenceIndex = dataRefIndex; gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, txt); if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList); txt->back_color = desc->back_color; txt->default_box = desc->default_pos; txt->default_style = desc->default_style; txt->displayFlags = desc->displayFlags; txt->vertical_justification = desc->vert_justif; txt->horizontal_justification = desc->horiz_justif; txt->font_table = (GF_FontTableBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_FTAB); txt->font_table->entry_count = desc->font_count; txt->font_table->fonts = (GF_FontRecord *) malloc(sizeof(GF_FontRecord) * desc->font_count); for (i=0; i<desc->font_count; i++) { txt->font_table->fonts[i].fontID = desc->fonts[i].fontID; if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = strdup(desc->fonts[i].fontName); } return e;}/*blindly adds text - note we don't rely on terminaison characters to handle utf8 and utf16 data in the same way. It is the user responsability to signal UTF16*/GF_Err gf_isom_text_add_text(GF_TextSample *samp, char *text_data, u32 text_len){ if (!samp) return GF_BAD_PARAM; if (!text_len) return GF_OK; samp->text = (char*)realloc(samp->text, sizeof(char) * (samp->len + text_len) ); memcpy(samp->text + samp->len, text_data, sizeof(char) * text_len); samp->len += text_len; return GF_OK;}GF_Err gf_isom_text_set_utf16_marker(GF_TextSample *samp){ /*we MUST have an empty sample*/ if (!samp || samp->text) return GF_BAD_PARAM; samp->text = (char*)malloc(sizeof(char) * 2); samp->text[0] = (char) 0xFE; samp->text[1] = (char) 0xFF; samp->len = 2; return GF_OK;}GF_Err gf_isom_text_add_style(GF_TextSample *samp, GF_StyleRecord *rec){ if (!samp || !rec) return GF_BAD_PARAM; if (!samp->styles) { samp->styles = (GF_TextStyleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STYL); if (!samp->styles) return GF_OUT_OF_MEM; } samp->styles->styles = (GF_StyleRecord*)realloc(samp->styles->styles, sizeof(GF_StyleRecord)*(samp->styles->entry_count+1)); if (!samp->styles->styles) return GF_OUT_OF_MEM; samp->styles->styles[samp->styles->entry_count] = *rec; samp->styles->entry_count++; return GF_OK;}GF_Err gf_isom_text_add_highlight(GF_TextSample *samp, u16 start_char, u16 end_char){ GF_TextHighlightBox *a; if (!samp) return GF_BAD_PARAM; if (start_char == end_char) return GF_BAD_PARAM; a = (GF_TextHighlightBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_HLIT); if (!a) return GF_OUT_OF_MEM; a->startcharoffset = start_char; a->endcharoffset = end_char; return gf_list_add(samp->others, a);}GF_Err gf_isom_text_set_highlight_color(GF_TextSample *samp, u8 r, u8 g, u8 b, u8 a){ if (!samp) return GF_BAD_PARAM; if (!samp->highlight_color) { samp->highlight_color = (GF_TextHighlightColorBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_HCLR); if (!samp->highlight_color) return GF_OUT_OF_MEM; } samp->highlight_color->hil_color = a; samp->highlight_color->hil_color <<= 8; samp->highlight_color->hil_color = r; samp->highlight_color->hil_color <<= 8; samp->highlight_color->hil_color = g; samp->highlight_color->hil_color <<= 8; samp->highlight_color->hil_color = b; return GF_OK;}GF_Err gf_isom_text_set_highlight_color_argb(GF_TextSample *samp, u32 argb){ if (!samp) return GF_BAD_PARAM; if (!samp->highlight_color) { samp->highlight_color = (GF_TextHighlightColorBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_HCLR); if (!samp->highlight_color) return GF_OUT_OF_MEM; } samp->highlight_color->hil_color = argb; return GF_OK;}/*3GPP spec is quite obscur here*/GF_Err gf_isom_text_add_karaoke(GF_TextSample *samp, u32 start_time){ if (!samp) return GF_BAD_PARAM; samp->cur_karaoke = (GF_TextKaraokeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_KROK); if (!samp->cur_karaoke) return GF_OUT_OF_MEM; samp->cur_karaoke->highlight_starttime = start_time; return gf_list_add(samp->others, samp->cur_karaoke);}GF_Err gf_isom_text_set_karaoke_segment(GF_TextSample *samp, u32 end_time, u16 start_char, u16 end_char){ if (!samp || !samp->cur_karaoke) return GF_BAD_PARAM; samp->cur_karaoke->records = (KaraokeRecord*)realloc(samp->cur_karaoke->records, sizeof(KaraokeRecord)*(samp->cur_karaoke->entrycount+1)); if (!samp->cur_karaoke->records) return GF_OUT_OF_MEM; samp->cur_karaoke->records[samp->cur_karaoke->entrycount].end_charoffset = end_char; samp->cur_karaoke->records[samp->cur_karaoke->entrycount].start_charoffset = start_char; samp->cur_karaoke->records[samp->cur_karaoke->entrycount].highlight_endtime = end_time; samp->cur_karaoke->entrycount++; return GF_OK;}GF_Err gf_isom_text_set_scroll_delay(GF_TextSample *samp, u32 scroll_delay){ if (!samp) return GF_BAD_PARAM; if (!samp->scroll_delay) { samp->scroll_delay = (GF_TextScrollDelayBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_DLAY); if (!samp->scroll_delay) return GF_OUT_OF_MEM; } samp->scroll_delay->scroll_delay = scroll_delay; return GF_OK;}GF_Err gf_isom_text_add_hyperlink(GF_TextSample *samp, char *URL, char *altString, u16 start_char, u16 end_char){ GF_TextHyperTextBox*a; if (!samp) return GF_BAD_PARAM; a = (GF_TextHyperTextBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_HREF); if (!a) return GF_OUT_OF_MEM; a->startcharoffset = start_char; a->endcharoffset = end_char; a->URL = URL ? strdup(URL) : NULL; a->URL_hint = altString ? strdup(altString) : NULL; return gf_list_add(samp->others, a);}GF_Err gf_isom_text_set_box(GF_TextSample *samp, s16 top, s16 left, s16 bottom, s16 right){ if (!samp) return GF_BAD_PARAM; if (!samp->box) { samp->box = (GF_TextBoxBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_TBOX); if (!samp->box) return GF_OUT_OF_MEM; } samp->box->box.top = top; samp->box->box.left = left; samp->box->box.bottom = bottom; samp->box->box.right = right; return GF_OK;}GF_Err gf_isom_text_add_blink(GF_TextSample *samp, u16 start_char, u16 end_char){ GF_TextBlinkBox *a; if (!samp) return GF_BAD_PARAM; a = (GF_TextBlinkBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_BLNK); if (!a) return GF_OUT_OF_MEM; a->startcharoffset = start_char; a->endcharoffset = end_char; return gf_list_add(samp->others, a);}GF_Err gf_isom_text_set_wrap(GF_TextSample *samp, u8 wrap_flags){ if (!samp) return GF_BAD_PARAM; if (!samp->wrap) { samp->wrap = (GF_TextWrapBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_TWRP); if (!samp->wrap) return GF_OUT_OF_MEM; } samp->wrap->wrap_flag = wrap_flags; return GF_OK;}static GFINLINE GF_Err gpp_write_modifier(GF_BitStream *bs, GF_Box *a){ GF_Err e; if (!a) return GF_OK; e = gf_isom_box_size(a); if (!e) e = gf_isom_box_write(a, bs); return e;}GF_ISOSample *gf_isom_text_to_sample(GF_TextSample *samp){ GF_Err e; GF_ISOSample *res; GF_BitStream *bs; u32 i; if (!samp) return NULL; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u16(bs, samp->len); if (samp->len) gf_bs_write_data(bs, samp->text, samp->len); e = gpp_write_modifier(bs, (GF_Box *)samp->styles); if (!e) e = gpp_write_modifier(bs, (GF_Box *)samp->highlight_color); if (!e) e = gpp_write_modifier(bs, (GF_Box *)samp->scroll_delay); if (!e) e = gpp_write_modifier(bs, (GF_Box *)samp->box); if (!e) e = gpp_write_modifier(bs, (GF_Box *)samp->wrap); if (!e) { GF_Box *a; i=0; while ((a = (GF_Box*)gf_list_enum(samp->others, &i))) { e = gpp_write_modifier(bs, a); if (e) break; } } if (e) { gf_bs_del(bs); return NULL; } res = gf_isom_sample_new(); if (!res) { gf_bs_del(bs); return NULL; } gf_bs_get_content(bs, &res->data, &res->dataLength); gf_bs_del(bs); res->IsRAP = 1; return res;}GF_Err gf_isom_text_has_similar_description(GF_ISOFile *movie, u32 trackNumber, GF_TextSampleDescriptor *desc, u32 *outDescIdx, Bool *same_box, Bool *same_styles){ GF_TrackBox *trak; GF_Err e; u32 i, j, count; GF_TextSampleEntryBox *txt; *same_box = *same_styles = 0; *outDescIdx = 0; if (!desc) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return GF_BAD_PARAM; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -