Exemple #1
0
void MC_Modified(GF_Node *node)
{
	MediaControlStack *stack =(MediaControlStack *) gf_node_get_private(node);
	if (!stack) return;
	if (stack->changed!=2) {
		/*check URL*/
		if (MC_URLChanged(&stack->url, &stack->control->url))
			stack->changed = 2;
		/*check speed (play/pause)*/
		else if (stack->media_speed != stack->control->mediaSpeed)
			stack->changed = 1;
		/*check mediaStartTime (seek)*/
		else if (stack->media_start != stack->control->mediaStartTime) {
			/*do not reevaluate if mediaStartTime is reset to -1 (current time)*/
			if (stack->control->mediaStartTime!=-1.0)
				stack->changed = 2;
			/*check mediaStopTime <0 (timeshift buffer control)*/
		} else if (stack->media_stop != stack->control->mediaStopTime) {
			if (stack->control->mediaStopTime<=0)
				stack->changed = 2;
		}
//		else stack->changed = 1;
	}

	gf_node_dirty_set( gf_sg_get_root_node(gf_node_get_graph(node)), 0, 1);
	/*invalidate scene, we recompute MC state in render*/
	gf_term_invalidate_compositor(stack->parent->root_od->term);
}
Exemple #2
0
static void gf_inline_check_restart(GF_Scene *scene)
{
	/*no ctrl if no duration*/
	if (!scene->duration) return;
	if (!scene->needs_restart) gf_odm_check_segment_switch(scene->root_od);
	if (scene->needs_restart) return;

	if (scene->root_od->media_ctrl && scene->root_od->media_ctrl->control->loop) {
		GF_Clock *ck = gf_odm_get_media_clock(scene->root_od);
		if (ck->has_seen_eos) {
			u32 now = gf_clock_time(ck);
			u64 dur = scene->duration;
			if (scene->root_od->media_ctrl->current_seg) {
				/*only process when all segments are played*/
				if (gf_list_count(scene->root_od->media_ctrl->seg) <= scene->root_od->media_ctrl->current_seg) {
					scene->needs_restart = 1;
					scene->root_od->media_ctrl->current_seg = 0;
				}
			}
			else {
				Double s, e;
				s = now;
				s/=1000;
				e = -1;
				MC_GetRange(scene->root_od->media_ctrl, &s, &e);
				if ((e>=0) && (e<GF_MAX_FLOAT)) dur = (u32) (e*1000);
				if (dur<=now) {
					scene->needs_restart = 1;
					scene->root_od->media_ctrl->current_seg = 0;
				} else {
					/*trigger render until to watch for restart...*/
					gf_term_invalidate_compositor(scene->root_od->term);
				}
			}
		} else {
			/*trigger render until to watch for restart...*/
			gf_term_invalidate_compositor(scene->root_od->term);
		}
	}
}
Exemple #3
0
void gf_cm_unlock_input(GF_CompositionMemory *cb, GF_CMUnit *cu, u32 cu_size, Bool codec_reordering)
{
	/*nothing dispatched, ignore*/
	if (!cu_size || (!cu->data && !cu->frame && !cb->pY) ) {
		if (cu->frame) {
			cu->frame->Release(cu->frame);
			cu->frame = NULL;
		}
		cu->dataLength = 0;
		cu->TS = 0;
		return;
	}
	gf_odm_lock(cb->odm, 1);
//		assert(cu->frame);

	if (codec_reordering) {
		cb->input = cb->input->next;
	} else {
		cu = gf_cm_reorder_unit(cb, cu, codec_reordering);
		assert(cu);
	}

	if (cu) {
		/*FIXME - if the CU already has data, this is spatial scalability so same num buffers*/
		if (!cu->dataLength) cb->UnitCount += 1;
		cu->dataLength = cu_size;
		cu->RenderedLength = 0;

		/*turn off buffering for audio - this must be done now rather than when fetching first output frame since we're not
		sure output is fetched (Switch node, ...)*/
		if ( (cb->Status == CB_BUFFER) && (cb->UnitCount >= cb->Capacity) ) {
			/*done with buffering*/
			cb->Status = CB_BUFFER_DONE;
			
			//for audio, turn off buffering now. For video, we will wait for the first frame to be drawn
			if (cb->odm->codec->type == GF_STREAM_AUDIO)
				cb_set_buffer_off(cb);
		}

		//new FPS regulation doesn't need this signaling
#if 0
		/*since a new CU is here notify the compositor*/
		if ((cb->odm->codec->type==GF_STREAM_VISUAL) && cb->odm->mo && cb->odm->mo->num_open) {
			gf_term_invalidate_compositor(cb->odm->term);
		}
#endif
	}
	gf_odm_lock(cb->odm, 0);
}
Exemple #4
0
/*render : setup media sensor and update timing in case of inline scenes*/
void RenderMediaSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_Clock *ck;
	MediaSensorStack *st = (MediaSensorStack *)gf_node_get_private(node);

	if (is_destroy) {
		/*unlink from OD*/
		if (st->stream && st->stream->odm) 
			gf_list_del_item(st->stream->odm->ms_stack, st);

		gf_list_del(st->seg);
		gf_free(st);
		return;
	}

	if (!st->stream) st->stream = gf_mo_register(node, &st->sensor->url, 0, 0);
	if (!st->stream || !st->stream->odm) return;

	if (!st->is_init) {
		gf_list_add(st->stream->odm->ms_stack, st);
		gf_odm_init_segments(st->stream->odm, st->seg, &st->sensor->url);
		st->is_init = 1;
		st->active_seg = 0;
		
	}
	/*media sensor bound to natural media (audio, video) is updated when fetching the stream
	data for rendering.*/

	ck = NULL;
	/*check inline scenes - if the scene is set to restart DON'T MODIFY SENSOR: since we need a 2 render
	passes to restart inline, scene is considered as not running*/
	if (st->stream->odm->subscene && !st->stream->odm->subscene->needs_restart) {
		if (st->stream->odm->subscene->scene_codec) ck = st->stream->odm->subscene->scene_codec->ck;
		/*dynamic scene*/
		else ck = st->stream->odm->subscene->dyn_ck;
		/*since audio may be used alone through an inline scene, we need to refresh the graph*/
		if (ck && !ck->has_seen_eos && st->stream->odm->state) gf_term_invalidate_compositor(st->stream->odm->term);
	}
	/*check anim streams*/
	else if (st->stream->odm->codec && (st->stream->odm->codec->type==GF_STREAM_SCENE)) ck = st->stream->odm->codec->ck;
	/*check OCR streams*/
	else if (st->stream->odm->ocr_codec) ck = st->stream->odm->ocr_codec->ck;

	if (ck && gf_clock_is_started(ck) ) {
		st->stream->odm->current_time = gf_clock_time(ck);
		mediasensor_update_timing(st->stream->odm, 0);
	}
}
Exemple #5
0
void gf_cm_set_eos(GF_CompositionMemory *cb)
{
	gf_odm_lock(cb->odm, 1);
	/*we may have a pb if the stream is so short that the EOS is signaled 
	while we're buffering. In this case we shall turn the clock on and 
	keep a trace of the EOS notif*/
	if (cb->Status == CB_BUFFER) {
		cb->Status = CB_BUFFER_DONE;
		gf_clock_buffer_off(cb->odm->codec->ck);
		cb->odm->codec->ck->data_timeout = 0;
		GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ODM%d: buffering off at %d (nb buffering on clock: %d)\n", cb->odm->OD->objectDescriptorID, gf_term_get_time(cb->odm->term), cb->odm->codec->ck->Buffering));
	}
	cb->HasSeenEOS = 1;
	gf_term_invalidate_compositor(cb->odm->term);
	gf_odm_lock(cb->odm, 0);
}
Exemple #6
0
void gf_cm_unlock_input(GF_CompositionMemory *cb, GF_CMUnit *cu, u32 cu_size, Bool codec_reordering)
{
	/*nothing dispatched, ignore*/
	if (!cu_size) {
		cu->dataLength = 0;
		cu->TS = 0;
		return;
	}
	gf_odm_lock(cb->odm, 1);

	if (cu->TS < cb->input->TS)
		cu = cu;


	if (codec_reordering) {
		cb->input = cb->input->next;
	} else {
		cu = gf_cm_reorder_unit(cb, cu, codec_reordering);
		assert(cu);
	}

	if (cu) {
		/*FIXME - if the CU already has data, this is spatial scalability so same num buffers*/
		if (!cu->dataLength) cb->UnitCount += 1;
		cu->dataLength = cu_size;
		cu->RenderedLength = 0;

		/*turn off buffering - this must be done now rather than when fetching first output frame since we're not 
		sure output is fetched (Switch node, ...)*/
		if ( (cb->Status == CB_BUFFER) && (cb->UnitCount >= cb->Capacity) ) {
			/*done with buffering, signal to the clock (ONLY ONCE !)*/
			cb->Status = CB_BUFFER_DONE;
			gf_clock_buffer_off(cb->odm->codec->ck);
			cb->odm->codec->ck->data_timeout = 0;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ODM%d: buffering off at %d (nb buffering on clock: %d)\n", cb->odm->OD->objectDescriptorID, gf_term_get_time(cb->odm->term), cb->odm->codec->ck->Buffering));

			gf_term_service_media_event(cb->odm->parentscene->root_od, GF_EVENT_MEDIA_CANPLAY);
		} 

		/*since a new CU is here notify the compositor*/
		if ((cb->odm->codec->type==GF_STREAM_VISUAL) && cb->odm->mo && cb->odm->mo->num_open) {
			gf_term_invalidate_compositor(cb->odm->term);
		}
	}
	gf_odm_lock(cb->odm, 0);
}
Exemple #7
0
static Bool gf_inline_set_scene(M_Inline *root)
{
	GF_MediaObject *mo;
	GF_Scene *parent;
	GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root);
	parent = (GF_Scene *)gf_sg_get_private(graph);
	if (!parent) return 0;

	mo = gf_scene_get_media_object_ex(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0, NULL, 0, (GF_Node*)root);
	if (!mo || !mo->odm) return 0;

	if (!mo->odm->subscene) {
		gf_term_invalidate_compositor(parent->root_od->term);
		return 0;
	}
	/*assign inline scene as private stack of inline node, and remember inline node for event propagation*/
	gf_node_set_private((GF_Node *)root, mo->odm->subscene);
	/*play*/
	gf_mo_play(mo, 0, -1, 0);
	return 1;
}
Exemple #8
0
/*only URL can be changed, so reset and get new URL*/
void MS_Modified(GF_Node *node)
{
	MediaSensorStack *st = (MediaSensorStack *)gf_node_get_private(node);
	if (!st) return;
	
	while (gf_list_count(st->seg)) gf_list_rem(st->seg, 0);

	if (st->stream) {
		/*unlink from OD*/
		if (st->stream->odm && st->stream->odm->ms_stack) 
			gf_list_del_item(st->stream->odm->ms_stack, st);

		gf_mo_unregister(node, st->stream);
		if (st->sensor->isActive) {
			st->sensor->isActive = 0;
			gf_node_event_out((GF_Node *) st->sensor, 4/*"isActive"*/);
		}
	}
	st->stream = NULL;
	st->is_init = 0;
	gf_term_invalidate_compositor(st->parent->root_od->term);
}
Exemple #9
0
void gf_cm_set_eos(GF_CompositionMemory *cb)
{
	gf_odm_lock(cb->odm, 1);
	/*we may have a pb if the stream is so short that the EOS is signaled
	while we're buffering. In this case we shall turn the clock on and
	keep a trace of the EOS notif*/
	if (cb->Status == CB_BUFFER) {
		cb->Status = CB_BUFFER_DONE;
		gf_clock_buffer_off(cb->odm->codec->ck);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] CB EOS - ODM%d: buffering off at OTB %u (STB %d) (nb wait on clock: %d)\n", cb->odm->OD->objectDescriptorID, gf_clock_time(cb->odm->codec->ck), gf_term_get_time(cb->odm->term), cb->odm->codec->ck->Buffering));
	}
	cb->HasSeenEOS = 1;

	//in bench mode eos cannot be signaled through flush of composition memory since it is always empty - do it here
	if (cb->odm->term->bench_mode==2) {
		cb->Status = CB_STOP;
		gf_odm_signal_eos(cb->odm);
	}

	gf_term_invalidate_compositor(cb->odm->term);
	gf_odm_lock(cb->odm, 0);
}
Exemple #10
0
void gf_inline_restart(GF_Scene *scene)
{
	scene->needs_restart = 1;
	gf_term_invalidate_compositor(scene->root_od->term);
}
Exemple #11
0
void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy)
{
	Bool shall_restart, need_restart;
	GF_MediaObject *prev;
	GF_ObjectManager *odm;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	MediaControlStack *stack =(MediaControlStack *) gf_node_get_private(node);

	if (is_destroy) {
		GF_ObjectManager *odm;
		MediaControlStack *stack = (MediaControlStack *) gf_node_get_private(node);

		/*reset ODM using this control*/
		if (stack->stream) {
			if (stack->stream->odm) {
				odm = stack->stream->odm;
				gf_odm_remove_mediacontrol(odm, stack);
			}
			/*also removes the association ck<->MC if the object has been destroyed before the node*/
			if (stack->ck) stack->ck->mc = NULL;
		}
		gf_list_del(stack->seg);
		gf_sg_vrml_mf_reset(&stack->url, GF_SG_VRML_MFURL);
		gf_free(stack);
		return;
	}
	//we need to disable culling otherwise we may never be called back again ...
	tr_state->disable_cull = 1;

	/*not changed nothing to do - note we need to register with stream yet for control switching...*/
	if (stack->stream && (!stack->changed || !stack->control->enabled)) return;

	need_restart = (stack->changed==2) ? 1 : 0;
	shall_restart = (stack->control->mediaStartTime>=0) ? 1 : 0;

	/*check url target*/
	if (stack->stream) {
		if (MC_URLChanged(&stack->url, &stack->control->url)) {
			gf_sg_vrml_mf_reset(&stack->url, GF_SG_VRML_MFURL);

			prev = stack->stream;
			if (gf_list_find(stack->parent->scene_objects, prev)<0)
				prev = NULL;

			stack->stream = gf_scene_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0);
			if (stack->stream) {
				if (!stack->stream->odm) return;
				/*MediaControl on inline: if dynamic scene, make sure it is connected before attaching...*/
				if (stack->stream->odm->subscene) {
					if (stack->stream->odm->subscene->is_dynamic_scene && !stack->stream->odm->subscene->dyn_ck) return;
				}
				gf_sg_vrml_field_copy(&stack->url, &stack->control->url, GF_SG_VRML_MFURL);

				/*remove from prev*/
				if (prev && prev->odm && (prev != stack->stream)) gf_odm_remove_mediacontrol(prev->odm, stack);
				/*register with new*/
				/*if we assigned the media control to an exiting object - force the state of the object*/
				gf_odm_set_mediacontrol((GF_ObjectManager *) stack->stream->odm, stack);

				while (gf_list_count(stack->seg)) gf_list_rem(stack->seg, 0);
				gf_odm_init_segments((GF_ObjectManager *) stack->stream->odm, stack->seg, &stack->control->url);

				stack->current_seg = 0;
				//do not restart if no mediaStartTime and speed is 1
				if ((stack->control->mediaStartTime>0) || gf_list_count(stack->seg) || (stack->control->mediaSpeed != FIX_ONE) ) {
					shall_restart = need_restart = 1;
				} else {
					shall_restart = need_restart = 0;
					//URL changed, we are by default in PLAY mode.
					stack->media_speed = 1;
				}

				stack->ck = gf_odm_get_media_clock(stack->stream->odm);
			}
			/*control has been removed and we were paused, resume*/
			else if (stack->paused) {
				mediacontrol_resume((GF_ObjectManager *) prev->odm, 0);
				stack->paused = 0;
			}
			/*MediaControl has been detached*/
			else {
				if (prev)
					gf_odm_remove_mediacontrol(prev->odm, stack);
				return;
			}
		}
	} else {
		stack->stream = gf_scene_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0);
		if (!stack->stream || !stack->stream->odm) {
			if (stack->control->url.count) gf_term_invalidate_compositor(stack->parent->root_od->term);
			stack->stream = NULL;
			stack->changed = 0;
			return;
		}
		stack->ck = gf_odm_get_media_clock(stack->stream->odm);
		/*OD not ready yet*/
		if (!stack->ck) {
			stack->stream = NULL;
			if (stack->control->url.count) {
				stack->is_init = 0;
				gf_term_invalidate_compositor(stack->parent->root_od->term);
			}
			return;
		}
		gf_sg_vrml_field_copy(&stack->url, &stack->control->url, GF_SG_VRML_MFURL);
		gf_odm_set_mediacontrol((GF_ObjectManager *) stack->stream->odm, stack);

		while (gf_list_count(stack->seg)) gf_list_rem(stack->seg, 0);
		gf_odm_init_segments((GF_ObjectManager *) stack->stream->odm, stack->seg, &stack->control->url);
		stack->current_seg = 0;

		/*we shouldn't have to restart unless start/stop times have been changed, which is tested below*/
		need_restart = 0;
	}

	if (!stack->changed || !stack->control->enabled || !stack->stream) return;


	/*if not previously enabled and now enabled, switch all other controls off and reactivate*/
	if (!stack->enabled) {
		stack->enabled = 1;
		need_restart = gf_odm_switch_mediacontrol(stack->stream->odm, stack);
	}

	stack->changed = 0;

	if (!stack->control->mediaSpeed) shall_restart = 0;

	odm = (GF_ObjectManager *)stack->stream->odm;

	/*check for changes*/
	if (!stack->is_init) {
		/*not linked yet*/
		if (!odm) return;
		stack->media_speed = stack->control->mediaSpeed;
		stack->enabled = stack->control->enabled;
		stack->media_start = stack->control->mediaStartTime;
		stack->media_stop = stack->control->mediaStopTime;
		stack->is_init = 1;
		stack->paused = 0;
		/*the object has already been started, and media start time is not 0, restart*/
		if (stack->stream->num_open) {
			if ( (stack->media_start > 0) || (gf_list_count(stack->seg)>0 )  || (stack->media_speed!=FIX_ONE ) ) {
				mediacontrol_restart(odm);
			} else if (stack->media_speed == 0) {
				mediacontrol_pause(odm);
				stack->paused = 1;
			}
		}
		return;
	}

	if (stack->media_speed != stack->control->mediaSpeed) {
		/*if no speed pause*/
		if (!stack->control->mediaSpeed && !stack->paused) {
			mediacontrol_pause(odm);
			stack->paused = 1;
		}
		/*else resume if paused*/
		else if (stack->control->mediaSpeed && stack->paused) {
			mediacontrol_resume(odm, 0);
			stack->paused = 0;
			need_restart += shall_restart;
		}
		/*else set speed*/
		else if (stack->media_speed && stack->control->mediaSpeed) {
			/*don't set speed if we have to restart the media ...*/
			if (!shall_restart) MC_SetSpeed(odm, stack->control->mediaSpeed);
			need_restart += shall_restart;
		}
		/*init state was paused*/
		else if (!stack->media_speed) {
			need_restart ++;
		}
		stack->media_speed = stack->control->mediaSpeed;
	}
	/*check start/stop changes*/
	if (stack->media_start != stack->control->mediaStartTime) {
		stack->media_start = stack->control->mediaStartTime;
		need_restart += shall_restart;
	}
	/*stop change triggers restart no matter what (new range) if playing*/
	if (stack->media_stop != stack->control->mediaStopTime) {
		stack->media_stop = stack->control->mediaStopTime;
		if (stack->control->mediaSpeed) need_restart = 1;
	}

	if (need_restart) {
		mediacontrol_restart(odm);
	}

	/*handle preroll*/

}