Exemplo n.º 1
0
Arquivo: odf_dec.c Projeto: erelh/gpac
static void ODS_SetupOD(GF_Scene *scene, GF_ObjectDescriptor *od)
{
    GF_ObjectManager *odm;
    odm = gf_scene_find_odm(scene, od->objectDescriptorID);
    /*remove the old OD*/
    if (odm) gf_odm_disconnect(odm, 1);
    odm = gf_odm_new();
    odm->OD = od;
    odm->term = scene->root_od->term;
    odm->parentscene = scene;
    gf_list_add(scene->resources, odm);

    /*locate service owner*/
    gf_odm_setup_object(odm, scene->root_od->net_service);
}
Exemplo n.º 2
0
static void ODS_SetupOD(GF_InlineScene *is, GF_ObjectDescriptor *od)
{
	GF_ObjectManager *odm;
	odm = gf_is_find_odm(is, od->objectDescriptorID);
	/*remove the old OD*/
	if (odm) gf_odm_disconnect(odm, 1);
	odm = gf_odm_new();
	odm->OD = od;
	odm->term = is->root_od->term;
	odm->parentscene = is;
	gf_list_add(is->ODlist, odm);

	/*locate service owner*/
	gf_odm_setup_object(odm, is->root_od->net_service);
}
Exemplo n.º 3
0
static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_check)
{
	u32 i, min_od_id;
	GF_MediaObject *the_mo;
	GF_Scene *scene;
	GF_ObjectManager *odm, *root;
	GF_ObjectDescriptor *od;
	GET_TERM();

	root = service->owner;
	if (!root) {
	  GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Service %s] has not root, aborting !\n", service->url));
	  return;
	}
	if (root->flags & GF_ODM_DESTROYED) {
	  GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Service %s] root has been scheduled for destruction - aborting !\n", service->url));
	  return;
	}
	scene = root->subscene ? root->subscene : root->parentscene;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Service %s] %s\n", service->url, media_desc ? "Adding new media object" : "Regenerating scene graph"));
	if (!media_desc) {
		if (!no_scene_check) gf_scene_regenerate(scene);
		return;
	}

	switch (media_desc->tag) {
	case GF_ODF_OD_TAG:
	case GF_ODF_IOD_TAG:
		if (root && (root->net_service == service)) {
			od = (GF_ObjectDescriptor *) media_desc;
			break;
		}
	default:
		gf_odf_desc_del(media_desc);
		return;
	}

	gf_term_lock_net(term, 1);
	/*object declared this way are not part of an OD stream and are considered as dynamic*/
/*	od->objectDescriptorID = GF_MEDIA_EXTERNAL_ID; */

	/*check if we have a mediaObject in the scene not attached and matching this object*/
	the_mo = NULL;
	odm = NULL;
	min_od_id = 0;
	for (i=0; i<gf_list_count(scene->scene_objects); i++) {
		char *frag, *ext;
		GF_ESD *esd;
		char *url;
		u32 match_esid = 0;
		GF_MediaObject *mo = gf_list_get(scene->scene_objects, i);

		if ((mo->OD_ID != GF_MEDIA_EXTERNAL_ID) && (min_od_id<mo->OD_ID))
			min_od_id = mo->OD_ID;

		if (!mo->odm) continue;
		/*if object is attached to a service, don't bother looking in a different one*/
		if (mo->odm->net_service && (mo->odm->net_service != service)) continue;

		/*already assigned object - this may happen since the compositor has no control on when objects are declared by the service,
		therefore opening file#video and file#audio may result in the objects being declared twice if the service doesn't
		keep track of declared objects*/
		if (mo->odm->OD) {
			if (od->objectDescriptorID && is_same_od(mo->odm->OD, od)) {
				/*reassign OD ID*/
				mo->OD_ID = od->objectDescriptorID;
				gf_odf_desc_del(media_desc);
				gf_term_lock_net(term, 0);
				return;
			}
			continue;
		}
		if (mo->OD_ID != GF_MEDIA_EXTERNAL_ID) {
			if (mo->OD_ID == od->objectDescriptorID) {
				the_mo = mo;
				odm = mo->odm;
				break;
			}
			continue;
		}
		if (!mo->URLs.count || !mo->URLs.vals[0].url) continue;

		frag = NULL;
		ext = strrchr(mo->URLs.vals[0].url, '#');
		if (ext) {
			frag = strchr(ext, '=');
			ext[0] = 0;
		}
		url = mo->URLs.vals[0].url;
		if (!strnicmp(url, "file://localhost", 16)) url += 16;
		else if (!strnicmp(url, "file://", 7)) url += 7;
		else if (!strnicmp(url, "gpac://", 7)) url += 7;
		else if (!strnicmp(url, "pid://", 6)) match_esid = atoi(url+6);

		if (!match_esid && !strstr(service->url, url)) {
			if (ext) ext[0] = '#';
			continue;
		}
		if (ext) ext[0] = '#';

		esd = gf_list_get(od->ESDescriptors, 0);
		if (match_esid && (esd->ESID != match_esid))
			continue;
		/*match type*/
		switch (esd->decoderConfig->streamType) {
		case GF_STREAM_VISUAL:
			if (mo->type != GF_MEDIA_OBJECT_VIDEO) continue;
			break;
		case GF_STREAM_AUDIO:
			if (mo->type != GF_MEDIA_OBJECT_AUDIO) continue;
			break;
		case GF_STREAM_PRIVATE_MEDIA:
			if ((mo->type != GF_MEDIA_OBJECT_AUDIO) && (mo->type != GF_MEDIA_OBJECT_VIDEO)) continue;
			break;
		case GF_STREAM_SCENE:
			if (mo->type != GF_MEDIA_OBJECT_UPDATES) continue;
			break;
		default:
			continue;
		}
		if (frag) {
			u32 frag_id = 0;
			u32 ID = od->objectDescriptorID;
			if (ID==GF_MEDIA_EXTERNAL_ID) ID = esd->ESID;
			frag++;
			frag_id = atoi(frag);
			if (ID!=frag_id) continue;
		}
		the_mo = mo;
		odm = mo->odm;
		break;
	}

	/*add a pass on scene->resource to check for min_od_id,
	otherwise we may have another modules declaring an object with ID 0 from
	another thread, which will assert (only one object with a givne OD ID)*/
	for (i=0; i<gf_list_count(scene->resources); i++) {
		GF_ObjectManager *an_odm = gf_list_get(scene->resources, i);

		if (an_odm->OD && (an_odm->OD->objectDescriptorID != GF_MEDIA_EXTERNAL_ID) && (min_od_id < an_odm->OD->objectDescriptorID))
			min_od_id = an_odm->OD->objectDescriptorID;
	}

	if (!odm) {
		odm = gf_odm_new();
		odm->term = term;
		odm->parentscene = scene;
		gf_list_add(scene->resources, odm);
	}
	odm->OD = od;
	odm->mo = the_mo;
	odm->flags |= GF_ODM_NOT_IN_OD_STREAM;
	if (!od->objectDescriptorID) {
		od->objectDescriptorID = min_od_id + 1;
	}

	if (the_mo) the_mo->OD_ID = od->objectDescriptorID;
	if (!scene->selected_service_id)
		scene->selected_service_id = od->ServiceID;


	/*net is unlocked before seting up the object as this might trigger events going into JS and deadlocks
	with the compositor*/
	gf_term_lock_net(term, 0);

	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] setup object - MO %08x\n", odm->OD->objectDescriptorID, odm->mo));
	gf_odm_setup_object(odm, service);

	/*OD inserted by service: resetup scene*/
	if (!no_scene_check && scene->is_dynamic_scene) gf_scene_regenerate(scene);
}