GF_EXPORT GF_Err gf_term_process_flush(GF_Terminal *term) { u32 i; CodecEntry *ce; if (!(term->flags & GF_TERM_NO_COMPOSITOR_THREAD) ) return GF_BAD_PARAM; /*update till frame mature*/ while (1) { if (term->flags & GF_TERM_NO_DECODER_THREAD) { gf_term_handle_services(term); gf_mx_p(term->mm_mx); i=0; while ((ce = (CodecEntry*)gf_list_enum(term->codecs, &i))) { gf_codec_process(ce->dec, 10000); } gf_mx_v(term->mm_mx); } if (!gf_sc_draw_frame(term->compositor, NULL)) break; if (! (term->user->init_flags & GF_TERM_NO_REGULATION)) break; } return GF_OK; }
GF_EXPORT GF_Err gf_term_process_flush(GF_Terminal *term) { u32 i; CodecEntry *ce; if (!(term->flags & GF_TERM_NO_COMPOSITOR_THREAD) ) return GF_BAD_PARAM; /*update till frame mature*/ while (1) { if (term->flags & GF_TERM_NO_DECODER_THREAD) { gf_term_handle_services(term); gf_mx_p(term->mm_mx); i=0; while ((ce = (CodecEntry*)gf_list_enum(term->codecs, &i))) { gf_codec_process(ce->dec, 10000); } gf_mx_v(term->mm_mx); } if (!gf_sc_draw_frame(term->compositor, 1, NULL)) { if (!term->root_scene || !term->root_scene->root_od) break; if (gf_list_count(term->media_queue) ) continue; //wait for audio to be flushed if (gf_sc_check_audio_pending(term->compositor) ) continue; //force end of buffer if (gf_scene_check_clocks(term->root_scene->root_od->net_service, term->root_scene, 1)) break; } if (! (term->user->init_flags & GF_TERM_NO_REGULATION)) break; } return GF_OK; }
static u32 MM_SimulationStep_Decoder(GF_Terminal *term, u32 *nb_active_decs) { CodecEntry *ce; GF_Err e; u32 count, remain; u32 time_taken, time_slice, time_left; #ifndef GF_DISABLE_LOG term->compositor->networks_time = gf_sys_clock(); #endif // GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Media Manager] Entering simultion step\n")); gf_term_handle_services(term); #ifndef GF_DISABLE_LOG term->compositor->networks_time = gf_sys_clock() - term->compositor->networks_time; #endif #ifndef GF_DISABLE_LOG term->compositor->decoders_time = gf_sys_clock(); #endif gf_mx_p(term->mm_mx); count = gf_list_count(term->codecs); time_left = term->frame_duration; *nb_active_decs = 0; if (term->last_codec >= count) term->last_codec = 0; remain = count; /*this is ultra basic a nice scheduling system would be much better*/ while (remain) { ce = (CodecEntry*)gf_list_get(term->codecs, term->last_codec); if (!ce) break; if (!(ce->flags & GF_MM_CE_RUNNING) || (ce->flags & GF_MM_CE_THREADED) || ce->dec->force_cb_resize) { remain--; if (!remain) break; term->last_codec = (term->last_codec + 1) % count; continue; } time_slice = ce->dec->Priority * time_left / term->cumulated_priority; if (ce->dec->PriorityBoost) time_slice *= 2; time_taken = gf_sys_clock(); (*nb_active_decs) ++; e = gf_codec_process(ce->dec, time_slice); time_taken = gf_sys_clock() - time_taken; /*avoid signaling errors too often...*/ #ifndef GPAC_DISABLE_LOG if (e) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODM%d] Decoding Error %s\n", ce->dec->odm->OD->objectDescriptorID, gf_error_to_string(e) )); } else { //GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] Decode time slice %d ms out of %d ms\n", ce->dec->decio ? ce->dec->decio->module_name : "RAW", time_taken, time_left )); } #endif if (ce->flags & GF_MM_CE_DISCARDED) { gf_free(ce); gf_list_rem(term->codecs, term->last_codec); count--; if (!count) break; } else { if (ce->dec->CB && (ce->dec->CB->UnitCount >= ce->dec->CB->Min)) ce->dec->PriorityBoost = 0; } term->last_codec = (term->last_codec + 1) % count; remain -= 1; if (time_left > time_taken) { time_left -= time_taken; if (!remain) break; } else { time_left = 0; break; } } gf_mx_v(term->mm_mx); #ifndef GF_DISABLE_LOG term->compositor->decoders_time = gf_sys_clock() - term->compositor->decoders_time; #endif return time_left; }