void gf_cm_set_status(GF_CompositionMemory *cb, u32 Status) { if (cb->Status == Status) return; gf_odm_lock(cb->odm, 1); /*if we're asked for play, trigger on buffering*/ if (Status == CB_PLAY) { switch (cb->Status) { case CB_STOP: if (cb->odm->disable_buffer_at_next_play) { cb->Status = CB_BUFFER_DONE; } else { cb->Status = CB_BUFFER; gf_clock_buffer_on(cb->odm->codec->ck); GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] CB status changed - ODM%d: buffering on at OTB %d (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)); } break; case CB_PAUSE: cb->Status = CB_PLAY; break; /*this should never happen (calling play while already buffering ...)*/ case CB_BUFFER: cb->LastRenderedTS = 0; break; default: cb->Status = Status; break; } } else { cb->LastRenderedTS = 0; if (cb->Status == CB_BUFFER) { gf_clock_buffer_off(cb->odm->codec->ck); GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] CB status changed - 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)); } if (Status == CB_STOP) { gf_cm_reset(cb); cb->LastRenderedTS = 0; } cb->Status = Status; if (Status==CB_BUFFER) { gf_clock_buffer_on(cb->odm->codec->ck); GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] CB status changed - ODM%d: buffering on at OTB %d (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)); } } gf_odm_lock(cb->odm, 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); }
void gf_es_reset_buffers(GF_Channel *ch) { gf_mx_p(ch->mx); if (ch->buffer) gf_free(ch->buffer); ch->buffer = NULL; ch->len = ch->allocSize = 0; gf_db_unit_del(ch->AU_buffer_first); ch->AU_buffer_first = ch->AU_buffer_last = NULL; ch->AU_Count = 0; if (ch->odm->codec && ch->odm->codec->CB) gf_cm_reset(ch->odm->codec->CB); ch->BufferTime = 0; gf_mx_v(ch->mx); }