u32 RunSingleDec(void *ptr) { GF_Err e; u32 time_left; CodecEntry *ce = (CodecEntry *) ptr; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[MediaDecoder %d] Entering thread ID %d\n", ce->dec->odm->OD->objectDescriptorID, gf_th_id() )); while (ce->flags & GF_MM_CE_RUNNING) { time_left = gf_sys_clock(); gf_mx_p(ce->mx); e = gf_codec_process(ce->dec, ce->dec->odm->term->frame_duration); if (e) gf_term_message(ce->dec->odm->term, ce->dec->odm->net_service->url, "Decoding Error", e); gf_mx_v(ce->mx); time_left = gf_sys_clock() - time_left; /*no priority boost this way for systems codecs, priority is dynamically set by not releasing the graph when late and moving on*/ if (!ce->dec->CB || (ce->dec->CB->UnitCount == ce->dec->CB->Capacity)) ce->dec->PriorityBoost = 0; /*while on don't sleep*/ if (ce->dec->PriorityBoost) continue; if (time_left) { while (time_left > ce->dec->odm->term->frame_duration) time_left -= ce->dec->odm->term->frame_duration; gf_sleep(time_left); } else { gf_sleep(ce->dec->odm->term->frame_duration); } } ce->flags |= GF_MM_CE_DEAD; return 0; }
RTPChannel *next_carousel(LiveSession *sess, u32 *timeout) { RTPChannel *to_send = NULL; u32 i, time, count, now; if (!sess->start_time) sess->start_time = gf_sys_clock(); now = gf_sys_clock() - sess->start_time; time = (u32) -1; count = gf_list_count(sess->streams); for (i=0; i<count; i++) { RTPChannel *ch = gf_list_get(sess->streams, i); if (!ch->carousel_period) continue; if (!ch->carousel_size) continue; if (!ch->last_carousel_time) ch->last_carousel_time = now; if (ch->last_carousel_time + ch->carousel_period < time) { to_send = ch; time = ch->last_carousel_time + ch->carousel_period; } } if (!to_send) { if (timeout) *timeout = 0; return NULL; } if (timeout) { if (time>now) time-=now; else time=0; *timeout = time; } return to_send; }
static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e) { u64 cts, dts; RTPStream *ch = (RTPStream *)udta; if (!ch->rtcp_init) { if (!ch->rtcp_check_start) { ch->rtcp_check_start = gf_sys_clock(); return; } else if (gf_sys_clock() - ch->rtcp_check_start <= RTCP_DEFAULT_TIMEOUT_MS) { return; } GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Timeout for RTCP: no SR recevied after %d ms - forcing playback, sync may be broken\n", RTCP_DEFAULT_TIMEOUT_MS)); ch->rtcp_init = 1; } cts = hdr->compositionTimeStamp; dts = hdr->decodingTimeStamp; hdr->compositionTimeStamp -= ch->ts_offset; hdr->decodingTimeStamp -= ch->ts_offset; if (ch->rtp_ch->packet_loss) e = GF_REMOTE_SERVICE_ERROR; if (ch->owner->first_packet_drop && (hdr->packetSequenceNumber >= ch->owner->first_packet_drop) ) { if ( (hdr->packetSequenceNumber - ch->owner->first_packet_drop) % ch->owner->frequency_drop) gf_service_send_packet(ch->owner->service, ch->channel, payload, size, hdr, e); } else { gf_service_send_packet(ch->owner->service, ch->channel, payload, size, hdr, e); } hdr->compositionTimeStamp = cts; hdr->decodingTimeStamp = dts; }
GF_EXPORT u32 gf_term_process_step(GF_Terminal *term) { u32 nb_decs=0; u32 time_taken = gf_sys_clock(); if (term->flags & GF_TERM_NO_DECODER_THREAD) { MM_SimulationStep_Decoder(term, &nb_decs); } if (term->flags & GF_TERM_NO_COMPOSITOR_THREAD) { u32 ms_until_next; gf_sc_draw_frame(term->compositor, &ms_until_next); if (ms_until_next<term->compositor->frame_duration/2) { time_taken=0; } } time_taken = gf_sys_clock() - time_taken; if (time_taken > term->compositor->frame_duration) { time_taken = 0; } else { time_taken = term->compositor->frame_duration - time_taken; } if (term->bench_mode || (term->user->init_flags & GF_TERM_NO_REGULATION)) return time_taken; if (2*time_taken >= term->compositor->frame_duration) { gf_sleep(nb_decs ? 1 : time_taken); } return time_taken; }
GF_Err libxml_load_svg(GF_LoadCompare *lc, char *item_path, u32 *loadtime) { GF_Err e = GF_OK; GF_SceneGraph *sg; u32 i, starttime, endtime; void *p; u32 nb; if (lc->spread_repeat) nb = 1; else nb = lc->nbloads ; *loadtime = 0; for (i = 0; i<nb; i++) { sg = gf_sg_new(); starttime = gf_sys_clock(); p = DANAE_NewSVGParser(item_path, sg); DANAE_SVGParser_Parse(p); DANAE_SVGParser_Terminate(); endtime = gf_sys_clock(); if (lc->verbose) fprintf(stdout, "LibXML single parsing: %d\n", endtime-starttime); *loadtime += endtime-starttime; gf_sg_del(sg); } return e; }
u32 MM_Loop(void *par) { GF_Terminal *term = (GF_Terminal *) par; Bool do_scene = (term->flags & GF_TERM_NO_VISUAL_THREAD) ? 1 : 0; Bool do_codec = (term->flags & GF_TERM_NO_DECODER_THREAD) ? 0 : 1; Bool do_regulate = (term->user->init_flags & GF_TERM_NO_REGULATION) ? 0 : 1; gf_th_set_priority(term->mm_thread, term->priority); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[MediaManager] Entering thread ID %d\n", gf_th_id() )); // GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("(RTI] Terminal Cycle Log\tServices\tDecoders\tCompositor\tSleep\n")); while (term->flags & GF_TERM_RUNNING) { u32 left; if (do_codec) left = MM_SimulationStep_Decoder(term); else left = term->frame_duration; if (do_scene) { u32 time_taken = gf_sys_clock(); gf_sc_draw_frame(term->compositor); time_taken = gf_sys_clock() - time_taken; if (left>time_taken) left -= time_taken; else left = 0; } if (do_regulate) gf_sleep(left); } term->flags |= GF_TERM_DEAD; return 0; }
Bool visual_2d_draw_frame(GF_VisualManager *visual, GF_Node *root, GF_TraverseState *tr_state, Bool is_root_visual) { GF_SceneGraph *sg; GF_Matrix2D backup; u32 i; Bool res; GF_Err e; #ifndef GPAC_DISABLE_LOG u32 itime, time = gf_sys_clock(); #endif gf_mx2d_copy(backup, tr_state->transform); visual->bounds_tracker_modif_flag = DRAWABLE_HAS_CHANGED; e = visual_2d_init_draw(visual, tr_state); if (e) { gf_mx2d_copy(tr_state->transform, backup); GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Visual2D] Cannot init draw phase: %s\n", gf_error_to_string(e))); return 0; } #ifndef GPAC_DISABLE_LOG itime = gf_sys_clock(); visual->compositor->traverse_setup_time = itime - time; time = itime; #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Traversing scene subtree (root node %s)\n", root ? gf_node_get_class_name(root) : "none")); if (is_root_visual) { gf_node_traverse(root, tr_state); i=0; while ((sg = (GF_SceneGraph*)gf_list_enum(visual->compositor->extra_scenes, &i))) { gf_sc_traverse_subscene(visual->compositor, root, sg, tr_state); } } else { gf_node_traverse(root, tr_state); } #ifndef GPAC_DISABLE_LOG itime = gf_sys_clock(); visual->compositor->traverse_and_direct_draw_time = itime - time; time = itime; #endif gf_mx2d_copy(tr_state->transform, backup); res = visual_2d_terminate_draw(visual, tr_state); #ifndef GPAC_DISABLE_LOG if (!tr_state->immediate_draw) { visual->compositor->indirect_draw_time = gf_sys_clock() - time; } #endif return res; }
void RP_ProcessRTCP(RTPStream *ch, char *pck, u32 size) { Bool has_sr; GF_Err e; if (ch->status == RTP_Connected) return; ch->rtcp_bytes += size; e = gf_rtp_decode_rtcp(ch->rtp_ch, pck, size, &has_sr); if (e<0) return; /*update sync if on pure RTP*/ if (!ch->rtcp_init && has_sr) { Double ntp_clock; ntp_clock = ch->rtp_ch->last_SR_NTP_sec; ntp_clock += ((Double)ch->rtp_ch->last_SR_NTP_frac)/0xFFFFFFFF; if (!ch->owner->last_ntp) { //add safety in case this RTCP report is received before another report //that was supposed to come in earlier (with earlier NTP) //Double safety_offset, time = ch->rtp_ch->last_SR_rtp_time; //time /= ch->rtp_ch->TimeScale; //safety_offset = time/2; ch->owner->last_ntp = ntp_clock; } if (ntp_clock >= ch->owner->last_ntp) { ntp_clock -= ch->owner->last_ntp; } else { ntp_clock = 0; } //assert(ch->rtp_ch->last_SR_rtp_time >= (u64) (ntp_clock * ch->rtp_ch->TimeScale)); ch->ts_offset = ch->rtp_ch->last_SR_rtp_time; ch->ts_offset -= (s64) (ntp_clock * ch->rtp_ch->TimeScale); GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTCP] At %d Using Sender Report to map RTP TS %d to NTP clock %g - new TS offset "LLD" \n", gf_sys_clock(), ch->rtp_ch->last_SR_rtp_time, ntp_clock, ch->ts_offset )); ch->rtcp_init = 1; ch->check_rtp_time = RTP_SET_TIME_NONE; } if (e == GF_EOS) { ch->flags |= RTP_EOS; ch->stat_stop_time = gf_sys_clock(); gf_service_send_packet(ch->owner->service, ch->channel, NULL, 0, NULL, GF_EOS); } }
u32 MM_SimulationStep_Compositor(GF_Terminal *term, u32 time_left) { u32 time_taken = gf_sys_clock(); gf_sc_draw_frame(term->compositor); time_taken = gf_sys_clock() - time_taken; if (time_left>time_taken) time_left -= time_taken; else time_left = 0; return time_left; }
void RP_ReadStream(RTPStream *ch) { u32 size, tot_size; if (!ch->rtp_ch) return; /*NOTE: A weird bug on windows wrt to select(): if both RTP and RTCP are in the same loop there is a hudge packet drop on RTP. We therefore split RTP and RTCP reading, this is not a big deal as the RTCP traffic is far less than RTP, and we should never have more than one RTCP packet reading per RTP reading loop NOTE2: a better implementation would be to use select() to get woken up... */ tot_size = 0; while (1) { size = gf_rtp_read_rtcp(ch->rtp_ch, ch->buffer, RTP_BUFFER_SIZE); if (!size) break; tot_size += size; RP_ProcessRTCP(ch, ch->buffer, size); } while (1) { size = gf_rtp_read_rtp(ch->rtp_ch, ch->buffer, RTP_BUFFER_SIZE); if (!size) break; tot_size += size; RP_ProcessRTP(ch, ch->buffer, size); } /*and send the report*/ if (ch->flags & RTP_ENABLE_RTCP) gf_rtp_send_rtcp_report(ch->rtp_ch, SendTCPData, ch); if (tot_size) ch->owner->udp_time_out = 0; /*detect timeout*/ if (ch->owner->udp_time_out) { if (!ch->last_udp_time) { ch->last_udp_time = gf_sys_clock(); } else if (ch->rtp_ch->net_info.IsUnicast && !(ch->flags & RTP_MOBILEIP) ) { u32 diff = gf_sys_clock() - ch->last_udp_time; if (diff >= ch->owner->udp_time_out) { char szMessage[1024]; GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] UDP Timeout after %d ms\n", diff)); sprintf(szMessage, "No data received in %d ms", diff); gf_term_on_message(ch->owner->service, GF_IP_UDP_TIMEOUT, szMessage); ch->status = RTP_Unavailable; } } } }
static void mouse_move(DDContext *ctx, GF_VideoOutput *vout) { if (ctx->fullscreen) { ctx->last_mouse_move = gf_sys_clock(); if (ctx->cursor_type==GF_CURSOR_HIDE) DD_SetCursor(vout, ctx->cursor_type_backup); } }
/*CPU and Memory Usage*/ GF_EXPORT Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) { TInt ram, ram_free; u32 now, time; #ifdef __SERIES60_3X__ TModuleMemoryInfo mi; #endif TTimeIntervalMicroSeconds tims; RProcess cur_process; RThread cur_th; now = gf_sys_clock(); if (!rti->sampling_instant) { rti->sampling_instant = now; if (cur_th.GetCpuTime(tims) != KErrNone) { return 0; } #ifdef __SERIES60_3X__ rti->process_cpu_time = (u32) (tims.Int64() / 1000); #else rti->process_cpu_time = (u32) ( TInt64(tims.Int64() / 1000).GetTInt() ); #endif return 0; } if (rti->sampling_instant + refresh_time_ms > now) return 0; rti->sampling_period_duration = now - rti->sampling_instant; rti->sampling_instant = now; if (cur_th.Process(cur_process) != KErrNone) { return 0; } #ifdef __SERIES60_3X__ if (cur_process.GetMemoryInfo(mi) != KErrNone) { return 0; } rti->process_memory = mi.iCodeSize + mi.iConstDataSize + mi.iInitialisedDataSize + mi.iUninitialisedDataSize; #endif if (cur_th.GetCpuTime(tims) != KErrNone) { return 0; } #ifdef __SERIES60_3X__ time = (u32) (tims.Int64() / 1000); #else time = (u32) ( TInt64(tims.Int64() / 1000).GetTInt() ); #endif rti->process_cpu_time_diff = time - rti->process_cpu_time; rti->process_cpu_time = time; rti->process_cpu_usage = 100*rti->process_cpu_time_diff / rti->sampling_period_duration; if (rti->process_cpu_usage > 100) rti->process_cpu_usage = 100; HAL::Get(HALData::EMemoryRAM, ram); HAL::Get(HALData::EMemoryRAMFree, ram_free); rti->physical_memory = ram; rti->physical_memory_avail = ram_free; #ifdef GPAC_MEMORY_TRACKING rti->gpac_memory = gpac_allocated_memory; #endif return 1; }
static void Osmo4_progress_cbk(void *usr, char *title, u32 done, u32 total) { #ifndef GPAC_GUI_ONLY COsmo4AppView *view = (COsmo4AppView *) usr; COsmo4AppUi *app = (COsmo4AppUi *) CEikonEnv::Static()->AppUi(); if (done==total) { app->SetInfo(NULL); } else if (view->last_title_update + 500 < gf_sys_clock()) { char szName[1024]; view->last_title_update = gf_sys_clock(); sprintf(szName, "%s %02d %%", title, (done*100 / total) ); app->SetInfo(szName); } #endif }
u32 gf_sc_ar_get_clock(GF_AudioRenderer *ar) { if (ar->audio_out) return ar->current_time; if (ar->Frozen) return ar->freeze_time - ar->start_time; return gf_sys_clock() - ar->start_time; }
static void gf_ar_freeze_intern(GF_AudioRenderer *ar, Bool DoFreeze, Bool for_reconfig, Bool reset_hw_buffer) { gf_mixer_lock(ar->mixer, 1); if (DoFreeze) { if (!ar->Frozen) { ar->FreezeTime = gf_sys_clock(); if (!for_reconfig && ar->audio_out && ar->audio_out->Play) ar->audio_out->Play(ar->audio_out, 0); ar->Frozen = 1; } } else { if (ar->Frozen) { if (!for_reconfig && ar->audio_out && ar->audio_out->Play) ar->audio_out->Play(ar->audio_out, reset_hw_buffer ? 2 : 1); ar->Frozen = 0; ar->startTime += gf_sys_clock() - ar->FreezeTime; } } gf_mixer_lock(ar->mixer, 0); }
u32 MM_Loop(void *par) { GF_Terminal *term = (GF_Terminal *) par; Bool do_scene = (term->flags & GF_TERM_NO_VISUAL_THREAD) ? 1 : 0; Bool do_codec = (term->flags & GF_TERM_NO_DECODER_THREAD) ? 0 : 1; Bool do_regulate = (term->user->init_flags & GF_TERM_NO_REGULATION) ? 0 : 1; gf_th_set_priority(term->mm_thread, term->priority); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[MediaManager] Entering thread ID %d\n", gf_th_id() )); // GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("(RTI] Terminal Cycle Log\tServices\tDecoders\tCompositor\tSleep\n")); while (term->flags & GF_TERM_RUNNING) { u32 nb_decs = 0; u32 left = 0; if (do_codec) left = MM_SimulationStep_Decoder(term, &nb_decs); else left = term->frame_duration; if (do_scene) { u32 ms_until_next=0; u32 time_taken = gf_sys_clock(); gf_sc_draw_frame(term->compositor, &ms_until_next); time_taken = gf_sys_clock() - time_taken; if (ms_until_next<term->frame_duration/2) { left = 0; } else if (left>time_taken) left -= time_taken; else left = 0; } if (do_regulate) { if (term->bench_mode) { gf_sleep(0); } else { if (left==term->frame_duration) { //if nothing was done during this pass but we have active decoder, just yield. We don't want to sleep since //composition memory could be released at any time. We should have a signal here, rather than a wait gf_sleep(nb_decs ? 0 : term->frame_duration/2); } } } } term->flags |= GF_TERM_DEAD; return 0; }
GF_EXPORT void gf_sys_init() { if (!sys_init) { memset(&the_rti, 0, sizeof(GF_SystemRTInfo)); the_rti.pid = getpid(); sys_start_time = gf_sys_clock(); } sys_init += 1; }
static GF_Err RAW_Flush(GF_VideoOutput *dr, GF_Window *dest) { #if 0 RAWCTX; char szName[1024]; sprintf(szName, "test%d.png", gf_sys_clock()); gf_img_png_enc_file(rc->pixels, rc->width, rc->height, rc->width*rc->bpp, rc->pixel_format, szName); #endif return GF_OK; }
static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 path_mtu, u32 ttl, char *ifce_addr, char *sdp_name) { RTPChannel *rtpch; u32 count = gf_seng_get_stream_count(livesess->seng); u32 i; char *iod64 = gf_seng_get_base64_iod(livesess->seng); char *sdp = gf_rtp_streamer_format_sdp_header("GPACSceneStreamer", ip, NULL, iod64); if (iod64) gf_free(iod64); for (i=0; i<count; i++) { u16 ESID; u32 st, oti, ts; char *config = NULL; u32 config_len; gf_seng_get_stream_config(livesess->seng, i, &ESID, &config, &config_len, &st, &oti, &ts); GF_SAFEALLOC(rtpch, RTPChannel); rtpch->timescale = ts; rtpch->init_time = gf_sys_clock(); switch (st) { case GF_STREAM_OD: case GF_STREAM_SCENE: rtpch->rtp = gf_rtp_streamer_new_extended(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SYSTEMS_CAROUSEL, (char *) config, config_len, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4); if (rtpch->rtp) { gf_rtp_streamer_disable_auto_rtcp(rtpch->rtp); rtpch->manual_rtcp = 1; } break; default: rtpch->rtp = gf_rtp_streamer_new(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SIGNAL_RAP, (char *) config, config_len); break; } rtpch->ESID = ESID; rtpch->adjust_carousel_time = 1; gf_list_add(livesess->streams, rtpch); gf_rtp_streamer_append_sdp(rtpch->rtp, ESID, (char *) config, config_len, NULL, &sdp); /*fetch initial config of the broadcast*/ gf_seng_get_stream_carousel_info(livesess->seng, ESID, &rtpch->carousel_period, &rtpch->aggregate_on_stream); port += 2; } if (sdp) { FILE *out = gf_f64_open(sdp_name, "wt"); fprintf(out, "%s", sdp); fclose(out); gf_free(sdp); } }
static void live_session_callback(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) { LiveSession *livesess = (LiveSession *) calling_object; RTPChannel *rtpch; u32 i=0; while ( (rtpch = gf_list_enum(livesess->streams, &i))) { if (rtpch->ESID == ESID) { /*store carousel data*/ if (livesess->carousel_generation && rtpch->carousel_period) { if (rtpch->carousel_alloc < size) { rtpch->carousel_data = gf_realloc(rtpch->carousel_data, size); rtpch->carousel_alloc = size; } memcpy(rtpch->carousel_data, data, size); rtpch->carousel_size = size; rtpch->carousel_ts = ts; rtpch->time_at_carousel_store = gf_sys_clock(); fprintf(stderr, "\nStream %d: Storing new carousel TS "LLD", %d bytes\n", ESID, ts, size); } /*send data*/ else { u32 critical = 0; Bool rap = rtpch->rap; if (livesess->carousel_generation) rap = 1; ts += rtpch->timescale*((u64)gf_sys_clock()-rtpch->init_time + rtpch->ts_delta)/1000; if (rtpch->critical) critical = rtpch->critical; else if (livesess->critical) critical = 1; gf_rtp_streamer_send_au_with_sn(rtpch->rtp, data, size, ts, ts, rap, critical); fprintf(stderr, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rap, critical); rtpch->rap = rtpch->critical = 0; if (rtpch->manual_rtcp) gf_rtp_streamer_send_rtcp(rtpch->rtp, 0, 0, 0, 0, 0); } return; } } }
GF_Err gpacctx_load_file(GF_LoadCompare *lc, char *item_path, u32 *loadtime) { GF_Err e = GF_OK; GF_SceneLoader load; GF_SceneGraph *sg; u32 i, starttime, endtime; u32 nb; if (lc->spread_repeat) nb = 1; else nb = lc->nbloads ; *loadtime = 0; for (i = 0; i<nb; i++) { memset(&load, 0, sizeof(GF_SceneLoader)); sg = gf_sg_new(); load.ctx = gf_sm_new(sg); load.OnProgress = load_progress; load.fileName = item_path; starttime = gf_sys_clock(); e = gf_sm_load_init(&load); if (e) { fprintf(stderr, "Error loading file %s\n", item_path); } else { e = gf_sm_load_run(&load); if (e) { fprintf(stderr, "Error loading file %s\n", item_path); } else { endtime = gf_sys_clock(); *loadtime += endtime-starttime; } gf_sm_load_done(&load); } gf_sm_del(load.ctx); gf_sg_del(sg); } return e; }
static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch) { u32 now = gf_sys_clock(); u64 ts=0; if (ch) { if (ch->carousel_size) { ts = ch->carousel_ts + ch->timescale * ( (ch->adjust_carousel_time ? (u64)gf_sys_clock() : ch->time_at_carousel_store) - ch->init_time + ch->ts_delta)/1000; gf_rtp_streamer_send_au_with_sn(ch->rtp, ch->carousel_data, ch->carousel_size, ts, ts, 1, 0); ch->last_carousel_time = now - livesess->start_time; fprintf(stderr, "Stream %d: Sending carousel at TS "LLD", %d bytes\n", ch->ESID, ts, ch->carousel_size); if (ch->manual_rtcp) { ts = ch->carousel_ts + ch->timescale * ( gf_sys_clock() - ch->init_time + ch->ts_delta)/1000; gf_rtp_streamer_send_rtcp(ch->rtp, 1, (u32) ts, 0, 0, 0); } } } else { u32 i=0; while (NULL != (ch = gf_list_enum(livesess->streams, &i))) { if (ch->carousel_size) { if (ch->adjust_carousel_time) { ts = ch->carousel_ts + ch->timescale*(gf_sys_clock()-ch->init_time + ch->ts_delta)/1000; } else { ts = ch->carousel_ts; } gf_rtp_streamer_send_au_with_sn(ch->rtp, ch->carousel_data, ch->carousel_size, ts, ts, 1, 0); ch->last_carousel_time = now - livesess->start_time; fprintf(stderr, "Stream %d: Sending carousel at TS "LLD" , %d bytes\n", ch->ESID, ts, ch->carousel_size); if (ch->manual_rtcp) { ts = ch->carousel_ts + ch->timescale*(gf_sys_clock()-ch->init_time + ch->ts_delta)/1000; gf_rtp_streamer_send_rtcp(ch->rtp, 1, (u32) ts, 0, 0, 0); } } } } }
GF_EXPORT u32 gf_term_process_step(GF_Terminal *term) { u32 time_taken = gf_sys_clock(); if (term->flags & GF_TERM_NO_DECODER_THREAD) { MM_SimulationStep_Decoder(term); } if (term->flags & GF_TERM_NO_COMPOSITOR_THREAD) { gf_sc_draw_frame(term->compositor); } time_taken = gf_sys_clock() - time_taken; if (time_taken > term->compositor->frame_duration) { time_taken = 0; } else { time_taken = term->compositor->frame_duration - time_taken; } if (term->user->init_flags & GF_TERM_NO_REGULATION) return time_taken; gf_sleep(time_taken); return time_taken; }
GF_Err load_mp4(GF_LoadCompare *lc, GF_ISOFile *mp4, u32 *loadtime) { GF_Err e = GF_OK; GF_SceneLoader load; GF_SceneGraph *sg; u32 i, starttime, endtime; u32 nb; if (lc->spread_repeat) nb = 1; else nb = lc->nbloads ; *loadtime = 0; for (i = 0; i< nb; i++) { memset(&load, 0, sizeof(GF_SceneLoader)); sg = gf_sg_new(); load.ctx = gf_sm_new(sg); load.isom = mp4; starttime = gf_sys_clock(); e = gf_sm_load_init(&load); if (e) { fprintf(stderr, "Error loading MP4 file\n"); } else { e = gf_sm_load_run(&load); if (e) { fprintf(stderr, "Error loading MP4 file\n"); } else { endtime = gf_sys_clock(); *loadtime += endtime-starttime; } gf_sm_load_done(&load); } gf_sm_del(load.ctx); gf_sg_del(sg); } return e; }
static Bool OGG_ReadPage(OGGReader *read, ogg_page *oggpage) { char buf[OGG_BUFFER_SIZE]; GF_Err e; /*remote file, check if we use cache*/ if (read->is_remote) { u32 total_size; GF_NetIOStatus status; e = gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, &status); /*not ready*/ if ((e<GF_OK) || (status > GF_NETIO_DATA_EXCHANGE)) return 0; if (status == GF_NETIO_DATA_EXCHANGE) { if (!total_size && !read->is_live) { read->is_live = 1; read->tune_in_time = gf_sys_clock(); } else if (!read->is_live && !read->ogfile) { const char *szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) return 0; read->ogfile = gf_fopen((char *) szCache, "rb"); if (!read->ogfile) return 0; } } } while (ogg_sync_pageout(&read->oy, oggpage ) != 1 ) { char *buffer; u32 bytes; if (read->ogfile) { if (feof(read->ogfile)) { OGG_EndOfFile(read); return 0; } bytes = (u32) fread(buf, 1, OGG_BUFFER_SIZE, read->ogfile); } else { e = gf_dm_sess_fetch_data(read->dnload, buf, OGG_BUFFER_SIZE, &bytes); if (e) return 0; } if (!bytes) return 0; buffer = ogg_sync_buffer(&read->oy, bytes); memcpy(buffer, buf, bytes); ogg_sync_wrote(&read->oy, bytes); } return 1; }
static void SR_ForwardUserEvent(GF_Renderer *sr, GF_Event *ev) { GF_USER_SENDEVENT(sr->user, ev); if ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT)) { u32 now; GF_Event event; /*emulate doubleclick*/ now = gf_sys_clock(); if (now - last_lclick_time < 250) { event.type = GF_EVENT_MOUSEDOUBLECLICK; event.mouse.key_states = sr->key_states; event.mouse.x = ev->mouse.x; event.mouse.y = ev->mouse.y; GF_USER_SENDEVENT(sr->user, &event); } last_lclick_time = now; } }
static void on_gpac_rti_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list) { if (!log_file) return; if (lm & GF_LOG_RTI) { GF_SystemRTInfo rti; if (fmt) vfprintf(log_file, fmt, list); gf_sys_get_rti(rti_update_time_ms, &rti, 0); fprintf(log_file, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t\t", gf_sys_clock(), gf_term_get_time_in_ms(term), rti.total_cpu_usage, (u32) gf_term_get_framerate(term, 0), (u32) ( rti.gpac_memory / 1024) ); } else if (fmt && (ll>=GF_LOG_INFO)) { vfprintf(log_file, fmt, list); } }
static Bool CTXLoad_CheckDownload(CTXLoadPriv *priv) { u64 size; FILE *f; u32 now = gf_sys_clock(); if (!priv->file_size && (now - priv->last_check_time < 1000) ) return GF_FALSE; f = gf_fopen(priv->file_name, "rt"); if (!f) return GF_FALSE; gf_fseek(f, 0, SEEK_END); size = gf_ftell(f); gf_fclose(f); /*we MUST have a complete file for now ...*/ if (!priv->file_size) { if (priv->last_check_size == size) return GF_TRUE; priv->last_check_size = size; priv->last_check_time = now; } else { if (size==priv->file_size) return GF_TRUE; } return GF_FALSE; }
void RP_ProcessCommands(RTSPSession *sess) { GF_RTSPCommand *com; GF_Err e; u32 time; com = RP_GetCommand(sess); /*if asked or command to send, flushout TCP - TODO: check what's going on with ANNOUNCE*/ if ((com && !(sess->flags & RTSP_WAIT_REPLY) ) || (sess->flags & RTSP_TCP_FLUSH) ) { while (1) { e = gf_rtsp_session_read(sess->session); if (e) break; } sess->flags &= ~RTSP_TCP_FLUSH; } /*handle response or announce*/ if ( (com && (sess->flags & RTSP_WAIT_REPLY) ) /*|| (!com && sess->owner->handle_announce)*/) { e = gf_rtsp_get_response(sess->session, sess->rtsp_rsp); if (e!= GF_IP_NETWORK_EMPTY) { e = RP_ProcessResponse(sess, com, e); /*this is a service connect error -> plugin may be discarded */ if (e!=GF_OK) { RP_RemoveCommand(sess); gf_rtsp_command_del(com); gf_term_on_connect(sess->owner->service, NULL, e); return; } RP_RemoveCommand(sess); gf_rtsp_command_del(com); sess->flags &= ~RTSP_WAIT_REPLY; sess->command_time = 0; } else { /*evaluate timeout*/ time = gf_sys_clock() - sess->command_time; /*don't waste time waiting for teardown ACK, half a sec is enough. If server is not replying in time it is likely to never reply (happens with RTP over RTSP) -> kill session and create new one*/ if (!strcmp(com->method, GF_RTSP_TEARDOWN) && (time>=500) ) time = sess->owner->time_out; //signal what's going on if (time >= sess->owner->time_out) { if (!strcmp(com->method, GF_RTSP_TEARDOWN)) gf_rtsp_session_reset(sess->session, 1); RP_ProcessResponse(sess, com, GF_IP_NETWORK_FAILURE); RP_RemoveCommand(sess); gf_rtsp_command_del(com); sess->flags &= ~RTSP_WAIT_REPLY; sess->command_time = 0; gf_rtsp_reset_aggregation(sess->session); } } return; } if (!com) return; /*send command - check RTSP session state first*/ switch (gf_rtsp_get_session_state(sess->session)) { case GF_RTSP_STATE_WAITING: case GF_RTSP_STATE_WAIT_FOR_CONTROL: return; case GF_RTSP_STATE_INVALIDATED: RP_SendFailure(sess, com, GF_IP_NETWORK_FAILURE); RP_RemoveCommand(sess); gf_rtsp_command_del(com); sess->flags &= ~RTSP_WAIT_REPLY; sess->command_time = 0; return; } /*process*/ com->User_Agent = (char*)gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(sess->owner->service), "Downloader", "UserAgent"); if (!com->User_Agent) com->User_Agent = "GPAC " GPAC_VERSION " RTSP Client"; com->Accept_Language = RTSP_LANGUAGE; /*if no session assigned and a session ID is valid, use it*/ if (sess->session_id && !com->Session) com->Session = sess->session_id; e = GF_OK; /*preprocess describe before sending (always the ESD url thing)*/ if (!strcmp(com->method, GF_RTSP_DESCRIBE)) { com->Session = NULL; if (!RP_PreprocessDescribe(sess, com)) { e = GF_BAD_PARAM; goto exit; } } /*preprocess play/stop/pause before sending (aggregation)*/ if (!strcmp(com->method, GF_RTSP_PLAY) || !strcmp(com->method, GF_RTSP_PAUSE) || !strcmp(com->method, GF_RTSP_TEARDOWN)) { //command is skipped if (!RP_PreprocessUserCom(sess, com)) { e = GF_BAD_PARAM; goto exit; } } e = gf_rtsp_send_command(sess->session, com); if (e) { RP_SendFailure(sess, com, e); RP_ProcessResponse(sess, com, e); } else { sess->command_time = gf_sys_clock(); sess->flags |= RTSP_WAIT_REPLY; } exit: /*reset static strings*/ com->User_Agent = NULL; com->Accept_Language = NULL; com->Session = NULL; /*remove command*/ if (e) { RP_RemoveCommand(sess); gf_rtsp_command_del(com); sess->flags &= ~RTSP_WAIT_REPLY; sess->command_time = 0; } }
static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param) { u32 i; GF_MPD_In *mpdin = (GF_MPD_In *) ifce->proxy_udta; if (!param || !ifce || !ifce->proxy_udta) return GF_BAD_PARAM; /*gets byte range of init segment (for local validation)*/ if (param->command_type==GF_NET_SERVICE_QUERY_INIT_RANGE) { param->url_query.next_url = NULL; param->url_query.start_range = 0; param->url_query.end_range = 0; mpdin->in_seek = 0; for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) { GF_MPDGroup *group; if (!gf_dash_is_group_selected(mpdin->dash, i)) continue; group = gf_dash_get_group_udta(mpdin->dash, i); if (group->segment_ifce == ifce) { gf_dash_group_get_segment_init_url(mpdin->dash, i, ¶m->url_query.start_range, ¶m->url_query.end_range); return GF_OK; } } return GF_SERVICE_ERROR; } /*gets URL and byte range of next segment - if needed, adds butstream switching segment info*/ if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) { Bool group_done; u32 nb_segments_cached; u32 group_idx=0; GF_MPDGroup *group=NULL; const char *src_url; Bool discard_first_cache_entry = 1; u32 timer = gf_sys_clock(); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Query Next request from input service %s\n", ifce->module_name)); param->url_query.discontinuity_type = 0; if (mpdin->in_seek) { mpdin->in_seek = 0; param->url_query.discontinuity_type = 2; discard_first_cache_entry = 0; } for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) { if (!gf_dash_is_group_selected(mpdin->dash, i)) continue; group = gf_dash_get_group_udta(mpdin->dash, i); if (group->segment_ifce == ifce) { group_idx = i; break; } group=NULL; } if (!group) { return GF_SERVICE_ERROR; } while (gf_dash_is_running(mpdin->dash) ) { group_done=0; nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done); if (nb_segments_cached>=2) break; if (group_done) { if (!gf_dash_get_period_switch_status(mpdin->dash) && !gf_dash_in_last_period(mpdin->dash) ) { GF_NetworkCommand com; memset(&com, 0, sizeof(GF_NetworkCommand)); com.command_type = GF_NET_BUFFER_QUERY; while (gf_dash_get_period_switch_status(mpdin->dash) != 1) { gf_term_on_command(mpdin->service, &com, GF_OK); if (!com.buffer.occupancy) { gf_dash_request_period_switch(mpdin->dash); break; } gf_sleep(20); } } return GF_EOS; } gf_sleep(16); } nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done); if (nb_segments_cached < 2) { GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] No more file in cache, EOS\n")); return GF_EOS; } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer))); } if (discard_first_cache_entry) { gf_dash_group_discard_segment(mpdin->dash, group_idx); } gf_dash_group_get_next_segment_location(mpdin->dash, group_idx, ¶m->url_query.next_url, ¶m->url_query.start_range, ¶m->url_query.end_range, ¶m->url_query.next_url_init_or_switch_segment, ¶m->url_query.switch_start_range , ¶m->url_query.switch_end_range, &src_url); { u32 timer2 = gf_sys_clock() - timer ; if (timer2 > 1000) { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waiting for download to end took a long time : %u ms\n", timer2)); } if (param->url_query.end_range) { GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s (Media Range: "LLD"-"LLD")\n", src_url, param->url_query.start_range, param->url_query.end_range)); } else { GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s\n", src_url)); } GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] segment start time %g sec\n", gf_dash_group_current_segment_start_time(mpdin->dash, group_idx) )); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waited %d ms - Elements in cache: %u/%u\n\tCache file name %s\n", timer2, gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done), gf_dash_group_get_max_segments_in_cache(mpdin->dash, group_idx), param->url_query.next_url )); } return GF_OK; } return GF_OK; }