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); }
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); } }
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); } }
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; } } }
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); } }