Example #1
0
/*access to the first available CU for rendering
this is a blocking call since input may change the output (temporal scalability)*/
GF_CMUnit *gf_cm_get_output(GF_CompositionMemory *cb)
{
	GF_CMUnit *out = NULL;

	/*if paused or stop or buffering, do nothing*/
	switch (cb->Status) {
	case CB_BUFFER:
		return NULL;
	case CB_STOP:
	case CB_PAUSE:
		/*only visual buffers deliver data when paused*/
		if (cb->odm->codec->type != GF_STREAM_VISUAL) goto exit;
		break;
	case CB_BUFFER_DONE:
		cb->Status = CB_PLAY;
		break;
	}

	/*no output*/
	if (!cb->output->dataLength) {
		if ((cb->Status != CB_STOP) && cb->HasSeenEOS && (cb->odm && cb->odm->codec)) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Switching composition memory to stop state - time %d\n", cb->odm->OD->objectDescriptorID, (u32) cb->odm->media_stop_time));

			cb->Status = CB_STOP;
			cb->odm->current_time = (u32) cb->odm->media_stop_time;
#ifndef GPAC_DISABLE_VRML
			/*force update of media time*/
			mediasensor_update_timing(cb->odm, 1);
#endif
		}
		goto exit;
	}

	/*update the timing*/
	if ((cb->Status != CB_STOP) && cb->odm && cb->odm->codec) {
		cb->odm->current_time = cb->output->TS;

		/*handle visual object - EOS if no more data (we keep the last CU for rendering, so check next one)*/
		if (cb->HasSeenEOS && (!cb->output->next->dataLength || (cb->Capacity==1))) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Switching composition memory to stop state - time %d\n", cb->odm->OD->objectDescriptorID, (u32) cb->odm->media_stop_time));
			cb->Status = CB_STOP;
			cb->odm->current_time = (u32) cb->odm->media_stop_time;
#ifndef GPAC_DISABLE_VRML
			/*force update of media time*/
			mediasensor_update_timing(cb->odm, 1);
#endif
			gf_odm_signal_eos(cb->odm);
		}
	}
	out = cb->output;

	//assert(out->TS >= cb->LastRenderedTS);

exit:
	return out;
}
Example #2
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);
}
Example #3
0
/*access to the first available CU for rendering
this is a blocking call since input may change the output (temporal scalability)*/
GF_CMUnit *gf_cm_get_output(GF_CompositionMemory *cb)
{
	/*if paused or stop or buffering, do nothing*/
	switch (cb->Status) {
	case CB_BUFFER:
	case CB_STOP:
		/*only visual buffers deliver data when buffering or stop*/
		if (cb->odm->codec->type != GF_STREAM_VISUAL) return NULL;
		break;
	case CB_BUFFER_DONE:
		//For non-visual output move to play state upon fetch
		if (cb->odm->codec->type != GF_STREAM_VISUAL)
			cb->Status = CB_PLAY;
		break;
	//we always deliver in pause, up to the caller to decide to consume or not the frame
	case CB_PAUSE:
		break;
	}

	/*no output*/
	if (!cb->UnitCount || !cb->output->dataLength) {
		if ((cb->Status != CB_STOP) && cb->HasSeenEOS && (cb->odm && cb->odm->codec)) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Switching composition memory to stop state - time %d\n", cb->odm->OD->objectDescriptorID, (u32) cb->odm->media_stop_time));

			if ((cb->Status==CB_BUFFER_DONE) && (cb->odm->codec->type == GF_STREAM_VISUAL) ){
				gf_clock_buffer_off(cb->odm->codec->ck);
			}
			cb->Status = CB_STOP;
			cb->odm->media_current_time = (u32) cb->odm->media_stop_time;
#ifndef GPAC_DISABLE_VRML
			/*force update of media time*/
			mediasensor_update_timing(cb->odm, 1);
#endif
			gf_odm_signal_eos(cb->odm);
		}
		return NULL;
	}

	/*update the timing*/
	if ((cb->Status != CB_STOP) && cb->odm && cb->odm->codec) {
		if (cb->odm->codec->ck->has_media_time_shift) {
			cb->odm->media_current_time = cb->output->TS + cb->odm->codec->ck->media_time_at_init - cb->odm->codec->ck->init_time;
		} else {
			cb->odm->media_current_time = cb->output->TS;
		}

		/*handle visual object - EOS if no more data (we keep the last CU for rendering, so check next one)*/
		if (cb->HasSeenEOS && (cb->odm->codec->type == GF_STREAM_VISUAL) && (!cb->output->next->dataLength || (cb->Capacity==1))) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] Switching composition memory to stop state - time %d\n", cb->odm->OD->objectDescriptorID, (u32) cb->odm->media_stop_time));
			if (cb->Status==CB_BUFFER_DONE) {
				gf_clock_buffer_off(cb->odm->codec->ck);
			}
			cb->Status = CB_STOP;
			cb->odm->media_current_time = (u32) cb->odm->media_stop_time;
#ifndef GPAC_DISABLE_VRML
			/*force update of media time*/
			mediasensor_update_timing(cb->odm, 1);
#endif
			gf_odm_signal_eos(cb->odm);
		}
	}
	if (cb->output->sender_ntp) {
		cb->LastRenderedNTPDiff = gf_net_get_ntp_diff_ms(cb->output->sender_ntp);
		cb->LastRenderedNTP = cb->output->sender_ntp;
	}

	return cb->output;
}