示例#1
0
static void UpdateBackgroundTexture(GF_TextureHandler *txh)
{
	gf_sc_texture_update_frame(txh, 0);
	/*restart texture if needed (movie background controled by MediaControl)*/
	if (txh->stream_finished && gf_mo_get_loop(txh->stream, 0)) 
		gf_sc_texture_restart(txh);
}
示例#2
0
static void SVG_Update_image(GF_TextureHandler *txh)
{	
	MFURL *txurl = &(((SVG_video_stack *)gf_node_get_private(txh->owner))->txurl);

	/*setup texture if needed*/
	if (!txh->is_open && txurl->count) {
		gf_sc_texture_play_from_to(txh, txurl, 0, -1, GF_FALSE, GF_FALSE);
	}

	gf_sc_texture_update_frame(txh, GF_FALSE);
	/*URL is present but not opened - redraw till fetch*/
	if (txh->stream && (!txh->tx_io || txh->needs_refresh) ) {
		/*mark all subtrees using this image as dirty*/
		gf_node_dirty_parents(txh->owner);
		gf_sc_invalidate(txh->compositor, NULL);
	}
}
示例#3
0
static void movietexture_update(GF_TextureHandler *txh)
{
	M_MovieTexture *txnode = (M_MovieTexture *) txh->owner;
	MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(txh->owner);

	/*setup texture if needed*/
	if (!txh->is_open) return;
	if (!txnode->isActive && st->first_frame_fetched) return;

	/*when fetching the first frame disable resync*/
	gf_sc_texture_update_frame(txh, 0);

	if (txh->stream_finished) {
		if (movietexture_get_loop(st, txnode)) {
			gf_sc_texture_restart(txh);
		}
		/*if active deactivate*/
		else if (txnode->isActive && gf_mo_should_deactivate(st->txh.stream) ) {
			movietexture_deactivate(st, txnode);
		}
	}
	/*first frame is fetched*/
	if (!st->first_frame_fetched && (txh->needs_refresh) ) {
		st->first_frame_fetched = 1;
		txnode->duration_changed = gf_mo_get_duration(txh->stream);
		gf_node_event_out(txh->owner, 7/*"duration_changed"*/);
		/*stop stream if needed*/
		if (!txnode->isActive && txh->is_open) {
			gf_mo_pause(txh->stream);
			/*make sure the refresh flag is not cleared*/
			txh->needs_refresh = 1;
			gf_sc_invalidate(txh->compositor, NULL);
		}
	}
	if (txh->needs_refresh) {
		/*mark all subtrees using this image as dirty*/
		gf_node_dirty_parents(txh->owner);
	}
}
示例#4
0
static void imagetexture_update(GF_TextureHandler *txh)
{
	if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) {
		MFURL url = ((M_ImageTexture *) txh->owner)->url;

		/*setup texture if needed*/
		if (!txh->is_open && url.count) {
			gf_sc_texture_play(txh, &url);
		}
		gf_sc_texture_update_frame(txh, 0);

		if (
		    /*URL is present but not opened - redraw till fetch*/
		    /* (txh->stream && !txh->tx_io) && */
		    /*image has been updated*/
		    txh->needs_refresh) {
			/*mark all subtrees using this image as dirty*/
			gf_node_dirty_parents(txh->owner);
			gf_sc_invalidate(txh->compositor, NULL);
		}
		return;
	}
	/*cache texture case*/
	else {
		M_CacheTexture *ct = (M_CacheTexture *) txh->owner;

		/*decode cacheTexture data */
		if ((ct->data || ct->image.buffer) && !txh->data) {
#ifndef GPAC_DISABLE_AV_PARSERS
			u32 out_size;
			GF_Err e;

			/*BT/XMT playback: load to memory*/
			if (ct->image.buffer) {
				char *par = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) );
				char *src_url = gf_url_concatenate(par, ct->image.buffer);
				FILE *test = gf_fopen( src_url ? src_url : ct->image.buffer, "rb");
				if (test) {
					fseek(test, 0, SEEK_END);
					ct->data_len = (u32) gf_ftell(test);
					ct->data = gf_malloc(sizeof(char)*ct->data_len);
					fseek(test, 0, SEEK_SET);
					if (ct->data_len != fread(ct->data, 1, ct->data_len, test)) {
						GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: IO err\n", src_url ? src_url : ct->image.buffer ) );
						gf_free(ct->data);
						ct->data = NULL;
						ct->data_len = 0;
					}
					gf_fclose(test);
				} else {
					GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: not found\n", src_url ? src_url : ct->image.buffer ) );
				}
				ct->image.buffer = NULL;
				if (src_url) gf_free(src_url);
			}

			/*BIFS decoded playback*/
			switch (ct->objectTypeIndication) {
			case GPAC_OTI_IMAGE_JPEG:
				out_size = 0;
				e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size, 3);
				if (e==GF_BUFFER_TOO_SMALL) {
					u32 BPP;
					txh->data = gf_malloc(sizeof(char) * out_size);
					if (txh->pixelformat==GF_PIXEL_GREYSCALE) BPP = 1;
					else BPP = 3;

					e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size, BPP);
					if (e==GF_OK) {
						gf_sc_texture_allocate(txh);
						gf_sc_texture_set_data(txh);
						txh->needs_refresh = 1;
						txh->stride = out_size / txh->height;
					}
				}
				break;
			case GPAC_OTI_IMAGE_PNG:
				out_size = 0;
				e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size);
				if (e==GF_BUFFER_TOO_SMALL) {
					txh->data = gf_malloc(sizeof(char) * out_size);
					e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size);
					if (e==GF_OK) {
						gf_sc_texture_allocate(txh);
						gf_sc_texture_set_data(txh);
						txh->needs_refresh = 1;
						txh->stride = out_size / txh->height;
					}
				}
				break;
			}

#endif // GPAC_DISABLE_AV_PARSERS

			/*cacheURL is specified, store the image*/
			if (ct->cacheURL.buffer) {
				u32 i;
				u8 hash[20];
				FILE *cached_texture;
				char szExtractName[GF_MAX_PATH], section[64], *opt, *src_url;
				opt = (char *) gf_cfg_get_key(txh->compositor->user->config, "General", "CacheDirectory");
				if (opt) {
					strcpy(szExtractName, opt);
				} else {
					opt = gf_get_default_cache_directory();
					strcpy(szExtractName, opt);
					gf_free(opt);
				}
				strcat(szExtractName, "/");
				src_url = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) );

				gf_sha1_csum((u8 *)src_url, (u32) strlen(src_url), hash);
				for (i=0; i<20; i++) {
					char t[3];
					t[2] = 0;
					sprintf(t, "%02X", hash[i]);
					strcat(szExtractName, t);
				}
				strcat(szExtractName, "_");

				strcat(szExtractName, ct->cacheURL.buffer);
				cached_texture = gf_fopen(szExtractName, "wb");
				if (cached_texture) {
					gf_fwrite(ct->data, 1, ct->data_len, cached_texture);
					gf_fclose(cached_texture);
				}

				/*and write cache info*/
				if (ct->expirationDate!=0) {
					sprintf(section, "@cache=%p", ct);
					gf_cfg_set_key(txh->compositor->user->config, section, "serviceURL", src_url);
					gf_cfg_set_key(txh->compositor->user->config, section, "cacheFile", szExtractName);
					gf_cfg_set_key(txh->compositor->user->config, section, "cacheName", ct->cacheURL.buffer);

					if (ct->expirationDate>0) {
						char exp[50];
						u32 sec, frac;
						gf_net_get_ntp(&sec, &frac);
						sec += ct->expirationDate;
						sprintf(exp, "%u", sec);
						gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", exp);
					} else {
						gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", "0");
					}
				}
			}

			/*done with image, destroy buffer*/
			if (ct->data) gf_free(ct->data);
			ct->data = NULL;
			ct->data_len = 0;
		}
	}
}
示例#5
0
static void SVG_Update_video(GF_TextureHandler *txh)
{
	GF_FieldInfo init_vis_info;
	SVG_video_stack *stack = (SVG_video_stack *) gf_node_get_private(txh->owner);
	
	if (!txh->is_open) {
		SVG_InitialVisibility init_vis;
		if (stack->first_frame_fetched) return;

		init_vis = SVG_INITIALVISIBILTY_WHENSTARTED;

		if (gf_node_get_attribute_by_tag(txh->owner, TAG_SVG_ATT_initialVisibility, GF_FALSE, GF_FALSE, &init_vis_info) == GF_OK) {
			init_vis = *(SVG_InitialVisibility *)init_vis_info.far_ptr;
		}

		/*opens stream only at first access to fetch first frame if needed*/
		if (init_vis == SVG_INITIALVISIBILTY_ALWAYS) {
			svg_play_texture((SVG_video_stack*)stack, NULL);
			gf_sc_invalidate(txh->compositor, NULL);
		}
		return;
	} 

	/*when fetching the first frame disable resync*/
	gf_sc_texture_update_frame(txh, GF_FALSE);

	/* only when needs_refresh = 1, first frame is fetched */
	if (!stack->first_frame_fetched) {
		if (txh->needs_refresh) {
			stack->first_frame_fetched = GF_TRUE;
			/*stop stream if needed*/
			if (!gf_smil_timing_is_active(txh->owner)) {
				gf_sc_texture_stop(txh);
				//make sure the refresh flag is not cleared
				txh->needs_refresh = GF_TRUE;
			}
		}
	}

	if (!stack->audio && stack->audio_dirty) {
		u32 res = gf_mo_has_audio(stack->txh.stream);
		if (res != 2) {
			stack->audio_dirty = GF_FALSE;
			if (res) {
				GF_FieldInfo att_vid, att_aud;
				stack->audio = gf_node_new(gf_node_get_graph(stack->txh.owner), TAG_SVG_audio);
				gf_node_register(stack->audio, NULL);
				if (gf_node_get_attribute_by_tag(stack->txh.owner, TAG_XLINK_ATT_href, GF_FALSE, GF_FALSE, &att_vid)==GF_OK) {
					gf_node_get_attribute_by_tag(stack->audio, TAG_XLINK_ATT_href, GF_TRUE, GF_FALSE, &att_aud);
					gf_svg_attributes_copy(&att_aud, &att_vid, GF_FALSE);
				}
				/*BYPASS SMIL TIMING MODULE!!*/
				compositor_init_svg_audio(stack->txh.compositor, stack->audio, GF_TRUE);
			}
		}
	}
	
	/*we have no choice but retraversing the graph until we're inactive since the movie framerate and
	the compositor framerate are likely to be different */
	if (!txh->stream_finished) 
	if (txh->needs_refresh)
		gf_sc_invalidate(txh->compositor, NULL);

	if (stack->stop_requested) {
		stack->stop_requested = GF_FALSE;
		gf_sc_texture_stop(&stack->txh);
	}
}