Esempio n. 1
0
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();
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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);

    }
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
File: saf.c Progetto: erelh/gpac
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);
}
Esempio n. 7
0
static void xml_sax_parse_entity(GF_SAXParser *parser)
{
	char szName[1024];
	u32 i = 0;
	XML_Entity *ent = (XML_Entity *)gf_list_last(parser->entities);
	char *skip_chars = " \t\n\r";
	i=0;
	if (ent && ent->value) ent = NULL;
	if (ent) skip_chars = NULL;

	while (parser->current_pos+i < parser->line_size) {
		u8 c = parser->buffer[parser->current_pos+i];
		if (skip_chars && strchr(skip_chars, c)) {
			if (c=='\n') parser->line++;
			parser->current_pos++;
			continue;
		}
		if (!ent && (c=='%')) {
			parser->current_pos+=i+1;
			parser->sax_state = SAX_STATE_SKIP_DOCTYPE;
			return;
		}
		else if (!ent && ((c=='\"') || (c=='\'')) ) {
			szName[i] = 0;
			GF_SAFEALLOC(ent, XML_Entity);
			ent->name = gf_strdup(szName);
			ent->namelen = strlen(ent->name);
			ent->sep = c;
			parser->current_pos += 1+i;
			assert(parser->current_pos < parser->line_size);
			xml_sax_swap(parser);
			i=0;
			gf_list_add(parser->entities, ent);
			skip_chars = NULL;
		} else if (ent && c==ent->sep) {
			xml_sax_store_text(parser, i);

			ent->value = xml_get_current_text(parser);
			if (!ent->value) ent->value = gf_strdup("");

			parser->current_pos += 1;
			assert(parser->current_pos < parser->line_size);
			xml_sax_swap(parser);
			parser->sax_state = SAX_STATE_SKIP_DOCTYPE;
			return;
		} else if (!ent) {
			szName[i] = c;
			i++;
		} else {
			i++;
		}
	}
	xml_sax_store_text(parser, i);
}
Esempio n. 8
0
static GF_AUContext *gf_seng_create_new_au(GF_StreamContext *sc, u32 time) 
{
    GF_AUContext *new_au, *last_au;
    last_au = gf_list_last(sc->AUs);
    if (last_au && last_au->timing == time) {
        GF_LOG(GF_LOG_DEBUG, GF_LOG_SCENE, ("[SceneEngine] Forcing new AU\n"));
        time++;
    }
    new_au = gf_sm_stream_au_new(sc, time, 0, 0);
    return new_au;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
	}
}
Esempio n. 11
0
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);
	}
}
Esempio n. 12
0
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);
	}
}
Esempio n. 13
0
static void on_dom_text_content(void *cbk, const char *content, Bool is_cdata)
{
	GF_DOMParser *par = (GF_DOMParser *)cbk;
	GF_XMLNode *node;
	GF_XMLNode *last = (GF_XMLNode *)gf_list_last(par->stack);
	if (!last) return;
	assert(last->content);

	GF_SAFEALLOC(node, GF_XMLNode);
	node->type = is_cdata ? GF_XML_CDATA_TYPE : GF_XML_TEXT_TYPE;
	node->name = gf_strdup(content);
	gf_list_add(last->content, node);
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
File: saf.c Progetto: erelh/gpac
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);
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
File: saf_in.c Progetto: Bevara/GPAC
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);
}
Esempio n. 18
0
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;
	}
}
Esempio n. 19
0
GF_Err SetTrackDuration(GF_TrackBox *trak)
{
    u64 trackDuration;
    u32 i;
    GF_EdtsEntry *ent;
    GF_EditListBox *elst;
    GF_Err e;

    //the total duration is the media duration: adjust it in case...
    e = Media_SetDuration(trak);
    if (e) return e;

    //assert the timeScales are non-NULL
    if (!trak->moov->mvhd->timeScale || !trak->Media->mediaHeader->timeScale) return GF_ISOM_INVALID_FILE;
    trackDuration = (trak->Media->mediaHeader->duration * trak->moov->mvhd->timeScale) / trak->Media->mediaHeader->timeScale;

    //if we have an edit list, the duration is the sum of all the editList
    //entries' duration (always expressed in MovieTimeScale)
    if (trak->editBox && !trak->editBox->last_is_empty && trak->editBox->editList) {
        trackDuration = 0;
        elst = trak->editBox->editList;
        i=0;
        while ((ent = (GF_EdtsEntry*)gf_list_enum(elst->entryList, &i))) {
            trackDuration += ent->segmentDuration;
            if (ent->mediaRate && !ent->segmentDuration) {
                trak->editBox->last_is_empty = 1;
            }
        }

        if (trak->editBox->last_is_empty) {
            ent = (GF_EdtsEntry*) gf_list_last(elst->entryList);
            ent->segmentDuration = trackDuration;
        }
    }
    trak->Header->duration = trackDuration;
    trak->Header->modificationTime = gf_isom_get_mp4time();
    return GF_OK;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
//WARNING: MOVIETIME IS EXPRESSED IN MEDIA TS
GF_Err GetMediaTime(GF_TrackBox *trak, Bool force_non_empty, u64 movieTime, u64 *MediaTime, s64 *SegmentStartTime, s64 *MediaOffset, u8 *useEdit, u64 *next_edit_start_plus_one)
{
#if 0
    GF_Err e;
    u32 sampleNumber, prevSampleNumber;
    u64 firstDTS;
#endif
    u32 i, count;
    Bool last_is_empty = 0;
    u64 time, lastSampleTime;
    s64 mtime;
    GF_EdtsEntry *ent;
    Double scale_ts;
    GF_SampleTableBox *stbl = trak->Media->information->sampleTable;

    if (next_edit_start_plus_one) *next_edit_start_plus_one = 0;
    *useEdit = 1;
    *MediaTime = 0;
    //no segment yet...
    *SegmentStartTime = -1;
    *MediaOffset = -1;
    if (!trak->moov->mvhd->timeScale || !trak->Media->mediaHeader->timeScale || !stbl->SampleSize) {
        return GF_ISOM_INVALID_FILE;
    }

    //no samples...
    if (!stbl->SampleSize->sampleCount) {
        lastSampleTime = 0;
    } else {
        lastSampleTime = trak->Media->mediaHeader->duration;
    }

    //No edits, 1 to 1 mapping
    if (! trak->editBox || !trak->editBox->editList) {
        *MediaTime = movieTime;
        //check this is in our media time line
        if ((*MediaTime > lastSampleTime)
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
                && !trak->moov->mov->moof
#endif
           ) {
            *MediaTime = lastSampleTime;
        }
        *useEdit = 0;
        return GF_OK;
    }
    //browse the edit list and get the time
    scale_ts = trak->Media->mediaHeader->timeScale;
    scale_ts /= trak->moov->mvhd->timeScale;

    time = 0;
    ent = NULL;
    count=gf_list_count(trak->editBox->editList->entryList);
    for (i=0; i<count; i++) {
        ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, i);
        if ( (time + ent->segmentDuration) * scale_ts > movieTime) {
            if (!force_non_empty || (ent->mediaTime >= 0)) {
                if (next_edit_start_plus_one) *next_edit_start_plus_one = 1 + (u64) ((time + ent->segmentDuration) * scale_ts);
                goto ent_found;
            }
        }
        time += ent->segmentDuration;
        last_is_empty = ent->segmentDuration ? 0 : 1;
    }

    if (last_is_empty) {
        ent = (GF_EdtsEntry *)gf_list_last(trak->editBox->editList->entryList);
        if (ent->mediaRate==1) {
            *MediaTime = movieTime + ent->mediaTime;
        } else {
            ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, 0);
            if (ent->mediaRate==-1) {
                u64 dur = (u64) (ent->segmentDuration * scale_ts);
                *MediaTime = (movieTime > dur) ? (movieTime-dur) : 0;
            }
        }
        *useEdit = 0;
        return GF_OK;
    }


    //we had nothing in the list (strange file but compliant...)
    //return the 1 to 1 mapped vale of the last media sample
    if (!ent) {
        *MediaTime = movieTime;
        //check this is in our media time line
        if (*MediaTime > lastSampleTime) *MediaTime = lastSampleTime;
        *useEdit = 0;
        return GF_OK;
    }
    //request for a bigger time that what we can give: return the last sample (undefined behavior...)
    *MediaTime = lastSampleTime;
    return GF_OK;

ent_found:
    //OK, we found our entry, set the SegmentTime
    *SegmentStartTime = time;

    //we request an empty list, there's no media here...
    if (ent->mediaTime < 0) {
        *MediaTime = 0;
        return GF_OK;
    }
    //we request a dwell edit
    if (! ent->mediaRate) {
        *MediaTime = ent->mediaTime;
        //no media offset
        *MediaOffset = 0;
        *useEdit = 2;
        return GF_OK;
    }

    /*WARNING: this can be "-1" when doing searchForward mode (to prevent jumping to next entry)*/
    mtime = ent->mediaTime + movieTime - (time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale);
    if (mtime<0) mtime = 0;
    *MediaTime = (u64) mtime;
    *MediaOffset = ent->mediaTime;

#if 0
    //
    //Sanity check: is the requested time valid ? This is to cope with wrong EditLists
    //we have the translated time, but we need to make sure we have a sample at this time ...
    //we have to find a COMPOSITION time
    e = findEntryForTime(stbl, (u32) *MediaTime, 1, &sampleNumber, &prevSampleNumber);
    if (e) return e;

    //first case: our time is after the last sample DTS (it's a broken editList somehow)
    //set the media time to the last sample
    if (!sampleNumber && !prevSampleNumber) {
        *MediaTime = lastSampleTime;
        return GF_OK;
    }
    //get the appropriated sample
    if (!sampleNumber) sampleNumber = prevSampleNumber;

    stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
    CTS = 0;
    if (stbl->CompositionOffset) stbl_GetSampleCTS(stbl->CompositionOffset, sampleNumber, &CTS);

    //now get the entry sample (the entry time gives the CTS, and we need the DTS
    e = findEntryForTime(stbl, (u32) ent->mediaTime, 0, &sampleNumber, &prevSampleNumber);
    if (e) return e;

    //oops, the mediaTime indicates a sample that is not in our media !
    if (!sampleNumber && !prevSampleNumber) {
        *MediaTime = lastSampleTime;
        return GF_ISOM_INVALID_FILE;
    }
    if (!sampleNumber) sampleNumber = prevSampleNumber;

    stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &firstDTS);

    //and store the "time offset" of the desired sample in this segment
    //this is weird, used to rebuild the timeStamp when reading from the track, not the
    //media ...
    *MediaOffset = firstDTS;
#endif
    return GF_OK;
}
Esempio n. 24
0
static void get_domtext_width(GF_Node *node, SVGAllAttributes *atts, GF_TraverseState *tr_state)
{
	u32 i;
	GF_Font *font;
	Fixed block_width, *entry;
	GF_FontManager *fm;
	GF_TextSpan *span;
	GF_DOMText *dom_text = (GF_DOMText *)node;

	if (!dom_text->textContent) return;

	fm = tr_state->visual->compositor->font_manager;
	if (!fm) return;

	font = svg_set_font(tr_state, fm);
	if (!font) return;

	span = svg_get_text_span(fm, font, tr_state->svg_props->font_size->value, (tr_state->count_x>1), (tr_state->count_y>1), GF_FALSE, atts, dom_text->textContent, atts->xml_lang ? *atts->xml_lang : NULL, tr_state);
	if (!span) return;

	i=0;
	//count_x, _y: number of x- (y-) position of characters to come in the text flow
	while ( (i<span->nb_glyphs)
	        && ( (tr_state->count_x>1) || (tr_state->count_y>1) )
	      ) {
		block_width = (span->glyphs[i] ? span->glyphs[i]->horiz_advance : font->max_advance_h) * span->font_scale;

		//store width in tr_state->x_anchors
		entry = (Fixed*)gf_malloc(sizeof(Fixed));
		if (span->flags & GF_TEXT_SPAN_RIGHT_TO_LEFT) *entry = -block_width;
		else *entry = block_width;

		gf_list_add(tr_state->x_anchors, entry);

		if (tr_state->count_x>0) tr_state->count_x--;
		if (tr_state->count_y>0) tr_state->count_y--;
		i++;
	}

	//chars are taken one by one while there are indicated positions, then remaining chars are treated as a block
	if (i<span->nb_glyphs) {
		block_width = 0;
		while (i<span->nb_glyphs) {
			block_width += (span->glyphs[i] ? span->glyphs[i]->horiz_advance : font->max_advance_h) * span->font_scale;
			i++;
		}
		//if last indicated position, create a new item
		if ((tr_state->count_x==1)||(tr_state->count_y==1)
		        || !gf_list_count(tr_state->x_anchors) ) {
			entry = (Fixed*)gf_malloc(sizeof(Fixed));
			*entry = block_width;

			if (span->flags & GF_TEXT_SPAN_RIGHT_TO_LEFT) *entry = -block_width;
			else *entry = block_width;

			gf_list_add(tr_state->x_anchors, entry);
		} else { // (count_x == 0 && count_y == 0) otherwise increment last one
			Fixed *prec_lw = gf_list_last(tr_state->x_anchors);
			(*prec_lw) += block_width;
		}
		//force counters to 0 for next spans/DOM texts
		if (tr_state->count_x==1) tr_state->count_x = 0;
		if (tr_state->count_y==1) tr_state->count_y = 0;
	}
	gf_font_manager_delete_span(fm, span);
}
Esempio n. 25
0
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);
	} 
}
Esempio n. 26
0
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;
}