📄 svg_media.c
字号:
svg_sa_render_bitmap(node, rs); break;#endif case TAG_SVG_image: svg_render_bitmap(node, rs); break; } }}void svg_init_image(Render2D *sr, GF_Node *node){ u32 tag; SVG_image_stack *st; GF_SAFEALLOC(st, SVG_image_stack) st->graph = drawable_new(); st->graph->node = node; gf_sr_texture_setup(&st->txh, sr->compositor, node); st->txh.update_texture_fcnt = SVG_Update_image; st->txh.flags = 0; tag = gf_node_get_tag(node); /* builds the MFURL to be used by the texture */ switch (tag) {#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_image: gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->txurl), & ((SVG_SA_imageElement*)node)->xlink->href); break;#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_image: gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->txurl), & ((SVG_SA_imageElement*)node)->xlink->href); break;#endif case TAG_SVG_image: { GF_FieldInfo href_info; if (gf_svg_get_attribute_by_tag(node, TAG_SVG_ATT_xlink_href, 0, 0, &href_info) == GF_OK) { gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->txurl), href_info.far_ptr); } } break; } gf_node_set_private(node, st); gf_node_set_callback_function(node, SVG_Render_image);}/*********************//* SVG video element *//*********************/static void SVG_Update_video(GF_TextureHandler *txh){ SVG_video_stack *st = (SVG_video_stack *) gf_node_get_private(txh->owner); if (!txh->is_open) { u32 tag; SVG_InitialVisibility init_vis; if (st->first_frame_fetched) return; tag = gf_node_get_tag(txh->owner); init_vis = SVG_INITIALVISIBILTY_WHENSTARTED; switch (tag) {#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_video: init_vis = ((SVG_SA_videoElement *)txh->owner)->initialVisibility; break;#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_video: init_vis = ((SVG_SANI_videoElement *)txh->owner)->initialVisibility; break;#endif case TAG_SVG_video: { GF_FieldInfo init_vis_info; if (gf_svg_get_attribute_by_tag(txh->owner, TAG_SVG_ATT_initialVisibility, 0, 0, &init_vis_info) == GF_OK) { init_vis = *(SVG_InitialVisibility *)init_vis_info.far_ptr; } } break; } /*opens stream only at first access to fetch first frame if needed*/ if (init_vis == SVG_INITIALVISIBILTY_ALWAYS) { svg_play_texture((SVG_image_stack*)st, NULL); gf_sr_invalidate(txh->compositor, NULL); } return; } /*when fetching the first frame disable resync*/ gf_sr_texture_update_frame(txh, 0); /* only when needs_refresh = 1, first frame is fetched */ if (!st->first_frame_fetched) { if (!st->audio && gf_mo_has_audio(st->txh.stream)) { GF_FieldInfo att_vid, att_aud; st->audio = gf_node_new(st->txh.owner->sgprivate->scenegraph, TAG_SVG_audio); gf_node_register(st->audio, NULL); if (gf_svg_get_attribute_by_tag(st->txh.owner, TAG_SVG_ATT_xlink_href, 0, 0, &att_vid)==GF_OK) { gf_svg_get_attribute_by_tag(st->audio, TAG_SVG_ATT_xlink_href, 1, 0, &att_aud); gf_svg_attributes_copy(&att_aud, &att_vid, 0); } /*BYPASS SMIL TIMING MODULE!!*/ svg_init_audio((Render2D *)st->txh.compositor->visual_renderer->user_priv, st->audio, 1); } if (txh->needs_refresh) { st->first_frame_fetched = 1; /*stop stream if needed*/ if (!gf_smil_timing_is_active(txh->owner)) { gf_sr_texture_stop(txh); //make sure the refresh flag is not cleared txh->needs_refresh = 1; } } } /*we have no choice but retraversing the graph until we're inactive since the movie framerate and the renderer framerate are likely to be different */ if (!txh->stream_finished) gf_sr_invalidate(txh->compositor, NULL); if (st->stop_requested) { st->stop_requested = 0; gf_sr_texture_stop(&st->txh); }}static void svg_audio_smil_evaluate_ex(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status, GF_Node *audio, GF_Node *video);static void svg_video_smil_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status){ SVG_video_stack *stack = (SVG_video_stack *)gf_node_get_private((GF_Node *)rti->timed_elt); switch (status) { case SMIL_TIMING_EVAL_UPDATE: if (!stack->txh.is_open) { svg_play_texture((SVG_image_stack*)stack, NULL); } else if (stack->txh.stream_finished && (rti->media_duration<0) ) { Double dur = gf_mo_get_duration(stack->txh.stream); if (dur <= 0) { dur = stack->txh.last_frame_time; dur /= 1000; } gf_smil_set_media_duration(rti, dur); } break; case SMIL_TIMING_EVAL_FREEZE: case SMIL_TIMING_EVAL_REMOVE: stack->stop_requested = 1; break; case SMIL_TIMING_EVAL_REPEAT: gf_sr_texture_restart(&stack->txh); break; } if (stack->audio) svg_audio_smil_evaluate_ex(rti, normalized_scene_time, status, stack->audio, stack->txh.owner);}static void SVG_Render_video(GF_Node *node, void *rs, Bool is_destroy){ SVG_video_stack *st = (SVG_video_stack *)gf_node_get_private(node); if (is_destroy) { gf_sr_texture_destroy(&st->txh); gf_sg_mfurl_del(st->txurl); drawable_del(st->graph); if (st->audio) { gf_node_unregister(st->audio, NULL); } free(st); } else { switch (gf_node_get_tag(node)) {#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_video: svg_sa_render_bitmap(node, rs); break;#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_video: svg_sa_render_bitmap(node, rs); break;#endif case TAG_SVG_video: svg_render_bitmap(node, rs); if (st->audio) gf_node_render(st->audio, rs); break; } }}void svg_init_video(Render2D *sr, GF_Node *node){ u32 tag; SVG_video_stack *st; GF_SAFEALLOC(st, SVG_video_stack) st->graph = drawable_new(); st->graph->node = node; gf_sr_texture_setup(&st->txh, sr->compositor, node); st->txh.update_texture_fcnt = SVG_Update_video; st->txh.flags = 0; /* create an MFURL from the SVG iri */ tag = gf_node_get_tag(node); switch (tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_video:#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_video:#endif gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->txurl), & ((SVG_SA_videoElement *)node)->xlink->href); gf_smil_timing_init_runtime_info(node); if (((SVG_SA_Element *)node)->timing->runtime) { SMIL_Timing_RTI *rti = ((SVG_SA_Element *)node)->timing->runtime; rti->evaluate = svg_video_smil_evaluate; } break;#endif case TAG_SVG_video: { GF_FieldInfo href_info; if (gf_svg_get_attribute_by_tag(node, TAG_SVG_ATT_xlink_href, 0, 0, &href_info) == GF_OK) { gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->txurl), href_info.far_ptr); } if (((SVGTimedAnimBaseElement *)node)->timingp->runtime) { SMIL_Timing_RTI *rti = ((SVGTimedAnimBaseElement *)node)->timingp->runtime; rti->evaluate = svg_video_smil_evaluate; } } break; } gf_node_set_private(node, st); gf_node_set_callback_function(node, SVG_Render_video);}/*********************//* SVG audio element *//*********************/static void svg_audio_smil_evaluate_ex(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status, GF_Node *audio, GF_Node *video){ SVG_audio_stack *stack; if (!audio) audio = rti->timed_elt; stack = (SVG_audio_stack *)gf_node_get_private(audio); switch (status) { case SMIL_TIMING_EVAL_UPDATE: if (!stack->is_active) { SVGAllAttributes atts; gf_svg_flatten_attributes((SVG_Element*) (video ? video : audio), &atts); if (gf_sr_audio_open(&stack->input, &stack->aurl, atts.clipBegin ? (*atts.clipBegin) : 0.0, atts.clipEnd ? (*atts.clipEnd) : -1.0) == GF_OK) { gf_mo_set_speed(stack->input.stream, FIX_ONE); stack->is_active = 1; } } else if (!audio && stack->input.stream_finished && (rti->media_duration < 0) ) { Double dur = gf_mo_get_duration(stack->input.stream); if (dur <= 0) { dur = gf_mo_get_last_frame_time(stack->input.stream); dur /= 1000; } gf_smil_set_media_duration(rti, dur); } break; case SMIL_TIMING_EVAL_REPEAT: if (stack->is_active) gf_sr_audio_restart(&stack->input); break; case SMIL_TIMING_EVAL_FREEZE: gf_sr_audio_stop(&stack->input); stack->is_active = 0; break; case SMIL_TIMING_EVAL_REMOVE: gf_sr_audio_stop(&stack->input); stack->is_active = 0; break; case SMIL_TIMING_EVAL_DEACTIVATE: if (stack->is_active) { gf_sr_audio_stop(&stack->input); gf_sr_audio_unregister(&stack->input); stack->is_active = 0; } break; }}static void svg_audio_smil_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status){ svg_audio_smil_evaluate_ex(rti, normalized_scene_time, status, NULL, NULL);}static void SVG_Render_audio(GF_Node *node, void *rs, Bool is_destroy){ u32 tag; SVGAllAttributes all_atts; SVGPropertiesPointers backup_props; u32 backup_flags; RenderEffect2D *eff = (RenderEffect2D*)rs; SVG_audio_stack *st = (SVG_audio_stack *)gf_node_get_private(node); if (is_destroy) { gf_sr_audio_stop(&st->input); gf_sr_audio_unregister(&st->input); gf_sg_mfurl_del(st->aurl); free(st); return; } if (st->is_active) { gf_sr_audio_register(&st->input, (GF_BaseEffect*)rs); } tag = gf_node_get_tag(node); switch (tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_audio:#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_audio:#endif /*for heritage and anims*/ svg_sa_render_base(node, (RenderEffect2D *)rs, &backup_props, &backup_flags); break;#endif case TAG_SVG_audio: gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); svg_render_base(node, &all_atts, (RenderEffect2D *)rs, &backup_props, &backup_flags); break; } /*store mute flag*/ st->input.is_muted = 0; if ((eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) || svg_is_display_off(eff->svg_props) || (*(eff->svg_props->visibility) == SVG_VISIBILITY_HIDDEN) ) { st->input.is_muted = 1; } if (eff->svg_props->audio_level) { st->input.intensity = eff->svg_props->audio_level->value; } else { st->input.intensity = FIX_ONE; } memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); eff->svg_flags = backup_flags;}void svg_init_audio(Render2D *sr, GF_Node *node, Bool slaved_timing){ u32 tag; SVG_audio_stack *st; GF_SAFEALLOC(st, SVG_audio_stack) gf_sr_audio_setup(&st->input, sr->compositor, node); /* create an MFURL from the SVG iri */ tag = gf_node_get_tag(node); switch (tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_audio:#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_audio:#endif gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->aurl), & ((SVG_SA_audioElement *)node)->xlink->href); if (!slaved_timing && ((SVG_SA_Element *)node)->timing->runtime) { SMIL_Timing_RTI *rti = ((SVG_SA_Element *)node)->timing->runtime; rti->evaluate = svg_audio_smil_evaluate; } break;#endif case TAG_SVG_audio: { GF_FieldInfo href_info; if (gf_svg_get_attribute_by_tag(node, TAG_SVG_ATT_xlink_href, 0, 0, &href_info) == GF_OK) { gf_term_set_mfurl_from_uri(sr->compositor->term, &(st->aurl), href_info.far_ptr); } if (!slaved_timing && ((SVGTimedAnimBaseElement *)node)->timingp->runtime) { SMIL_Timing_RTI *rti = ((SVGTimedAnimBaseElement *)node)->timingp->runtime; rti->evaluate = svg_audio_smil_evaluate; } } break; } gf_node_set_private(node, st); gf_node_set_callback_function(node, SVG_Render_audio);}#endif //GPAC_DISABLE_SVG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -