Esempio n. 1
0
/*render : setup media sensor and update timing in case of inline scenes*/
void RenderMediaSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	GF_Clock *ck;
	Bool do_update_clock = 1;
	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;
	}
	//we need to disable culling otherwise we may never be called back again ...
	tr_state->disable_cull = 1;

	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;
		if (st->stream->odm->subscene->is_dynamic_scene) do_update_clock = 0;
	}
	/*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) ) {
		if (do_update_clock)
			st->stream->odm->media_current_time = gf_clock_media_time(ck);
		mediasensor_update_timing(st->stream->odm, 0);
	}
	//if main addon is VoD and selected and clock is paused, fire a timeshift update
	else if (st->stream->odm->subscene && st->stream->odm->subscene->sys_clock_at_main_activation) {
		GF_Event evt;
		memset(&evt, 0, sizeof(evt));
		evt.type = GF_EVENT_TIMESHIFT_UPDATE;
		gf_term_send_event(st->stream->odm->term, &evt);
	}
}
Esempio n. 2
0
GF_EXPORT
GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info)
{
    GF_ObjectManager *an_odm;
    GF_Channel *ch;
    GF_Codec *codec;

    memset(info, 0, sizeof(GF_MediaInfo));

    if (!term || !odm || !info) return GF_BAD_PARAM;
    if (!gf_term_check_odm(term, odm)) return GF_BAD_PARAM;

    info->od = odm->OD;

    info->duration = (Double) (s64)odm->duration;
    info->duration /= 1000;

    codec = odm->codec;
    an_odm = odm;
    while (!codec) {
        if (!an_odm->lower_layer_odm) break;
        an_odm = an_odm->lower_layer_odm;
        codec = an_odm->codec;
    }

    if (codec) {
        /*since we don't remove ODs that failed setup, check for clock*/
        if (codec->ck) {
            if (codec->CB) {
                info->current_time = odm->media_current_time ? odm->media_current_time : codec->last_unit_cts;
                info->ntp_diff = codec->CB->LastRenderedNTPDiff;
            } else {
                info->current_time = gf_clock_media_time(codec->ck);
            }
        }
        info->current_time /= 1000;
        info->nb_dropped = codec->nb_dropped;
    } else if (odm->subscene) {
        if (odm->subscene->scene_codec) {
            if (odm->subscene->scene_codec->ck) {
                info->current_time = gf_clock_media_time(odm->subscene->scene_codec->ck);
                info->current_time /= 1000;
            }
            info->duration = (Double) (s64)odm->subscene->duration;
            info->duration /= 1000;
            info->nb_dropped = odm->subscene->scene_codec->nb_dropped;
            codec = odm->subscene->scene_codec;
        } else if (odm->subscene->is_dynamic_scene) {
            if (odm->subscene->dyn_ck) {
                info->current_time = gf_clock_media_time(odm->subscene->dyn_ck);
                info->current_time /= 1000;
            }
            info->generated_scene = 1;
        }
    }
    if (info->duration && info->current_time>info->duration)
        info->current_time = info->duration;

    info->buffer = -2;
    info->db_unit_count = 0;

    /*Warning: is_open==2 means object setup, don't check then*/
    if (odm->state==GF_ODM_STATE_IN_SETUP) {
        info->status = 3;
    } else if (odm->state==GF_ODM_STATE_BLOCKED) {
        info->status = 0;
        info->protection = 2;
    } else if (odm->state) {
        u32 i, buf;
        GF_Clock *ck;

        ck = gf_odm_get_media_clock(odm);
        /*no clock means setup failed*/
        if (!ck) {
            info->status = 4;
        } else {
            info->status = gf_clock_is_started(ck) ? 1 : 2;
            info->clock_drift = ck->drift;

            info->buffer = -1;
            info->min_buffer = -1;
            info->max_buffer = 0;
            buf = 0;
            i=0;
            while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) {
                info->db_unit_count += ch->AU_Count;
                if (!ch->is_pulling || ch->MaxBuffer) {
                    if (ch->MaxBuffer) info->buffer = 0;
                    buf += ch->BufferTime;

                    if (ch->MaxBuffer> info->max_buffer) info->max_buffer = ch->MaxBuffer;
                    if (ch->MinBuffer < info->min_buffer) info->min_buffer = ch->MinBuffer;

                }
                if (ch->is_protected) info->protection = ch->ipmp_tool ? 1 : 2;

            }
            if (buf) info->buffer = (s32) buf;
        }
    }

    info->has_profiles = (odm->flags & GF_ODM_HAS_PROFILES) ? 1 : 0;
    if (info->has_profiles) {
        info->inline_pl = (odm->flags & GF_ODM_INLINE_PROFILES) ? 1 : 0;
        info->OD_pl = odm->OD_PL;
        info->scene_pl = odm->Scene_PL;
        info->audio_pl = odm->Audio_PL;
        info->visual_pl = odm->Visual_PL;
        info->graphics_pl = odm->Graphics_PL;
    }

    if (odm->net_service) {
        info->service_handler = odm->net_service->ifce->module_name;
        info->service_url = odm->net_service->url;
        if (odm->net_service->owner == odm) info->owns_service = 1;
    } else if ((odm->subscene && odm->subscene->graph_attached) || (odm->codec)) {
        info->service_url = "No associated network Service";
    } else {
        info->service_url = "Service not found or error";
    }

    if (codec) {
        if (codec->decio && codec->decio->GetName) {
            info->codec_name = codec->decio->GetName(codec->decio);
        } else {
            info->codec_name = codec->decio->module_name;
        }
        info->od_type = codec->type;

        if (codec->CB) {
            info->cb_max_count = codec->CB->Capacity;
            info->cb_unit_count = codec->CB->UnitCount;
            if (codec->direct_vout) {
                info->direct_video_memory = 1;
            }
        }
        get_codec_stats(codec, info);
    }

    if (odm->subscene) {
        gf_sg_get_scene_size_info(odm->subscene->graph, &info->width, &info->height);
    } else if (odm->mo) {
        switch (info->od_type) {
        case GF_STREAM_VISUAL:
            gf_mo_get_visual_info(odm->mo, &info->width, &info->height, NULL, &info->par, &info->pixelFormat, NULL);
            break;
        case GF_STREAM_AUDIO:
            gf_mo_get_audio_info(odm->mo, &info->sample_rate, &info->bits_per_sample, &info->num_channels, NULL);
            info->clock_drift = 0;
            break;
        case GF_STREAM_TEXT:
            gf_mo_get_visual_info(odm->mo, &info->width, &info->height, NULL, NULL, NULL, NULL);
            break;
        }
    }

    ch = (GF_Channel*)gf_list_get(odm->channels, 0);
    if (ch && ch->esd->langDesc) info->lang = ch->esd->langDesc->langCode;

    if (odm->mo && odm->mo->URLs.count)
        info->media_url = odm->mo->URLs.vals[0].url;
    return GF_OK;
}