コード例 #1
0
ファイル: media_control.c プロジェクト: bbshocking/gpac
void mediacontrol_restart(GF_ObjectManager *odm)
{
	GF_List *to_restart;
	GF_ObjectManager *ctrl_od;
	GF_Clock *ck, *scene_ck;
	u32 i;
	u32 current_seg;
#ifndef GPAC_DISABLE_VRML
	MediaControlStack *ctrl;
#endif

	if (!odm || (odm->flags & GF_ODM_NO_TIME_CTRL) ) return;

#ifndef GPAC_DISABLE_VRML
	ctrl = gf_odm_get_mediacontrol(odm);
	if (ctrl) {
		/*we have a control - filter calls to only handle objects owning media control*/
		ctrl_od = ctrl->stream->odm;
		/*if media control owns the scene this OD refers to the scene is always restarted - TODO make that an option*/
		if (!ctrl_od->subscene) {
			if (ctrl->stream->odm != odm) return;
		}
		odm = ctrl->stream->odm;

		/*this is inline restart - only possible through media control*/
		if (odm->subscene && odm->subscene->root_od==ctrl->stream->odm) {
			gf_inline_restart(odm->subscene);
			return;
		}
	}
#endif

	/*if clock is main scene clock do nothing*/
	scene_ck = gf_odm_get_media_clock(odm->parentscene->root_od);
	if (gf_odm_shares_clock(odm, scene_ck)) {
		if (odm->parentscene->is_dynamic_scene)
			gf_scene_restart_dynamic(odm->parentscene, 0, 0);
		return;
	}

	/*otherwise locate all objects sharing the clock*/
	ck = gf_odm_get_media_clock(odm);
	if (!ck) return;

	current_seg = 0;
#ifndef GPAC_DISABLE_VRML
	/*store current segment idx*/
	if (ctrl) {
		current_seg = ctrl->current_seg;
		/*if last segment is passed restart*/
		if (gf_list_count(ctrl->seg) == current_seg) current_seg = 0;
	}
#endif

	to_restart = gf_list_new();
	/*do stop/start in 2 pass, it's much cleaner for servers*/
	i=0;
	while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(odm->parentscene->resources, &i))) {
		if (!gf_odm_shares_clock(ctrl_od, ck)) continue;
		/*if running, stop and collect for restart*/
		if (ctrl_od->state) {
			gf_odm_stop(ctrl_od, 1);
			gf_list_add(to_restart, ctrl_od);
		}
	}
	/*force clock reset since we don't know how OD ordering is done*/
	gf_clock_reset(ck);
#ifndef GPAC_DISABLE_VRML
	if (ctrl) ctrl->current_seg = current_seg;
#endif

	/*play on all ODs collected for restart*/
	i=0;
	while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(to_restart, &i))) {
		gf_odm_start(ctrl_od, 0);
	}
	gf_list_del(to_restart);
}
コード例 #2
0
ファイル: validator.c プロジェクト: bigbensk/gpac
static void validator_xvs_add_event_dom(GF_Validator *validator, GF_Event *event) 
{
    GF_XMLNode *evt_node;
    GF_XMLAttribute *att;
    
    GF_SAFEALLOC(evt_node, GF_XMLNode);

    switch (event->type) {
	case GF_EVENT_CLICK: 
	case GF_EVENT_MOUSEUP:
	case GF_EVENT_MOUSEDOWN: 
	case GF_EVENT_MOUSEOVER: 
	case GF_EVENT_MOUSEOUT:
	case GF_EVENT_MOUSEMOVE:
	case GF_EVENT_MOUSEWHEEL:
	case GF_EVENT_KEYUP:
	case GF_EVENT_KEYDOWN:
	case GF_EVENT_TEXTINPUT:
        evt_node->name = gf_strdup(gf_dom_event_get_name(event->type));
        break;
    }
    
    if (!evt_node->name) {
        gf_free(evt_node);
        return;
    }

    evt_node->attributes = gf_list_new();

    GF_SAFEALLOC(att, GF_XMLAttribute);
    att->name = gf_strdup("time");
    att->value = gf_malloc(100);
    sprintf(att->value, "%f", gf_scene_get_time(validator->term->root_scene)*1000);
    gf_list_add(evt_node->attributes, att);

    switch (event->type) {
	case GF_EVENT_CLICK: 
	case GF_EVENT_MOUSEUP:
	case GF_EVENT_MOUSEDOWN: 
	case GF_EVENT_MOUSEOVER: 
	case GF_EVENT_MOUSEOUT:
	case GF_EVENT_MOUSEMOVE:
	case GF_EVENT_MOUSEWHEEL:
        if (event->type == GF_EVENT_MOUSEDOWN || event->type == GF_EVENT_MOUSEUP) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("button");
            switch (event->mouse.button) {
                case 0:
                    att->value = gf_strdup("Left");
                    break;
                case 1:
                    att->value = gf_strdup("Middle");
                    break;
                case 2:
                    att->value = gf_strdup("Right");
                    break;
            }
            gf_list_add(evt_node->attributes, att);
        }
        GF_SAFEALLOC(att, GF_XMLAttribute);
        att->name = gf_strdup("x");
        att->value = gf_malloc(100);
        sprintf(att->value, "%d", event->mouse.x);
        gf_list_add(evt_node->attributes, att);
        GF_SAFEALLOC(att, GF_XMLAttribute);
        att->name = gf_strdup("y");
        att->value = gf_malloc(100);
        sprintf(att->value, "%d", event->mouse.y);
        gf_list_add(evt_node->attributes, att);
        if (event->type == GF_EVENT_MOUSEWHEEL) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("wheel_pos");
            att->value = gf_malloc(100);
            sprintf(att->value, "%f", event->mouse.wheel_pos);
            gf_list_add(evt_node->attributes, att);
        }
        if (event->mouse.key_states & GF_KEY_MOD_SHIFT) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("shift");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
        if (event->mouse.key_states & GF_KEY_MOD_CTRL) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("ctrl");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
        if (event->mouse.key_states & GF_KEY_MOD_ALT) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("alt");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
        break;
	/*Key Events*/
	case GF_EVENT_KEYUP:
	case GF_EVENT_KEYDOWN:
	case GF_EVENT_LONGKEYPRESS:
        GF_SAFEALLOC(att, GF_XMLAttribute);
        att->name = gf_strdup("key_identifier");
        att->value = gf_strdup(gf_dom_get_key_name(event->key.key_code));
        gf_list_add(evt_node->attributes, att);        
        if (event->key.flags & GF_KEY_MOD_SHIFT) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("shift");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
        if (event->key.flags & GF_KEY_MOD_CTRL) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("ctrl");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
        if (event->key.flags & GF_KEY_MOD_ALT) {
            GF_SAFEALLOC(att, GF_XMLAttribute);
            att->name = gf_strdup("alt");
            att->value = gf_strdup("true");
            gf_list_add(evt_node->attributes, att);
        }
		break;
	case GF_EVENT_TEXTINPUT:
        GF_SAFEALLOC(att, GF_XMLAttribute);
        att->name = gf_strdup("unicode-char");
        att->value = gf_malloc(100);
        sprintf(att->value, "%d", event->character.unicode_char);
        gf_list_add(evt_node->attributes, att);
        break;
    }
    gf_list_add(validator->xvs_node->content, evt_node);
    /* adding an extra text node for line break in serialization */
    GF_SAFEALLOC(evt_node, GF_XMLNode);
    evt_node->type = GF_XML_TEXT_TYPE;
    evt_node->name = gf_strdup("\n");
    gf_list_add(validator->xvs_node->content, evt_node);
} 
コード例 #3
0
ファイル: configfile.c プロジェクト: noelove/GPAC-old
/*!
 * \brief Parses the config file if any and clears the existing structure
 */
GF_Err gf_cfg_parse_config_file(GF_Config * tmp, const char * filePath, const char * file_name)
{
	IniSection *p;
	IniKey *k;
	FILE *file;
	char *ret;
	char *line;
	u32 line_alloc = MAX_INI_LINE;
	char fileName[GF_MAX_PATH];

	gf_cfg_clear(tmp);

	if (filePath && ((filePath[strlen(filePath)-1] == '/') || (filePath[strlen(filePath)-1] == '\\')) ) {
		strcpy(fileName, filePath);
		strcat(fileName, file_name);
	} else if (filePath) {
		sprintf(fileName, "%s%c%s", filePath, GF_PATH_SEPARATOR, file_name);
	} else {
		strcpy(fileName, file_name);
	}

	tmp->fileName = gf_strdup(fileName);
	tmp->sections = gf_list_new();
	file = gf_f64_open(fileName, "rt");
	if (!file)
	  return GF_IO_ERR;
	/* load the file */
	p = NULL;
	line = gf_malloc(sizeof(char)*line_alloc);
	memset(line, 0, sizeof(char)*line_alloc);

	while (!feof(file)) {
		u32 read;
		ret = fgets(line, line_alloc, file);
		read = strlen(line);
		while (read + 1 == line_alloc) {
			line_alloc += MAX_INI_LINE;
			line = gf_realloc(line, sizeof(char)*line_alloc);
			ret = fgets(line+read, MAX_INI_LINE, file);
			read = strlen(line);
		}
		if (!ret) continue;

		/* get rid of the end of line stuff */
		while (1) {
			u32 len = strlen(line);
			if (!len) break;
			if ((line[len-1] != '\n') && (line[len-1] != '\r')) break;
			line[len-1] = 0;
		}
		if (!strlen(line)) continue;
		if (line[0] == '#') continue;

		
		/* new section */
		if (line[0] == '[') {
			p = (IniSection *) gf_malloc(sizeof(IniSection));
			p->keys = gf_list_new();
			p->section_name = gf_strdup(line + 1);
			p->section_name[strlen(line) - 2] = 0;
			while (p->section_name[strlen(p->section_name) - 1] == ']' || p->section_name[strlen(p->section_name) - 1] == ' ') p->section_name[strlen(p->section_name) - 1] = 0;
			gf_list_add(tmp->sections, p);
		}
		else if (strlen(line) && (strchr(line, '=') != NULL) ) {
			if (!p) {
				gf_list_del(tmp->sections);
				gf_free(tmp->fileName);
				gf_free(tmp);
				fclose(file);
				gf_free(line);
				return GF_IO_ERR;
			}

			k = (IniKey *) gf_malloc(sizeof(IniKey));
			memset((void *)k, 0, sizeof(IniKey));
			ret = strchr(line, '=');
			if (ret) {
				ret[0] = 0;
				k->name = gf_strdup(line);
				while (k->name[strlen(k->name) - 1] == ' ') k->name[strlen(k->name) - 1] = 0;
				ret[0] = '=';
				ret += 1;
				while (ret[0] == ' ') ret++;
				if ( ret[0] != 0) {
					k->value = gf_strdup(ret);
					while (k->value[strlen(k->value) - 1] == ' ') k->value[strlen(k->value) - 1] = 0;
				} else {
					k->value = gf_strdup("");
				}
			}
			gf_list_add(p->keys, k);
		}
	}
	gf_free(line);
	fclose(file);
	return GF_OK;
}
コード例 #4
0
ファイル: swf_svg.c プロジェクト: DmitrySigaev/gpac-sf
static GF_Err swf_svg_show_frame(SWFReader *read)
{
	u32     i;
	u32     len;
	GF_List *sdl = gf_list_new(); // sorted display list

	/* sorting the display list because SVG/CSS z-index is not well supported */
	while (gf_list_count(read->display_list))
	{
		Bool        inserted = GF_FALSE;
		DispShape   *s;

		s = (DispShape *)gf_list_get(read->display_list, 0);
		gf_list_rem(read->display_list, 0);

		for (i = 0; i < gf_list_count(sdl); i++)
		{
			DispShape *s2 = (DispShape *)gf_list_get(sdl, i);
			if (s->depth < s2->depth)
			{
				gf_list_insert(sdl, s, i);
				inserted = GF_TRUE;
				break;
			}
		}
		if (!inserted)
		{
			gf_list_add(sdl, s);
		}
	}
	gf_list_del(read->display_list);
	read->display_list = sdl;

	/* dumping the display list */
	len = gf_list_count(read->display_list);
	for (i=0; i<len; i++)
	{
		DispShape   *s;
		s = (DispShape *)gf_list_get(read->display_list, i);
		swf_svg_print(read, "<use xlink:href=\"#S%d\" ", s->char_id);
		//swf_svg_print(read, "z-index=\"%d\" ", s->depth);
		swf_svg_print_matrix(read, &s->mat);
		swf_svg_print(read, "/>\n");
		read->empty_frame = GF_FALSE;
	}
	if (!read->empty_frame) {
		read->print_frame_header = GF_TRUE;
		read->frame_header_offset = 0;
		swf_svg_print(read, "<g display=\"none\">\n");
		swf_svg_print(read, "<animate id=\"frame%d_anim\" attributeName=\"display\" to=\"inline\" ", read->current_frame);
		swf_svg_print(read, "begin=\"%g\" ", 1.0*(read->current_frame)/read->frame_rate);
		if (read->current_frame+1 < read->frame_count) {
			swf_svg_print(read, "end=\"frame%d_anim.begin\" fill=\"remove\" ", (read->current_frame+1));
		} else {
			swf_svg_print(read, "fill=\"freeze\" ");
		}
		swf_svg_print(read, "/>\n");
		read->print_frame_header = GF_FALSE;

		swf_svg_print(read, "</g>\n");
	}
	read->add_sample(read->user, read->svg_data, read->svg_data_size, read->current_frame*1000/read->frame_rate, (read->current_frame == 0));
	gf_free(read->svg_data);
	read->svg_data = NULL;
	read->svg_data_size = 0;

	read->empty_frame = GF_TRUE;
	return GF_OK;
}
コード例 #5
0
ファイル: loadcompare.c プロジェクト: Kurtnoise/gpac
int main(int argc, char **argv)
{
	u32 i;
	char *arg;
	GF_LoadCompare lc;
	Bool single = 0;
	char *out = NULL;
	char in[256] = ".";

	fprintf(stdout, "LASeR and SVG Comparison tool\n");

	memset(&lc, 0, sizeof(GF_LoadCompare));
	lc.nbloads = 1;
	lc.out = stdout;
	
	for (i = 1; i < (u32) argc ; i++) {
		arg = argv[i];
		if (!stricmp(arg, "-out")) {
			out = argv[i+1];
			i++;
		} else if (!stricmp(arg, "-single")) {
			single = 1;
			strcpy(in, argv[i+1]);
			i++;
		} else if (!stricmp(arg, "-dir")) {
			strcpy(in, argv[i+1]);
			i++;
		} else if (!stricmp(arg, "-nloads")) {
			lc.nbloads = (u32)atoi(argv[i+1]);
			i++;
		} else if (!stricmp(arg, "-regenerate")) {
			lc.regenerate = 1;
		} else if (!stricmp(arg, "-xmt")) {
			lc.type = XMT;
		} else if (!stricmp(arg, "-svg")) {
			lc.type = SVG;
		} else if (!stricmp(arg, "-spread_repeat")) {
			lc.spread_repeat = 1;
		} else if (!stricmp(arg, "-verbose")) {
			lc.verbose = (u32)atoi(argv[i+1]);
			i++;
		} else {
			usage();
			return -1;
		}	
	}

	gf_sys_init();
	if (out) lc.out = fopen(out, "wt");
	if (!lc.out) {
		fprintf(stderr, "Cannot open output file %s\n", out);
		return -1;
	}

	if (lc.type == SVG) {
		fprintf(lc.out,"File Name\tSVG Size\tSVG Load Time\tLibXML Load Time\tSVGZ Size\tSVGZ Load Time\tLibXML GZ Load Time\tMP4 Size\tMP4 Load Time\tDecoded SVG Size\tDecoded SVG Load Time\n");
	} else if (lc.type == XMT) {
		fprintf(lc.out,"File Name\tXMT Size\tXMT Load Time\tBT Size\tBT Load Time\n");
	}

	lc.data = gf_list_new();

	if (single) {
		LoadData *ld;
		char *tmp = strrchr(in, GF_PATH_SEPARATOR);
		loadcompare_one(&lc, tmp+1, in);
		ld = gf_list_get(lc.data, 0);
		print_load_data(&lc, ld);
		gf_free(ld);
	} else {
		if (lc.spread_repeat) {
			for (lc.repeat_index = 0; lc.repeat_index < lc.nbloads; lc.repeat_index ++) {
				if (lc.verbose) fprintf(stdout, "Loop %d\n", lc.repeat_index);
				if (lc.type == SVG) {
					gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
				} else if (lc.type == XMT) {
					gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
				}
			}
			for (i=0; i<gf_list_count(lc.data); i++) {
				LoadData *ld = gf_list_get(lc.data, i);
				print_load_data(&lc, ld);
				gf_free(ld);
			}
		} else {
			if (lc.type == SVG) {
				gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
			} else if (lc.type == XMT) {
				gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
			}
		}
	}
	gf_list_del(lc.data);
		
	if (lc.out) fclose(lc.out);
	gf_sys_close();
	return 0;
}
コード例 #6
0
ファイル: svg_text.c プロジェクト: bigbensk/gpac
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;
}
コード例 #7
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
static GF_Err TTD_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd)
{
	TTDPriv *priv = (TTDPriv *)plug->privateStack;
	GF_Err e;
	GF_Node *root, *n1, *n2;
	const char *opt;
	/*no scalable, no upstream*/
	if (priv->nb_streams || esd->decoderConfig->upstream) return GF_NOT_SUPPORTED;
	if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return GF_NON_COMPLIANT_BITSTREAM;

	priv->cfg = (GF_TextConfig *) gf_odf_desc_new(GF_ODF_TEXT_CFG_TAG);
	e = gf_odf_get_text_config(esd->decoderConfig->decoderSpecificInfo, (u8) esd->decoderConfig->objectTypeIndication, priv->cfg);
	if (e) {
		gf_odf_desc_del((GF_Descriptor *) priv->cfg);
		priv->cfg = NULL;
		return e;
	}
	priv->nb_streams++;
	if (!priv->cfg->timescale) priv->cfg->timescale = 1000;

	priv->sg = gf_sg_new_subscene(priv->inlineScene->graph);

	root = ttd_create_node(priv, TAG_MPEG4_OrderedGroup, NULL);
	gf_sg_set_root_node(priv->sg, root);
	gf_node_register(root, NULL);
	/*root transform*/
	priv->tr_track = (M_Transform2D *)ttd_create_node(priv, TAG_MPEG4_Transform2D, NULL);
	add_child((GF_Node *) priv->tr_track, root);

	TTD_UpdateSizeInfo(priv);

	/*txt track background*/
	n1 = ttd_create_node(priv, TAG_MPEG4_Shape, NULL);
	add_child(n1, (GF_Node *) priv->tr_track);
	((M_Shape *)n1)->appearance = ttd_create_node(priv, TAG_MPEG4_Appearance, NULL);
	gf_node_register(((M_Shape *)n1)->appearance, n1);
	priv->mat_track = (M_Material2D *) ttd_create_node(priv, TAG_MPEG4_Material2D, NULL);
	priv->mat_track->filled = 1;
	priv->mat_track->transparency = 1;
	((M_Appearance *) ((M_Shape *)n1)->appearance)->material = (GF_Node *) priv->mat_track;
	gf_node_register((GF_Node *) priv->mat_track, ((M_Shape *)n1)->appearance);
	n2 = ttd_create_node(priv, TAG_MPEG4_Rectangle, NULL);
	((M_Rectangle *)n2)->size.x = 0;
	((M_Rectangle *)n2)->size.y = 0;
	((M_Shape *)n1)->geometry = n2;
	gf_node_register(n2, n1);
	priv->rec_track = (M_Rectangle *)n2;

	/*txt box background*/
	priv->tr_box = (M_Transform2D *) ttd_create_node(priv, TAG_MPEG4_Transform2D, NULL);
	add_child((GF_Node*) priv->tr_box, (GF_Node*)priv->tr_track);
	n1 = ttd_create_node(priv, TAG_MPEG4_Shape, NULL);
	add_child(n1, (GF_Node*)priv->tr_box);
	((M_Shape *)n1)->appearance = ttd_create_node(priv, TAG_MPEG4_Appearance, NULL);
	gf_node_register(((M_Shape *)n1)->appearance, n1);
	priv->mat_box = (M_Material2D *) ttd_create_node(priv, TAG_MPEG4_Material2D, NULL);
	priv->mat_box->filled = 1;
	priv->mat_box->transparency = 1;
	((M_Appearance *) ((M_Shape *)n1)->appearance)->material = (GF_Node *)priv->mat_box;
	gf_node_register((GF_Node *)priv->mat_box, ((M_Shape *)n1)->appearance);
	priv->rec_box = (M_Rectangle *) ttd_create_node(priv, TAG_MPEG4_Rectangle, NULL);
	priv->rec_box->size.x = 0;
	priv->rec_box->size.y = 0;
	((M_Shape *)n1)->geometry = (GF_Node *) priv->rec_box;
	gf_node_register((GF_Node *) priv->rec_box, n1);

	priv->dlist = (M_Layer2D *) ttd_create_node(priv, TAG_MPEG4_Layer2D, NULL);
	priv->dlist->size.x = priv->cfg->text_width;
	priv->dlist->size.y = priv->cfg->text_height;
	add_child((GF_Node *)priv->dlist, (GF_Node *)priv->tr_box);

	priv->blink_nodes = gf_list_new();
	priv->ts_blink = (M_TimeSensor *) ttd_create_node(priv, TAG_MPEG4_TimeSensor, "TimerBlink");
	priv->ts_blink->cycleInterval = 0.25;
	priv->ts_blink->startTime = 0.0;
	priv->ts_blink->loop = 1;
	priv->process_blink = (M_ScalarInterpolator *) ttd_create_node(priv, TAG_MPEG4_ScalarInterpolator, NULL);
	/*override set_fraction*/
	priv->process_blink->on_set_fraction = ttd_set_blink_fraction;
	gf_node_set_private((GF_Node *) priv->process_blink, priv);
	/*route from fraction_changed to set_fraction*/
	gf_sg_route_new(priv->sg, (GF_Node *) priv->ts_blink, 6, (GF_Node *) priv->process_blink, 0);

	priv->ts_scroll = (M_TimeSensor *) ttd_create_node(priv, TAG_MPEG4_TimeSensor, "TimerScroll");
	priv->ts_scroll->cycleInterval = 0;
	priv->ts_scroll->startTime = -1;
	priv->ts_scroll->loop = 0;
	priv->process_scroll = (M_ScalarInterpolator *) ttd_create_node(priv, TAG_MPEG4_ScalarInterpolator, NULL);
	/*override set_fraction*/
	priv->process_scroll->on_set_fraction = ttd_set_scroll_fraction;
	gf_node_set_private((GF_Node *) priv->process_scroll, priv);
	/*route from fraction_changed to set_fraction*/
	gf_sg_route_new(priv->sg, (GF_Node *) priv->ts_scroll, 6, (GF_Node *) priv->process_scroll, 0);

	gf_node_register((GF_Node *) priv->ts_blink, NULL);
	gf_node_register((GF_Node *) priv->process_blink, NULL);
	gf_node_register((GF_Node *) priv->ts_scroll, NULL);
	gf_node_register((GF_Node *) priv->process_scroll, NULL);

	/*option setup*/
	opt = gf_modules_get_option((GF_BaseInterface *)plug, "StreamingText", "UseTexturing");
	priv->use_texture = (opt && !strcmp(opt, "yes")) ? 1 : 0;
	opt = gf_modules_get_option((GF_BaseInterface *)plug, "StreamingText", "OutlineText");
	priv->outline = (opt && !strcmp(opt, "yes")) ? 1 : 0;
	return e;
}
コード例 #8
0
ファイル: Playlist.cpp プロジェクト: OpenHEVC/gpac
wxPlaylist::wxPlaylist(wxWindow *parent)
	: wxFrame(parent, -1, wxString(_T("Osmo4 Playlist")), wxDefaultPosition, wxDefaultSize,
	          wxCLOSE_BOX | wxSYSTEM_MENU | wxCAPTION | wxRESIZE_BORDER)
{

	m_pApp = (wxOsmo4Frame *)parent;

	m_pOpen = new wxBitmap(pl_open);
	m_pSave = new wxBitmap(pl_save);
	m_pAdd = new wxBitmap(pl_add);
	m_pRem = new wxBitmap(pl_rem);
	m_pUp = new wxBitmap(pl_up);
	m_pDown = new wxBitmap(pl_down);
	m_pSort = new wxBitmap(pl_sort);

	m_pToolBar = CreateToolBar(wxTB_HORIZONTAL);
	m_pAddBut = new wxMenuButton(m_pToolBar, ID_PL_ADD_FILE, *m_pAdd);
	wxMenu *menu = new wxMenu();
	menu->Append(ID_PL_ADD_URL, wxT("&Url"));
	menu->Append(ID_PL_ADD_DIR, wxT("&Directory"));
	menu->Append(ID_PL_ADD_DIR_REC, wxT("&Directory and subfolders"));
	m_pAddBut->AssignMenu(menu);
	m_pAddBut->SetToolTip(wxString(wxT("Add Files")));

	m_pRemBut = new wxMenuButton(m_pToolBar, ID_PL_REM_FILE, *m_pRem);
	menu = new wxMenu();
	menu->Append(ID_PL_REM_ALL, wxT("&Clear"));
	menu->Append(ID_PL_REM_DEAD, wxT("&Remove dead entries"));
	m_pRemBut->AssignMenu(menu);
	m_pRemBut->SetToolTip(wxString(wxT("Remove Selected Files")));

	m_pSortBut = new wxMenuButton(m_pToolBar, ID_PL_SORT_FILE, *m_pSort);
	menu = new wxMenu();
	menu->Append(ID_PL_SORT_TITLE, wxT("&Sort by Title"));
	menu->Append(ID_PL_SORT_FILE, wxT("&Sort by file name"));
	menu->Append(ID_PL_SORT_DUR, wxT("&Sort by Duration"));
	menu->AppendSeparator();
	menu->Append(ID_PL_REVERSE, wxT("&Reverse"));
	menu->Append(ID_PL_RANDOMIZE, wxT("&Randomize"));
	m_pSortBut->AssignMenu(menu);
	m_pSortBut->SetToolTip(wxString(wxT("Sort Playlist by filename")));

	m_pToolBar->AddTool(ID_PL_OPEN, wxT(""), *m_pOpen, wxT("Open Playlist"));
	m_pToolBar->AddTool(ID_PL_SAVE, wxT(""), *m_pSave, wxT("Save Playlist"));
	m_pToolBar->AddSeparator();
	m_pToolBar->AddControl(m_pAddBut);
	m_pToolBar->AddControl(m_pRemBut);
	m_pToolBar->AddSeparator();
	m_pToolBar->AddTool(ID_PL_UP, wxT(""), *m_pUp, wxT("Moves Selected Files Up"));
	m_pToolBar->AddTool(ID_PL_DOWN, wxT(""), *m_pDown, wxT("Moves Selected Files Down"));
	m_pToolBar->AddSeparator();
	m_pToolBar->AddControl(m_pSortBut);
	m_pToolBar->Realize();

	m_FileList = new wxListCtrl(this, ID_FILE_LIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);

	m_FileList->InsertColumn(0, wxT(""), wxLIST_FORMAT_LEFT, 1);
	m_FileList->InsertColumn(1, wxT("Title"), wxLIST_FORMAT_LEFT, 1);
	m_FileList->InsertColumn(2, wxT("Duration"), wxLIST_FORMAT_LEFT, 1);

	m_entries = gf_list_new();
	m_cur_entry = -1;
	m_all_dead_entries = -1;

	SetSize(220, 380);
	Centre();
}
コード例 #9
0
ファイル: video_muxer.c プロジェクト: Bevara/GPAC
/**
 * A function which takes FFmpeg H265 extradata (SPS/PPS) and bring them ready to be pushed to the MP4 muxer.
 * @param extradata
 * @param extradata_size
 * @param dstcfg
 * @returns GF_OK is the extradata was parsed and is valid, other values otherwise.
 */
static GF_Err hevc_import_ffextradata(const u8 *extradata, const u64 extradata_size, GF_HEVCConfig *dst_cfg)
{
#ifdef GPAC_DISABLE_AV_PARSERS
	return GF_OK;
#else
	HEVCState hevc;
	GF_HEVCParamArray *vpss = NULL, *spss = NULL, *ppss = NULL;
	GF_BitStream *bs;
	char *buffer = NULL;
	u32 buffer_size = 0;
	if (!extradata || (extradata_size < sizeof(u32)))
		return GF_BAD_PARAM;
	bs = gf_bs_new(extradata, extradata_size, GF_BITSTREAM_READ);
	if (!bs)
		return GF_BAD_PARAM;

	memset(&hevc, 0, sizeof(HEVCState));
	hevc.sps_active_idx = -1;

	while (gf_bs_available(bs)) {
		s32 idx;
		GF_AVCConfigSlot *slc;
		u8 nal_unit_type, temporal_id, layer_id;
		u64 nal_start;
		u32 nal_size;

		if (gf_bs_read_u32(bs) != 0x00000001) {
			gf_bs_del(bs);
			return GF_BAD_PARAM;
		}
		nal_start = gf_bs_get_position(bs);
		nal_size = gf_media_nalu_next_start_code_bs(bs);
		if (nal_start + nal_size > extradata_size) {
			gf_bs_del(bs);
			return GF_BAD_PARAM;
		}

		if (nal_size > buffer_size) {
			buffer = (char*)gf_realloc(buffer, nal_size);
			buffer_size = nal_size;
		}
		gf_bs_read_data(bs, buffer, nal_size);
		gf_bs_seek(bs, nal_start);

		gf_media_hevc_parse_nalu(bs, &hevc, &nal_unit_type, &temporal_id, &layer_id);
		if (layer_id) {
			gf_bs_del(bs);
			gf_free(buffer);
			return GF_BAD_PARAM;
		}

		switch (nal_unit_type) {
		case GF_HEVC_NALU_VID_PARAM:
			idx = gf_media_hevc_read_vps(buffer, nal_size , &hevc);
			if (idx < 0) {
				gf_bs_del(bs);
				gf_free(buffer);
				return GF_BAD_PARAM;
			}

			assert(hevc.vps[idx].state == 1); //we don't expect multiple VPS
			if (hevc.vps[idx].state == 1) {
				hevc.vps[idx].state = 2;
				hevc.vps[idx].crc = gf_crc_32(buffer, nal_size);

				dst_cfg->avgFrameRate = hevc.vps[idx].rates[0].avg_pic_rate;
				dst_cfg->constantFrameRate = hevc.vps[idx].rates[0].constand_pic_rate_idc;
				dst_cfg->numTemporalLayers = hevc.vps[idx].max_sub_layers;
				dst_cfg->temporalIdNested = hevc.vps[idx].temporal_id_nesting;

				if (!vpss) {
					GF_SAFEALLOC(vpss, GF_HEVCParamArray);
					vpss->nalus = gf_list_new();
					gf_list_add(dst_cfg->param_array, vpss);
					vpss->array_completeness = 1;
					vpss->type = GF_HEVC_NALU_VID_PARAM;
				}

				slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
				slc->size = nal_size;
				slc->id = idx;
				slc->data = (char*)gf_malloc(sizeof(char)*slc->size);
				memcpy(slc->data, buffer, sizeof(char)*slc->size);

				gf_list_add(vpss->nalus, slc);
			}
			break;
		case GF_HEVC_NALU_SEQ_PARAM:
			idx = gf_media_hevc_read_sps(buffer, nal_size, &hevc);
			if (idx < 0) {
				gf_bs_del(bs);
				gf_free(buffer);
				return GF_BAD_PARAM;
			}

			assert(!(hevc.sps[idx].state & AVC_SPS_DECLARED)); //we don't expect multiple SPS
			if ((hevc.sps[idx].state & AVC_SPS_PARSED) && !(hevc.sps[idx].state & AVC_SPS_DECLARED)) {
				hevc.sps[idx].state |= AVC_SPS_DECLARED;
				hevc.sps[idx].crc = gf_crc_32(buffer, nal_size);
			}

			dst_cfg->configurationVersion = 1;
			dst_cfg->profile_space = hevc.sps[idx].ptl.profile_space;
			dst_cfg->tier_flag = hevc.sps[idx].ptl.tier_flag;
			dst_cfg->profile_idc = hevc.sps[idx].ptl.profile_idc;
			dst_cfg->general_profile_compatibility_flags = hevc.sps[idx].ptl.profile_compatibility_flag;
			dst_cfg->progressive_source_flag = hevc.sps[idx].ptl.general_progressive_source_flag;
			dst_cfg->interlaced_source_flag = hevc.sps[idx].ptl.general_interlaced_source_flag;
			dst_cfg->non_packed_constraint_flag = hevc.sps[idx].ptl.general_non_packed_constraint_flag;
			dst_cfg->frame_only_constraint_flag = hevc.sps[idx].ptl.general_frame_only_constraint_flag;

			dst_cfg->constraint_indicator_flags = hevc.sps[idx].ptl.general_reserved_44bits;
			dst_cfg->level_idc = hevc.sps[idx].ptl.level_idc;

			dst_cfg->chromaFormat = hevc.sps[idx].chroma_format_idc;
			dst_cfg->luma_bit_depth = hevc.sps[idx].bit_depth_luma;
			dst_cfg->chroma_bit_depth = hevc.sps[idx].bit_depth_chroma;

			if (!spss) {
				GF_SAFEALLOC(spss, GF_HEVCParamArray);
				spss->nalus = gf_list_new();
				gf_list_add(dst_cfg->param_array, spss);
				spss->array_completeness = 1;
				spss->type = GF_HEVC_NALU_SEQ_PARAM;
			}

			slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
			slc->size = nal_size;
			slc->id = idx;
			slc->data = (char*)gf_malloc(sizeof(char)*slc->size);
			memcpy(slc->data, buffer, sizeof(char)*slc->size);
			gf_list_add(spss->nalus, slc);
			break;
		case GF_HEVC_NALU_PIC_PARAM:
			idx = gf_media_hevc_read_pps(buffer, nal_size, &hevc);
			if (idx < 0) {
				gf_bs_del(bs);
				gf_free(buffer);
				return GF_BAD_PARAM;
			}

			assert(hevc.pps[idx].state == 1); //we don't expect multiple PPS
			if (hevc.pps[idx].state == 1) {
				hevc.pps[idx].state = 2;
				hevc.pps[idx].crc = gf_crc_32(buffer, nal_size);

				if (!ppss) {
					GF_SAFEALLOC(ppss, GF_HEVCParamArray);
					ppss->nalus = gf_list_new();
					gf_list_add(dst_cfg->param_array, ppss);
					ppss->array_completeness = 1;
					ppss->type = GF_HEVC_NALU_PIC_PARAM;
				}

				slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
				slc->size = nal_size;
				slc->id = idx;
				slc->data = (char*)gf_malloc(sizeof(char)*slc->size);
				memcpy(slc->data, buffer, sizeof(char)*slc->size);

				gf_list_add(ppss->nalus, slc);
			}
			break;
		default:
			break;
		}

		if (gf_bs_seek(bs, nal_start+nal_size)) {
			assert(nal_start+nal_size <= gf_bs_get_size(bs));
			break;
		}
	}

	gf_bs_del(bs);
	gf_free(buffer);

	return GF_OK;
#endif
}
コード例 #10
0
ファイル: avc_ext.c プロジェクト: wipple/gpac
/* Rewrite mode:
 * mode = 0: playback
 * mode = 1: streaming
 */
GF_Err gf_isom_nalu_sample_rewrite(GF_MediaBox *mdia, GF_ISOSample *sample, u32 sampleNumber, GF_MPEGVisualSampleEntryBox *entry)
{
	Bool is_hevc = 0;
	GF_Err e = GF_OK;
	GF_ISOSample *ref_samp;
	GF_BitStream *src_bs, *ref_bs, *dst_bs;
	u64 offset;
	u32 ref_nalu_size, data_offset, data_length, copy_size, nal_size, max_size, di, nal_unit_size_field, cur_extract_mode, extractor_mode;
	Bool rewrite_ps, rewrite_start_codes;
	u8 ref_track_ID, ref_track_num;
	s8 sample_offset, nal_type;
	u32 nal_hdr;
	char *buffer;
	GF_ISOFile *file = mdia->mediaTrack->moov->mov;

	src_bs = ref_bs = dst_bs = NULL;
	ref_samp = NULL;
	buffer = NULL;
	rewrite_ps = (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG) ? 1 : 0;
	if (! sample->IsRAP) rewrite_ps = 0;
	rewrite_start_codes = (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_ANNEXB_FLAG) ? 1 : 0;
	extractor_mode = mdia->mediaTrack->extractor_mode&0x0000FFFF;

	if (extractor_mode == GF_ISOM_NALU_EXTRACT_INSPECT) {
		if (!rewrite_ps && !rewrite_start_codes)
			return GF_OK;
	}

	if (!entry) return GF_BAD_PARAM;
	nal_unit_size_field = 0;
	/*if svc rewrire*/
	if (entry->svc_config && entry->svc_config->config) nal_unit_size_field = entry->svc_config->config->nal_unit_size;
	/*if mvc rewrire*/

	/*otherwise do nothing*/
	else if (!rewrite_ps && !rewrite_start_codes) {
		return GF_OK;
	}

	if (!nal_unit_size_field) {
		if (entry->avc_config) nal_unit_size_field = entry->avc_config->config->nal_unit_size;
		else if (entry->hevc_config) {
			nal_unit_size_field = entry->hevc_config->config->nal_unit_size;
			is_hevc = 1;
		}
	}
	if (!nal_unit_size_field) return GF_ISOM_INVALID_FILE;

	dst_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	src_bs = gf_bs_new(sample->data, sample->dataLength, GF_BITSTREAM_READ);
	max_size = 4096;

	/*rewrite start code with NALU delim*/
	if (rewrite_start_codes) {
		gf_bs_write_int(dst_bs, 1, 32);
		if (is_hevc) {
			gf_bs_write_int(dst_bs, 0, 1);
			gf_bs_write_int(dst_bs, GF_HEVC_NALU_ACCESS_UNIT, 6);
			gf_bs_write_int(dst_bs, 0, 9);
			/*pic-type - by default we signal all slice types possible*/
			gf_bs_write_int(dst_bs, 2, 3);
			gf_bs_write_int(dst_bs, 0, 5);
		} else {
			gf_bs_write_int(dst_bs, (sample->data[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT, 8);
			gf_bs_write_int(dst_bs, 0xF0 , 8); /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/;
		}
	}

	if (rewrite_ps) {
		if (is_hevc) {
			u32 i, count;
			count = gf_list_count(entry->hevc_config->config->param_array);
			for (i=0; i<count; i++) {
				GF_HEVCParamArray *ar = gf_list_get(entry->hevc_config->config->param_array, i);
				rewrite_nalus_list(ar->nalus, dst_bs, rewrite_start_codes, nal_unit_size_field);
			}

			/*little optimization if we are not asked to start codes: copy over the sample*/
			if (!rewrite_start_codes) {
				gf_bs_write_data(dst_bs, sample->data, sample->dataLength);
				gf_free(sample->data);
				sample->data = NULL;
				gf_bs_get_content(dst_bs, &sample->data, &sample->dataLength);
				gf_bs_del(src_bs);
				gf_bs_del(dst_bs);
				return GF_OK;
			}
		} else {

			/*this is an SVC track: get all SPS/PPS from this track down to the base layer and rewrite them*/
			if (mdia->mediaTrack->has_base_layer) {
				u32 j;
				GF_List *nalu_sps = gf_list_new();
				GF_List *nalu_pps = gf_list_new();
				GF_TrackReferenceTypeBox *dpnd = NULL;
				Track_FindRef(mdia->mediaTrack, GF_ISOM_REF_SCAL, &dpnd);

#if 0
				/*get all upper layers with SCAL reference to this track*/
				for (j = 0; j < gf_isom_get_track_count(file); j++) {
					if (gf_isom_has_track_reference(file, j+1, GF_ISOM_REF_SCAL, mdia->mediaTrack->Header->trackID)) {
						u32 tkID;
						GF_TrackBox *base_track;
						GF_MPEGVisualSampleEntryBox *base_entry;
						gf_isom_get_reference_ID(file, j+1, GF_ISOM_REF_SCAL, 1, &tkID);

						base_track = GetTrackbyID(mdia->mediaTrack->moov, tkID);
						base_entry = base_track ? gf_list_get(base_track->Media->information->sampleTable->SampleDescription->other_boxes, 0) : NULL;
						if (base_entry)
							merge_nalus(base_entry, nalu_sps, nalu_pps);
					}
				}

#endif

				merge_nalus(entry, nalu_sps, nalu_pps);
				if (dpnd) {
					for (j=0; j<dpnd->trackIDCount; j++) {
						GF_TrackBox *base_track = GetTrackbyID(mdia->mediaTrack->moov, dpnd->trackIDs[j]);
						GF_MPEGVisualSampleEntryBox *base_entry = base_track ? gf_list_get(base_track->Media->information->sampleTable->SampleDescription->other_boxes, 0) : NULL;
						if (base_entry)
							merge_nalus(base_entry, nalu_sps, nalu_pps);
					}
				}

				//rewrite nalus
				rewrite_nalus_list(nalu_sps, dst_bs, rewrite_start_codes, nal_unit_size_field);
				rewrite_nalus_list(nalu_pps, dst_bs, rewrite_start_codes, nal_unit_size_field);

				gf_list_del(nalu_sps);
				gf_list_del(nalu_pps);
			} else {

				if (entry->avc_config) {
					rewrite_nalus_list(entry->avc_config->config->sequenceParameterSets, dst_bs, rewrite_start_codes, nal_unit_size_field);
					rewrite_nalus_list(entry->avc_config->config->pictureParameterSets, dst_bs, rewrite_start_codes, nal_unit_size_field);
					rewrite_nalus_list(entry->avc_config->config->sequenceParameterSetExtensions, dst_bs, rewrite_start_codes, nal_unit_size_field);
				}

				/*add svc config */
				if (entry->svc_config) {
					rewrite_nalus_list(entry->svc_config->config->sequenceParameterSets, dst_bs, rewrite_start_codes, nal_unit_size_field);
					rewrite_nalus_list(entry->svc_config->config->pictureParameterSets, dst_bs, rewrite_start_codes, nal_unit_size_field);
				}

				/*little optimization if we are not asked to rewrite extractors or start codes: copy over the sample*/
				if (!entry->svc_config && !rewrite_start_codes) {
					gf_bs_write_data(dst_bs, sample->data, sample->dataLength);
					gf_free(sample->data);
					sample->data = NULL;
					gf_bs_get_content(dst_bs, &sample->data, &sample->dataLength);
					gf_bs_del(src_bs);
					gf_bs_del(dst_bs);
					return GF_OK;
				}

			}
		}
	}

	buffer = (char *)gf_malloc(sizeof(char)*max_size);

	while (gf_bs_available(src_bs))
	{
		nal_size = gf_bs_read_int(src_bs, 8*nal_unit_size_field);
		if (nal_size>max_size) {
			buffer = (char*) gf_realloc(buffer, sizeof(char)*nal_size);
			max_size = nal_size;
		}
		if (is_hevc) {
			nal_hdr = gf_bs_read_u16(src_bs);
			nal_type = (nal_hdr&0x7E00) >> 9;
		} else {
			nal_hdr = gf_bs_read_u8(src_bs);
			nal_type = nal_hdr & 0x1F;
		}

		if (is_hevc) {
			/*we already wrote this stuff*/
			if (nal_type==GF_HEVC_NALU_ACCESS_UNIT) {
				gf_bs_skip_bytes(src_bs, nal_size-2);
				continue;
			}

			/*rewrite nal*/
			gf_bs_read_data(src_bs, buffer, nal_size-2);
			if (rewrite_start_codes)
				gf_bs_write_u32(dst_bs, 1);
			else
				gf_bs_write_int(dst_bs, nal_size, 8*nal_unit_size_field);

			gf_bs_write_u16(dst_bs, nal_hdr);
			gf_bs_write_data(dst_bs, buffer, nal_size-2);

			continue;
		}

		/*we already wrote this stuff*/
		if (nal_type==GF_AVC_NALU_ACCESS_UNIT) {
			gf_bs_skip_bytes(src_bs, nal_size-1);
			continue;
		}

		//extractor
		if (nal_type == 31) {
			switch (extractor_mode) {
			case 0:
				gf_bs_read_int(src_bs, 24); //3 bytes of NALUHeader in extractor
				ref_track_ID = gf_bs_read_u8(src_bs);
				sample_offset = (s8) gf_bs_read_int(src_bs, 8);
				data_offset = gf_bs_read_u32(src_bs);
				data_length = gf_bs_read_u32(src_bs);

				ref_track_num = gf_isom_get_track_by_id(file, ref_track_ID);
				if (!ref_track_num) {
					e = GF_BAD_PARAM;
					goto exit;
				}
				cur_extract_mode = gf_isom_get_nalu_extract_mode(file, ref_track_num);
				gf_isom_set_nalu_extract_mode(file, ref_track_num, GF_ISOM_NALU_EXTRACT_INSPECT);
				ref_samp = gf_isom_get_sample(file, ref_track_num, sampleNumber+sample_offset, &di);
				if (!ref_samp) {
					e = GF_IO_ERR;
					goto exit;
				}
				ref_bs = gf_bs_new(ref_samp->data, ref_samp->dataLength, GF_BITSTREAM_READ);
				offset = 0;
				while (gf_bs_available(ref_bs)) {
					if (gf_bs_get_position(ref_bs) < data_offset) {
						ref_nalu_size = gf_bs_read_int(ref_bs, 8*nal_unit_size_field);
						offset += ref_nalu_size + nal_unit_size_field;
						if ((offset > data_offset) || (offset >= gf_bs_get_size(ref_bs))) {
							e = GF_BAD_PARAM;
							goto exit;
						}

						e = gf_bs_seek(ref_bs, offset);
						if (e)
							goto exit;
						continue;
					}
					ref_nalu_size = gf_bs_read_int(ref_bs, 8*nal_unit_size_field);
					copy_size = data_length ? data_length : ref_nalu_size;
					assert(copy_size <= ref_nalu_size);
					nal_hdr = gf_bs_read_u8(ref_bs); //rewrite NAL type
					if ((copy_size-1)>max_size) {
						buffer = (char*)gf_realloc(buffer, sizeof(char)*(copy_size-1));
						max_size = copy_size-1;
					}
					gf_bs_read_data(ref_bs, buffer, copy_size-1);

					if (rewrite_start_codes)
						gf_bs_write_u32(dst_bs, 1);
					else
						gf_bs_write_int(dst_bs, copy_size, 8*nal_unit_size_field);

					gf_bs_write_u8(dst_bs, nal_hdr);
					gf_bs_write_data(dst_bs, buffer, copy_size-1);
				}

				gf_isom_sample_del(&ref_samp);
				ref_samp = NULL;
				gf_bs_del(ref_bs);
				ref_bs = NULL;
				gf_isom_set_nalu_extract_mode(file, ref_track_num, cur_extract_mode);
				break;
			default:
				//skip to end of this NALU
				gf_bs_skip_bytes(src_bs, nal_size-1);
				continue;
			}
		} else {
			gf_bs_read_data(src_bs, buffer, nal_size-1);
			if (rewrite_start_codes)
				gf_bs_write_u32(dst_bs, 1);
			else
				gf_bs_write_int(dst_bs, nal_size, 8*nal_unit_size_field);

			gf_bs_write_u8(dst_bs, nal_hdr);
			gf_bs_write_data(dst_bs, buffer, nal_size-1);
		}
	}
コード例 #11
0
ファイル: sample_descs.c プロジェクト: HungMingWu/gpac
void gf_isom_sample_entry_init(GF_SampleEntryBox *ent)
{
	ent->protections = gf_list_new();
}
コード例 #12
0
ファイル: avc_ext.c プロジェクト: wipple/gpac
GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, count;
	GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *)s;

	if (ptr->config) gf_odf_avc_cfg_del(ptr->config);
	ptr->config = gf_odf_avc_cfg_new();
	ptr->config->configurationVersion = gf_bs_read_u8(bs);
	ptr->config->AVCProfileIndication = gf_bs_read_u8(bs);
	ptr->config->profile_compatibility = gf_bs_read_u8(bs);
	ptr->config->AVCLevelIndication = gf_bs_read_u8(bs);
	if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) {
		gf_bs_read_int(bs, 6);
	} else {
		ptr->config->complete_representation = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 5);
	}
	ptr->config->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
	gf_bs_read_int(bs, 3);
	count = gf_bs_read_int(bs, 5);

	ptr->size -= 7; //including 2nd count

	for (i=0; i<count; i++) {
		GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) gf_malloc(sizeof(GF_AVCConfigSlot));
		sl->size = gf_bs_read_u16(bs);
		sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
		gf_bs_read_data(bs, sl->data, sl->size);
		gf_list_add(ptr->config->sequenceParameterSets, sl);
		ptr->size -= 2+sl->size;
	}

	count = gf_bs_read_u8(bs);
	for (i=0; i<count; i++) {
		GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot));
		sl->size = gf_bs_read_u16(bs);
		sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
		gf_bs_read_data(bs, sl->data, sl->size);
		gf_list_add(ptr->config->pictureParameterSets, sl);
		ptr->size -= 2+sl->size;
	}

	if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) {

		switch (ptr->config->AVCProfileIndication) {
		case 100:
		case 110:
		case 122:
		case 144:
			if (!ptr->size) {
#ifndef GPAC_DISABLE_AV_PARSERS
				AVCState avc;
				s32 idx, vui_flag_pos;
				GF_AVCConfigSlot *sl = gf_list_get(ptr->config->sequenceParameterSets, 0);
				idx = gf_media_avc_read_sps(sl->data, sl->size, &avc, 0, &vui_flag_pos);
				if (idx>=0) {
					ptr->config->chroma_format = avc.sps[idx].chroma_format;
					ptr->config->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8;
					ptr->config->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8;
				}
#else
				/*set default values ...*/
				ptr->config->chroma_format = 1;
				ptr->config->luma_bit_depth = 8;
				ptr->config->chroma_bit_depth = 8;
#endif
				return GF_OK;
			}
			gf_bs_read_int(bs, 6);
			ptr->config->chroma_format = gf_bs_read_int(bs, 2);
			gf_bs_read_int(bs, 5);
			ptr->config->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
			gf_bs_read_int(bs, 5);
			ptr->config->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);

			count = gf_bs_read_int(bs, 8);
			ptr->size -= 4;
			if (count) {
				ptr->config->sequenceParameterSetExtensions = gf_list_new();
				for (i=0; i<count; i++) {
					GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot));
					sl->size = gf_bs_read_u16(bs);
					sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
					gf_bs_read_data(bs, sl->data, sl->size);
					gf_list_add(ptr->config->sequenceParameterSetExtensions, sl);
					ptr->size -= sl->size + 2;
				}
			}
			break;
		}
	}
	return GF_OK;
}
コード例 #13
0
ファイル: ait.c プロジェクト: bigbensk/gpac
static GF_Err gf_m2ts_decode_ait(GF_M2TS_AIT *ait, char  *data, u32 data_size, u32 table_id)
{

	GF_BitStream *bs;
	u8 temp_descriptor_tag;
	u32 data_shift, app_desc_data_shift, ait_app_data_shift;
	u32 nb_of_protocol;

	data_shift = 0;
	temp_descriptor_tag = 0;
	ait_app_data_shift = 0;
	bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ);

	ait->common_descriptors = gf_list_new();
	if(ait->common_descriptors == NULL){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Error during common_descriptors list initialization, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->application_decoded = gf_list_new();
	if(ait->application_decoded == NULL){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Error during application list initialization, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}

	ait->table_id = gf_bs_read_int(bs,8);	
	ait->section_syntax_indicator = gf_bs_read_int(bs,1);
	gf_bs_read_int(bs,3);
	ait->section_length = gf_bs_read_int(bs,12);	
	if( (data[1] & 0x0C) != 0){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length is not correct abroding \n"));
	}else if( ait->section_length > AIT_SECTION_LENGTH_MAX){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length should not exceed 1021. Wrong section, abording processing \n"));
	}
	ait->test_application_flag = gf_bs_read_int(bs,1);
	if(ait->test_application_flag == 1){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] test application flag is at 1. API transmitted for testing, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->application_type = gf_bs_read_int(bs,15);	
	if(ait->application_type != APPLICATION_TYPE_HTTP_APPLICATION){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] application type should 0x10. Wrong section, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	gf_bs_read_int(bs,2);
	ait->version_number = gf_bs_read_int(bs,5);

	ait->current_next_indicator = gf_bs_read_int(bs,1);	
	if(!ait->current_next_indicator){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] current next indicator should be at 1 \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->section_number = gf_bs_read_int(bs,8);
	ait->last_section_number = gf_bs_read_int(bs,8);	
	gf_bs_read_int(bs,4);/* bit shifting */
	ait->common_descriptors_length = gf_bs_read_int(bs,12);	
	gf_bs_read_int(bs,(unsigned int)ait->common_descriptors_length/8);
	gf_bs_read_int(bs,4);/* bit shifting */	
	ait->application_loop_length = gf_bs_read_int(bs,12);

	data_shift = (u32)(gf_bs_get_position(bs)) + ait->common_descriptors_length/8;

	while (ait_app_data_shift < ait->application_loop_length) {

		GF_M2TS_AIT_APPLICATION_DECODE* application;
		GF_SAFEALLOC(application,GF_M2TS_AIT_APPLICATION_DECODE);
		application->application_descriptors = gf_list_new();
		application->index_app_desc_id = 0;

		/* application loop */
		application->organisation_id = gf_bs_read_int(bs,32);	
		application->application_id= gf_bs_read_int(bs,16);
		application->application_control_code= gf_bs_read_int(bs,8);
		gf_bs_read_int(bs,4);/* bit shifting */
		application->application_descriptors_loop_length= gf_bs_read_int(bs,12);		

		ait_app_data_shift += 9;
		app_desc_data_shift = 0;
		nb_of_protocol = 0;

		while (app_desc_data_shift< application->application_descriptors_loop_length) {
			temp_descriptor_tag = gf_bs_read_int(bs,8);
			switch (temp_descriptor_tag) {
				case APPLICATION_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						u8 i;
						GF_M2TS_APPLICATION_DESCRIPTOR *application_descriptor;
						GF_SAFEALLOC(application_descriptor, GF_M2TS_APPLICATION_DESCRIPTOR);
						application_descriptor->descriptor_tag = temp_descriptor_tag;
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						application_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						application_descriptor->application_profiles_length = gf_bs_read_int(bs,8);
						application_descriptor->application_profile = gf_bs_read_int(bs,16);
						application_descriptor->version_major = gf_bs_read_int(bs,8);
						application_descriptor->version_minor = gf_bs_read_int(bs,8);
						application_descriptor->version_micro = gf_bs_read_int(bs,8);
						application_descriptor->service_bound_flag = gf_bs_read_int(bs,1);
						application_descriptor->visibility = gf_bs_read_int(bs,2);
						gf_bs_read_int(bs,5); /*bit shift*/
						application_descriptor->application_priority = gf_bs_read_int(bs,8);
						if (nb_of_protocol > 0) {
							for (i=0; i<nb_of_protocol; i++) {						
								application_descriptor->transport_protocol_label[i] = gf_bs_read_int(bs,8);
							}
						} else {
							application_descriptor->transport_protocol_label[0] = gf_bs_read_int(bs,8);
						}
						if (pre_processing_pos+application_descriptor->descriptor_length != gf_bs_get_position(bs) || application_descriptor->application_profile == 2 /* PVR feature */) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),application_descriptor->descriptor_length));
							gf_free(application_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,application_descriptor);
						app_desc_data_shift += (2+ application_descriptor->descriptor_length);
						break;
					}
				case APPLICATION_NAME_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_APPLICATION_NAME_DESCRIPTOR* name_descriptor;
						GF_SAFEALLOC(name_descriptor, GF_M2TS_APPLICATION_NAME_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						name_descriptor->descriptor_tag = temp_descriptor_tag;
						name_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						name_descriptor->ISO_639_language_code = gf_bs_read_int(bs,24);
						name_descriptor->application_name_length = gf_bs_read_int(bs,8);
						name_descriptor->application_name_char = (char*) gf_calloc(name_descriptor->application_name_length+1,sizeof(char));
						gf_bs_read_data(bs,name_descriptor->application_name_char,name_descriptor->application_name_length);
						name_descriptor->application_name_char[name_descriptor->application_name_length] = 0 ;
						if (pre_processing_pos+name_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),name_descriptor->descriptor_length));
							gf_free(name_descriptor->application_name_char);
							gf_free(name_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,name_descriptor);
						app_desc_data_shift += (2+ name_descriptor->descriptor_length);
						break;
					}
				case TRANSPORT_PROTOCOL_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR* protocol_descriptor;
						GF_SAFEALLOC(protocol_descriptor, GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						nb_of_protocol++;
						protocol_descriptor->descriptor_tag = temp_descriptor_tag;
						protocol_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						protocol_descriptor->protocol_id = gf_bs_read_int(bs,16);
						protocol_descriptor->transport_protocol_label = gf_bs_read_int(bs,8);
						switch (protocol_descriptor->protocol_id) {
				case CAROUSEL:
					{
						GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte;
						GF_SAFEALLOC(Carousel_selector_byte, GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE);
						Carousel_selector_byte->remote_connection = gf_bs_read_int(bs,1);
						gf_bs_read_int(bs,7); /* bit shifting */
						if (Carousel_selector_byte->remote_connection) {
							Carousel_selector_byte->original_network_id = gf_bs_read_int(bs,16);
							Carousel_selector_byte->transport_stream_id = gf_bs_read_int(bs,16);
							Carousel_selector_byte->service_id = gf_bs_read_int(bs,16);
						}
						Carousel_selector_byte->component_tag = gf_bs_read_int(bs,8);
						protocol_descriptor->selector_byte = Carousel_selector_byte;
						break;
					}
				case TRANSPORT_HTTP:
					{					
						u32 i;								
						GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte;
						GF_SAFEALLOC(Transport_http_selector_byte, GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE);					
						Transport_http_selector_byte->URL_base_length = gf_bs_read_int(bs,8);
						//printf("Transport_http_selector_byte->URL_base_length %d \n",Transport_http_selector_byte->URL_base_length);
						Transport_http_selector_byte->URL_base_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_base_length+1,sizeof(char));
						gf_bs_read_data(bs,Transport_http_selector_byte->URL_base_byte ,(u32)(Transport_http_selector_byte->URL_base_length));
						Transport_http_selector_byte->URL_base_byte[Transport_http_selector_byte->URL_base_length] = 0;
						Transport_http_selector_byte->URL_extension_count = gf_bs_read_int(bs,8);
						if (Transport_http_selector_byte->URL_extension_count) {
							Transport_http_selector_byte->URL_extentions = (GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION*) gf_calloc(Transport_http_selector_byte->URL_extension_count,sizeof(GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION));
							for (i=0; i < Transport_http_selector_byte->URL_extension_count;i++) {
								Transport_http_selector_byte->URL_extentions[i].URL_extension_length = gf_bs_read_int(bs,8);
								Transport_http_selector_byte->URL_extentions[i].URL_extension_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_extentions[i].URL_extension_length+1,sizeof(char));
								gf_bs_read_data(bs,Transport_http_selector_byte->URL_extentions[i].URL_extension_byte,(u32)(Transport_http_selector_byte->URL_extentions[i].URL_extension_length));
								Transport_http_selector_byte->URL_extentions[i].URL_extension_byte[Transport_http_selector_byte->URL_extentions[i].URL_extension_length] = 0;
							}
						}
						protocol_descriptor->selector_byte = Transport_http_selector_byte;
						break;
					}
				default:
					{
						GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Protocol ID %d unsupported, ignoring the selector byte \n",protocol_descriptor->protocol_id));
					}
						}
						if (pre_processing_pos+protocol_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),protocol_descriptor->descriptor_length));
							if (protocol_descriptor->protocol_id == CAROUSEL) {						
								GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte = (GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE*) protocol_descriptor->selector_byte;								
								gf_free(Carousel_selector_byte);								
							} else if(protocol_descriptor->protocol_id ==TRANSPORT_HTTP) {
								u32 i;
								GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte = (GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE*) protocol_descriptor->selector_byte;								
								gf_free(Transport_http_selector_byte->URL_base_byte);
								for(i = 0; i < Transport_http_selector_byte->URL_extension_count;i++){										
									gf_free(Transport_http_selector_byte->URL_extentions[i].URL_extension_byte);
								}
								gf_free(Transport_http_selector_byte);						
							}
							gf_free(protocol_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,protocol_descriptor);					
						app_desc_data_shift += (2+ protocol_descriptor->descriptor_length);
						break;
					}
				case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR:
					{
						u64 pre_processing_pos;					
						GF_M2TS_SIMPLE_APPLICATION_LOCATION* Simple_application_location;
						GF_SAFEALLOC(Simple_application_location, GF_M2TS_SIMPLE_APPLICATION_LOCATION);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						Simple_application_location->descriptor_tag = temp_descriptor_tag;
						Simple_application_location->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						Simple_application_location->initial_path_bytes = (char*)gf_calloc(Simple_application_location->descriptor_length+1,sizeof(char));
						gf_bs_read_data(bs,Simple_application_location->initial_path_bytes ,(u32)(Simple_application_location->descriptor_length));
						Simple_application_location->initial_path_bytes[Simple_application_location->descriptor_length] = 0;
						if (pre_processing_pos+Simple_application_location->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),Simple_application_location->descriptor_length));
							gf_free(Simple_application_location->initial_path_bytes);
							gf_free(Simple_application_location);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,Simple_application_location);
						app_desc_data_shift += (2+ Simple_application_location->descriptor_length);
						break;
					}
				case APPLICATION_USAGE_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_APPLICATION_USAGE* Application_usage;
						GF_SAFEALLOC(Application_usage, GF_M2TS_APPLICATION_USAGE);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						Application_usage->descriptor_tag = temp_descriptor_tag;
						Application_usage->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						Application_usage->usage_type = gf_bs_read_int(bs,8);
						if (pre_processing_pos+Application_usage->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),Application_usage->descriptor_length));
							gf_free(Application_usage);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,Application_usage);
						app_desc_data_shift += (2+ Application_usage->descriptor_length);
						break;
					}
				case APPLICATION_BOUNDARY_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						u32 i;
						GF_M2TS_APPLICATION_BOUNDARY_DESCRIPTOR* boundary_descriptor;
						GF_SAFEALLOC(boundary_descriptor, GF_M2TS_APPLICATION_BOUNDARY_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						boundary_descriptor->descriptor_tag = temp_descriptor_tag;
						boundary_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						boundary_descriptor->boundary_extension_count = gf_bs_read_int(bs,8);
						if (boundary_descriptor->boundary_extension_count > 0) {
							boundary_descriptor->boundary_extension_info = (GF_M2TS_APPLICATION_BOUNDARY_EXTENSION_INFO*)gf_calloc(boundary_descriptor->boundary_extension_count,sizeof(GF_M2TS_APPLICATION_BOUNDARY_EXTENSION_INFO));
							for (i=0;i<boundary_descriptor->boundary_extension_count;i++) {
								boundary_descriptor->boundary_extension_info[i].boundary_extension_length = gf_bs_read_int(bs,8);
								if (boundary_descriptor->boundary_extension_info[i].boundary_extension_length > 0) {
									boundary_descriptor->boundary_extension_info[i].boundary_extension_byte = (char*)gf_calloc(boundary_descriptor->boundary_extension_info[i].boundary_extension_length+1,sizeof(char));
									gf_bs_read_data(bs,boundary_descriptor->boundary_extension_info[i].boundary_extension_byte ,(u32)(boundary_descriptor->boundary_extension_info[i].boundary_extension_length));
									boundary_descriptor->boundary_extension_info[i].boundary_extension_byte[boundary_descriptor->boundary_extension_info[i].boundary_extension_length] = 0;
								}
							}
						}
						if (pre_processing_pos+boundary_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),boundary_descriptor->descriptor_length));
							if (boundary_descriptor->boundary_extension_count > 0) {
								u32 i;
								for (i=0;i<boundary_descriptor->boundary_extension_count;i++) {
									if (boundary_descriptor->boundary_extension_info[i].boundary_extension_length > 0) {
										gf_free(boundary_descriptor->boundary_extension_info[i].boundary_extension_byte);
									}
								}
								gf_free(boundary_descriptor->boundary_extension_info);
							}
							gf_free(boundary_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,boundary_descriptor);
						app_desc_data_shift += (2+ boundary_descriptor->descriptor_length);
						break;					
					}
				default:
					{
						u8 length;
						GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor tag %d unknown, ignoring the descriptor \n",temp_descriptor_tag));
						/* get descriptor's length */
						length = gf_bs_read_int(bs,8);
						/* bit shifting (eq descriptor's length)*/
						gf_bs_read_int(bs,8*length);					
					}

			}

		}
		ait_app_data_shift += application->application_descriptors_loop_length; 
		gf_list_add(ait->application_decoded,application);		
	}

	data_shift +=ait->application_loop_length;
	ait->CRC_32 = gf_bs_read_int(bs,32);
	data_shift += 4;


	if (data_shift != data_size) {
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] AIT processed length error. Difference between byte shifting %d and data size %d \n",data_shift,data_size));
		return GF_CORRUPTED_DATA;
	}

	return GF_OK;
}
コード例 #14
0
ファイル: ait.c プロジェクト: bigbensk/gpac
static void gf_m2ts_process_ait(GF_M2TS_Demuxer *ts, GF_M2TS_AIT* ait){

	u32 nb_app_desc, k, desc_id, nb_of_app, j;
	GF_M2TS_CHANNEL_APPLICATION_INFO* ChanAppInfo;
	char *url_base, *url_appli_path;

	nb_of_app = gf_list_count(ait->application_decoded);
	url_base = NULL;
	url_appli_path = NULL;
	j=0;

	/* Link the AIT and the channel */
	ChanAppInfo = gf_m2ts_get_channel_application_info(ts->ChannelAppList,ait->service_id);	

	if(!ChanAppInfo){
		GF_SAFEALLOC(ChanAppInfo,GF_M2TS_CHANNEL_APPLICATION_INFO);
		ChanAppInfo->service_id = ait->service_id;
		ChanAppInfo->Application = gf_list_new();
		ChanAppInfo->ait_pid = ait->pid;
		gf_list_add(ts->ChannelAppList,ChanAppInfo);
	}

	ChanAppInfo->nb_application = nb_of_app;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DSMCC] ChanAppInfo->nb_application %d \n",ChanAppInfo->nb_application));
	
	for(j=0 ; j<nb_of_app ; j++){
		GF_M2TS_AIT_APPLICATION* Application;
		GF_M2TS_AIT_APPLICATION_DECODE* application_decoded;
		GF_SAFEALLOC(Application,GF_M2TS_AIT_APPLICATION);
		gf_list_add(ChanAppInfo->Application,Application);			
		Application->http_url = NULL;
		Application->carousel_url = NULL;

		application_decoded = (GF_M2TS_AIT_APPLICATION_DECODE*)gf_list_get(ait->application_decoded,j);
		nb_app_desc = gf_list_count(application_decoded->application_descriptors);
		Application->application_control_code = application_decoded->application_control_code;
		Application->application_id = application_decoded->application_id;
		Application->broadband = 0;
		Application->broadcast = 0;
		ChanAppInfo->version_number = ait->version_number;
		
		k=0;
		for(k=0 ; k<nb_app_desc ; k++){
			desc_id = application_decoded->application_descriptors_id[k];
			switch(desc_id){
							case APPLICATION_DESCRIPTOR:
								{
									GF_M2TS_APPLICATION_DESCRIPTOR* application_descriptor = (GF_M2TS_APPLICATION_DESCRIPTOR*)gf_list_get(application_decoded->application_descriptors,k);
									Application->priority = application_descriptor->application_priority;
									Application->application_profile = application_descriptor->application_profile;

									break;
								}
							case APPLICATION_NAME_DESCRIPTOR:
								{
									GF_M2TS_APPLICATION_NAME_DESCRIPTOR* name_descriptor = (GF_M2TS_APPLICATION_NAME_DESCRIPTOR*)gf_list_get(application_decoded->application_descriptors,k);
									Application->appli_name = gf_strdup(name_descriptor->application_name_char);
									break;
								}
							case TRANSPORT_PROTOCOL_DESCRIPTOR:
								{
									GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR* protocol_descriptor = (GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR*)gf_list_get(application_decoded->application_descriptors,k);

									switch(protocol_descriptor->protocol_id){
										case CAROUSEL:
											{									
												GF_Err e;												
												GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte = (GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE*)protocol_descriptor->selector_byte;
												if(ts->process_dmscc){
													GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord = gf_m2ts_get_dmscc_overlord(ts->dsmcc_controler,ait->service_id);
													Application->broadcast = 1;
													if(!dsmcc_overlord){
														char app_url[1024], char_service_id[128];
														
														memset(&app_url,0,1024*sizeof(char));
														memset(&char_service_id,0,128*sizeof(char));

														dsmcc_overlord = gf_m2ts_init_dsmcc_overlord(ait->service_id);
														dsmcc_overlord->application_id = Application->application_id;
														sprintf(char_service_id,"%d",dsmcc_overlord->service_id);
														dsmcc_overlord->root_dir = (char*)gf_calloc(strlen(ts->dsmcc_root_dir)+2+strlen(char_service_id),sizeof(char));
														sprintf(dsmcc_overlord->root_dir,"%s%c%s",ts->dsmcc_root_dir,GF_PATH_SEPARATOR,char_service_id);
														e = gf_mkdir(dsmcc_overlord->root_dir);
														if(e){															
															GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error during the creation of the directory %s \n",dsmcc_overlord->root_dir));
															if(e == GF_BAD_PARAM){
																gf_cleanup_dir(dsmcc_overlord->root_dir);
															}
														}
														sprintf(app_url,"%s%cindex.html",dsmcc_overlord->root_dir,GF_PATH_SEPARATOR);
														Application->carousel_url = gf_strdup(app_url);											
														gf_list_add(ts->dsmcc_controler,dsmcc_overlord);
													}
												}
												if(Carousel_selector_byte->remote_connection){
													Application->carousel_pid = Carousel_selector_byte->service_id;
												}
												Application->component_tag = Carousel_selector_byte->component_tag;

												break;
											}
										case TRANSPORT_HTTP:
											{
												GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte = (GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE*)protocol_descriptor->selector_byte;
												url_base = Transport_http_selector_byte->URL_base_byte;
												Application->broadband = 1;
											}
										default:
											{
											}
									}
									break;
								}
							case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR:
								{
									GF_M2TS_SIMPLE_APPLICATION_LOCATION* Simple_application_location = (GF_M2TS_SIMPLE_APPLICATION_LOCATION*)gf_list_get(application_decoded->application_descriptors,k);
									url_appli_path = Simple_application_location->initial_path_bytes;
									break;
								}
							case APPLICATION_USAGE_DESCRIPTOR:
								{
									break;
								}
							default:
								{
									GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[Process AIT] Descriptor tag %d unknown, ignoring the descriptor \n",desc_id));
								}
			}

			if((url_base != NULL) && ( url_appli_path != NULL)){
				u32 url_length = (strlen(url_base)+strlen(url_appli_path));
				Application->http_url = (char*)gf_calloc(url_length + 1,sizeof(char));
				sprintf(Application->http_url,"%s%s",url_base,url_appli_path);
				Application->http_url[url_length]=0;
				Application->url_received = 1;
				url_base = NULL;
				url_appli_path = NULL;
				GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[Process AIT] SERVICE ID %d  URL %s  \n",ChanAppInfo->service_id,Application->http_url));
			}

		}
	}
	if(ts->process_dmscc){
		GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord = gf_m2ts_get_dmscc_overlord(ts->dsmcc_controler,ait->service_id);

		if(dsmcc_overlord && !gf_m2ts_is_dmscc_app(ChanAppInfo)){			
			gf_cleanup_dir(dsmcc_overlord->root_dir);
			gf_rmdir(dsmcc_overlord->root_dir);	
			gf_m2ts_delete_dsmcc_overlord(dsmcc_overlord);

		}
	}
}
コード例 #15
0
ファイル: audio_render.c プロジェクト: fcsteagu/gpac-1
GF_EXPORT
GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al)
{
	GF_AudioMixer *mixer;
	u32 sr, ch, bps, ch_cfg;
	if (!compositor || !al || !al->on_audio_frame || !al->on_audio_reconfig) return GF_BAD_PARAM;
	if (!compositor->audio_renderer) return GF_NOT_SUPPORTED;

	mixer = compositor->audio_renderer->mixer;
	gf_mixer_lock(mixer, 1);

	if (!compositor->audio_renderer->audio_listeners) compositor->audio_renderer->audio_listeners = gf_list_new();
	gf_list_add(compositor->audio_renderer->audio_listeners, al);

	gf_mixer_get_config(mixer, &sr, &ch, &bps, &ch_cfg);

	al->on_audio_reconfig(al->udta, sr, bps, ch, ch_cfg);

	gf_mixer_lock(mixer, 0);
	return GF_OK;
}
コード例 #16
0
ファイル: script_enc.c プロジェクト: ARSekkat/gpac
GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n)
{
	char *ptr;
	ScriptEnc sc_enc;
	if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM;

	memset(&sc_enc, 0, sizeof(ScriptEnc));
	sc_enc.codec = codec;
	sc_enc.script = n;
	sc_enc.bs = bs;
	sc_enc.identifiers = gf_list_new();
	sc_enc.id_buf = gf_list_new();
	sc_enc.err = GF_OK;

	if (codec->is_encoding_command) {
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Script::isList", NULL);
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
	} else {
		EncScriptFields(&sc_enc);
	}
	/*reserevd*/
	GF_BIFS_WRITE_INT(codec, bs, 1, 1, "reserved", NULL);

	if (script_field) {
		sc_enc.cur_buf = (char *)script_field->script_text;
	} else if (((M_Script*)n)->url.count) {
		sc_enc.cur_buf = (char *)((M_Script*)n)->url.vals[0].script_text;
	}
	if (sc_enc.cur_buf) {
		if (!strnicmp(sc_enc.cur_buf, "javascript:", 11)
		        || !strnicmp(sc_enc.cur_buf, "vrmlscript:", 11)
		        || !strnicmp(sc_enc.cur_buf, "ECMAScript:", 11)
		   ) {
			sc_enc.cur_buf += 11;
		} else if (!strnicmp(sc_enc.cur_buf, "mpeg4script:", 12) ) {
			sc_enc.cur_buf += 12;
		}
	}

	/*encode functions*/
	while (sc_enc.cur_buf && sc_enc.cur_buf[0] && (sc_enc.cur_buf[0]!='}')) {
		if (strchr("\r\n\t ", sc_enc.cur_buf[0]) ) {
			sc_enc.cur_buf++;
			continue;
		}
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasFunction", NULL);
		SFE_Function(&sc_enc);
		if (sc_enc.err) break;
	}
	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasFunction", NULL);

	//clean up
	while (gf_list_count(sc_enc.identifiers)) {
		ptr = (char *)gf_list_get(sc_enc.identifiers, 0);
		gf_list_rem(sc_enc.identifiers, 0);
		gf_free(ptr);
	}
	gf_list_del(sc_enc.identifiers);
	/*in case of error this is needed*/
	while (gf_list_count(sc_enc.id_buf)) {
		ptr = (char *)gf_list_get(sc_enc.id_buf, 0);
		gf_list_rem(sc_enc.id_buf, 0);
		gf_free(ptr);
	}
	gf_list_del(sc_enc.id_buf);

	return sc_enc.err;
}
コード例 #17
0
ファイル: svg_text.c プロジェクト: bigbensk/gpac
static void svg_traverse_textArea(GF_Node *node, void *rs, Bool is_destroy)
{	
	SVGPropertiesPointers backup_props;
	u32 backup_flags;
	GF_Matrix mx3d;
	GF_Matrix2D backup_matrix;
	DrawableContext *ctx = NULL;
	GF_ChildNodeItem *child;
	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;

	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->text_parent = node;
	tr_state->in_svg_text_area++;

	if (tr_state->traversing_mode==TRAVERSE_PICK) {
		if (*tr_state->svg_props->pointer_events!=SVG_POINTEREVENTS_NONE) {
			compositor_svg_apply_local_transformation(tr_state, &atts, &backup_matrix, &mx3d);
			gf_font_spans_pick(node, st->spans, tr_state, &st->bounds, 1, st->drawable);

			/*and browse children*/
			child = ((GF_ParentNode *) node)->children;
			while (child) {
				gf_node_traverse(child->node, tr_state);
				child = child->next;
			}
			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;
		}
		tr_state->in_svg_text_area--;
		tr_state->text_parent = NULL;
		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);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(st->drawable, tr_state);
		drawable_reset_path(st->drawable);

		tr_state->max_length = (atts.width ? (atts.width->type == SVG_NUMBER_AUTO ? FIX_MAX : atts.width->value) : FIX_MAX);
		tr_state->max_height = (atts.height ? (atts.height->type == SVG_NUMBER_AUTO ? FIX_MAX : atts.height->value) : FIX_MAX);
		tr_state->base_x = (atts.x ? atts.x->value : 0);
		tr_state->base_y = (atts.y ? atts.y->value : 0);
		/*init the xml:space algo*/
		tr_state->last_char_type = 0;
		/*let it initialize from first font*/
		tr_state->line_spacing = 0;
		tr_state->text_end_x = 0;
		tr_state->text_end_y = (tr_state->svg_props->line_increment->type == SVG_NUMBER_AUTO ? 0 : tr_state->svg_props->line_increment->value);

		tr_state->x_anchors = gf_list_new();

		if (tr_state->svg_props->font_size && (tr_state->svg_props->font_size->value <= tr_state->max_height)) {
			Fixed remain;
			u32 c, refresh_to_idx, prev_refresh;
			/*switch to bounds mode, and recompute children*/
			mode = tr_state->traversing_mode;
			tr_state->traversing_mode = TRAVERSE_GET_BOUNDS;

			prev_refresh = tr_state->refresh_children_bounds;
			tr_state->refresh_children_bounds = 0;
			c = refresh_to_idx = 0;
			child = ((GF_ParentNode *) text)->children;
			while (child) {
				c++;
				switch  (gf_node_get_tag(child->node)) {
				case TAG_DOMText:
					svg_traverse_dom_text_area(child->node, &atts, tr_state, st->spans); 
					break;
				case TAG_SVG_tspan:
					/*mark tspan as dirty to force rebuild*/
					gf_node_dirty_set(child->node, 0, 0);
					gf_node_traverse(child->node, tr_state); 
					break;
				case TAG_SVG_switch:
				case TAG_SVG_a:
				case TAG_SVG_tbreak:
					gf_node_traverse(child->node, tr_state); 
					break;
				default:
					break;
				}
				if (tr_state->refresh_children_bounds) {
					tr_state->refresh_children_bounds=0;
					refresh_to_idx=c;
				}

				child=child->next;
			}
			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;

			svg_text_area_reset_state(tr_state);
			gf_list_del(tr_state->x_anchors);
			tr_state->x_anchors = NULL;

			remain = 0;
			if (tr_state->refresh_children_bounds) {
				refresh_to_idx = (u32) -1;
				tr_state->base_shift = 0;
			}
			if (tr_state->svg_props->display_align) {
				switch (*tr_state->svg_props->display_align) {
				case SVG_DISPLAYALIGN_CENTER:
					remain = (tr_state->max_height-tr_state->text_end_y) / 2;
					break;
				case SVG_DISPLAYALIGN_AFTER:
					remain = tr_state->max_height - tr_state->text_end_y;
					break;
				default:
					remain = 0;
					break;
				}
				if (remain<0) remain=0;
				if (remain) {
					refresh_to_idx = (u32) -1;
					tr_state->base_shift = remain;
					svg_text_area_shift_bounds(st, tr_state);
				}
			} 

			if (refresh_to_idx) {
				tr_state->refresh_children_bounds=1;
				/*and retraverse in case of bounds adjustements*/
				child = ((GF_ParentNode *) text)->children;
				while (child) {
					switch (gf_node_get_tag(child->node)) {
					case TAG_DOMText:
						break;
					case TAG_SVG_tspan:
					case TAG_SVG_switch:
					case TAG_SVG_a:
						gf_node_traverse(child->node, tr_state); 
						break;
					default:
						break;
					}
					child=child->next;
					refresh_to_idx--;
					if (!refresh_to_idx) break;
				}
				tr_state->base_shift = 0;
			}
			tr_state->traversing_mode = mode;
			tr_state->refresh_children_bounds = prev_refresh;
		}
		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);
		
		child = ((GF_ParentNode *) text)->children;
		while (child) {
			switch  (gf_node_get_tag(child->node)) {
			case TAG_DOMText:
				break;
			case TAG_SVG_tspan:
			case TAG_SVG_switch:
			case TAG_SVG_a:
				gf_node_traverse(child->node, tr_state); 
				break;
			default:
				break;
			}
			child = child->next;
		}
	}
	tr_state->in_svg_text_area--;
	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;
}
コード例 #18
0
ファイル: isom_store.c プロジェクト: golgol7777/gpac
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter)
{
	GF_Err e;
	u8 converted;
	u32 i;
	GF_Box *a;
	u64 offset, shift_offset, prev;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	//first setup the writers
	e = SetupWriters(mw, writers, 1);
	if (e) goto exit;


	if (movie->is_jp2) {
		gf_bs_write_u32(bs, 12);
		gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
		gf_bs_write_u32(bs, 0x0D0A870A);
	}
	if (movie->brand) {
		e = gf_isom_box_size((GF_Box *)movie->brand);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->brand, bs);
		if (e) goto exit;
	}
	if (movie->pdin) {
		e = gf_isom_box_size((GF_Box *)movie->pdin);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
		if (e) goto exit;
	}

	e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter);
	if (e) goto exit;

	shift_offset = 0;
	prev = 0;
	for (;;) {
		offset = GetMoovAndMetaSize(movie, writers);
		if (offset==prev) break;
		prev = offset;
		if (movie->mdat && movie->mdat->dataSize)
			offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		e = ShiftOffset(movie, writers, offset-shift_offset,&converted);
		if (e) goto exit;
		shift_offset = offset;
	}

	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;

	/*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */
	if (movie->mdat && movie->mdat->dataSize) {
		if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8;
		e = gf_isom_box_size((GF_Box *)movie->mdat);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->mdat, bs);
		if (e) goto exit;
	}

	//we don't need the offset as we are writing...
	ResetWriters(writers);
	e = DoInterleave(mw, writers, bs, 0, 0, drift_inter);
	if (e) goto exit;

	//then the rest
	i=0;
	while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_MOOV:
		case GF_ISOM_BOX_TYPE_META:
		case GF_ISOM_BOX_TYPE_FTYP:
		case GF_ISOM_BOX_TYPE_PDIN:
		case GF_ISOM_BOX_TYPE_MDAT:
			break;
		default:
			e = gf_isom_box_size(a);
			if (e) goto exit;
			e = gf_isom_box_write(a, bs);
			if (e) goto exit;
		}
	}

exit:
	CleanWriters(writers);
	gf_list_del(writers);
	return e;
}
コード例 #19
0
ファイル: os_accessor.cpp プロジェクト: Bevara/Access-open
static Bool enum_modules(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info)
{
	AccessorInstance *inst;
#if CHECK_MODULE
	QueryInterface query_func;
	LoadInterface load_func;
	ShutdownInterface del_func;
#ifdef WIN32
	HMODULE ModuleLib;
#else
	void *ModuleLib;
	s32 _flags;
#endif

#endif

	GF_ModuleManager *pm = (GF_ModuleManager*)cbck;

	if (strstr(item_name, "nposmozilla")) return GF_FALSE;
	if (strncmp(item_name, "gm_", 3) && strncmp(item_name, "libgm_", 6)) return GF_FALSE;
	if (gf_accessor_is_loaded(pm, item_name) ) return GF_FALSE;

#if CHECK_MODULE

#ifdef WIN32
	ModuleLib = LoadLibrary(item_path);
	if (!ModuleLib) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s\n", item_name));
		return GF_FALSE;
	}

#ifdef _WIN32_WCE
	query_func = (QueryInterface) GetProcAddress(ModuleLib, _T("QueryInterface"));
	load_func = (LoadInterface) GetProcAddress(ModuleLib, _T("LoadInterface"));
	del_func = (ShutdownInterface) GetProcAddress(ModuleLib, _T("ShutdownInterface"));
#else
	query_func = (QueryInterface) GetProcAddress(ModuleLib, "QueryInterface");
	load_func = (LoadInterface) GetProcAddress(ModuleLib, "LoadInterface");
	del_func = (ShutdownInterface) GetProcAddress(ModuleLib, "ShutdownInterface");
#endif
	FreeLibrary(ModuleLib);

#else

#ifdef RTLD_GLOBAL
	_flags =RTLD_LAZY | RTLD_GLOBAL;
#else
	_flags =RTLD_LAZY;
#endif

	ModuleLib = dlopen(item_name, _flags);
	if (!ModuleLib) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s, error is %s\n", item_name, dlerror()));
		goto next;
	}

	query_func = (QueryInterface) dlsym(ModuleLib, "QueryInterface");
	load_func = (LoadInterface) dlsym(ModuleLib, "LoadInterface");
	del_func = (ShutdownInterface) dlsym(ModuleLib, "ShutdownInterface");
	dlclose(ModuleLib);
#endif

	if (!load_func || !query_func || !del_func) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CORE,
		       ("[Core] Could not find some signatures in module %s: QueryInterface=%p, LoadInterface=%p, ShutdownInterface=%p\n",
		        item_name, load_func, query_func, del_func));
		return GF_FALSE;
	}
#endif

	GF_SAFEALLOC(inst, AccessorInstance);
	inst->interfaces = gf_list_new();
	inst->plugman = pm;
	inst->name = gf_strdup(item_name);
	inst->dir = gf_strdup(item_path);
	gf_url_get_resource_path(item_path, inst->dir);
	GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Added module %s.\n", inst->name));
	gf_list_add(pm->plug_list, inst);
	return GF_FALSE;
}
コード例 #20
0
ファイル: isom_store.c プロジェクト: golgol7777/gpac
//write the file track by track, with moov box before or after the mdat
GF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs)
{
	GF_Err e;
	u8 converted;
	u32 i;
	u64 offset, shift_offset, prev, totSize, begin;
	GF_Box *a;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	begin = totSize = 0;

	//first setup the writers
	e = SetupWriters(mw, writers, 0);
	if (e) goto exit;

	if (!moovFirst) {
		if (movie->openMode == GF_ISOM_OPEN_WRITE) {
			begin = 0;
			totSize = gf_isom_datamap_get_offset(movie->editFileMap);
			/*start boxes have not been written yet, do it*/
			if (!totSize) {
				if (movie->is_jp2) {
					gf_bs_write_u32(movie->editFileMap->bs, 12);
					gf_bs_write_u32(movie->editFileMap->bs, GF_4CC('j','P',' ',' '));
					gf_bs_write_u32(movie->editFileMap->bs, 0x0D0A870A);
					totSize += 12;
					begin += 12;
				}
				if (movie->brand) {
					e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit;
					e = gf_isom_box_write((GF_Box *)movie->brand, movie->editFileMap->bs); if (e) goto exit;
					totSize += movie->brand->size;
					begin += movie->brand->size;
				}
				if (movie->pdin) {
					e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit;
					e = gf_isom_box_write((GF_Box *)movie->pdin, movie->editFileMap->bs); if (e) goto exit;
					totSize += movie->pdin->size;
					begin += movie->pdin->size;
				}
			} else {
				if (movie->is_jp2) begin += 12;
				if (movie->brand) begin += movie->brand->size;
				if (movie->pdin) begin += movie->pdin->size;
			}
			totSize -= begin;
		} else {
			if (movie->is_jp2) {
				gf_bs_write_u32(bs, 12);
				gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
				gf_bs_write_u32(bs, 0x0D0A870A);
			}
			if (movie->brand) {
				e = gf_isom_box_size((GF_Box *)movie->brand);
				if (e) goto exit;
				e = gf_isom_box_write((GF_Box *)movie->brand, bs);
				if (e) goto exit;
			}
			/*then progressive download*/
			if (movie->pdin) {
				e = gf_isom_box_size((GF_Box *)movie->pdin);
				if (e) goto exit;
				e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
				if (e) goto exit;
			}
		}

		//if the moov is at the end, write directly
		i=0;
		while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
			switch (a->type) {
			/*written by hand*/
			case GF_ISOM_BOX_TYPE_MOOV:
			case GF_ISOM_BOX_TYPE_META:
			case GF_ISOM_BOX_TYPE_FTYP:
			case GF_ISOM_BOX_TYPE_PDIN:
				break;
			case GF_ISOM_BOX_TYPE_MDAT:
				//in case we're capturing
				if (movie->openMode == GF_ISOM_OPEN_WRITE) {
					//emulate a write to recreate our tables (media data already written)
					e = DoWrite(mw, writers, bs, 1, begin);
					if (e) goto exit;
					continue;
				}
				//to avoid computing the size each time write always 4 + 4 + 8 bytes before
				begin = gf_bs_get_position(bs);
				gf_bs_write_u64(bs, 0);
				gf_bs_write_u64(bs, 0);
				e = DoWrite(mw, writers, bs, 0, gf_bs_get_position(bs));
				if (e) goto exit;
				totSize = gf_bs_get_position(bs) - begin;
				break;
			default:
				e = gf_isom_box_size(a);
				if (e) goto exit;
				e = gf_isom_box_write(a, bs);
				if (e) goto exit;
				break;
			}
		}

		//OK, write the movie box.
		e = WriteMoovAndMeta(movie, writers, bs);
		if (e) goto exit;

		/*if data has been written, update mdat size*/
		if (totSize) {
			offset = gf_bs_get_position(bs);
			e = gf_bs_seek(bs, begin);
			if (e) goto exit;
			if (totSize > 0xFFFFFFFF) {
				gf_bs_write_u32(bs, 1);
			} else {
				gf_bs_write_u32(bs, (u32) totSize);
			}
			gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT);
			if (totSize > 0xFFFFFFFF) gf_bs_write_u64(bs, totSize);
			e = gf_bs_seek(bs, offset);
		}
		movie->mdat->size = totSize;
		goto exit;
	}

	//nope, we have to write the moov first. The pb is that 
	//1 - we don't know its size till the mdat is written
	//2 - we don't know the ofset at which the mdat will start...
	//3 - once the mdat is written, the chunkOffset table can have changed...
	
	if (movie->is_jp2) {
		gf_bs_write_u32(bs, 12);
		gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
		gf_bs_write_u32(bs, 0x0D0A870A);
	}
	if (movie->brand) {
		e = gf_isom_box_size((GF_Box *)movie->brand);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->brand, bs);
		if (e) goto exit;
	}
	/*then progressive dnload*/
	if (movie->pdin) {
		e = gf_isom_box_size((GF_Box *)movie->pdin);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
		if (e) goto exit;
	}
	//What we will do is first emulate the write from the begining...
	//note: this will set the size of the mdat
	e = DoWrite(mw, writers, bs, 1, gf_bs_get_position(bs));
	if (e) goto exit;
	
	shift_offset = 0;
	prev = 0;

	for (;;) {
		offset = GetMoovAndMetaSize(movie, writers);
		if (offset==prev) break;
		prev = offset;
		offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		e = ShiftOffset(movie, writers, offset-shift_offset, &converted);
		if (e) goto exit;
		shift_offset = offset;
	}

	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;
	e = gf_isom_box_size((GF_Box *)movie->mdat);
	if (e) goto exit;
	e = gf_isom_box_write((GF_Box *)movie->mdat, bs);
	if (e) goto exit;

	//we don't need the offset as the moov is already written...
	ResetWriters(writers);
	e = DoWrite(mw, writers, bs, 0, 0);
	if (e) goto exit;
	//then the rest
	i=0;
	while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_MOOV:
		case GF_ISOM_BOX_TYPE_META:
		case GF_ISOM_BOX_TYPE_FTYP:
		case GF_ISOM_BOX_TYPE_PDIN:
		case GF_ISOM_BOX_TYPE_MDAT:
			break;
		default:
			e = gf_isom_box_size(a);
			if (e) goto exit;
			e = gf_isom_box_write(a, bs);
			if (e) goto exit;
		}
	}

exit:
	CleanWriters(writers);
	gf_list_del(writers);
	return e;
}
コード例 #21
0
ファイル: meta.c プロジェクト: ScandalCorp/ccextractor
GF_Err gf_isom_add_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path, const char *item_name, const char *mime_type, const char *content_encoding, const char *URL, const char *URN, char *data, u32 data_len)
{
    GF_Err e;
    GF_ItemLocationEntry *location_entry;
    GF_ItemInfoEntryBox *infe;
    GF_MetaBox *meta;
    u32 lastItemID = 0;

    if (!self_reference && !item_name && !resource_path) return GF_BAD_PARAM;
    e = CanAccessMovie(file, GF_ISOM_OPEN_WRITE);
    if (e) return e;
    meta = gf_isom_get_meta(file, root_meta, track_num);
    if (!meta) {
        GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Trying to add item, but missing meta box"));
        return GF_BAD_PARAM;
    }

    e = FlushCaptureMode(file);
    if (e) return e;

    /*check file exists */
    if (!URN && !URL && !self_reference && !data) {
        FILE *src = gf_f64_open(resource_path, "rb");
        if (!src) return GF_URL_ERROR;
        fclose(src);
    }

    if (meta->item_infos) {
        u32 i;
        u32 item_count = gf_list_count(meta->item_infos->item_infos);
        for (i = 0; i < item_count; i++) {
            GF_ItemInfoEntryBox *e= (GF_ItemInfoEntryBox *)gf_list_get(meta->item_infos->item_infos, i);
            if (e->item_ID > lastItemID) lastItemID = e->item_ID;
        }
    }

    infe = (GF_ItemInfoEntryBox *)infe_New();
    infe->item_ID = ++lastItemID;

    /*get relative name*/
    if (item_name) {
        infe->item_name = gf_strdup(item_name);
    } else if (resource_path) {
        if (strrchr(resource_path, GF_PATH_SEPARATOR)) {
            infe->item_name = gf_strdup(strrchr(resource_path, GF_PATH_SEPARATOR) + 1);
        } else {
            infe->item_name = gf_strdup(resource_path);
        }
    }

    if (mime_type) {
        infe->content_type = gf_strdup(mime_type);
    } else {
        infe->content_type = gf_strdup("application/octet-stream");
    }
    if (content_encoding) infe->content_encoding = gf_strdup(content_encoding);

    /*Creation of the ItemLocation */
    location_entry = (GF_ItemLocationEntry*)gf_malloc(sizeof(GF_ItemLocationEntry));
    if (!location_entry) {
        gf_isom_box_del((GF_Box *)infe);
        return GF_OUT_OF_MEM;
    }
    memset(location_entry, 0, sizeof(GF_ItemLocationEntry));
    location_entry->extent_entries = gf_list_new();

    /*Creates an mdat if it does not exist*/
    if (!file->mdat) {
        file->mdat = (GF_MediaDataBox *)mdat_New();
        gf_list_add(file->TopBoxes, file->mdat);
    }

    /*Creation an ItemLocation Box if it does not exist*/
    if (!meta->item_locations) meta->item_locations = (GF_ItemLocationBox *)iloc_New();
    gf_list_add(meta->item_locations->location_entries, location_entry);
    location_entry->item_ID = lastItemID;

    if (!meta->item_infos) meta->item_infos = (GF_ItemInfoBox *) iinf_New();
    e = gf_list_add(meta->item_infos->item_infos, infe);
    if (e) return e;

    /*0: the current file*/
    location_entry->data_reference_index = 0;
    if (self_reference) {
        GF_ItemExtentEntry *entry;
        GF_SAFEALLOC(entry, GF_ItemExtentEntry);
        gf_list_add(location_entry->extent_entries, entry);
        if (!infe->item_name) infe->item_name = gf_strdup("");
        return GF_OK;
    }

    /*file not copied, just referenced*/
    if (URL || URN) {
        u32 dataRefIndex;
        if (!meta->file_locations) meta->file_locations = (GF_DataInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DINF);
        if (!meta->file_locations->dref) meta->file_locations->dref = (GF_DataReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
        e = Media_FindDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
        if (e) return e;
        if (!dataRefIndex) {
            e = Media_CreateDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
            if (e) return e;
        }
        location_entry->data_reference_index = dataRefIndex;
    }

    /*capture mode, write to disk*/
    if ((file->openMode == GF_ISOM_OPEN_WRITE) && !location_entry->data_reference_index) {
        FILE *src;
        GF_ItemExtentEntry *entry;
        GF_SAFEALLOC(entry, GF_ItemExtentEntry);

        location_entry->base_offset = gf_bs_get_position(file->editFileMap->bs);

        /*update base offset size*/
        if (location_entry->base_offset>0xFFFFFFFF) meta->item_locations->base_offset_size = 8;
        else if (location_entry->base_offset && !meta->item_locations->base_offset_size) meta->item_locations->base_offset_size = 4;

        entry->extent_length = 0;
        entry->extent_offset = 0;
        gf_list_add(location_entry->extent_entries, entry);

        if (data) {
            gf_bs_write_data(file->editFileMap->bs, data, data_len);
            /*update length size*/
            if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
            else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
        } else if (resource_path) {
            src = gf_f64_open(resource_path, "rb");
            if (src) {
                char cache_data[4096];
                u64 remain;
                gf_f64_seek(src, 0, SEEK_END);
                entry->extent_length = gf_f64_tell(src);
                gf_f64_seek(src, 0, SEEK_SET);

                remain = entry->extent_length;
                while (remain) {
                    u32 size_cache = (remain>4096) ? 4096 : (u32) remain;
                    size_cache = fread(cache_data, 1, size_cache, src);
                    gf_bs_write_data(file->editFileMap->bs, cache_data, size_cache);
                    remain -= size_cache;
                }
                fclose(src);

                /*update length size*/
                if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
                else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
            }
        }
    }
    /*store full path for info*/
    else if (!location_entry->data_reference_index) {
        if (data) {
            infe->full_path = (char *) gf_malloc(sizeof(char) * data_len);
            memcpy(infe->full_path, data, sizeof(char) * data_len);
            infe->data_len = data_len;
        } else {
            infe->full_path = gf_strdup(resource_path);
            infe->data_len = 0;
        }
    }
    return GF_OK;
}
コード例 #22
0
ファイル: scene_manager.c プロジェクト: ARSekkat/gpac
GF_EXPORT
GF_Err gf_sm_aggregate(GF_SceneManager *ctx, u16 ESID)
{
	GF_Err e;
	u32 i, stream_count;
#ifndef GPAC_DISABLE_VRML
	u32 j;
	GF_AUContext *au;
	GF_Command *com;
#endif

	e = GF_OK;

#if DEBUG_RAP
	com_count = 0;
	stream_count = gf_list_count(ctx->streams);
	for (i=0; i<stream_count; i++) {
		GF_StreamContext *sc = (GF_StreamContext *)gf_list_get(ctx->streams, i);
		if (sc->streamType == GF_STREAM_SCENE) {
			au_count = gf_list_count(sc->AUs);
			for (j=0; j<au_count; j++) {
				au = (GF_AUContext *)gf_list_get(sc->AUs, j);
				com_count += gf_list_count(au->commands);
			}
		}
	}
	GF_LOG(GF_LOG_INFO, GF_LOG_SCENE, ("[SceneManager] Making RAP with %d commands\n", com_count));
#endif

	stream_count = gf_list_count(ctx->streams);
	for (i=0; i<stream_count; i++) {
		GF_AUContext *carousel_au;
		GF_List *carousel_commands;
		GF_StreamContext *aggregate_on_stream;
		GF_StreamContext *sc = (GF_StreamContext *)gf_list_get(ctx->streams, i);
		if (ESID && (sc->ESID!=ESID)) continue;

		/*locate the AU in which our commands will be aggregated*/
		carousel_au = NULL;
		carousel_commands = NULL;
		aggregate_on_stream = sc->aggregate_on_esid ? gf_sm_get_stream(ctx, sc->aggregate_on_esid) : NULL;
		if (aggregate_on_stream==sc) {
			carousel_commands = gf_list_new();
		} else if (aggregate_on_stream) {
			if (!gf_list_count(aggregate_on_stream->AUs)) {
				carousel_au = gf_sm_stream_au_new(aggregate_on_stream, 0, 0, 1);
			} else {
				/* assert we already performed aggregation */
				assert(gf_list_count(aggregate_on_stream->AUs)==1);
				carousel_au = gf_list_get(aggregate_on_stream->AUs, 0);
			}
			carousel_commands = carousel_au->commands;
		}
		/*TODO - do this as well for ODs*/
#ifndef GPAC_DISABLE_VRML
		if (sc->streamType == GF_STREAM_SCENE) {
			Bool has_modif = 0;
			/*we check for each stream if it is a base stream (SceneReplace ...) - several streams may carry RAPs if inline nodes are used*/
			Bool base_stream_found = 0;

			/*in DIMS we use an empty initial AU with no commands to signal the RAP*/
			if (sc->objectType == GPAC_OTI_SCENE_DIMS) base_stream_found = 1;

			/*apply all commands - this will also apply the SceneReplace*/
			while (gf_list_count(sc->AUs)) {
				u32 count;
				au = (GF_AUContext *) gf_list_get(sc->AUs, 0);
				gf_list_rem(sc->AUs, 0);

				/*AU not aggregated*/
				if (au->flags & GF_SM_AU_NOT_AGGREGATED) {
					gf_sm_au_del(sc, au);
					continue;
				}

				count = gf_list_count(au->commands);

				for (j=0; j<count; j++) {
					u32 store=0;
					com = gf_list_get(au->commands, j);
					if (!base_stream_found) {
						switch (com->tag) {
						case GF_SG_SCENE_REPLACE:
						case GF_SG_LSR_NEW_SCENE:
						case GF_SG_LSR_REFRESH_SCENE:
							base_stream_found = 1;
							break;
						}
					}

					/*aggregate the command*/

					/*if stream doesn't carry a carousel or carries the base carousel (scene replace), always apply the command*/
					if (base_stream_found || !sc->aggregate_on_esid) {
						store = 0;
					}
					/*otherwise, check wether the command should be kept in this stream as is, or can be aggregated on this stream*/
					else {
						switch (com->tag) {
						/*the following commands do not impact a sub-tree (eg do not deal with nodes), we cannot
						aggregate them... */
						case GF_SG_ROUTE_REPLACE:
						case GF_SG_ROUTE_DELETE:
						case GF_SG_ROUTE_INSERT:
						case GF_SG_PROTO_INSERT:
						case GF_SG_PROTO_DELETE:
						case GF_SG_PROTO_DELETE_ALL:
						case GF_SG_GLOBAL_QUANTIZER:
						case GF_SG_LSR_RESTORE:
						case GF_SG_LSR_SAVE:
						case GF_SG_LSR_SEND_EVENT:
						case GF_SG_LSR_CLEAN:
							/*todo check in which category to put these commands*/
//						case GF_SG_LSR_ACTIVATE:
//						case GF_SG_LSR_DEACTIVATE:
							store = 1;
							break;
						/*other commands:
							!!! we need to know if the target node of the command has been inserted in this stream !!!

						This is a tedious task, for now we will consider the following cases:
							- locate a similar command in the stored list: remove the similar one and aggregate on stream
							- by default all AUs are stored if the stream is in aggregate mode - we should fix that by checking insertion points:
							 if a command apllies on a node that has been inserted in this stream, we can aggregate, otherwise store
						*/
						default:
							/*check if we can directly store the command*/
							assert(carousel_commands);
							store = store_or_aggregate(sc, com, carousel_commands, &has_modif);
							break;
						}
					}

					switch (store) {
					/*command has been merged with a previous command in carousel and needs to be destroyed*/
					case 2:
						gf_list_rem(au->commands, j);
						j--;
						count--;
						gf_sg_command_del((GF_Command *)com);
						break;
					/*command shall be moved to carousel without being applied*/
					case 1:
						gf_list_insert(carousel_commands, com, 0);
						gf_list_rem(au->commands, j);
						j--;
						count--;
						break;
					/*command can be applied*/
					default:
						e = gf_sg_command_apply(ctx->scene_graph, com, 0);
						break;
					}
				}
				gf_sm_au_del(sc, au);
			}

			/*and recreate scene replace*/
			if (base_stream_found) {
				au = gf_sm_stream_au_new(sc, 0, 0, 1);

				switch (sc->objectType) {
				case GPAC_OTI_SCENE_BIFS:
				case GPAC_OTI_SCENE_BIFS_V2:
					com = gf_sg_command_new(ctx->scene_graph, GF_SG_SCENE_REPLACE);
					break;
				case GPAC_OTI_SCENE_LASER:
					com = gf_sg_command_new(ctx->scene_graph, GF_SG_LSR_NEW_SCENE);
					break;
				case GPAC_OTI_SCENE_DIMS:
				/* We do not create a new command, empty AU is enough in DIMS*/
				default:
					com = NULL;
					break;
				}

				if (com) {
					com->node = ctx->scene_graph->RootNode;
					ctx->scene_graph->RootNode = NULL;
					gf_list_del(com->new_proto_list);
					com->new_proto_list = ctx->scene_graph->protos;
					ctx->scene_graph->protos = NULL;
					/*indicate the command is the aggregated scene graph, so that PROTOs and ROUTEs
					are taken from the scenegraph when encoding*/
					com->aggregated = 1;
					gf_list_add(au->commands, com);
				}
			}
			/*update carousel flags of the AU*/
			else if (carousel_commands) {
				/*if current stream caries its own carousel*/
				if (!carousel_au) {
					carousel_au = gf_sm_stream_au_new(sc, 0, 0, 1);
					gf_list_del(carousel_au->commands);
					carousel_au->commands = carousel_commands;
				}
				carousel_au->flags |= GF_SM_AU_RAP | GF_SM_AU_CAROUSEL;
				if (has_modif) carousel_au->flags |= GF_SM_AU_MODIFIED;
			}
		}
#endif
	}
	return e;
}
コード例 #23
0
GF_EXPORT
void gf_smil_timing_init_runtime_info(GF_Node *timed_elt)
{
	s32 interval_index;
	GF_SceneGraph *sg;
	SMIL_Timing_RTI *rti;
	SMILTimingAttributesPointers *timingp = NULL;
	u32 tag = gf_node_get_tag(timed_elt);

	if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {
		SVGAllAttributes all_atts;
		SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)timed_elt;
		gf_svg_flatten_attributes((SVG_Element *)e, &all_atts);
		e->timingp = malloc(sizeof(SMILTimingAttributesPointers));
		e->timingp->begin		= all_atts.begin;
		e->timingp->clipBegin	= all_atts.clipBegin;
		e->timingp->clipEnd		= all_atts.clipEnd;
		e->timingp->dur			= all_atts.dur;
		e->timingp->end			= all_atts.end;
		e->timingp->fill		= all_atts.smil_fill;
		e->timingp->max			= all_atts.max;
		e->timingp->min			= all_atts.min;
		e->timingp->repeatCount = all_atts.repeatCount;
		e->timingp->repeatDur	= all_atts.repeatDur;
		e->timingp->restart		= all_atts.restart;
		timingp = e->timingp;
	} 
#ifdef GPAC_ENABLE_SVG_SA
	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {
		SVG_SA_Element *e = (SVG_SA_Element *)timed_elt;
		e->timingp = malloc(sizeof(SMILTimingAttributesPointers));
		e->timingp->begin		= &e->timing->begin;
		e->timingp->clipBegin	= &e->timing->clipBegin;
		e->timingp->clipEnd		= &e->timing->clipEnd;
		e->timingp->dur			= &e->timing->dur;
		e->timingp->end			= &e->timing->end;
		e->timingp->fill		= &e->timing->fill;
		e->timingp->max			= &e->timing->max;
		e->timingp->min			= &e->timing->min;
		e->timingp->repeatCount = &e->timing->repeatCount;
		e->timingp->repeatDur	= &e->timing->repeatDur;
		e->timingp->restart		= &e->timing->restart;
		timingp = e->timingp;
	}
#endif
#ifdef GPAC_ENABLE_SVG_SANI
	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {
		SVG_SANI_Element *e = (SVG_SANI_Element *)timed_elt;
		e->timingp = malloc(sizeof(SMILTimingAttributesPointers));
		e->timingp->begin		= &e->timing->begin;
		e->timingp->clipBegin	= &e->timing->clipBegin;
		e->timingp->clipEnd		= &e->timing->clipEnd;
		e->timingp->dur			= &e->timing->dur;
		e->timingp->end			= &e->timing->end;
		e->timingp->fill		= &e->timing->fill;
		e->timingp->max			= &e->timing->max;
		e->timingp->min			= &e->timing->min;
		e->timingp->repeatCount = &e->timing->repeatCount;
		e->timingp->repeatDur	= &e->timing->repeatDur;
		e->timingp->restart		= &e->timing->restart;
		timingp = e->timingp;
	}
#endif
	else {
		return;
	}

	if (!timingp) return;

	GF_SAFEALLOC(rti, SMIL_Timing_RTI)
	timingp->runtime = rti;
	rti->timed_elt = timed_elt;
	rti->timingp = timingp;
	rti->status = SMIL_STATUS_WAITING_TO_BEGIN;
	rti->evaluate_status = SMIL_TIMING_EVAL_NONE;	
	rti->intervals = gf_list_new();
	rti->current_interval = NULL;
	rti->evaluate = gf_smil_timing_null_timed_function;
	rti->scene_time = -1;
	rti->media_duration = -1;

	gf_smil_timing_init_interval_list(rti);
	interval_index = gf_smil_timing_find_interval_index(rti, GF_MAX_DOUBLE);
	if (interval_index >= 0) {
		rti->current_interval_index = interval_index;
		rti->current_interval = (SMIL_Interval*)gf_list_get(rti->intervals, rti->current_interval_index);
	} 

	sg = timed_elt->sgprivate->scenegraph;
	while (sg->parent_scene) sg = sg->parent_scene;
	gf_smil_timing_add_to_sg(sg, rti);
}
コード例 #24
0
static GF_Renderer *SR_New(GF_User *user)
{
	const char *sOpt;
	GF_VisualRenderer *vrend;
	GF_GLConfig cfg, *gl_cfg;
	Bool forced = 1;
	GF_Renderer *tmp;
	GF_SAFEALLOC(tmp, GF_Renderer);
	if (!tmp) return NULL;
	tmp->user = user;

	/*load renderer to check for GL flag*/
	if (! (user->init_flags & (GF_TERM_FORCE_2D | GF_TERM_FORCE_3D)) ) {
		sOpt = gf_cfg_get_key(user->config, "Rendering", "RendererName");
		if (sOpt) {
			tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RENDERER_INTERFACE);
			if (!tmp->visual_renderer) sOpt = NULL;
		}
		forced = 0;
	}
	if (!tmp->visual_renderer) {
		u32 i, count;
		count = gf_modules_get_count(user->modules);
		for (i=0; i<count; i++) {
			tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface(user->modules, i, GF_RENDERER_INTERFACE);
			if (tmp->visual_renderer) {
				if ((tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_2D)) 
					|| (!tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_3D)) ) {

					GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Renderer] Renderer %s loaded but not matching init flags %08x\n", tmp->visual_renderer->module_name, user->init_flags));
					gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);
					tmp->visual_renderer = NULL;
					continue;
				}
				break;
			}
		}
		if (!forced && tmp->visual_renderer) gf_cfg_set_key(user->config, "Rendering", "RendererName", tmp->visual_renderer->module_name);
	}

	if (!tmp->visual_renderer) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Renderer] Cannot load any visual renderer - aborting\n"));
		free(tmp);
		return NULL;
	}

	memset(&cfg, 0, sizeof(cfg));
	cfg.double_buffered = 1;
	gl_cfg = tmp->visual_renderer->bNeedsGL ? &cfg : NULL;
	vrend = tmp->visual_renderer;
	tmp->visual_renderer = NULL;
	/*load video out*/
	sOpt = gf_cfg_get_key(user->config, "Video", "DriverName");
	if (sOpt) {
		tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_VIDEO_OUTPUT_INTERFACE);
		if (tmp->video_out) {
			tmp->video_out->evt_cbk_hdl = tmp;
			tmp->video_out->on_event = gf_sr_on_event;
			/*init hw*/
			if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg) != GF_OK) {
				gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);
				tmp->video_out = NULL;
			}
		} else {
			sOpt = NULL;
		}
	}

	if (!tmp->video_out) {
		u32 i, count;
		count = gf_modules_get_count(user->modules);
		for (i=0; i<count; i++) {
			tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface(user->modules, i, GF_VIDEO_OUTPUT_INTERFACE);
			if (!tmp->video_out) continue;
			tmp->video_out->evt_cbk_hdl = tmp;
			tmp->video_out->on_event = gf_sr_on_event;
			/*init hw*/
			if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg)==GF_OK) {
				gf_cfg_set_key(user->config, "Video", "DriverName", tmp->video_out->module_name);
				break;
			}
			gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);
			tmp->video_out = NULL;
		}
	}
	tmp->visual_renderer = vrend;
	if (!tmp->video_out ) {
		gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);
		free(tmp);
		return NULL;
	}

	/*try to load a raster driver*/
	sOpt = gf_cfg_get_key(user->config, "Rendering", "Raster2D");
	if (sOpt) {
		tmp->r2d = (GF_Raster2D *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RASTER_2D_INTERFACE);
		if (!tmp->r2d) {
			sOpt = NULL;
		} else if (!check_graphics2D_driver(tmp->r2d)) {
			gf_modules_close_interface((GF_BaseInterface *)tmp->r2d);
			tmp->r2d = NULL;
			sOpt = NULL;
		}
	}
	if (!tmp->r2d) {
		u32 i, count;
		count = gf_modules_get_count(user->modules);
		for (i=0; i<count; i++) {
			tmp->r2d = (GF_Raster2D *) gf_modules_load_interface(user->modules, i, GF_RASTER_2D_INTERFACE);
			if (!tmp->r2d) continue;
			if (check_graphics2D_driver(tmp->r2d)) break;
			gf_modules_close_interface((GF_BaseInterface *)tmp->r2d);
			tmp->r2d = NULL;
		}
		if (tmp->r2d) gf_cfg_set_key(user->config, "Rendering", "Raster2D", tmp->r2d->module_name);
	}

	/*and init*/
	if (tmp->visual_renderer->LoadRenderer(tmp->visual_renderer, tmp) != GF_OK) {
		gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);
		tmp->video_out->Shutdown(tmp->video_out);
		gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);
		free(tmp);
		return NULL;
	}

	tmp->mx = gf_mx_new();
	tmp->textures = gf_list_new();
	tmp->frame_rate = 30.0;	
	tmp->frame_duration = 33;
	tmp->time_nodes = gf_list_new();
#ifdef GF_SR_EVENT_QUEUE
	tmp->events = gf_list_new();
	tmp->ev_mx = gf_mx_new();
#endif
	
	SR_ResetFrameRate(tmp);	
	/*set font engine if any*/
	SR_SetFontEngine(tmp);
	
	tmp->extra_scenes = gf_list_new();
	tmp->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR | GF_INTERACT_NAVIGATION;
	return tmp;
}
コード例 #25
0
GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n)
{
	GF_Err e;
	u32 i, count, nbBits;
	char *ptr;
	ScriptParser parser;
	Bool has_fields = 0;
	e = GF_OK;
	if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM;

	parser.codec = codec;
	parser.script = n;
	parser.bs = bs;
	parser.length = 500;
	parser.string = (char *) malloc(sizeof(char)* parser.length);
	parser.string[0] = 0;
	parser.identifiers = gf_list_new();
	parser.new_line = (char *) (codec->dec_memory_mode ? "\n" : NULL);
	parser.indent = 0;

	//first parse fields

	if (gf_bs_read_int(bs, 1)) {
		//endFlag
		while (!gf_bs_read_int(bs, 1)){
			e = ParseScriptField(&parser);
			if (e) goto exit;
			else has_fields = 1;
		}
	} else {
		nbBits = gf_bs_read_int(bs, 4);
		count = gf_bs_read_int(bs, nbBits);
		for (i=0; i<count; i++) {
			e = ParseScriptField(&parser);
			if (e) goto exit;
			else has_fields = 1;
		}
	}
	//reserevd
	gf_bs_read_int(bs, 1);
	//then parse
	SFS_AddString(&parser, "javascript:");
	SFS_AddString(&parser, parser.new_line);

	//hasFunction
	while (gf_bs_read_int(bs, 1)) {
		SFS_AddString(&parser, "function ");
		SFS_Identifier(&parser);
		SFS_Arguments(&parser, 0);
		SFS_Space(&parser);
		SFS_StatementBlock(&parser, 1);
		SFS_Line(&parser);
	}

	SFS_Line(&parser);

	if (script_field->script_text) free(script_field->script_text);
	script_field->script_text = (unsigned char *) strdup(parser.string);

exit:
	//clean up
	while (gf_list_count(parser.identifiers)) {
		ptr = (char *)gf_list_get(parser.identifiers, 0);
		free(ptr);
		gf_list_rem(parser.identifiers, 0);
	}
	gf_list_del(parser.identifiers);
	if (parser.string) free(parser.string);
	return e;
}
コード例 #26
0
ファイル: live.c プロジェクト: drakeguan/gpac
int live_session(int argc, char **argv)
{
	GF_Err e;
	u32 i;
	char *filename = NULL;
	char *dst = NULL;
	char *ifce_addr = NULL;
	char *sdp_name = "session.sdp";
	u16 dst_port = 7000;
	u32 load_type=0;
	u32 check;
	u32 ttl = 1;
	u32 path_mtu = 1450;
	s32 next_time;
	u64 last_src_modif, mod_time;
	char *src_name = NULL;
	Bool run, has_carousel, no_rap;
	Bool udp = 0;
	u16 sk_port=0;
	GF_Socket *sk = NULL;
	LiveSession livesess;
	RTPChannel *ch;
	char *update_buffer = NULL;
	u32 update_buffer_size = 0;
	u16 aggregate_on_stream;
	Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, version_inc;
	Bool update_context;
	u32 period, ts_delta, signal_critical;
	u16 es_id;
	e = GF_OK;
	aggregate_au = 1;
	es_id = 0;
	no_rap = 0;
	gf_sys_init(GF_FALSE);

	memset(&livesess, 0, sizeof(LiveSession));

	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_INFO);

	for (i=1; i<(u32) argc; i++) {
		char *arg = argv[i];
		if (arg[0] != '-') filename = arg;
		else if (!strnicmp(arg, "-dst=", 5)) dst = arg+5;
		else if (!strnicmp(arg, "-port=", 6)) dst_port = atoi(arg+6);
		else if (!strnicmp(arg, "-sdp=", 5)) sdp_name = arg+5;
		else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(arg+5);
		else if (!strnicmp(arg, "-ttl=", 5)) ttl = atoi(arg+5);
		else if (!strnicmp(arg, "-ifce=", 6)) ifce_addr = arg+6;
		else if (!strnicmp(arg, "-no-rap", 7)) no_rap = 1;
		else if (!strnicmp(arg, "-dims", 5)) load_type = GF_SM_LOAD_DIMS;
		else if (!strnicmp(arg, "-src=", 5)) src_name = arg+5;
		else if (!strnicmp(arg, "-udp=", 5)) {
			sk_port = atoi(arg+5);
			udp = 1;
		}
		else if (!strnicmp(arg, "-tcp=", 5)) {
			sk_port = atoi(arg+5);
			udp = 0;
		}
	}
	if (!filename) {
		fprintf(stderr, "Missing filename\n");
		PrintLiveUsage();
		return 1;
	}

	if (dst_port && dst) livesess.streams = gf_list_new();

	livesess.seng = gf_seng_init(&livesess, filename, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0);
	if (!livesess.seng) {
		fprintf(stderr, "Cannot create scene engine\n");
		return 1;
	}
	if (livesess.streams) live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, ifce_addr, sdp_name);

	has_carousel = 0;
	last_src_modif = src_name ? gf_file_modification_time(src_name) : 0;

	if (sk_port) {
		sk = gf_sk_new(udp ? GF_SOCK_TYPE_UDP : GF_SOCK_TYPE_TCP);
		if (udp) {
			e = gf_sk_bind(sk, NULL, sk_port, NULL, 0, 0);
			if (e != GF_OK) {
				if (sk) gf_sk_del(sk);
				sk = NULL;
			}
		} else {
		}
	}


	for (i=0; i<(u32) argc; i++) {
		char *arg = argv[i];
		if (!strnicmp(arg, "-rap=", 5)) {
			u32 period, id, j;
			RTPChannel *ch;
			period = id = 0;
			if (strchr(arg, ':')) {
				sscanf(arg, "-rap=ESID=%u:%u", &id, &period);
				e = gf_seng_enable_aggregation(livesess.seng, id, 1);
				if (e) {
					fprintf(stderr, "Cannot enable aggregation on stream %u: %s\n", id, gf_error_to_string(e));
					goto exit;
				}
			} else {
				sscanf(arg, "-rap=%u", &period);
			}

			j=0;
			while (NULL != (ch = gf_list_enum(livesess.streams, &j))) {
				if (!id || (ch->ESID==id))
					ch->carousel_period = period;
			}
			has_carousel = 1;
		}
	}

	i=0;
	while (NULL != (ch = gf_list_enum(livesess.streams, &i))) {
		if (ch->carousel_period) {
			has_carousel = 1;
			break;
		}
	}

	update_context = 0;

	if (has_carousel || !no_rap) {
		livesess.carousel_generation = 1;
		gf_seng_encode_context(livesess.seng, live_session_callback);
		livesess.carousel_generation = 0;
	}

	live_session_send_carousel(&livesess, NULL);

	check = 10;
	run = 1;
	while (run) {
		check--;
		if (!check) {
			check = 10;
			if (gf_prompt_has_input()) {
				char c = gf_prompt_get_char();
				switch (c) {
				case 'q':
					run=0;
					break;
				case 'U':
					livesess.critical = 1;
				case 'u':
				{
					GF_Err e;
					char szCom[8192];
					fprintf(stderr, "Enter command to send:\n");
					szCom[0] = 0;
					if (1 > scanf("%[^\t\n]", szCom)) {
						fprintf(stderr, "No command entered properly, aborting.\n");
						break;
					}
					/*stdin flush bug*/
					while (getchar()!='\n') {}
					e = gf_seng_encode_from_string(livesess.seng, 0, 0, szCom, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					e = gf_seng_aggregate_context(livesess.seng, 0);
					livesess.critical = 0;
					update_context = 1;
				}
				break;
				case 'E':
					livesess.critical = 1;
				case 'e':
				{
					GF_Err e;
					char szCom[8192];
					fprintf(stderr, "Enter command to send:\n");
					szCom[0] = 0;
					if (1 > scanf("%[^\t\n]", szCom)) {
						printf("No command entered properly, aborting.\n");
						break;
					}
					/*stdin flush bug*/
					while (getchar()!='\n') {}
					e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					livesess.critical = 0;
					e = gf_seng_aggregate_context(livesess.seng, 0);

				}
				break;

				case 'p':
				{
					char rad[GF_MAX_PATH];
					fprintf(stderr, "Enter output file name - \"std\" for stderr: ");
					if (1 > scanf("%s", rad)) {
						fprintf(stderr, "No ouput file name entered, aborting.\n");
						break;
					}
					e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad);
					fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e));
				}
				break;
				case 'F':
					update_context = 1;
				case 'f':
					livesess.force_carousel = 1;
					break;
				}
				e = GF_OK;
			}
		}

		/*process updates from file source*/
		if (src_name) {
			mod_time = gf_file_modification_time(src_name);
			if (mod_time != last_src_modif) {
				FILE *srcf;
				char flag_buf[201], *flag;
				fprintf(stderr, "Update file modified - processing\n");
				last_src_modif = mod_time;

				srcf = gf_fopen(src_name, "rt");
				if (!srcf) continue;

				/*checks if we have a broadcast config*/
				if (!fgets(flag_buf, 200, srcf))
					flag_buf[0] = '\0';
				gf_fclose(srcf);

				aggregate_on_stream = (u16) -1;
				adjust_carousel_time = force_rap = discard_pending = signal_rap = signal_critical = 0;
				aggregate_au = version_inc = 1;
				period = -1;
				ts_delta = 0;
				es_id = 0;

				/*find our keyword*/
				flag = strstr(flag_buf, "gpac_broadcast_config ");
				if (flag) {
					flag += strlen("gpac_broadcast_config ");
					/*move to next word*/
					while (flag && (flag[0]==' ')) flag++;

					while (1) {
						char *sep = strchr(flag, ' ');
						if (sep) sep[0] = 0;
						if (!strnicmp(flag, "esid=", 5)) es_id = atoi(flag+5);
						else if (!strnicmp(flag, "period=", 7)) period = atoi(flag+7);
						else if (!strnicmp(flag, "ts=", 3)) ts_delta = atoi(flag+3);
						else if (!strnicmp(flag, "carousel=", 9)) aggregate_on_stream = atoi(flag+9);
						else if (!strnicmp(flag, "restamp=", 8)) adjust_carousel_time = atoi(flag+8);

						else if (!strnicmp(flag, "discard=", 8)) discard_pending = atoi(flag+8);
						else if (!strnicmp(flag, "aggregate=", 10)) aggregate_au = atoi(flag+10);
						else if (!strnicmp(flag, "force_rap=", 10)) force_rap = atoi(flag+10);
						else if (!strnicmp(flag, "rap=", 4)) signal_rap = atoi(flag+4);
						else if (!strnicmp(flag, "critical=", 9)) signal_critical = atoi(flag+9);
						else if (!strnicmp(flag, "vers_inc=", 9)) version_inc = atoi(flag+9);
						if (sep) {
							sep[0] = ' ';
							flag = sep+1;
						} else {
							break;
						}
					}

					set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc);
				}

				e = gf_seng_encode_from_file(livesess.seng, es_id, aggregate_au ? 0 : 1, src_name, live_session_callback);
				if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
				e = gf_seng_aggregate_context(livesess.seng, 0);

				update_context = no_rap ? 0 : 1;
			}
		}

		/*process updates from socket source*/
		if (sk) {
			char buffer[2049];
			u32 bytes_read;
			u32 update_length;
			u32 bytes_received;


			e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read);
			if (e == GF_OK) {
				u32 hdr_length = 0;
				u8 cmd_type = buffer[0];
				bytes_received = 0;
				switch (cmd_type) {
				case 0:
				{
					GF_BitStream *bs = gf_bs_new(buffer, bytes_read, GF_BITSTREAM_READ);
					gf_bs_read_u8(bs);
					es_id = gf_bs_read_u16(bs);
					aggregate_on_stream = gf_bs_read_u16(bs);
					if (aggregate_on_stream==0xFFFF) aggregate_on_stream = -1;
					adjust_carousel_time = gf_bs_read_int(bs, 1);
					force_rap = gf_bs_read_int(bs, 1);
					aggregate_au = gf_bs_read_int(bs, 1);
					discard_pending = gf_bs_read_int(bs, 1);
					signal_rap = gf_bs_read_int(bs, 1);
					signal_critical = gf_bs_read_int(bs, 1);
					version_inc = gf_bs_read_int(bs, 1);
					gf_bs_read_int(bs, 1);
					period = gf_bs_read_u16(bs);
					if (period==0xFFFF) period = -1;
					ts_delta = gf_bs_read_u16(bs);
					update_length = gf_bs_read_u32(bs);
					hdr_length = 12;
					gf_bs_del(bs);
				}

				set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc);
				break;
				default:
					update_length = 0;
					break;
				}

				if (update_buffer_size <= update_length) {
					update_buffer = gf_realloc(update_buffer, update_length+1);
					update_buffer_size = update_length+1;
				}
				if (update_length && (bytes_read>hdr_length) ) {
					memcpy(update_buffer, buffer+hdr_length, bytes_read-hdr_length);
					bytes_received = bytes_read-hdr_length;
				}
				while (bytes_received<update_length) {
					e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read);
					switch (e) {
					case GF_IP_NETWORK_EMPTY:
						break;
					case GF_OK:
						memcpy(update_buffer+bytes_received, buffer, bytes_read);
						bytes_received += bytes_read;
						break;
					default:
						fprintf(stderr, "Error with UDP socket : %s\n", gf_error_to_string(e));
						break;
					}
				}
				update_buffer[update_length] = 0;

				if (update_length) {
					e = gf_seng_encode_from_string(livesess.seng, es_id, aggregate_au ? 0 : 1, update_buffer, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					e = gf_seng_aggregate_context(livesess.seng, 0);

					update_context = 1;
				}
			}
		}

		if (update_context) {
			livesess.carousel_generation=1;
			e = gf_seng_encode_context(livesess.seng, live_session_callback	);
			livesess.carousel_generation=0;
			update_context = 0;
		}

		if (livesess.force_carousel) {
			live_session_send_carousel(&livesess, NULL);
			livesess.force_carousel = 0;
			continue;
		}

		if (!has_carousel) {
			gf_sleep(10);
			continue;
		}
		ch = next_carousel(&livesess, (u32 *) &next_time);
		if ((ch==NULL) || (next_time > 20)) {
			gf_sleep(20);
			continue;
		}
		if (next_time) gf_sleep(next_time);
		live_session_send_carousel(&livesess, ch);
	}

exit:
	live_session_shutdown(&livesess);
	if (update_buffer) gf_free(update_buffer);
	if (sk) gf_sk_del(sk);
	gf_sys_close();
	return e ? 1 : 0;
}
コード例 #27
0
ファイル: validator.c プロジェクト: bigbensk/gpac
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;
}
コード例 #28
0
ファイル: mpeg4_background.c プロジェクト: Bevara/GPAC
void compositor_init_background(GF_Compositor *compositor, GF_Node *node)
{
	BackgroundStack *ptr;
	GF_SAFEALLOC(ptr, BackgroundStack);

	ptr->compositor = compositor;
	ptr->reg_stacks = gf_list_new();
	((M_Background *)node)->on_set_bind = back_set_bind;

	gf_mx_init(ptr->current_mx);

	/*build texture cube*/
	ptr->front_mesh = new_mesh();
	mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, 0);
	mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, 0);
	mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, FIX_ONE);
	mesh_set_triangle(ptr->front_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->front_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->front_mesh);

	ptr->back_mesh = new_mesh();
	mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, 0);
	mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, 0);
	mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, FIX_ONE);
	mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->back_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->back_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->back_mesh);

	ptr->top_mesh = new_mesh();
	mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, 0);
	mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, 0);
	mesh_set_triangle(ptr->top_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->top_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->top_mesh);

	ptr->bottom_mesh = new_mesh();
	mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, 0);
	mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, FIX_ONE);
	mesh_set_triangle(ptr->bottom_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->bottom_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->bottom_mesh);

	ptr->left_mesh = new_mesh();
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, 0);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->left_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->left_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->left_mesh);

	ptr->right_mesh = new_mesh();
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, 0);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->right_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->right_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->right_mesh);


	gf_sc_texture_setup(&ptr->txh_back, compositor, node);
	ptr->txh_back.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_front, compositor, node);
	ptr->txh_front.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_top, compositor, node);
	ptr->txh_top.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_bottom, compositor, node);
	ptr->txh_bottom.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_left, compositor, node);
	ptr->txh_left.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_right, compositor, node);
	ptr->txh_right.update_texture_fcnt = UpdateBackgroundTexture;

	gf_node_set_private(node, ptr);
	gf_node_set_callback_function(node, TraverseBackground);

}
コード例 #29
0
ファイル: mpeg4_layer_3d.c プロジェクト: TotoLulu94/gpac
static void TraverseLayer3D(GF_Node *node, void *rs, Bool is_destroy)
{
	Bool prev_layer, changed = 0;
	GF_List *oldb, *oldv, *oldf, *oldn;
	GF_Rect rc;
	u32 cur_lights;
	GF_List *node_list_backup;
	GF_BBox bbox_backup;
	GF_Matrix model_backup;
	GF_Matrix2D mx2d_backup;
	GF_Camera *prev_cam;
	GF_VisualManager *old_visual;
	GF_Matrix2D *transform;
	M_Layer3D *l = (M_Layer3D *)node;
	Layer3DStack *st = (Layer3DStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;
	GF_TraverseState a_tr;
	u32 old_type_3d;

	if (is_destroy) {
		DestroyLayer3D(node);
		return;
	}
	if (st->unsupported) return;

	memcpy(&a_tr, tr_state, sizeof(GF_TraverseState));

	if (gf_node_dirty_get(node)) {

		/*main visual in pixel metrics, use output width*/
		if (tr_state->pixel_metrics && (tr_state->visual->compositor->visual==tr_state->visual)) {
			st->clip.width = INT2FIX(tr_state->visual->compositor->vp_width);
			st->clip.height = INT2FIX(tr_state->visual->compositor->vp_height);
		} else {
			visual_get_size_info(tr_state, &st->clip.width, &st->clip.height);
		}
		/*setup bounds in local coord system*/
		if (l->size.x>=0) st->clip.width = l->size.x;
		if (l->size.y>=0) st->clip.height = l->size.y;
		st->clip = gf_rect_center(st->clip.width, st->clip.height);

		changed = 1;
	}

	transform = &tr_state->transform;

	/*layer3D maintains its own stacks*/
	oldb = tr_state->backgrounds;
	oldv = tr_state->viewpoints;
	oldf = tr_state->fogs;
	oldn = tr_state->navigations;
	old_visual = tr_state->visual;
	prev_layer = tr_state->is_layer;
	prev_cam = tr_state->camera;
	bbox_backup = tr_state->bbox;


	switch (tr_state->traversing_mode) {
	case TRAVERSE_GET_BOUNDS:
		if (!tr_state->for_node) {
			tr_state->bounds = st->clip;
			gf_bbox_from_rect(&tr_state->bbox, &st->clip);
			return;
		}
	case TRAVERSE_PICK:
		/*layers can only be used in a 2D context*/
		if (tr_state->camera && tr_state->camera->is_3D)
			return;
		break;

	case TRAVERSE_SORT:
		/*layers can only be used in a 2D context*/
		if (tr_state->camera && tr_state->camera->is_3D)
			return;

		if (tr_state->visual->compositor->hybrid_opengl) {
			DrawableContext *ctx = drawable_init_context_mpeg4(st->drawable, tr_state);
			if (!ctx) goto l3d_exit;
			ctx->aspect.fill_texture = &st->txh;
			ctx->flags |= CTX_APP_DIRTY | CTX_IS_TRANSPARENT;
			drawable_finalize_sort(ctx, tr_state, &st->clip);
			return;
		}
		break;
	case TRAVERSE_DRAW_2D:
		if (tr_state->visual->compositor->hybrid_opengl) {
			transform = &tr_state->ctx->transform;
			break;
		}
		layer3d_draw_2d(node, tr_state);
		return;
	case TRAVERSE_DRAW_3D:
	default:
		return;
	}

	/*layer3D maintains its own stacks*/
	tr_state->backgrounds = st->visual->back_stack;
	tr_state->viewpoints = st->visual->view_stack;
	tr_state->navigations = st->visual->navigation_stack;
	tr_state->fogs = st->visual->fog_stack;
	tr_state->is_layer = 1;
	tr_state->camera = &st->visual->camera;

	gf_mx_copy(model_backup, tr_state->model_matrix);
	gf_mx2d_copy(mx2d_backup, tr_state->transform);

	/*compute viewport in visual coordinate*/
	rc = st->clip;
	if (prev_cam) {

		gf_mx_apply_rect(&tr_state->model_matrix, &rc);

		if (tr_state->visual->compositor->hybrid_opengl) {
			gf_mx2d_apply_rect(transform, &rc);
		} else {
			gf_mx_apply_rect(&prev_cam->modelview, &rc);
		}

		if (tr_state->camera->flags & CAM_HAS_VIEWPORT)
			gf_mx_apply_rect(&prev_cam->viewport, &rc);

	} else {
		gf_mx2d_apply_rect(&tr_state->transform, &rc);

		/*switch visual*/
		tr_state->visual = st->visual;
	}


	/*check bindables*/
	gf_mx_init(tr_state->model_matrix);
	l3d_CheckBindables(node, tr_state, st->first);

	if (prev_cam) gf_mx_copy(tr_state->model_matrix, model_backup);

	/*drawing a layer means drawing all subelements as a whole (no depth sorting with parents)*/
	if ((tr_state->traversing_mode==TRAVERSE_SORT) || (tr_state->traversing_mode==TRAVERSE_DRAW_2D)) {
		u32 trav_mode = tr_state->traversing_mode;

		if (gf_node_dirty_get(node)) changed = 1;
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY|GF_SG_VRML_BINDABLE_DIRTY);

		/*!! we were in a 2D mode, setup associated texture !!*/
		if (!prev_cam) {
			switch (layer3d_setup_offscreen(node, st, tr_state, rc.width, rc.height)) {
			case 0:
				goto l3d_exit;
			case 2:
				if (!changed && !(st->visual->camera.flags & CAM_IS_DIRTY) && !st->visual->camera.anim_len) {
					GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer3D] No changes found , skipping 3D draw\n"));
					goto layer3d_unchanged_2d;
				}
			default:
				break;
			}
#ifdef GPAC_USE_TINYGL
			if (st->tgl_ctx) ostgl_make_current(st->tgl_ctx, 0);
#endif

			rc = st->vp;
			/*setup GL*/
			visual_3d_setup(tr_state->visual);
		}
		/*note that we don't backup the state as a layer3D cannot be declared in a layer3D*/
		tr_state->layer3d = node;


		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer3D] Redrawing\n"));

		layer3d_setup_clip(st, tr_state, prev_cam ? 1 : 0, rc);

		//this only happens in hybridGL mode
		if (trav_mode==TRAVERSE_DRAW_2D) {
			visual_2d_flush_hybgl_canvas(tr_state->visual, NULL, tr_state->ctx, tr_state);
		}

		old_type_3d = tr_state->visual->type_3d;
		tr_state->visual->type_3d = 2;

		visual_3d_clear_all_lights(tr_state->visual);

		cur_lights = tr_state->visual->num_lights;
		/*this will init projection. Note that we're binding the viewpoint in the current pixelMetrics context
		even if the viewpoint was declared in an inline below
		if no previous camera, we're using offscreen rendering, force clear */
		visual_3d_init_draw(tr_state, prev_cam ? 1 : 2);

		visual_3d_check_collisions(tr_state, NULL, l->children);
		tr_state->traversing_mode = TRAVERSE_SORT;

		/*shortcut node list*/
		node_list_backup = tr_state->visual->alpha_nodes_to_draw;
		tr_state->visual->alpha_nodes_to_draw = gf_list_new();

		/*reset cull flag*/
		tr_state->cull_flag = 0;
		group_3d_traverse(node, (GroupingNode *)st, tr_state);

		visual_3d_flush_contexts(tr_state->visual, tr_state);

		gf_list_del(tr_state->visual->alpha_nodes_to_draw);
		tr_state->visual->alpha_nodes_to_draw = node_list_backup;

		while (cur_lights < tr_state->visual->num_lights) {
			visual_3d_remove_last_light(tr_state->visual);
		}

		tr_state->traversing_mode = trav_mode ;
		tr_state->visual->type_3d = old_type_3d;
		tr_state->layer3d = NULL;

		/*!! we were in a 2D mode, create drawable context!!*/
		if (!prev_cam ) {
			DrawableContext *ctx;
			/*with TinyGL we draw directly to the offscreen buffer*/
#ifndef GPAC_USE_TINYGL
			gf_sc_copy_to_stencil(&st->txh);
#else
			if (st->txh.pixelformat==GF_PIXEL_RGBDS)
				gf_get_tinygl_depth(&st->txh);
#endif

			if (tr_state->visual->compositor->rasterizer->stencil_texture_modified)
				tr_state->visual->compositor->rasterizer->stencil_texture_modified(gf_sc_texture_get_stencil(&st->txh) );
			gf_sc_texture_set_stencil(&st->txh, gf_sc_texture_get_stencil(&st->txh) );
			changed = 1;

layer3d_unchanged_2d:

			/*restore visual*/
			tr_state->visual = old_visual;
			tr_state->appear = NULL;
			//	tr_state->camera = prev_cam;

			ctx = drawable_init_context_mpeg4(st->drawable, tr_state);
			if (!ctx) goto l3d_exit;
			ctx->aspect.fill_texture = &st->txh;
			ctx->flags |= CTX_NO_ANTIALIAS;
			if (changed) ctx->flags |= CTX_APP_DIRTY;
			if (st->txh.transparent) ctx->flags |= CTX_IS_TRANSPARENT;
			drawable_finalize_sort(ctx, tr_state, NULL);
		}
	}
	/*check picking - we must fall in our 2D clipper except when mvt is grabbed on layer*/
	else if (!gf_node_dirty_get(node)  && (tr_state->traversing_mode==TRAVERSE_PICK)) {
		GF_Ray prev_r;
		SFVec3f start, end;
		SFVec4f res;
		Fixed in_x, in_y;
		Bool do_pick = 0;

		if (!prev_cam) rc = st->vp;

		layer3d_setup_clip(st, tr_state, prev_cam ? 1 : 0, rc);

		old_type_3d = tr_state->visual->type_3d;
		tr_state->visual->type_3d = 2;

		if (tr_state->visual->compositor->active_layer==node) {
			do_pick = (tr_state->visual->compositor->grabbed_sensor || tr_state->visual->compositor->navigation_state) ? 1 : 0;
		}

		if (!prev_cam || tr_state->visual->compositor->hybrid_opengl) gf_mx_from_mx2d(&tr_state->model_matrix, &tr_state->transform);

		if (!do_pick && !gf_list_count(tr_state->visual->compositor->sensors))
			do_pick = gf_sc_pick_in_clipper(tr_state, &st->clip);

		if (!do_pick) {
			tr_state->visual->type_3d = old_type_3d;
			goto l3d_exit;
		}

		prev_r = tr_state->ray;

		compositor_get_2d_plane_intersection(&tr_state->ray, &start);

		gf_mx_inverse(&tr_state->model_matrix);
		gf_mx_apply_vec(&tr_state->model_matrix, &start);


		if (tr_state->visual->compositor->visual==tr_state->visual) {
			start.x = gf_mulfix(start.x, tr_state->visual->compositor->scale_x);
			start.y = gf_mulfix(start.y, tr_state->visual->compositor->scale_y);
		} else if (!prev_cam) {
			start.x = gf_muldiv(start.x, st->visual->camera.width, st->clip.width);
			start.y = gf_muldiv(start.y, st->visual->camera.height, st->clip.height);
		}

		visual_3d_setup_projection(tr_state, 1);

		in_x = 2 * gf_divfix(start.x, st->visual->camera.width);
		in_y = 2 * gf_divfix(start.y, st->visual->camera.height);

		res.x = in_x;
		res.y = in_y;
		res.z = -FIX_ONE;
		res.q = FIX_ONE;
		gf_mx_apply_vec_4x4(&st->visual->camera.unprojection, &res);
		if (!res.q) {
			tr_state->visual->type_3d = old_type_3d;
			goto l3d_exit;
		}
		start.x = gf_divfix(res.x, res.q);
		start.y = gf_divfix(res.y, res.q);
		start.z = gf_divfix(res.z, res.q);

		res.x = in_x;
		res.y = in_y;
		res.z = FIX_ONE;
		res.q = FIX_ONE;
		gf_mx_apply_vec_4x4(&st->visual->camera.unprojection, &res);
		if (!res.q) {
			tr_state->visual->type_3d = old_type_3d;
			goto l3d_exit;
		}
		end.x = gf_divfix(res.x, res.q);
		end.y = gf_divfix(res.y, res.q);
		end.z = gf_divfix(res.z, res.q);
		tr_state->ray = gf_ray(start, end);

		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer3D] Picking: cast ray\n\tOrigin %.4f %.4f %.4f - End %.4f %.4f %.4f\n\tDir %.4f %.4f %.4f\n",
		                                      FIX2FLT(tr_state->ray.orig.x), FIX2FLT(tr_state->ray.orig.y), FIX2FLT(tr_state->ray.orig.z),
		                                      FIX2FLT(end.x), FIX2FLT(end.y), FIX2FLT(end.z),
		                                      FIX2FLT(tr_state->ray.dir.x), FIX2FLT(tr_state->ray.dir.y), FIX2FLT(tr_state->ray.dir.z)));

		group_3d_traverse(node, (GroupingNode *)st, tr_state);
		tr_state->ray = prev_r;

		tr_state->visual->type_3d = old_type_3d;

		/*store info if navigation allowed - we just override any layer3D picked first since we are picking 2D
		objects*/
		if (tr_state->camera->navigate_mode || (tr_state->camera->navigation_flags & NAV_ANY))
			tr_state->layer3d = node;

		tr_state->traversing_mode = TRAVERSE_PICK;
	}

l3d_exit:

	/*restore camera*/
	tr_state->camera = prev_cam;
	if (prev_cam) {
		//remember to reload previous projection matrix
		visual_3d_projection_matrix_modified(tr_state->visual);
		if (tr_state->visual == old_visual) {
			visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp);
		}
	}
	tr_state->visual = old_visual;

	/*restore traversing state*/
	tr_state->backgrounds = oldb;
	tr_state->viewpoints = oldv;
	tr_state->fogs = oldf;
	tr_state->navigations = oldn;
	tr_state->bbox = bbox_backup;
	tr_state->is_layer = prev_layer;
	gf_mx_copy(tr_state->model_matrix, model_backup);
	gf_mx2d_copy(tr_state->transform, mx2d_backup);

	/*in case we missed bindables*/
	if (st->first) {
		st->first = 0;
		gf_node_dirty_set(node, 0, 0);
		gf_sc_invalidate(tr_state->visual->compositor, NULL);
	}
}
コード例 #30
0
ファイル: descriptors.c プロジェクト: ezdev128/gpac
GF_EXPORT
GF_HEVCConfig *gf_odf_hevc_cfg_read_bs(GF_BitStream *bs, Bool is_shvc)
{
	u32 i, count;
	GF_HEVCConfig *cfg = gf_odf_hevc_cfg_new();

	cfg->is_shvc = is_shvc;

	cfg->configurationVersion = gf_bs_read_int(bs, 8);

	if (!is_shvc) {
		cfg->profile_space = gf_bs_read_int(bs, 2);
		cfg->tier_flag = gf_bs_read_int(bs, 1);
		cfg->profile_idc = gf_bs_read_int(bs, 5);
		cfg->general_profile_compatibility_flags = gf_bs_read_int(bs, 32);

		cfg->progressive_source_flag = gf_bs_read_int(bs, 1);
		cfg->interlaced_source_flag = gf_bs_read_int(bs, 1);
		cfg->non_packed_constraint_flag = gf_bs_read_int(bs, 1);
		cfg->frame_only_constraint_flag = gf_bs_read_int(bs, 1);
		/*only lowest 44 bits used*/
		cfg->constraint_indicator_flags = gf_bs_read_long_int(bs, 44);
		cfg->level_idc = gf_bs_read_int(bs, 8);
	}

	gf_bs_read_int(bs, 4); //reserved
	cfg->min_spatial_segmentation_idc = gf_bs_read_int(bs, 12);

	gf_bs_read_int(bs, 6);//reserved
	cfg->parallelismType = gf_bs_read_int(bs, 2);

	if (!is_shvc) {
		gf_bs_read_int(bs, 6);
		cfg->chromaFormat = gf_bs_read_int(bs, 2);
		gf_bs_read_int(bs, 5);
		cfg->luma_bit_depth = gf_bs_read_int(bs, 3) + 8;
		gf_bs_read_int(bs, 5);
		cfg->chroma_bit_depth = gf_bs_read_int(bs, 3) + 8;
		cfg->avgFrameRate = gf_bs_read_int(bs, 16);
	}

	if (!is_shvc)
		cfg->constantFrameRate = gf_bs_read_int(bs, 2);
	else
		gf_bs_read_int(bs, 2); //reserved

	cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
	cfg->temporalIdNested = gf_bs_read_int(bs, 1);

	cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);

	count = gf_bs_read_int(bs, 8);
	for (i=0; i<count; i++) {
		u32 nalucount, j;
		GF_HEVCParamArray *ar;
		GF_SAFEALLOC(ar, GF_HEVCParamArray);
		if (!ar) {
			gf_odf_hevc_cfg_del(cfg);
			return NULL;
		}
		ar->nalus = gf_list_new();
		gf_list_add(cfg->param_array, ar);

		ar->array_completeness = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 1);
		ar->type = gf_bs_read_int(bs, 6);
		nalucount = gf_bs_read_int(bs, 16);
		for (j=0; j<nalucount; j++) {
			GF_AVCConfigSlot *sl;
			GF_SAFEALLOC(sl, GF_AVCConfigSlot );
			if (!sl) {
				gf_odf_hevc_cfg_del(cfg);
				return NULL;
			}

			sl->size = gf_bs_read_int(bs, 16);

			sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
			gf_bs_read_data(bs, sl->data, sl->size);
			gf_list_add(ar->nalus, sl);
		}
	}
	return cfg;
}