Esempio n. 1
0
/*NOTE: when starting/stoping a decoder we only lock the decoder mutex, NOT the media manager. This
avoids deadlocking in case a system codec waits for the scene graph and the compositor requests
a stop/start on a media*/
void gf_term_start_codec(GF_Codec *codec, Bool is_resume)
{
	GF_CodecCapability cap;
	CodecEntry *ce;
	GF_Terminal *term = codec->odm->term;
	if (!gf_list_count(codec->odm->channels)) return;
	ce = mm_get_codec(term->codecs, codec);
	if (!ce) return;

	/*lock dec*/
	if (ce->mx) gf_mx_p(ce->mx);

	/*clean decoder memory and wait for RAP*/
	if (codec->CB) gf_cm_reset(codec->CB);

	if (!is_resume) {
		cap.CapCode = GF_CODEC_WAIT_RAP;
		gf_codec_set_capability(codec, cap);

		if (codec->decio && (codec->decio->InterfaceType == GF_SCENE_DECODER_INTERFACE)) {
			cap.CapCode = GF_CODEC_SHOW_SCENE;
			cap.cap.valueInt = 1;
			gf_codec_set_capability(codec, cap);
		}
	}

	gf_codec_set_status(codec, GF_ESM_CODEC_PLAY);

	if (!(ce->flags & GF_MM_CE_RUNNING)) {
		ce->flags |= GF_MM_CE_RUNNING;
		if (ce->thread) {
			gf_th_run(ce->thread, RunSingleDec, ce);
			gf_th_set_priority(ce->thread, term->priority);
		} else {
			term->cumulated_priority += ce->dec->Priority+1;
		}
	}


	/*unlock dec*/
	if (ce->mx)
		gf_mx_v(ce->mx);
}
Esempio n. 2
0
void gf_term_stop_codec(GF_Codec *codec, Bool is_pause)
{
	GF_CodecCapability cap;
	Bool locked = 0;
	CodecEntry *ce;
	GF_Terminal *term = codec->odm->term;
	ce = mm_get_codec(term->codecs, codec);
	if (!ce) return;

	if (ce->mx) gf_mx_p(ce->mx);
	/*We must make sure:
		1- media codecs are synchrounously stop otherwise we could destroy the composition memory while
	the codec writes to it
		2- prevent deadlock for other codecs waiting for the scene graph
	*/
	else if (codec->CB) {
		locked = 1;
		gf_mx_p(term->mm_mx);
	} else {
		locked = gf_mx_try_lock(term->mm_mx);
	}

	if (!is_pause) {
		cap.CapCode = GF_CODEC_ABORT;
		cap.cap.valueInt = 0;
		gf_codec_set_capability(codec, cap);

		if (codec->decio && codec->odm->mo && (codec->odm->mo->flags & GF_MO_DISPLAY_REMOVE) ) {
			cap.CapCode = GF_CODEC_SHOW_SCENE;
			cap.cap.valueInt = 0;
			gf_codec_set_capability(codec, cap);
			codec->odm->mo->flags &= ~GF_MO_DISPLAY_REMOVE;
		}
	}

	/*for audio codec force CB to stop state to discard any pending AU. Not doing so would lead to a wrong estimation of the clock drift
	when resuming the object*/
	if (codec->type==GF_STREAM_AUDIO) {
		gf_codec_set_status(codec, GF_ESM_CODEC_STOP);
	}
	//if video is in a dynamic scene, reset the CB if user stop (eg codec was not in EOS). Otherwise (bifs,svg) we may want to keep the last decoded image
	else if ((codec->Status<GF_ESM_CODEC_EOS) && codec->odm && codec->odm->parentscene && codec->odm->parentscene->is_dynamic_scene && codec->CB && (codec->CB->Capacity>1)) {
		gf_codec_set_status(codec, GF_ESM_CODEC_STOP);
	}
	/*otherwise set status directly and don't touch CB state*/
	else {
		codec->Status = GF_ESM_CODEC_STOP;
	}

	/*don't wait for end of thread since this can be triggered within the decoding thread*/
	if (ce->flags & GF_MM_CE_RUNNING) {
		ce->flags &= ~GF_MM_CE_RUNNING;
		if (!ce->thread)
			term->cumulated_priority -= codec->Priority+1;
	}
	if (codec->CB) gf_cm_abort_buffering(codec->CB);

	if (ce->mx) gf_mx_v(ce->mx);
	/*cf note above*/
	else if (locked) gf_mx_v(term->mm_mx);
}