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

📄 text_import.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;		case 1:			if (sscanf(szLine, "%d:%d:%d,%d --> %d:%d:%d,%d", &sh, &sm, &ss, &sms, &eh, &em, &es, &ems) != 8) {				e = gf_import_message(import, GF_CORRUPTED_DATA, "Error scanning SRT frame %d timing", curLine);				goto exit;			}			start = (3600*sh + 60*sm + ss)*1000 + sms;			if (start<end) {				gf_import_message(import, GF_OK, "WARNING: corrupted SRT frame %d - starts (at %d ms) before end of previous one (%d ms) - adjusting time stamps", curLine, start, end);				start = end;			}			end = (3600*eh + 60*em + es)*1000 + ems;			/*make stream start at 0 by inserting a fake AU*/			if (first_samp && (start>0)) {				s = gf_isom_text_to_sample(samp);				s->DTS = 0;				gf_isom_add_sample(import->dest, track, 1, s);				gf_isom_sample_del(&s);				nb_samp++;			}			rec.style_flags = 0;			state = 2;						break;		default:			/*reset only when text is present*/			first_samp = 0;			/*go to line*/			if (txt_line) {				gf_isom_text_add_text(samp, "\n", 1);				char_len += 1;			}			ptr = (char *) szLine;			len = gf_utf8_mbstowcs(uniLine, 5000, (const char **) &ptr);			if (len == (u32) -1) {				e = gf_import_message(import, GF_CORRUPTED_DATA, "Invalid UTF data (line %d)", curLine);				goto exit;			}			char_line = 0;			i=j=0;			rem_styles = 0;			while (i<len) {				/*start of new style*/				if ( (uniLine[i]=='<') && (uniLine[i+2]=='>')) {					/*store prev style*/					if (set_end_char) {						assert(set_start_char);						gf_isom_text_add_style(samp, &rec);						set_end_char = set_start_char = 0;						rec.style_flags &= ~rem_styles;						rem_styles = 0;					}					if (set_start_char && (rec.startCharOffset != j)) {						rec.endCharOffset = char_len + j;						if (rec.style_flags) gf_isom_text_add_style(samp, &rec);					}					switch (uniLine[i+1]) {					case 'b': case 'B': 						rec.style_flags |= GF_TXT_STYLE_BOLD; 						set_start_char = 1;						rec.startCharOffset = char_len + j;						break;					case 'i': case 'I': 						rec.style_flags |= GF_TXT_STYLE_ITALIC; 						set_start_char = 1;						rec.startCharOffset = char_len + j;						break;					case 'u': case 'U': 						rec.style_flags |= GF_TXT_STYLE_UNDERLINED; 						set_start_char = 1;						rec.startCharOffset = char_len + j;						break;					}					i+=3;					continue;				}				/*end of prev style*/				if ( (uniLine[i]=='<') && (uniLine[i+1]=='/') && (uniLine[i+3]=='>')) {					switch (uniLine[i+2]) {					case 'b': case 'B': 						rem_styles |= GF_TXT_STYLE_BOLD; 						set_end_char = 1;						rec.endCharOffset = char_len + j;						break;					case 'i': case 'I': 						rem_styles |= GF_TXT_STYLE_ITALIC; 						set_end_char = 1;						rec.endCharOffset = char_len + j;						break;					case 'u': case 'U': 						rem_styles |= GF_TXT_STYLE_UNDERLINED; 						set_end_char = 1;						rec.endCharOffset = char_len + j;						break;					}					i+=4;					continue;				}				/*store style*/				if (set_end_char) {					gf_isom_text_add_style(samp, &rec);					set_end_char = 0;					set_start_char = 1;					rec.startCharOffset = char_len + j;					rec.style_flags &= ~rem_styles;					rem_styles = 0;				}				uniText[j] = uniLine[i];				j++;				i++;			}			/*store last style*/			if (set_end_char) {				gf_isom_text_add_style(samp, &rec);				set_end_char = 0;				set_start_char = 1;				rec.startCharOffset = char_len + j;				rec.style_flags &= ~rem_styles;				rem_styles = 0;			}			char_line = j;			uniText[j] = 0;			sptr = (u16 *) uniText;			len = gf_utf8_wcstombs(szText, 5000, (const u16 **) &sptr);			gf_isom_text_add_text(samp, szText, len);			char_len += char_line;			txt_line ++;			break;		}		if (duration && (start >= duration)) break;	}	/*final flush*/		if (end) {		gf_isom_text_reset(samp);		s = gf_isom_text_to_sample(samp);		s->DTS = (u64) (scale*(s64)end);		s->IsRAP = 1;		gf_isom_add_sample(import->dest, track, 1, s);		gf_isom_sample_del(&s);		nb_samp++;	}	gf_isom_delete_text_sample(samp);	gf_isom_set_last_sample_duration(import->dest, track, 0);	gf_set_progress("Importing SRT", nb_samp, nb_samp);exit:	if (e) gf_isom_remove_track(import->dest, track);	fclose(srt_in);	return e;}static GF_Err gf_text_import_sub(GF_MediaImporter *import){	FILE *sub_in;	u32 track, ID, timescale, i, j, desc_idx, start, end, prev_end, nb_samp, duration, file_size, len, line;	GF_TextConfig*cfg;	GF_Err e;	Double FPS;	GF_TextSample * samp;	Bool first_samp;	s32 unicode_type;	char szLine[2048], szTime[20], szText[2048];	GF_ISOSample *s;	sub_in = fopen(import->in_name, "rt");	fseek(sub_in, 0, SEEK_END);	file_size = ftell(sub_in);	fseek(sub_in, 0, SEEK_SET);		unicode_type = gf_text_get_utf_type(sub_in);	if (unicode_type<0) {		fclose(sub_in);		return gf_import_message(import, GF_NOT_SUPPORTED, "Unsupported SUB UTF encoding");	}	FPS = 25.0;	if (import->video_fps) FPS = import->video_fps;	cfg = NULL;	if (import->esd) {		if (!import->esd->slConfig) {			import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);			import->esd->slConfig->predefined = 2;			import->esd->slConfig->timestampResolution = 1000;		}		timescale = import->esd->slConfig->timestampResolution;		if (!timescale) timescale = 1000;		/*explicit text config*/		if (import->esd->decoderConfig && import->esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_TEXT_CFG_TAG) {			cfg = (GF_TextConfig *) import->esd->decoderConfig->decoderSpecificInfo;			import->esd->decoderConfig->decoderSpecificInfo = NULL;		}		ID = import->esd->ESID;	} else {		timescale = 1000;		ID = 0;	}		if (cfg && cfg->timescale) timescale = cfg->timescale;	track = gf_isom_new_track(import->dest, ID, GF_ISOM_MEDIA_TEXT, timescale);	if (!track) {		fclose(sub_in);		return gf_import_message(import, gf_isom_last_error(import->dest), "Error creating text track");	}	gf_isom_set_track_enabled(import->dest, track, 1);	if (import->esd && !import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track);	gf_text_import_set_language(import, track);	file_size = 0;	/*setup track*/	if (cfg) {		u32 count;		char *firstFont = NULL;		/*set track info*/		gf_isom_set_track_layout_info(import->dest, track, cfg->text_width<<16, cfg->text_height<<16, 0, 0, cfg->layer);		/*and set sample descriptions*/		count = gf_list_count(cfg->sample_descriptions);		for (i=0; i<count; i++) {			GF_TextSampleDescriptor *sd= (GF_TextSampleDescriptor *)gf_list_get(cfg->sample_descriptions, i);			if (!sd->font_count) {				sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord));				sd->font_count = 1;				sd->fonts[0].fontID = 1;				sd->fonts[0].fontName = strdup("Serif");			}			if (!sd->default_style.fontID) sd->default_style.fontID = sd->fonts[0].fontID;			if (!sd->default_style.font_size) sd->default_style.font_size = 16;			if (!sd->default_style.text_color) sd->default_style.text_color = 0xFF000000;			file_size = sd->default_style.font_size;			gf_isom_new_text_description(import->dest, track, sd, NULL, NULL, &desc_idx);			if (!firstFont) firstFont = sd->fonts[0].fontName;		}		gf_import_message(import, GF_OK, "Timed Text (SUB @ %02.2f) import - text track %d x %d, font %s (size %d)", FPS, cfg->text_width, cfg->text_height, firstFont, file_size);		gf_odf_desc_del((GF_Descriptor *)cfg);	} else {		u32 w, h;		GF_TextSampleDescriptor *sd;		gf_text_get_video_size(import->dest, &w, &h);		/*have to work with default - use max size (if only one video, this means the text region is the		entire display, and with bottom alignment things should be fine...*/		gf_isom_set_track_layout_info(import->dest, track, w<<16, h<<16, 0, 0, 0);		sd = (GF_TextSampleDescriptor*)gf_odf_desc_new(GF_ODF_TX3G_TAG);		sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord));		sd->font_count = 1;		sd->fonts[0].fontID = 1;		sd->fonts[0].fontName = strdup("Serif");		sd->back_color = 0x00000000;	/*transparent*/		sd->default_style.fontID = 1;		sd->default_style.font_size = TTXT_DEFAULT_FONT_SIZE;		sd->default_style.text_color = 0xFFFFFFFF;	/*white*/		sd->default_style.style_flags = 0;		sd->horiz_justif = 1; /*center of scene*/		sd->vert_justif = (s8) -1;	/*bottom of scene*/		if (import->flags & GF_IMPORT_SKIP_TXT_BOX) {			sd->default_pos.top = sd->default_pos.left = sd->default_pos.right = sd->default_pos.bottom = 0;		} else {			if ((sd->default_pos.bottom==sd->default_pos.top) || (sd->default_pos.right==sd->default_pos.left)) {				sd->default_pos.top = sd->default_pos.left = 0;				sd->default_pos.right = w;				sd->default_pos.bottom = h;			}		}		gf_isom_new_text_description(import->dest, track, sd, NULL, NULL, &desc_idx);		gf_import_message(import, GF_OK, "Timed Text (SUB @ %02.2f) import - text track %d x %d, font %s (size %d)", FPS, w, h, sd->fonts[0].fontName, TTXT_DEFAULT_FONT_SIZE);		gf_odf_desc_del((GF_Descriptor *)sd);	}	duration = (u32) (((Double) import->duration)*timescale/1000.0);	e = GF_OK;	nb_samp = 0;	samp = gf_isom_new_text_sample();	FPS = ((Double) timescale ) / FPS;	start = end = prev_end = 0;	line = 0;	first_samp = 1;	while (1) {		char *sOK = gf_text_get_utf8_line(szLine, 2048, sub_in, unicode_type);		if (!sOK) break;		REM_TRAIL_MARKS(szLine, "\r\n\t ")		line++;		len = strlen(szLine); 		if (!len) continue;		i=0;		if (szLine[i] != '{') {			e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Bad SUB file (line %d): expecting \"{\" got \"%c\"", line, szLine[i]);			goto exit;		}		while (szLine[i+1] && szLine[i+1]!='}') { szTime[i] = szLine[i+1]; i++; }		szTime[i] = 0;		start = atoi(szTime);		if (start<end) {			gf_import_message(import, GF_OK, "WARNING: corrupted SUB frame (line %d) - starts (at %d ms) before end of previous one (%d ms) - adjusting time stamps", line, start, end);			start = end;		}		j=i+2;		i=0;		if (szLine[i+j] != '{') {			e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Bad SUB file - expecting \"{\" got \"%c\"", szLine[i]);			goto exit;		}		while (szLine[i+1+j] && szLine[i+1+j]!='}') { szTime[i] = szLine[i+1+j]; i++; }		szTime[i] = 0;		end = atoi(szTime);		j+=i+2;		if (start>end) {			gf_import_message(import, GF_OK, "WARNING: corrupted SUB frame (line %d) - ends (at %d ms) before start of current frame (%d ms) - skipping", line, end, start);			continue;		}		gf_isom_text_reset(samp);		if (start && first_samp) {			s = gf_isom_text_to_sample(samp);			s->DTS = 0;			s->IsRAP = 1;			gf_isom_add_sample(import->dest, track, 1, s);			gf_isom_sample_del(&s);			first_samp = 0;			nb_samp++;		}		for (i=j; i<len; i++) {			if (szLine[i]=='|') {				szText[i-j] = '\n';			} else {				szText[i-j] = szLine[i];			}		}		szText[i-j] = 0;		gf_isom_text_add_text(samp, szText, strlen(szText) );		if (prev_end) {			GF_TextSample * empty_samp = gf_isom_new_text_sample();			s = gf_isom_text_to_sample(empty_samp);			s->DTS = (u64) (FPS*(s64)prev_end);			gf_isom_add_sample(import->dest, track, 1, s);			gf_isom_sample_del(&s);			nb_samp++;			gf_isom_delete_text_sample(empty_samp);		}		s = gf_isom_text_to_sample(samp);		s->DTS = (u64) (FPS*(s64)start);		gf_isom_add_sample(import->dest, track, 1, s);		gf_isom_sample_del(&s);		nb_samp++;		gf_isom_text_reset(samp);		prev_end = end;		gf_set_progress("Importing SUB", ftell(sub_in), file_size);		if (duration && (end >= duration)) break;	}	/*final flush*/	if (end) {		gf_isom_text_reset(samp);		s = gf_isom_text_to_sample(samp);		s->DTS = (u64)(FPS*(s64)end);		gf_isom_add_sample(import->dest, track, 1, s);		gf_isom_sample_del(&s);		nb_samp++;	}	gf_isom_delete_text_sample(samp);		gf_isom_set_last_sample_duration(import->dest, track, 0);	gf_set_progress("Importing SUB", nb_samp, nb_samp);exit:	if (e) gf_isom_remove_track(import->dest, track);	fclose(sub_in);	return e;}#define CHECK_STR(__str)	\	if (!__str) { \		e = gf_import_message(import, GF_BAD_PARAM, "Invalid XML formatting (line %d)", parser.line);	\		goto exit;	\	}	\u32 ttxt_get_color(GF_MediaImporter *import, char *val){	u32 r, g, b, a, res;	r = g = b = a = 0;	if (sscanf(val, "%x %x %x %x", &r, &g, &b, &a) != 4) {		gf_import_message(import, GF_OK, "Warning: color badly formatted");	}	res = (a&0xFF); res<<=8;	res |= (r&0xFF); res<<=8;	res |= (g&0xFF); res<<=8;	res |= (b&0xFF);	return res;}void ttxt_parse_text_box(GF_MediaImporter *import, GF_XMLNode *n, GF_BoxRecord *box){	u32 i=0;	GF_XMLAttribute *att;	memset(box, 0, sizeof(GF_BoxRecord));	while ( (att=(GF_XMLAttribute *)gf_list_enum(n->attributes, &i))) {		if (!stricmp(att->name, "top")) box->top = atoi(att->value);		else if (!stricmp(att->name, "bottom")) box->bottom = atoi(att->value);		else if (!stricmp(att->name, "left")) box->left = atoi(att->value);

⌨️ 快捷键说明

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