GF_EXPORT void gf_xml_dom_node_del(GF_XMLNode *node) { if (node->attributes) { while (gf_list_count(node->attributes)) { GF_XMLAttribute *att = (GF_XMLAttribute *)gf_list_last(node->attributes); gf_list_rem_last(node->attributes); if (att->name) gf_free(att->name); if (att->value) gf_free(att->value); gf_free(att); } gf_list_del(node->attributes); } if (node->content) { while (gf_list_count(node->content)) { GF_XMLNode *child = (GF_XMLNode *)gf_list_last(node->content); gf_list_rem_last(node->content); gf_xml_dom_node_del(child); } gf_list_del(node->content); } if (node->ns) gf_free(node->ns); if (node->name) gf_free(node->name); gf_free(node); }
void dc_cmd_data_destroy(CmdData *cmd_data) { while (gf_list_count(cmd_data->audio_lst)) { AudioDataConf *audio_data_conf = gf_list_last(cmd_data->audio_lst); gf_free(audio_data_conf->custom); gf_list_rem_last(cmd_data->audio_lst); gf_free(audio_data_conf); } gf_list_del(cmd_data->audio_lst); while (gf_list_count(cmd_data->video_lst)) { VideoDataConf *video_data_conf = gf_list_last(cmd_data->video_lst); gf_free(video_data_conf->custom); gf_list_rem_last(cmd_data->video_lst); gf_free(video_data_conf); } gf_list_del(cmd_data->video_lst); gf_list_del(cmd_data->asrc); gf_list_del(cmd_data->vsrc); gf_cfg_del(cmd_data->conf); gf_cfg_del(cmd_data->switch_conf); if (cmd_data->logfile) fclose(cmd_data->logfile); dc_task_destroy(&cmd_data->task_list); gf_sys_close(); }
void dc_audio_decoder_close(AudioInputFile *audio_input_file) { /* * Close the audio format context */ avformat_close_input(&audio_input_file->av_fmt_ctx); if (audio_input_file->av_pkt_list_mutex) { gf_mx_p(audio_input_file->av_pkt_list_mutex); while (gf_list_count(audio_input_file->av_pkt_list)) { AVPacket *pkt = gf_list_last(audio_input_file->av_pkt_list); av_free_packet(pkt); gf_list_rem_last(audio_input_file->av_pkt_list); } gf_list_del(audio_input_file->av_pkt_list); gf_mx_v(audio_input_file->av_pkt_list_mutex); gf_mx_del(audio_input_file->av_pkt_list_mutex); } av_fifo_free(audio_input_file->fifo); #ifdef DC_AUDIO_RESAMPLER avresample_free(&audio_input_file->aresampler); #endif }
static void gf_sm_reset_stream(GF_StreamContext *sc) { while (gf_list_count(sc->AUs)) { GF_AUContext *au = (GF_AUContext *)gf_list_last(sc->AUs); gf_list_rem_last(sc->AUs); gf_sm_au_del(sc, au); } }
static void bifs_info_del(BIFSStreamInfo *info) { while (1) { BIFSElementaryMask *em = (BIFSElementaryMask *)gf_list_last(info->config.elementaryMasks); if (!em) break; gf_list_rem_last(info->config.elementaryMasks); gf_free(em); } gf_free(info); }
void gf_saf_mux_del(GF_SAFMuxer *mux) { while (gf_list_count(mux->streams)) { GF_SAFStream *str = (GF_SAFStream *)gf_list_last(mux->streams); gf_list_rem_last(mux->streams); saf_stream_del(str); } gf_list_del(mux->streams); gf_mx_del(mux->mx); gf_free(mux); }
GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable) { u32 i, count, last_sample; GF_SubSampleInfoEntry *pSamp; GF_SubSampleEntry *pSubSamp; pSamp = NULL; last_sample = 0; count = gf_list_count(sub_samples->Samples); for (i=0; i<count; i++) { pSamp = (GF_SubSampleInfoEntry*) gf_list_get(sub_samples->Samples, i); /*TODO - do we need to support insertion of subsample info ?*/ if (last_sample + pSamp->sample_delta > sampleNumber) return GF_NOT_SUPPORTED; if (last_sample + pSamp->sample_delta == sampleNumber) break; last_sample += pSamp->sample_delta; pSamp = NULL; } if (!pSamp) { GF_SAFEALLOC(pSamp, GF_SubSampleInfoEntry); if (!pSamp) return GF_OUT_OF_MEM; pSamp->SubSamples = gf_list_new(); if (!pSamp->SubSamples ) { gf_free(pSamp); return GF_OUT_OF_MEM; } pSamp->sample_delta = sampleNumber - last_sample; gf_list_add(sub_samples->Samples, pSamp); } if ((subSampleSize>0xFFFF) && !sub_samples->version) { sub_samples->version = 1; } /*remove last subsample info*/ if (!subSampleSize) { pSubSamp = gf_list_last(pSamp->SubSamples); gf_list_rem_last(pSamp->SubSamples); gf_free(pSubSamp); if (!gf_list_count(pSamp->SubSamples)) { gf_list_del_item(sub_samples->Samples, pSamp); gf_list_del(pSamp->SubSamples); gf_free(pSamp); } return GF_OK; } /*add subsample*/ GF_SAFEALLOC(pSubSamp, GF_SubSampleEntry); if (!pSubSamp) return GF_OUT_OF_MEM; pSubSamp->subsample_size = subSampleSize; pSubSamp->subsample_priority = priority; pSubSamp->reserved = reserved; pSubSamp->discardable = discardable; return gf_list_add(pSamp->SubSamples, pSubSamp); }
GPAC_MediaRenderer::~GPAC_MediaRenderer() { if (m_mediaHistoryList) { /* empty mediaHistoryList */ while (gf_list_count(m_mediaHistoryList) > 0) { char * last = (char*)gf_list_last(m_mediaHistoryList); gf_list_rem_last(m_mediaHistoryList); gf_free(last); } gf_list_del(m_mediaHistoryList); } }
static void gf_sm_delete_stream(GF_StreamContext *sc) { while (gf_list_count(sc->AUs)) { GF_AUContext *au = (GF_AUContext *)gf_list_last(sc->AUs); gf_list_rem_last(sc->AUs); while (gf_list_count(au->commands)) { void *comptr = gf_list_last(au->commands); gf_list_rem_last(au->commands); switch (sc->streamType) { case GF_STREAM_OD: gf_odf_com_del((GF_ODCom**) & comptr); break; case GF_STREAM_SCENE: gf_sg_command_del((GF_Command *)comptr); break; } } gf_list_del(au->commands); free(au); } gf_list_del(sc->AUs); free(sc); }
static void saf_stream_del(GF_SAFStream *str) { if (str->mime_type) gf_free(str->mime_type); if (str->remote_url) gf_free(str->remote_url); if (str->dsi) gf_free(str->dsi); while (gf_list_count(str->aus)) { GF_SAFSample *au = (GF_SAFSample *)gf_list_last(str->aus); gf_list_rem_last(str->aus); if (au->data) gf_free(au->data); gf_free(au); } gf_list_del(str->aus); gf_free(str); }
static void xml_sax_reset(GF_SAXParser *parser) { while (1) { XML_Entity *ent = (XML_Entity *)gf_list_last(parser->entities); if (!ent) break; gf_list_rem_last(parser->entities); if (ent->name) gf_free(ent->name); if (ent->value) gf_free(ent->value); gf_free(ent); } if (parser->buffer) gf_free(parser->buffer); parser->buffer = NULL; parser->current_pos = 0; gf_free(parser->attrs); parser->attrs = NULL; gf_free(parser->sax_attrs); parser->sax_attrs = NULL; parser->nb_alloc_attrs = parser->nb_attrs = 0; }
void DeleteSAFReader(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; SAFIn *read = (SAFIn *)plug->priv; if (!ifce) return; while (gf_list_count(read->channels)) { SAFChannel *ch = (SAFChannel *)gf_list_last(read->channels); gf_list_rem_last(read->channels); if (ch->esd) gf_odf_desc_del((GF_Descriptor *) ch->esd); gf_free(ch); } gf_list_del(read->channels); if (read->saf_data) gf_free(read->saf_data); read->saf_data = NULL; gf_free(read); plug->priv = NULL; gf_free(plug); }
static void on_dom_node_end(void *cbk, const char *name, const char *ns) { GF_DOMParser *par = (GF_DOMParser *)cbk; GF_XMLNode *last = (GF_XMLNode *)gf_list_last(par->stack); gf_list_rem_last(par->stack); if (!last || strcmp(last->name, name) || (!ns && last->ns) || (ns && !last->ns) || (ns && strcmp(last->ns, ns) ) ) { par->parser->suspended = 1; gf_xml_dom_node_del(last); if (last==par->root) par->root=NULL; return; } if (last != par->root) { GF_XMLNode *node = (GF_XMLNode *)gf_list_last(par->stack); assert(node->content); assert(gf_list_find(node->content, last) == -1); gf_list_add(node->content, last); } }
static void on_dom_node_end(void *cbk, const char *name, const char *ns) { GF_DOMParser *par = (GF_DOMParser *)cbk; GF_XMLNode *last = (GF_XMLNode *)gf_list_last(par->stack); gf_list_rem_last(par->stack); if (!last || strcmp(last->name, name) || (!ns && last->ns) || (ns && !last->ns) || (ns && strcmp(last->ns, ns) ) ) { format_sax_error(par->parser, 0, "Invalid node stack: closing node is %s but %s was expected", name, last->name); par->parser->suspended = 1; gf_xml_dom_node_del(last); if (last==par->root) par->root=NULL; return; } if (last != par->root) { GF_XMLNode *node = (GF_XMLNode *)gf_list_last(par->stack); assert(node->content); assert(gf_list_find(node->content, last) == -1); gf_list_add(node->content, last); } }
static void gf_xml_dom_reset(GF_DOMParser *dom, Bool full_reset) { if (full_reset && dom->parser) { gf_xml_sax_del(dom->parser); dom->parser = NULL; } if (dom->stack) { while (gf_list_count(dom->stack)) { GF_XMLNode *n = (GF_XMLNode *)gf_list_last(dom->stack); gf_list_rem_last(dom->stack); if (dom->root==n) dom->root = NULL; gf_xml_dom_node_del(n); } gf_list_del(dom->stack); dom->stack = NULL; } if (full_reset && dom->root) { gf_xml_dom_node_del(dom->root); dom->root = NULL; } }
static void RP_cleanup(RTPClient *rtp) { RTSPSession *sess; while (gf_list_count(rtp->channels)) { RTPStream *ch = (RTPStream *)gf_list_get(rtp->channels, 0); gf_list_rem(rtp->channels, 0); RP_DeleteStream(ch); } while ( (sess = (RTSPSession *)gf_list_last(rtp->sessions)) ) { gf_list_rem_last(rtp->sessions); RP_DelSession(sess); } if (rtp->session_desc) gf_odf_desc_del(rtp->session_desc); rtp->session_desc = NULL; if (rtp->sdp_temp) { gf_free(rtp->sdp_temp->remote_url); gf_free(rtp->sdp_temp); } rtp->sdp_temp = NULL; }
void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg) { GF_List *l; switch (type) { case SVG_Paint_datatype: gf_svg_delete_paint(sg, (SVG_Paint *)value); break; case XMLRI_datatype: case XML_IDREF_datatype: gf_svg_reset_iri(sg, (XMLRI *)value); gf_free(value); break; case SVG_Focus_datatype: gf_svg_reset_iri(sg, & ((SVG_Focus*)value)->target); gf_free(value); break; case SVG_PathData_datatype: #if USE_GF_PATH gf_path_del((GF_Path *)value); #else gf_free(value); #endif break; case SVG_ID_datatype: case DOM_String_datatype: case SVG_ContentType_datatype: case SVG_LanguageID_datatype: if (*(SVG_String *)value) gf_free(*(SVG_String *)value); gf_free(value); break; case SVG_StrokeDashArray_datatype: if (((SVG_StrokeDashArray*)value)->array.vals) gf_free(((SVG_StrokeDashArray*)value)->array.vals); gf_free(value); break; case SVG_Numbers_datatype: case SVG_Coordinates_datatype: case SVG_Points_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { void *n = gf_list_last(l); gf_list_rem_last(l); gf_free(n); } gf_list_del(l); gf_free(value); break; case SVG_FontFamily_datatype: { SVG_FontFamily *ff = (SVG_FontFamily *)value; if (ff->value) gf_free(ff->value); gf_free(value); } break; case SMIL_AttributeName_datatype: { SMIL_AttributeName *an = (SMIL_AttributeName *)value; if (an->name) gf_free(an->name); gf_free(value); } break; case SMIL_Times_datatype: gf_smil_delete_times(*(SMIL_Times *)value); gf_free(value); break; case SMIL_AnimateValue_datatype: svg_delete_one_anim_value(((SMIL_AnimateValue *)value)->type, ((SMIL_AnimateValue *)value)->value, sg); gf_free(value); break; case SMIL_AnimateValues_datatype: gf_svg_reset_animate_values(*((SMIL_AnimateValues *)value), sg); gf_free(value); break; case DOM_StringList_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { char *n = gf_list_last(l); gf_list_rem_last(l); gf_free(n); } gf_list_del(l); gf_free(value); break; case XMLRI_List_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { XMLRI *r = gf_list_last(l); gf_list_rem_last(l); if (r->string) gf_free(r->string); gf_free(r); } gf_list_del(l); gf_free(value); break; case SMIL_KeyTimes_datatype: case SMIL_KeySplines_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { Fixed *f = gf_list_last(l); gf_list_rem_last(l); gf_free(f); } gf_list_del(l); gf_free(value); break; case SMIL_RepeatCount_datatype: case SMIL_Duration_datatype: case SVG_Length_datatype: case SVG_Coordinate_datatype: case SVG_Visibility_datatype: case SVG_Display_datatype: default: gf_free(value); } }
static void svg_traverse_resource(GF_Node *node, void *rs, Bool is_destroy, Bool is_foreign_object) { GF_Matrix2D backup_matrix; GF_Matrix mx_3d; GF_Matrix2D translate; SVGPropertiesPointers backup_props; u32 backup_flags, dirty; Bool is_fragment; GF_Node *used_node; GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVGAllAttributes all_atts; SVGlinkStack *stack = gf_node_get_private(node); SFVec2f prev_vp; SVG_Number *prev_opacity; if (is_destroy) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); gf_free(stack); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!all_atts.xlink_href) return; if (!compositor_svg_traverse_base(node, &all_atts, tr_state, &backup_props, &backup_flags)) return; dirty = gf_node_dirty_get(node); if (dirty & GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node); if (dirty & GF_SG_SVG_XLINK_HREF_DIRTY) { stack->fragment_id = NULL; stack->inline_sg = NULL; if (all_atts.xlink_href->string && (all_atts.xlink_href->string[0]=='#')) { stack->fragment_id = all_atts.xlink_href->string; stack->inline_sg = gf_node_get_graph(node); } else { GF_MediaObject *new_res = gf_mo_load_xlink_resource(node, is_foreign_object, 0, -1); if (new_res != stack->resource) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); stack->resource = new_res; } } } gf_node_dirty_clear(node, 0); /*locate the used node - this is done at each step to handle progressive loading*/ is_fragment = 0; used_node = NULL; if (!stack->inline_sg && !stack->fragment_id && all_atts.xlink_href) { if (all_atts.xlink_href->type == XMLRI_ELEMENTID) { used_node = all_atts.xlink_href->target; is_fragment = 1; } else if (stack->resource) { stack->inline_sg = gf_mo_get_scenegraph(stack->resource); if (!is_foreign_object) { stack->fragment_id = strchr(all_atts.xlink_href->string, '#'); } } } if (!used_node && stack->inline_sg) { if (stack->fragment_id) { used_node = gf_sg_find_node_by_name(stack->inline_sg, (char *) stack->fragment_id+1); is_fragment = 1; } else if (is_foreign_object) { used_node = gf_sg_get_root_node(stack->inline_sg); } } if (!used_node) goto end; /*stack use nodes for picking*/ gf_list_add(tr_state->use_stack, used_node); gf_list_add(tr_state->use_stack, node); gf_mx2d_init(translate); translate.m[2] = (all_atts.x ? all_atts.x->value : 0); translate.m[5] = (all_atts.y ? all_atts.y->value : 0); /*update VP size (SVG 1.1)*/ prev_vp = tr_state->vp_size; if (all_atts.width && all_atts.height) { tr_state->vp_size.x = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.width); tr_state->vp_size.y = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.height); } prev_opacity = tr_state->parent_use_opacity; tr_state->parent_use_opacity = all_atts.opacity; if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); if (!compositor_svg_is_display_off(tr_state->svg_props)) { gf_node_traverse(used_node, tr_state); gf_mx2d_apply_rect(&translate, &tr_state->bounds); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } /*SORT mode and visible, traverse*/ else if (!compositor_svg_is_display_off(tr_state->svg_props) && (*(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN)) { compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { gf_mx_add_matrix_2d(&tr_state->model_matrix, &translate); if (tr_state->traversing_mode==TRAVERSE_SORT) { GF_Matrix tmp; gf_mx_from_mx2d(&tmp, &translate); visual_3d_matrix_add(tr_state->visual, tmp.m); } } else #endif gf_mx2d_pre_multiply(&tr_state->transform, &translate); drawable_check_focus_highlight(node, tr_state, NULL); if (is_fragment) { gf_node_traverse(used_node, tr_state); } else { gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } gf_list_rem_last(tr_state->use_stack); gf_list_rem_last(tr_state->use_stack); tr_state->vp_size = prev_vp; tr_state->parent_use_opacity = prev_opacity; end: memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }
static Bool validator_xvs_open(GF_Validator *validator) { GF_Err e; GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[Validator] Opening Validation Script: %s\n", validator->xvs_filename)); validator->snapshot_number = 0; validator->xvs_parser = gf_xml_dom_new(); e = gf_xml_dom_parse(validator->xvs_parser, validator->xvs_filename, NULL, NULL); if (e != GF_OK) { if (validator->is_recording) { GF_SAFEALLOC(validator->xvs_node, GF_XMLNode); validator->xvs_node->name = gf_strdup("TestValidationScript"); validator->xvs_node->attributes = gf_list_new(); validator->xvs_node->content = gf_list_new(); } else { gf_xml_dom_del(validator->xvs_parser); validator->xvs_parser = NULL; return 0; } } else { validator->xvs_node = gf_xml_dom_get_root(validator->xvs_parser); } /* Get the file name from the XVS if not found in the XVL */ if (!validator->test_filename) { GF_XMLAttribute *att; GF_XMLAttribute *att_file; u32 att_index = 0; att_file = NULL; while (1) { att = gf_list_get(validator->xvs_node->attributes, att_index); if (!att) { break; } else if (!strcmp(att->name, "file")) { att_file = att; } att_index++; } if (!att_file) { gf_xml_dom_del(validator->xvs_parser); validator->xvs_parser = NULL; validator->xvs_node = NULL; return 0; } else { char *sep; sep = strrchr(att_file->value, GF_PATH_SEPARATOR); if (!sep) { validator->test_filename = att_file->value; } else { sep[0] = 0; validator->test_base = gf_strdup(att_file->value); sep[0] = GF_PATH_SEPARATOR; validator->test_filename = sep+1; } } } if (validator->is_recording) { GF_XMLNode *node; /* Removing prerecorded interactions */ while (gf_list_count(validator->xvs_node->content)) { GF_XMLNode *child = (GF_XMLNode *)gf_list_last(validator->xvs_node->content); gf_list_rem_last(validator->xvs_node->content); gf_xml_dom_node_del(child); } /* adding an extra text node for line break in serialization */ GF_SAFEALLOC(node, GF_XMLNode); node->type = GF_XML_TEXT_TYPE; node->name = gf_strdup("\n"); gf_list_add(validator->xvs_node->content, node); } else { validator->xvs_result = 1; } return 1; }
GF_Err gf_webvtt_merge_cues(GF_WebVTTParser *parser, u64 start, GF_List *cues) { GF_WebVTTSample *wsample; GF_WebVTTSample *prev_wsample; Bool has_continuation_cue = GF_FALSE; assert(gf_list_count(parser->samples) <= 1); wsample = gf_webvtt_sample_new(); wsample->start = start; prev_wsample = (GF_WebVTTSample *)gf_list_last(parser->samples); while (gf_list_count(cues)) { GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(cues, 0); gf_list_rem(cues, 0); /* add the cue to the current sample */ gf_list_add(wsample->cues, cue); /* update with the previous sample */ if (prev_wsample) { Bool found = GF_FALSE; while (!found && gf_list_count(prev_wsample->cues)) { GF_WebVTTCue *old_cue = (GF_WebVTTCue *)gf_list_get(prev_wsample->cues, 0); gf_list_rem(prev_wsample->cues, 0); if ( ((!cue->id && !old_cue->id) || (old_cue->id && cue->id && !strcmp(old_cue->id, cue->id))) && ((!cue->settings && !old_cue->settings) || (old_cue->settings && cue->settings && !strcmp(old_cue->settings, cue->settings))) && ((!cue->text && !old_cue->text) || (old_cue->text && cue->text && !strcmp(old_cue->text, cue->text))) ) { /* if it is the same cue, update its start with the initial start */ cue->start = old_cue->start; has_continuation_cue = GF_TRUE; found = GF_TRUE; if (old_cue->pre_text) { cue->pre_text = old_cue->pre_text; old_cue->pre_text = NULL; } if (old_cue->post_text) { cue->post_text = old_cue->post_text; old_cue->post_text = NULL; } /* delete the old cue */ gf_webvtt_cue_del(old_cue); } else { /* finalize the end cue time */ if (gf_webvtt_timestamp_is_zero(&old_cue->end)) { gf_webvtt_timestamp_set(&old_cue->end, wsample->start); } /* transfer the cue */ if (!has_continuation_cue) { /* the cue can be safely serialized while keeping the order */ parser->on_cue_read(parser->user, old_cue); } else { /* keep the cue in the current sample to respect cue start ordering */ gf_list_add(wsample->cues, old_cue); } } } } } /* No cue in the current sample */ if (prev_wsample) { while (gf_list_count(prev_wsample->cues)) { GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(prev_wsample->cues, 0); gf_list_rem(prev_wsample->cues, 0); /* finalize the end cue time */ if (gf_webvtt_timestamp_is_zero(&cue->end)) { gf_webvtt_timestamp_set(&cue->end, wsample->start); } /* transfer the cue */ if (!has_continuation_cue) { /* the cue can be safely serialized while keeping the order */ parser->on_cue_read(parser->user, cue); } else { /* keep the cue in the current sample to respect cue start ordering */ gf_list_add(wsample->cues, cue); } } gf_webvtt_sample_del(prev_wsample); gf_list_rem_last(parser->samples); prev_wsample = NULL; } else { /* nothing to do */ } if (gf_list_count(wsample->cues)) { gf_list_add(parser->samples, wsample); } else { gf_webvtt_sample_del(wsample); } return GF_OK; }
static void svg_traverse_text(GF_Node *node, void *rs, Bool is_destroy) { SVGPropertiesPointers backup_props; u32 backup_flags; GF_Matrix2D backup_matrix; GF_Matrix mx3d; GF_ChildNodeItem *child; DrawableContext *ctx; SVG_TextStack *st = (SVG_TextStack *)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVG_Element *text = (SVG_Element *)node; SVGAllAttributes atts; u32 i,imax; Fixed * lw; if (is_destroy) { drawable_del(st->drawable); svg_reset_text_stack(st); gf_list_del(st->spans); gf_free(st); return; } if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { svg_text_draw_2d(st, tr_state); return; } else if (tr_state->traversing_mode==TRAVERSE_GET_TEXT) { tr_state->text_parent = node; gf_font_spans_get_selection(node, st->spans, tr_state); /*and browse children*/ child = ((GF_ParentNode *) text)->children; while (child) { switch (gf_node_get_tag(child->node)) { case TAG_SVG_tspan: gf_node_traverse(child->node, tr_state); break; } child = child->next; } tr_state->text_parent = NULL; return; } gf_svg_flatten_attributes(text, &atts); if (!compositor_svg_traverse_base(node, &atts, tr_state, &backup_props, &backup_flags)) return; tr_state->in_svg_text++; tr_state->text_parent = node; if (tr_state->traversing_mode==TRAVERSE_PICK) { compositor_svg_apply_local_transformation(tr_state, &atts, &backup_matrix, &mx3d); if (*tr_state->svg_props->pointer_events!=SVG_POINTEREVENTS_NONE) gf_font_spans_pick(node, st->spans, tr_state, &st->bounds, 1, st->drawable); /*and browse children*/ child = ((GF_ParentNode *) text)->children; while (child) { switch (gf_node_get_tag(child->node)) { case TAG_SVG_tspan: gf_node_traverse(child->node, tr_state); break; } child = child->next; } memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx3d); tr_state->svg_flags = backup_flags; tr_state->text_parent = NULL; tr_state->in_svg_text--; return; } else if (tr_state->traversing_mode==TRAVERSE_GET_TEXT) { gf_font_spans_get_selection(node, st->spans, tr_state); memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; tr_state->text_parent = NULL; tr_state->in_svg_text--; return; } compositor_svg_apply_local_transformation(tr_state, &atts, &backup_matrix, &mx3d); if ( (st->prev_size != tr_state->svg_props->font_size->value) || (st->prev_flags != *tr_state->svg_props->font_style) || (st->prev_anchor != *tr_state->svg_props->text_anchor) || (gf_node_dirty_get(node) & (GF_SG_SVG_GEOMETRY_DIRTY | GF_SG_CHILD_DIRTY) ) || tr_state->visual->compositor->reset_fonts ) { u32 mode; child = ((GF_ParentNode *) text)->children; svg_reset_text_stack(st); tr_state->text_end_x = 0; tr_state->text_end_y = 0; /*init the xml:space algo*/ tr_state->last_char_type = 0; /*initialize x and y counters - stored at the traverse level for handling tspan & co*/ if (atts.text_x) tr_state->count_x = gf_list_count(*atts.text_x); else tr_state->count_x=0; if (atts.text_y) tr_state->count_y = gf_list_count(*atts.text_y); else tr_state->count_y=0; if (atts.text_rotate) tr_state->count_rotate = gf_list_count(*atts.text_rotate); else tr_state->count_rotate=0; /*horizontal justifiers container*/ tr_state->x_anchors = gf_list_new(); /*compute length of all text blocks*/ while (child) { svg_compute_text_width(child->node, &atts, tr_state); child=child->next; } /*apply justification of all blocks*/ imax=gf_list_count(tr_state->x_anchors); for (i=0; i<imax; i++) { lw=gf_list_get(tr_state->x_anchors, i); svg_apply_text_anchor(tr_state, lw); } /*re-initialize x and y counters for final compute*/ if (atts.text_x) tr_state->count_x = gf_list_count(*atts.text_x); else tr_state->count_x=0; if (atts.text_y) tr_state->count_y = gf_list_count(*atts.text_y); else tr_state->count_y=0; if (atts.text_rotate) tr_state->count_rotate = gf_list_count(*atts.text_rotate); else tr_state->count_rotate=0; tr_state->idx_rotate = 0; tr_state->chunk_index = 0; /*initialize current text position*/ if (!tr_state->text_end_x) { SVG_Coordinate *xc = (atts.text_x ? (SVG_Coordinate *) gf_list_get(*atts.text_x, 0) : NULL); tr_state->text_end_x = (xc ? xc->value : 0); } if (!tr_state->text_end_y) { SVG_Coordinate *yc = (atts.text_y ? (SVG_Coordinate *) gf_list_get(*atts.text_y, 0) : NULL); tr_state->text_end_y = (yc ? yc->value : 0); } /*pass x and y to children*/ tr_state->text_x = atts.text_x; tr_state->text_y = atts.text_y; tr_state->text_rotate = atts.text_rotate; drawable_reset_path(st->drawable); /*switch to bounds mode, and recompute children*/ mode = tr_state->traversing_mode; tr_state->traversing_mode = TRAVERSE_GET_BOUNDS; tr_state->last_char_type = 0; child = ((GF_ParentNode *) text)->children; while (child) { svg_traverse_text_block(child->node, &atts, tr_state, st->spans); child = child->next; } tr_state->traversing_mode = mode; gf_node_dirty_clear(node, 0); drawable_mark_modified(st->drawable, tr_state); st->prev_size = tr_state->svg_props->font_size->value; st->prev_flags = *tr_state->svg_props->font_style; st->prev_anchor = *tr_state->svg_props->text_anchor; while (gf_list_count(tr_state->x_anchors)) { Fixed *f = gf_list_last(tr_state->x_anchors); gf_list_rem_last(tr_state->x_anchors); gf_free(f); } gf_list_del(tr_state->x_anchors); tr_state->x_anchors = NULL; svg_update_bounds(st); } if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { if (!compositor_svg_is_display_off(tr_state->svg_props)) tr_state->bounds = st->bounds; } else if ((tr_state->traversing_mode == TRAVERSE_SORT) && !compositor_svg_is_display_off(tr_state->svg_props) && (*(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN) ) { ctx = drawable_init_context_svg(st->drawable, tr_state); if (ctx) svg_finalize_sort(ctx, st, tr_state); /*and browse children*/ child = ((GF_ParentNode *) text)->children; while (child) { switch (gf_node_get_tag(child->node)) { case TAG_SVG_tspan: gf_node_traverse(child->node, tr_state); break; case TAG_SVG_switch: gf_node_traverse(child->node, tr_state); break; } child = child->next; } } tr_state->in_svg_text--; tr_state->text_parent = NULL; compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx3d); memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }