/*locates and loads an input service (demuxer, parser) for this source buffer based on mime type or segment name*/ GF_Err gf_mse_source_buffer_load_parser(GF_HTML_SourceBuffer *sourcebuffer, const char *mime) { GF_InputService *parser = NULL; const char *sPlug; if (mime) { /* strip the 'codecs' and 'profile' parameters from the MIME type */ char *param = (char *)strchr(mime, ';'); if (param) { *param = 0; } /* Check MIME type to start the right InputService */ sPlug = gf_cfg_get_key(sourcebuffer->mediasource->service->term->user->config, "MimeTypes", mime); if (sPlug) sPlug = strrchr(sPlug, '"'); if (sPlug) { sPlug += 2; parser = (GF_InputService *) gf_modules_load_interface_by_name(sourcebuffer->mediasource->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); } if (param) { *param = ';'; } } if (parser) { sourcebuffer->parser = parser; parser->query_proxy = gf_mse_proxy; parser->proxy_udta = sourcebuffer; parser->proxy_type = GF_TRUE; return GF_OK; } else { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MSE] Error locating plugin for source - mime type %s\n", mime)); return GF_BAD_PARAM; } }
GF_FontManager *gf_font_manager_new(GF_User *user) { char *def_font = "SERIF"; u32 i, count; GF_FontManager *font_mgr; GF_FontReader *ifce; const char *opt; ifce = NULL; opt = gf_cfg_get_key(user->config, "FontEngine", "FontReader"); if (opt) { ifce = (GF_FontReader *) gf_modules_load_interface_by_name(user->modules, opt, GF_FONT_READER_INTERFACE); if (ifce && ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); ifce = NULL; } } if (!ifce) { count = gf_modules_get_count(user->modules); for (i=0; i<count; i++) { ifce = (GF_FontReader *) gf_modules_load_interface(user->modules, i, GF_FONT_READER_INTERFACE); if (!ifce) continue; if (ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); ifce = NULL; continue; } gf_cfg_set_key(user->config, "FontEngine", "FontReader", ifce->module_name); break; } } GF_SAFEALLOC(font_mgr, GF_FontManager); font_mgr->reader = ifce; font_mgr->id_buffer_size = 20; font_mgr->id_buffer = gf_malloc(sizeof(u32)*font_mgr->id_buffer_size); gf_font_manager_set_font(font_mgr, &def_font, 1, 0); font_mgr->default_font = font_mgr->font; font_mgr->line_path= gf_path_new(); gf_path_add_move_to(font_mgr->line_path, -FIX_ONE/2, FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, -FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, -FIX_ONE/2, -FIX_ONE/2); gf_path_close(font_mgr->line_path); opt = gf_cfg_get_key(user->config, "FontEngine", "WaitForFontLoad"); if (!opt) gf_cfg_set_key(user->config, "FontEngine", "WaitForFontLoad", "no"); if (opt && !strcmp(opt, "yes")) font_mgr->wait_font_load = 1; return font_mgr; }
/*locates input service (demuxer) based on mime type or segment name*/ static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, u32 group_index, const char *mime, const char *init_segment_name) { GF_InputService *segment_ifce; u32 i; const char *sPlug; if (mime) { /* Check MIME type to start the right InputService */ sPlug = gf_cfg_get_key(mpdin->service->term->user->config, "MimeTypes", mime); if (sPlug) sPlug = strrchr(sPlug, '"'); if (sPlug) { sPlug += 2; segment_ifce = (GF_InputService *) gf_modules_load_interface_by_name(mpdin->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); if (segment_ifce) { GF_MPDGroup *group; GF_SAFEALLOC(group, GF_MPDGroup); group->segment_ifce = segment_ifce; group->segment_ifce->proxy_udta = mpdin; group->segment_ifce->query_proxy = MPD_ClientQuery; group->mpdin = mpdin; group->idx = group_index; gf_dash_set_group_udta(mpdin->dash, group_index, group); return GF_OK; } } } if (init_segment_name) { for (i=0; i< gf_modules_get_count(mpdin->service->term->user->modules); i++) { GF_InputService *ifce = (GF_InputService *) gf_modules_load_interface(mpdin->service->term->user->modules, i, GF_NET_CLIENT_INTERFACE); if (!ifce) continue; if (ifce->CanHandleURL && ifce->CanHandleURL(ifce, init_segment_name)) { GF_MPDGroup *group; GF_SAFEALLOC(group, GF_MPDGroup); group->segment_ifce = ifce; group->segment_ifce->proxy_udta = mpdin; group->segment_ifce->query_proxy = MPD_ClientQuery; group->mpdin = mpdin; group->idx = group_index; gf_dash_set_group_udta(mpdin->dash, group_index, group); return GF_OK; } gf_modules_close_interface((GF_BaseInterface *) ifce); } } GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[MPD_IN] Error locating plugin for segment - mime type %s - name %s\n", mime, init_segment_name)); return GF_CODEC_NOT_FOUND; }
void SR_SetFontEngine(GF_Renderer *sr) { const char *sOpt; u32 i, count; GF_FontRaster *ifce; ifce = NULL; sOpt = gf_cfg_get_key(sr->user->config, "FontEngine", "DriverName"); if (sOpt) ifce = (GF_FontRaster *) gf_modules_load_interface_by_name(sr->user->modules, sOpt, GF_FONT_RASTER_INTERFACE); if (!ifce) { count = gf_modules_get_count(sr->user->modules); for (i=0; i<count; i++) { ifce = (GF_FontRaster *) gf_modules_load_interface(sr->user->modules, i, GF_FONT_RASTER_INTERFACE); if (ifce) { gf_cfg_set_key(sr->user->config, "FontEngine", "DriverName", ifce->module_name); sOpt = ifce->module_name; break; } } } if (!ifce) return; /*cannot init font engine*/ if (ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); return; } /*shutdown current*/ gf_sr_lock(sr, 1); if (sr->font_engine) { sr->font_engine->shutdown_font_engine(sr->font_engine); gf_modules_close_interface((GF_BaseInterface *)sr->font_engine); } sr->font_engine = ifce; /*success*/ gf_cfg_set_key(sr->user->config, "FontEngine", "DriverName", sOpt); sr->draw_next_frame = 1; gf_sr_lock(sr, 0); }
static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char *url, const char *parent_url, Bool no_mime_check, char **out_url, GF_Err *ret_code, GF_DownloadSession **the_session) { u32 i; GF_Err e; char *sURL, *qm, *frag, *ext, *mime_type, *url_res; char szExt[50]; const char *force_module = NULL; GF_InputService *ifce; Bool skip_mime = 0; memset(szExt, 0, sizeof(szExt)); (*ret_code) = GF_OK; ifce = NULL; mime_type = NULL; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Looking for plugin for URL %s\n", url)); *out_url = NULL; sURL = NULL; if (!url || !strncmp(url, "\\\\", 2) ) { (*ret_code) = GF_URL_ERROR; goto exit; } if (!strnicmp(url, "libplayer://", 12)) { force_module = "LibPlayer"; } /*used by GUIs scripts to skip URL concatenation*/ if (!strncmp(url, "gpac://", 7)) sURL = gf_strdup(url+7); /*opera-style localhost URLs*/ else if (!strncmp(url, "file://localhost", 16)) sURL = gf_strdup(url+16); else if (parent_url) sURL = gf_url_concatenate(parent_url, url); /*path absolute*/ if (!sURL) sURL = gf_strdup(url); if (gf_url_is_local(sURL)) gf_url_to_fs_path(sURL); if (the_session) *the_session = NULL; if (no_mime_check) { mime_type = NULL; } else { /*fetch a mime type if any. If error don't even attempt to open the service TRYTOFIXME: it would be nice to reuse the downloader created while fetching the mime type, however we don't know if the plugin will want it threaded or not.... */ mime_type = get_mime_type(term, sURL, &e, the_session); if (e) { (*ret_code) = e; goto exit; } } if (mime_type && (!stricmp(mime_type, "text/plain") || !stricmp(mime_type, "video/quicktime") || !stricmp(mime_type, "application/octet-stream") ) ) { skip_mime = 1; } ifce = NULL; /*load from mime type*/ if (mime_type && !skip_mime) { const char *sPlug = gf_cfg_get_key(term->user->config, "MimeTypes", mime_type); GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Mime type found: %s\n", mime_type)); if (!sPlug) { gf_free(mime_type); mime_type=NULL; } if (sPlug) sPlug = strrchr(sPlug, '"'); if (sPlug) { sPlug += 2; GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug)); ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); if (force_module && ifce && !strstr(ifce->module_name, force_module)) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; } if (ifce && !net_check_interface(ifce) ) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; } } } /* The file extension, if any, is before '?' if any or before '#' if any.*/ url_res = strrchr(sURL, '/'); if (!url_res) url_res = strrchr(sURL, '\\'); if (!url_res) url_res = sURL; qm = strchr(url_res, '?'); if (qm) { qm[0] = 0; ext = strrchr(url_res, '.'); qm[0] = '?'; } else { frag = strchr(url_res, '#'); if (frag) { frag[0] = 0; ext = strrchr(url_res, '.'); frag[0] = '#'; } else { ext = strrchr(url_res, '.'); } } if (ext && !stricmp(ext, ".gz")) { char *anext; ext[0] = 0; anext = strrchr(sURL, '.'); ext[0] = '.'; ext = anext; } /*no mime type: either local or streaming. If streaming discard extension checking*/ if (!ifce && !mime_type && strstr(sURL, "://") && strnicmp(sURL, "file://", 7)) ext = NULL; /*browse extensions for prefered module*/ if (!ifce && ext) { u32 keyCount; strncpy(szExt, &ext[1], 49); ext = strrchr(szExt, '?'); if (ext) ext[0] = 0; ext = strrchr(szExt, '#'); if (ext) ext[0] = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] No mime type found - checking by extension %s\n", szExt)); assert( term && term->user && term->user->modules); keyCount = gf_cfg_get_key_count(term->user->config, "MimeTypes"); for (i=0; i<keyCount; i++) { char *sPlug; const char *sKey; const char *sMime; sMime = gf_cfg_get_key_name(term->user->config, "MimeTypes", i); if (!sMime) continue; sKey = gf_cfg_get_key(term->user->config, "MimeTypes", sMime); if (!sKey) continue; if (!check_extension(sKey, szExt)) continue; sPlug = strrchr(sKey, '"'); if (!sPlug) continue; /*bad format entry*/ sPlug += 2; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Trying module[%i]=%s, mime=%s\n", i, sPlug, sMime)); ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); if (!ifce){ GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] module[%i]=%s, mime=%s, cannot be loaded for GF_NET_CLIENT_INTERFACE.\n", i, sPlug, sMime)); continue; } if (force_module && ifce && !strstr(ifce->module_name, force_module)) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; continue; } if (ifce && !net_check_interface(ifce)) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; continue; } break; } } /*browse all modules*/ if (!ifce) { GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Not found any interface, trying browsing all modules...\n")); for (i=0; i< gf_modules_get_count(term->user->modules); i++) { ifce = (GF_InputService *) gf_modules_load_interface(term->user->modules, i, GF_NET_CLIENT_INTERFACE); if (!ifce) continue; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Checking if module %s supports URL %s\n", ifce->module_name, sURL)); if (force_module && ifce && !strstr(ifce->module_name, force_module)) { } else if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) { break; } gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; } } exit: if (!ifce){ GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Did not find any input plugin for URL %s (%s)\n", sURL ? sURL : url, mime_type ? mime_type : "no mime type")); if (sURL) gf_free(sURL); if ( (*ret_code) == GF_OK) (*ret_code) = GF_NOT_SUPPORTED; *out_url = NULL; if (the_session && *the_session) { gf_dm_sess_del(*the_session); } } else { *out_url = sURL; GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Terminal] Found input plugin %s for URL %s (%s)\n", ifce->module_name, sURL, mime_type ? mime_type : "no mime type")); } if (mime_type) gf_free(mime_type); mime_type = NULL; return ifce; }
GF_AudioRenderer *gf_sc_ar_load(GF_User *user) { const char *sOpt; u32 i, count; u32 num_buffers, total_duration; GF_Err e; GF_AudioRenderer *ar; ar = (GF_AudioRenderer *) gf_malloc(sizeof(GF_AudioRenderer)); memset(ar, 0, sizeof(GF_AudioRenderer)); num_buffers = total_duration = 0; sOpt = gf_cfg_get_key(user->config, "Audio", "ForceConfig"); if (sOpt && !stricmp(sOpt, "yes")) { sOpt = gf_cfg_get_key(user->config, "Audio", "NumBuffers"); num_buffers = sOpt ? atoi(sOpt) : 6; sOpt = gf_cfg_get_key(user->config, "Audio", "TotalDuration"); total_duration = sOpt ? atoi(sOpt) : 400; } sOpt = gf_cfg_get_key(user->config, "Audio", "NoResync"); ar->disable_resync = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; sOpt = gf_cfg_get_key(user->config, "Audio", "DisableMultiChannel"); ar->disable_multichannel = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; ar->mixer = gf_mixer_new(ar); ar->user = user; sOpt = gf_cfg_get_key(user->config, "Audio", "Volume"); ar->volume = sOpt ? atoi(sOpt) : 75; sOpt = gf_cfg_get_key(user->config, "Audio", "Pan"); ar->pan = sOpt ? atoi(sOpt) : 50; if (! (user->init_flags & GF_TERM_NO_AUDIO) ) { /*get a prefered compositor*/ sOpt = gf_cfg_get_key(user->config, "Audio", "DriverName"); if (sOpt) { ar->audio_out = (GF_AudioOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_AUDIO_OUTPUT_INTERFACE); if (!ar->audio_out) { ar->audio_out = NULL; sOpt = NULL; } } if (!ar->audio_out) { GF_AudioOutput *raw_out = NULL; count = gf_modules_get_count(ar->user->modules); for (i=0; i<count; i++) { ar->audio_out = (GF_AudioOutput *) gf_modules_load_interface(ar->user->modules, i, GF_AUDIO_OUTPUT_INTERFACE); if (!ar->audio_out) continue; //in enum mode, only use raw out if everything else failed ... if (!stricmp(ar->audio_out->module_name, "Raw Audio Output")) { raw_out = ar->audio_out; ar->audio_out = NULL; continue; } GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Audio output module %s loaded\n", ar->audio_out->module_name)); /*check that's a valid audio compositor*/ if ((ar->audio_out->SelfThreaded && ar->audio_out->SetPriority) || ar->audio_out->WriteAudio) { /*remember the module we use*/ gf_cfg_set_key(user->config, "Audio", "DriverName", ar->audio_out->module_name); break; } gf_modules_close_interface((GF_BaseInterface *)ar->audio_out); ar->audio_out = NULL; } if (raw_out) { if (ar->audio_out) gf_modules_close_interface((GF_BaseInterface *)raw_out); else ar->audio_out = raw_out; } } /*if not init we run with a NULL audio compositor*/ if (ar->audio_out) { ar->audio_out->FillBuffer = gf_ar_fill_output; ar->audio_out->audio_renderer = ar; GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Setting up audio module %s\n", ar->audio_out->module_name)); e = ar->audio_out->Setup(ar->audio_out, ar->user->os_window_handler, num_buffers, total_duration); /*load main audio filter*/ gf_afc_load(&ar->filter_chain, user, (char*)gf_cfg_get_key(user->config, "Audio", "Filter")); if (e != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("Could not setup audio out %s\n", ar->audio_out->module_name)); gf_modules_close_interface((GF_BaseInterface *)ar->audio_out); ar->audio_out = NULL; } else { if (!ar->audio_out->SelfThreaded) { ar->th = gf_th_new("AudioRenderer"); gf_th_run(ar->th, gf_ar_proc, ar); } else { gf_ar_setup_output_format(ar); if (ar->audio_out->SetPriority) ar->audio_out->SetPriority(ar->audio_out, GF_THREAD_PRIORITY_REALTIME); } } } if (!ar->audio_out) { gf_cfg_set_key(user->config, "Audio", "DriverName", "No Audio Output Available"); } else { if (user->init_flags & GF_TERM_USE_AUDIO_HW_CLOCK) ar->clock_use_audio_out = GF_TRUE; } } /*init compositor timer*/ ar->start_time = gf_sys_clock_high_res(); ar->current_time = 0; return ar; }
static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) { char szPrefDec[500]; const char *sOpt; GF_BaseDecoder *ifce, *dec_ifce; u32 i, plugCount; u32 ifce_type; char *cfg; u32 cfg_size, dec_confidence; GF_Terminal *term = codec->odm->term; if (esd->decoderConfig->decoderSpecificInfo) { cfg = esd->decoderConfig->decoderSpecificInfo->data; cfg_size = esd->decoderConfig->decoderSpecificInfo->dataLength; } else { cfg = NULL; cfg_size = 0; } switch (esd->decoderConfig->streamType) { case GF_STREAM_AUDIO: case GF_STREAM_VISUAL: case GF_STREAM_ND_SUBPIC: ifce_type = GF_MEDIA_DECODER_INTERFACE; codec->process = MediaCodec_Process; break; case GF_STREAM_PRIVATE_MEDIA: ifce_type = GF_PRIVATE_MEDIA_DECODER_INTERFACE; codec->process = gf_codec_process_private_media; break; case GF_STREAM_PRIVATE_SCENE: ifce_type = GF_SCENE_DECODER_INTERFACE; codec->process = PrivateScene_Process; break; default: ifce_type = GF_SCENE_DECODER_INTERFACE; codec->process = SystemCodec_Process; if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_AFX) { ifce_type = GF_NODE_DECODER_INTERFACE; } break; } /*a bit dirty, if FFMPEG is used for demuxer load it for decoder too*/ if (0 && !stricmp(codec->odm->net_service->ifce->module_name, "FFMPEG demuxer")) { sOpt = "FFMPEG decoder"; } else { /*use user-defined module if any*/ sOpt = NULL; switch (esd->decoderConfig->streamType) { case GF_STREAM_VISUAL: if ((esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG) || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_PNG)) sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefImageDec"); else sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefVideoDec"); break; case GF_STREAM_AUDIO: sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefAudioDec"); break; default: break; } } dec_confidence = 0; ifce = NULL; if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); if (ifce) { if (ifce->CanHandleStream) { dec_confidence = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); if (dec_confidence==GF_CODEC_SUPPORTED) { codec->decio = ifce; return GF_OK; } if (dec_confidence==GF_CODEC_NOT_SUPPORTED) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; } } else { gf_modules_close_interface((GF_BaseInterface *) ifce); } } } dec_ifce = ifce; /*prefered codec module per streamType/objectType from config*/ sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); sOpt = gf_cfg_get_key(term->user->config, "Systems", szPrefDec); if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); if (ifce) { if (ifce->CanHandleStream) { u32 conf = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); if ((conf!=GF_CODEC_NOT_SUPPORTED) && (conf>=dec_confidence)) { /*switch*/ if (dec_ifce) gf_modules_close_interface((GF_BaseInterface *) dec_ifce); dec_confidence = conf; dec_ifce = ifce; ifce = NULL; if (dec_confidence==GF_CODEC_SUPPORTED) { codec->decio = dec_ifce; return GF_OK; } } } if (ifce) gf_modules_close_interface((GF_BaseInterface *) ifce); } } /*not found, check all modules*/ plugCount = gf_modules_get_count(term->user->modules); for (i = 0; i < plugCount ; i++) { ifce = (GF_BaseDecoder *) gf_modules_load_interface(term->user->modules, i, ifce_type); if (!ifce) continue; if (ifce->CanHandleStream) { u32 conf = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); if ((conf!=GF_CODEC_NOT_SUPPORTED) && (conf>=dec_confidence)) { /*switch*/ if (dec_ifce) gf_modules_close_interface((GF_BaseInterface *) dec_ifce); dec_confidence = conf; dec_ifce = ifce; ifce = NULL; } } if (ifce) gf_modules_close_interface((GF_BaseInterface *) ifce); } if (dec_ifce) { codec->decio = dec_ifce; sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); gf_cfg_set_key(term->user->config, "Systems", szPrefDec, dec_ifce->module_name); return GF_OK; } return GF_CODEC_NOT_FOUND; }
static GF_Renderer *SR_New(GF_User *user) { const char *sOpt; GF_VisualRenderer *vrend; GF_GLConfig cfg, *gl_cfg; Bool forced = 1; GF_Renderer *tmp; GF_SAFEALLOC(tmp, GF_Renderer); if (!tmp) return NULL; tmp->user = user; /*load renderer to check for GL flag*/ if (! (user->init_flags & (GF_TERM_FORCE_2D | GF_TERM_FORCE_3D)) ) { sOpt = gf_cfg_get_key(user->config, "Rendering", "RendererName"); if (sOpt) { tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RENDERER_INTERFACE); if (!tmp->visual_renderer) sOpt = NULL; } forced = 0; } if (!tmp->visual_renderer) { u32 i, count; count = gf_modules_get_count(user->modules); for (i=0; i<count; i++) { tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface(user->modules, i, GF_RENDERER_INTERFACE); if (tmp->visual_renderer) { if ((tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_2D)) || (!tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_3D)) ) { GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Renderer] Renderer %s loaded but not matching init flags %08x\n", tmp->visual_renderer->module_name, user->init_flags)); gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer); tmp->visual_renderer = NULL; continue; } break; } } if (!forced && tmp->visual_renderer) gf_cfg_set_key(user->config, "Rendering", "RendererName", tmp->visual_renderer->module_name); } if (!tmp->visual_renderer) { GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Renderer] Cannot load any visual renderer - aborting\n")); free(tmp); return NULL; } memset(&cfg, 0, sizeof(cfg)); cfg.double_buffered = 1; gl_cfg = tmp->visual_renderer->bNeedsGL ? &cfg : NULL; vrend = tmp->visual_renderer; tmp->visual_renderer = NULL; /*load video out*/ sOpt = gf_cfg_get_key(user->config, "Video", "DriverName"); if (sOpt) { tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_VIDEO_OUTPUT_INTERFACE); if (tmp->video_out) { tmp->video_out->evt_cbk_hdl = tmp; tmp->video_out->on_event = gf_sr_on_event; /*init hw*/ if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); tmp->video_out = NULL; } } else { sOpt = NULL; } } if (!tmp->video_out) { u32 i, count; count = gf_modules_get_count(user->modules); for (i=0; i<count; i++) { tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface(user->modules, i, GF_VIDEO_OUTPUT_INTERFACE); if (!tmp->video_out) continue; tmp->video_out->evt_cbk_hdl = tmp; tmp->video_out->on_event = gf_sr_on_event; /*init hw*/ if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg)==GF_OK) { gf_cfg_set_key(user->config, "Video", "DriverName", tmp->video_out->module_name); break; } gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); tmp->video_out = NULL; } } tmp->visual_renderer = vrend; if (!tmp->video_out ) { gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer); free(tmp); return NULL; } /*try to load a raster driver*/ sOpt = gf_cfg_get_key(user->config, "Rendering", "Raster2D"); if (sOpt) { tmp->r2d = (GF_Raster2D *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RASTER_2D_INTERFACE); if (!tmp->r2d) { sOpt = NULL; } else if (!check_graphics2D_driver(tmp->r2d)) { gf_modules_close_interface((GF_BaseInterface *)tmp->r2d); tmp->r2d = NULL; sOpt = NULL; } } if (!tmp->r2d) { u32 i, count; count = gf_modules_get_count(user->modules); for (i=0; i<count; i++) { tmp->r2d = (GF_Raster2D *) gf_modules_load_interface(user->modules, i, GF_RASTER_2D_INTERFACE); if (!tmp->r2d) continue; if (check_graphics2D_driver(tmp->r2d)) break; gf_modules_close_interface((GF_BaseInterface *)tmp->r2d); tmp->r2d = NULL; } if (tmp->r2d) gf_cfg_set_key(user->config, "Rendering", "Raster2D", tmp->r2d->module_name); } /*and init*/ if (tmp->visual_renderer->LoadRenderer(tmp->visual_renderer, tmp) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer); tmp->video_out->Shutdown(tmp->video_out); gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); free(tmp); return NULL; } tmp->mx = gf_mx_new(); tmp->textures = gf_list_new(); tmp->frame_rate = 30.0; tmp->frame_duration = 33; tmp->time_nodes = gf_list_new(); #ifdef GF_SR_EVENT_QUEUE tmp->events = gf_list_new(); tmp->ev_mx = gf_mx_new(); #endif SR_ResetFrameRate(tmp); /*set font engine if any*/ SR_SetFontEngine(tmp); tmp->extra_scenes = gf_list_new(); tmp->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR | GF_INTERACT_NAVIGATION; return tmp; }