📄 media_object.c
字号:
if (forceDrop<0) { /*only allow for explicit last frame keeping if only one node is using the resource otherwise this would block the composition memory*/ if (mo->num_open>1) forceDrop=0; else { gf_odm_lock(mo->odm, 0); return; } } /*discard frame*/ if (mo->odm->codec->CB->output->RenderedLength == mo->odm->codec->CB->output->dataLength) { if (forceDrop) { gf_cm_drop_output(mo->odm->codec->CB); forceDrop--;// if (forceDrop) mo->odm->codec->nb_droped++; } else { obj_time = gf_clock_time(mo->odm->codec->ck); if (mo->odm->codec->CB->output->next->dataLength) { if (2*obj_time < mo->timestamp + mo->odm->codec->CB->output->next->TS ) { mo->odm->codec->CB->output->RenderedLength = 0; } else { gf_cm_drop_output(mo->odm->codec->CB); } } else { gf_cm_drop_output(mo->odm->codec->CB); } } } } gf_odm_lock(mo->odm, 0);}GF_EXPORTvoid gf_mo_get_object_time(GF_MediaObject *mo, u32 *obj_time){ if (!gf_odm_lock_mo(mo)) return; /*regular media codec...*/ if (mo->odm->codec) { /*get absolute clock (without drift) for audio*/ if (mo->odm->codec->type==GF_STREAM_AUDIO) *obj_time = gf_clock_real_time(mo->odm->codec->ck); else *obj_time = gf_clock_time(mo->odm->codec->ck); } /*BIFS object */ else if (mo->odm->subscene && mo->odm->subscene->scene_codec) { *obj_time = gf_clock_time(mo->odm->subscene->scene_codec->ck); } /*unknown / unsupported object*/ else { *obj_time = 0; } gf_odm_lock(mo->odm, 0);}GF_EXPORTvoid gf_mo_play(GF_MediaObject *mo, Double clipBegin, Double clipEnd, Bool can_loop){ if (!mo) return; if (!mo->num_open && mo->odm) { Bool is_restart = 0; /*remove object from media queue*/ gf_term_lock_net(mo->odm->term, 1); gf_list_del_item(mo->odm->term->media_queue, mo->odm); gf_term_lock_net(mo->odm->term, 0); if (mo->odm->media_start_time == (u64) -1) is_restart = 1; if (mo->odm->flags & GF_ODM_NO_TIME_CTRL) { mo->odm->media_start_time = 0; } else { mo->odm->media_start_time = (u64) (clipBegin*1000); if (mo->odm->duration && (mo->odm->media_start_time > mo->odm->duration)) { if (can_loop) { mo->odm->media_start_time %= mo->odm->duration; } else { mo->odm->media_start_time = mo->odm->duration; } } if (clipEnd>=clipBegin) { mo->odm->media_stop_time = (u64) (clipEnd*1000); if (mo->odm->duration && (mo->odm->media_stop_time > mo->odm->duration)) { mo->odm->media_stop_time = 0; } } else { mo->odm->media_stop_time = 0; } } if (is_restart) { MC_Restart(mo->odm); } else { gf_odm_start(mo->odm); } } else if (mo->odm) { if (mo->num_to_restart) mo->num_restart--; if (!mo->num_restart && (mo->num_to_restart==mo->num_open+1) ) { MC_Restart(mo->odm); mo->num_to_restart = mo->num_restart = 0; } } mo->num_open++;}GF_EXPORTvoid gf_mo_stop(GF_MediaObject *mo){ if (!mo || !mo->num_open) return; mo->num_open--; if (!mo->num_open && mo->odm) { /*do not stop directly, this can delete channel data currently being decoded (BIFS anim & co)*/ gf_mx_p(mo->odm->term->net_mx); /*if object not in media queue, add it*/ if (gf_list_find(mo->odm->term->media_queue, mo->odm)<0) gf_list_add(mo->odm->term->media_queue, mo->odm); /*signal STOP request*/ mo->odm->media_start_time = (u64)-1; gf_mx_v(mo->odm->term->net_mx); if (mo->odm->codec && mo->odm->codec->CB) { GF_CompositionMemory *cb = mo->odm->codec->CB; GF_CMUnit *out = cb->output->next; while (out != cb->output) { out->dataLength = 0; out->TS = 0; out = out->next; } } } else { if (!mo->num_to_restart) { mo->num_restart = mo->num_to_restart = mo->num_open + 1; } }}GF_EXPORTvoid gf_mo_restart(GF_MediaObject *mo){ MediaControlStack *ctrl; if (!gf_odm_lock_mo(mo)) return; ctrl = ODM_GetMediaControl(mo->odm); /*if no control and not root of a scene, check timelines are unlocked*/ if (!ctrl && !mo->odm->subscene) { /*don't restart if sharing parent scene clock*/ if (gf_odm_shares_clock(mo->odm, gf_odm_get_media_clock(mo->odm->parentscene->root_od))) { gf_odm_lock(mo->odm, 0); return; } } /*all other cases, call restart to take into account clock references*/ MC_Restart(mo->odm); gf_odm_lock(mo->odm, 0);}GF_EXPORTBool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url){ u32 od_id; Bool ret = 0; if (!mo) return (url ? 1 : 0); od_id = URL_GetODID(url); if ( (mo->OD_ID == GF_ESM_DYNAMIC_OD_ID) && (od_id == GF_ESM_DYNAMIC_OD_ID)) { ret = !gf_mo_is_same_url(mo, url); } else { ret = (mo->OD_ID == od_id) ? 0 : 1; } /*special case for 3GPP text: if not playing and user node changed, force removing it*/ if (ret && mo->odm && !mo->num_open && (mo->type == GF_MEDIA_OBJECT_TEXT)) { mo->flags |= GF_MO_DISPLAY_REMOVE; gf_term_stop_codec(mo->odm->codec); } return ret;}GF_EXPORTvoid gf_mo_set_speed(GF_MediaObject *mo, Fixed speed){ MediaControlStack *ctrl; if (!mo) return; if (!mo->odm) { mo->speed = speed; return; } /*if media control forbidd that*/ ctrl = ODM_GetMediaControl(mo->odm); if (ctrl) return; gf_odm_set_speed(mo->odm, speed);}GF_EXPORTFixed gf_mo_get_speed(GF_MediaObject *mo, Fixed in_speed){ Fixed res; MediaControlStack *ctrl; if (!gf_odm_lock_mo(mo)) return in_speed; /*get control*/ ctrl = ODM_GetMediaControl(mo->odm); res = ctrl ? ctrl->control->mediaSpeed : in_speed; gf_odm_lock(mo->odm, 0); return res;}GF_EXPORTBool gf_mo_get_loop(GF_MediaObject *mo, Bool in_loop){ GF_Clock *ck; MediaControlStack *ctrl; if (!gf_odm_lock_mo(mo)) return in_loop; /*get control*/ ctrl = ODM_GetMediaControl(mo->odm); if (ctrl) in_loop = ctrl->control->loop; /*otherwise looping is only accepted if not sharing parent scene clock*/ ck = gf_odm_get_media_clock(mo->odm->parentscene->root_od); if (gf_odm_shares_clock(mo->odm, ck)) in_loop = 0; gf_odm_lock(mo->odm, 0); return in_loop;}GF_EXPORTDouble gf_mo_get_duration(GF_MediaObject *mo){ Double dur; if (!gf_odm_lock_mo(mo)) return -1.0; dur = ((Double) (s64)mo->odm->duration)/1000.0; gf_odm_lock(mo->odm, 0); return dur;}GF_EXPORTBool gf_mo_should_deactivate(GF_MediaObject *mo){ Bool res = 0; MediaControlStack *ctrl; if (!gf_odm_lock_mo(mo)) return 0; if (!mo->odm->state) { gf_odm_lock(mo->odm, 0); return 0; } /*get media control and see if object owning control is running*/ ctrl = ODM_GetMediaControl(mo->odm); if (!ctrl) res = 1; /*if ctrl and ctrl not ruling this mediaObject, deny deactivation*/ else if (ctrl->stream->odm != mo->odm) res = 0; /*this is currently under discussion in MPEG. for now we deny deactivation as soon as a mediaControl is here*/ else if (ctrl->stream->odm->state) res = 0; /*otherwise allow*/ else res = 1; gf_odm_lock(mo->odm, 0); return res;}GF_EXPORTBool gf_mo_is_muted(GF_MediaObject *mo){ Bool res = 0; if (!gf_odm_lock_mo(mo)) return 0; res = mo->odm->media_ctrl ? mo->odm->media_ctrl->control->mute : 0; gf_odm_lock(mo->odm, 0); return res;}GF_EXPORTBool gf_mo_is_done(GF_MediaObject *mo){ Bool res = 0; GF_Codec *codec; u64 dur; if (!gf_odm_lock_mo(mo)) return 0; /*for natural media use composition buffer*/ if (mo->odm->codec && mo->odm->codec->CB) res = (mo->odm->codec->CB->Status==CB_STOP) ? 1 : 0; /*otherwise check EOS and time*/ else { codec = mo->odm->codec; dur = mo->odm->duration; if (!mo->odm->codec) { if (!mo->odm->subscene) res = 0; else { codec = mo->odm->subscene->scene_codec; dur = mo->odm->subscene->duration; } } if (codec && (codec->Status==GF_ESM_CODEC_STOP)) { /*codec is done, check by duration*/ GF_Clock *ck = gf_odm_get_media_clock(mo->odm); if (gf_clock_time(ck) > dur) res = 1; } } gf_odm_lock(mo->odm, 0); return res;}/*resyncs clock - only audio objects are allowed to use this*/GF_EXPORTvoid gf_mo_adjust_clock(GF_MediaObject *mo, s32 ms_drift){ if (!mo || !mo->odm) return; if (!mo->odm->codec || (mo->odm->codec->type != GF_STREAM_AUDIO) ) return; gf_clock_adjust_drift(mo->odm->codec->ck, ms_drift);}GF_EXPORTu32 gf_mo_get_flags(GF_MediaObject *mo){ return mo ? mo->flags : 0;}GF_EXPORTvoid gf_mo_set_flag(GF_MediaObject *mo, u32 flag, Bool set_on){ if (mo) { if (set_on) mo->flags |= flag; else mo->flags &= ~flag; }}GF_EXPORTu32 gf_mo_get_last_frame_time(GF_MediaObject *mo){ return mo ? mo->timestamp : 0;}GF_EXPORTBool gf_mo_has_audio(GF_MediaObject *mo){ u32 i; GF_NetworkCommand com; GF_ClientService *ns; GF_InlineScene *is; if (!mo || !mo->odm) return 0; if (mo->type != GF_MEDIA_OBJECT_VIDEO) return 0; ns = mo->odm->net_service; is = mo->odm->parentscene; for (i=0; i<gf_list_count(is->ODlist); i++) { GF_ObjectManager *odm = gf_list_get(is->ODlist, i); if (odm->net_service != ns) continue; if (!odm->mo) continue; /*there is already an audio object in this service, do not recreate one*/ if (odm->mo->type == GF_MEDIA_OBJECT_AUDIO) return 0; } memset(&com, 0, sizeof(GF_NetworkCommand) ); com.command_type = GF_NET_SERVICE_HAS_AUDIO; if (gf_term_service_command(ns, &com) == GF_OK) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -