/*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; } /*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_COMPOSE, ("[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; /*force update of media time*/ MS_UpdateTiming(cb->odm, 1); } 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_COMPOSE, ("[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; /*force update of media time*/ MS_UpdateTiming(cb->odm, 1); } } out = cb->output; exit: return out; }
/*render : setup media sensor and update timing in case of inline scenes*/ void RenderMediaSensor(SFNode *node, void *rs) { Clock *ck; MediaSensorStack *st = Node_GetPrivate(node); if (!st->stream) st->stream = MO_FindObject(node, &st->sensor->url); if (!st->stream) return; if (!st->stream->odm) return; if (!st->is_init) { ChainAddEntry(st->stream->odm->ms_stack, st); ODM_InitSegmentDescriptors(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) { ck = st->stream->odm->subscene->scene_codec->ck; /*since audio may be used alone through an inline scene, we need to refresh the graph*/ if (st->stream->odm->is_open) Term_InvalidateScene(st->stream->term); } /*check anim streams*/ else if (st->stream->odm->codec && (st->stream->odm->codec->type==M4ST_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 && CK_IsStarted(ck) ) { st->stream->odm->current_time = CK_GetTime(ck); MS_UpdateTiming(st->stream->odm); } }