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

📄 timedtext_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	gf_node_changed((GF_Node *) n, NULL);		if (txt->box) {		br = txt->box->box;	} else {		br = td->default_pos;	}	if (!br.right || !br.bottom) {		br.top = br.left = 0;		br.right = priv->cfg->text_width;		br.bottom = priv->cfg->text_height;	}	thw = br.right - br.left;	thh = br.bottom - br.top;	if (!thw || !thh) {		br.top = br.left = 0;		thw = priv->cfg->text_width;		thh = priv->cfg->text_height;	}	priv->dlist->size.x = priv->rec_box->size.x = INT2FIX(thw);	priv->dlist->size.y = priv->rec_box->size.y = INT2FIX(thh);	gf_node_changed((GF_Node *) priv->rec_box, NULL);	form = (M_Form *) ttd_create_node(priv, TAG_MPEG4_Form, NULL);	form->size.x = INT2FIX(thw);	form->size.y = INT2FIX(thh);	thw /= 2;	thh /= 2;	tw = priv->cfg->text_width;	th = priv->cfg->text_height;	/*check translation, we must not get out of scene size - not supported in GPAC*/	offset = br.left - tw/2 + thw;	if (offset + thw < - tw/2) offset = - tw/2 + thw;	else if (offset - thw > tw/2) offset = tw/2 - thw;	priv->tr_box->translation.x = INT2FIX(offset);		offset = th/2 - br.top - thh;	if (offset + thh > th/2) offset = th/2 - thh;	else if (offset - thh < -th/2) offset = -th/2 + thh;	priv->tr_box->translation.y = INT2FIX(offset);		gf_node_dirty_set((GF_Node *)priv->tr_box, 0, 1);	if (priv->scroll_type) {		priv->ts_scroll->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_scroll);		gf_node_changed((GF_Node *) priv->ts_scroll, NULL);	}	priv->scroll_mode = 0;	if (td->displayFlags & GF_TXT_SCROLL_IN) priv->scroll_mode |= GF_TXT_SCROLL_IN;	if (td->displayFlags & GF_TXT_SCROLL_OUT) priv->scroll_mode |= GF_TXT_SCROLL_OUT;	priv->scroll_type = 0;	if (priv->scroll_mode) {		priv->scroll_type = (td->displayFlags & GF_TXT_SCROLL_DIRECTION)>>7;		priv->scroll_type ++;	}	/*no sample duration, cannot determine scroll rate, so just show*/	if (!sample_duration) priv->scroll_type = 0;	/*no scroll*/	if (!priv->scroll_mode) priv->scroll_type = 0;	if (priv->scroll_type) {		priv->tr_scroll = (M_Transform2D *) ttd_create_node(priv, TAG_MPEG4_Transform2D, NULL);		gf_node_list_add_child( &priv->dlist->children, (GF_Node*)priv->tr_scroll);		gf_node_register((GF_Node *) priv->tr_scroll, (GF_Node *) priv->dlist);		gf_node_list_add_child( &priv->tr_scroll->children, (GF_Node*)form);		gf_node_register((GF_Node *) form, (GF_Node *) priv->tr_scroll);		priv->tr_scroll->translation.x = priv->tr_scroll->translation.y = (priv->scroll_mode & GF_TXT_SCROLL_IN) ? -INT2FIX(1000) : 0;		/*if no delay, text is in motion for the duration of the sample*/		priv->scroll_time = FIX_ONE;		priv->scroll_delay = 0;		if (txt->scroll_delay) {			priv->scroll_delay = gf_divfix(INT2FIX(txt->scroll_delay->scroll_delay), INT2FIX(sample_duration));			if (priv->scroll_delay>FIX_ONE) priv->scroll_delay = FIX_ONE;			priv->scroll_time = (FIX_ONE - priv->scroll_delay);		}		/*if both scroll (in and out), use same scroll duration for both*/		if ((priv->scroll_mode & GF_TXT_SCROLL_IN) && (priv->scroll_mode & GF_TXT_SCROLL_OUT)) priv->scroll_time /= 2;	} else {		gf_node_list_add_child( &priv->dlist->children, (GF_Node*)form);		gf_node_register((GF_Node *) form, (GF_Node *) priv->dlist);		priv->tr_scroll = NULL;	}	if (is_utf_16) {		memcpy((char *) utf16_text, txt->text, sizeof(char) * txt->len);		((char *) utf16_text)[txt->len] = 0;		((char *) utf16_text)[txt->len+1] = 0;		char_count = txt->len / 2;	} else {		char *p = txt->text;		char_count = gf_utf8_mbstowcs(utf16_text, 2500, (const char **) &p);	}	chunks = gf_list_new();	/*flatten all modifiers*/	if (!txt->styles || !txt->styles->entry_count) {		GF_SAFEALLOC(tc, TTDTextChunk);		tc->end_char = char_count;		gf_list_add(chunks, tc);	} else {		GF_StyleRecord *srec = NULL;		char_offset = 0;		for (i=0; i<txt->styles->entry_count; i++) {			TTDTextChunk *tc;			srec = &txt->styles->styles[i];			if (srec->startCharOffset==srec->endCharOffset) continue;			/*handle not continuous modifiers*/			if (char_offset < srec->startCharOffset) {				GF_SAFEALLOC(tc, TTDTextChunk);				tc->start_char = char_offset;				tc->end_char = srec->startCharOffset;				gf_list_add(chunks, tc);			}			GF_SAFEALLOC(tc, TTDTextChunk);			tc->start_char = srec->startCharOffset;			tc->end_char = srec->endCharOffset;			tc->srec = srec;			gf_list_add(chunks, tc);			char_offset = srec->endCharOffset;		}		if (srec->endCharOffset<char_count) {			GF_SAFEALLOC(tc, TTDTextChunk);			tc->start_char = char_offset;			tc->end_char = char_count;			gf_list_add(chunks, tc);		}	}	/*apply all other modifiers*/	i=0;	while ((a = (GF_Box*)gf_list_enum(txt->others, &i))) {		TTD_SplitChunks(txt, char_count, chunks, a);	}	while (gf_list_count(chunks)) {		tc = (TTDTextChunk*)gf_list_get(chunks, 0);		gf_list_rem(chunks, 0);		TTD_NewTextChunk(priv, td, form, utf16_text, tc);		free(tc);	}	gf_list_del(chunks);	if (form->groupsIndex.vals[form->groupsIndex.count-1] != -1)		ttd_add_line(form);	/*rewrite form groupIndex - group is fine (eg one child per group)*/	idx.count = form->groupsIndex.count;	idx.vals = form->groupsIndex.vals;	form->groupsIndex.vals = NULL;	form->groupsIndex.count = 0;		nb_lines = 0;	start_idx = 0;	for (i=0; i<idx.count; i++) {		if (idx.vals[i] == -1) {			s32 *id;			u32 j;			/*only one item in line, no need for alignment, but still add a group (we could use the			item as a group but that would complicate the alignment generation)*/			if (start_idx==i-1) {				gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = idx.vals[start_idx];				gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;			} else {				/*spread horizontal 0 pixels (eg align) all items in line*/				gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = strdup(vertical ? "SV 0" : "SH 0");				for (j=start_idx; j<i; j++) {					gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = idx.vals[j];					/*also add a group for the line, for final justif*/					gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = idx.vals[j];				}				gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;				/*mark end of group*/				gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;			}			start_idx = i+1;			nb_lines ++;		}	}	free(idx.vals);	/*finally add constraints on lines*/	start_idx = gf_node_list_get_count(form->children) + 1;	/*horizontal alignment*/	gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s);	if (vertical) {		switch (td->vert_justif) {		case 1: s->buffer = strdup("AV"); break;/*center*/		case -1: s->buffer = strdup("AB"); break;/*bottom*/		default: s->buffer = strdup("AT"); break;/*top*/		}	} else {		switch (td->horiz_justif) {		case 1: s->buffer = strdup("AH"); break;/*center*/		case -1: s->buffer = strdup("AR"); break;/*right*/		default: s->buffer = strdup("AL"); break;/*left*/		}	}	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0;	for (i=0; i<nb_lines; i++) {		gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = i+start_idx;	}	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;	/*vertical alignment: first align all items vertically, 0 pixel */	gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = strdup(vertical ? "SH 0" : "SV 0"); 	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0;	for (i=0; i<nb_lines; i++) {		gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = i+start_idx;	}	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;	/*define a group with every item drawn*/	count = gf_node_list_get_count(form->children);	for (i=0; i<count; i++) {		gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = i+1;	}	gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;	gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s);	if (vertical) {		switch (td->horiz_justif) {		case 1: s->buffer = strdup("AH"); break;/*center*/		case -1: s->buffer = strdup("AR"); break;/*right*/		default: s->buffer = strdup("AL"); break;/*left*/		}	} else {		switch (td->vert_justif) {		case 1: s->buffer = strdup("AV"); break;/*center*/		case -1: s->buffer = strdup("AB"); break;/*bottom*/		default: s->buffer = strdup("AT"); break;/*top*/		}	}	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0;	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = start_idx + nb_lines;	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1;	gf_node_dirty_set((GF_Node *)form, 0, 1);	gf_node_changed((GF_Node *)form, NULL);	gf_node_changed((GF_Node *) priv->dlist, NULL);	if (gf_list_count(priv->blink_nodes)) {		/*restart time sensor*/		priv->ts_blink->startTime = gf_node_get_scene_time((GF_Node *) priv->ts_blink);		gf_node_changed((GF_Node *) priv->ts_blink, NULL);	}	priv->is_active = 1;	/*scroll timer also acts as AU timer*/	priv->ts_scroll->startTime = gf_node_get_scene_time((GF_Node *) priv->ts_scroll);	priv->ts_scroll->stopTime = priv->ts_scroll->startTime - 1.0;	priv->ts_scroll->cycleInterval = sample_duration;	priv->ts_scroll->cycleInterval /= priv->cfg->timescale;	priv->ts_scroll->cycleInterval -= 0.1;	gf_node_changed((GF_Node *) priv->ts_scroll, NULL);}static GF_Err TTD_ProcessData(GF_SceneDecoder*plug, char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 AU_time, u32 mmlevel){	GF_BitStream *bs;	GF_Err e = GF_OK;	TTDPriv *priv = (TTDPriv *)plug->privateStack;	bs = gf_bs_new(inBuffer, inBufferLength, GF_BITSTREAM_READ);	while (gf_bs_available(bs)) {		GF_TextSample *txt;		Bool is_utf_16;		u32 type, length, sample_index, sample_duration;		is_utf_16 = gf_bs_read_int(bs, 1);		gf_bs_read_int(bs, 4);		type = gf_bs_read_int(bs, 3);		length = gf_bs_read_u16(bs);				/*currently only full text samples are supported*/		if (type != 1) {			gf_bs_del(bs);			return GF_NOT_SUPPORTED;		}		sample_index = gf_bs_read_u8(bs);		/*duration*/		sample_duration = gf_bs_read_u24(bs);		length -= 8;		/*txt length is parsed with the sample*/		txt = gf_isom_parse_texte_sample(bs);		TTD_ApplySample(priv, txt, sample_index, is_utf_16, sample_duration);		gf_isom_delete_text_sample(txt);		/*since we support only TTU(1), no need to go on*/		break;	}	gf_bs_del(bs);	return e;}Bool TTD_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL){	TTDPriv *priv = (TTDPriv *)ifce->privateStack;	if (StreamType!=GF_STREAM_TEXT) return 0;	if (ObjectType!=0x08) return 0;	priv->PL = PL;	return 1;}void DeleteTimedTextDec(GF_BaseDecoder *plug){	TTDPriv *priv = (TTDPriv *)plug->privateStack;	/*in case something went wrong*/	if (priv->cfg) gf_odf_desc_del((GF_Descriptor *) priv->cfg);	free(priv);	free(plug);}GF_BaseDecoder *NewTimedTextDec(){	TTDPriv *priv;	GF_SceneDecoder *tmp;		GF_SAFEALLOC(tmp, GF_SceneDecoder);	if (!tmp) return NULL;	GF_SAFEALLOC(priv, TTDPriv);	tmp->privateStack = priv;	tmp->AttachStream = TTD_AttachStream;	tmp->DetachStream = TTD_DetachStream;	tmp->GetCapabilities = TTD_GetCapabilities;	tmp->SetCapabilities = TTD_SetCapabilities;	tmp->ProcessData = TTD_ProcessData;	tmp->AttachScene = TTD_AttachScene;	tmp->CanHandleStream = TTD_CanHandleStream;	tmp->ReleaseScene = TTD_ReleaseScene;	GF_REGISTER_MODULE_INTERFACE(tmp, GF_SCENE_DECODER_INTERFACE, "GPAC TimedText Decoder", "gpac distribution")	return (GF_BaseDecoder *) tmp;}GF_EXPORTBool QueryInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE: return 1;	case GF_NET_CLIENT_INTERFACE: return 1;	default: return 0;	}}#ifndef GPAC_READ_ONLYvoid DeleteTTReader(void *ifce);void *NewTTReader();#endifGF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewTimedTextDec();#ifndef GPAC_READ_ONLY	case GF_NET_CLIENT_INTERFACE: return (GF_BaseInterface *)NewTTReader();#endif	default: return NULL;	}}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		DeleteTimedTextDec((GF_BaseDecoder *)ifce);		break;#ifndef GPAC_READ_ONLY	case GF_NET_CLIENT_INTERFACE:		DeleteTTReader(ifce);		break;#endif	}}

⌨️ 快捷键说明

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