Mercurial > audlegacy
diff src/audacious/input.c @ 3959:a575c29cee05
- revive on-demand metadata retrieving. in the combination with "Detect file formats on demand", now audacious can load large directory in a few seconds.
- revise ext_hash to have lists of input plugins which associated with each extension.
- now input_check_file() makes use of ext_hash for file format probing to avoid full scan in the input list.
- make "detect file formats on demand" default.
- change tooltip text for on demand {detect|metadata}.
- move update request for playlist from idle function to event queue.
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Sat, 17 Nov 2007 17:07:46 +0900 |
parents | b747ad540903 |
children | 572258c68dfb |
line wrap: on
line diff
--- a/src/audacious/input.c Fri Nov 16 18:55:48 2007 +0100 +++ b/src/audacious/input.c Sat Nov 17 17:07:46 2007 +0900 @@ -306,6 +306,60 @@ } } + +/* do actual probing. this function is called from input_check_file() */ +static ProbeResult * +input_do_check_file(InputPlugin *ip, VFSFile *fd, gchar *filename_proxy, gboolean loading) +{ + ProbeResult *pr = NULL; + gint result = 0; + + g_return_val_if_fail(fd != NULL, NULL); + + vfs_rewind(fd); + + if (ip->probe_for_tuple && + cfg.use_pl_metadata && + (!loading || (loading && cfg.get_info_on_load)) ) { + + Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd); + + if (tuple != NULL) { + pr = g_new0(ProbeResult, 1); + pr->ip = ip; + pr->tuple = tuple; + tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy)); + + return pr; + } + } + + else if (ip->is_our_file_from_vfs != NULL) { + result = ip->is_our_file_from_vfs(filename_proxy, fd); + + if (result > 0) { + pr = g_new0(ProbeResult, 1); + pr->ip = ip; + + return pr; + } + } + + else if (ip->is_our_file != NULL) { + result = ip->is_our_file(filename_proxy); + + if (result > 0) { + pr = g_new0(ProbeResult, 1); + pr->ip = ip; + + return pr; + } + } + + return NULL; +} + + /* * input_check_file() * @@ -341,9 +395,15 @@ * Adapted to return ProbeResult structure. * * --nenolod, Jul 20 2007 + * + * Make use of ext_hash to avoid full scan in input list. + * + * --yaz, Nov 16 2007 */ + +/* if loading is TRUE, tuple probing can be skipped as regards configuration. */ ProbeResult * -input_check_file(const gchar * filename, gboolean show_warning) +input_check_file(const gchar *filename, gboolean loading) { VFSFile *fd; GList *node; @@ -351,20 +411,23 @@ gchar *filename_proxy; gint ret = 1; gchar *ext, *tmp, *tmp_uri; - gboolean use_ext_filter; + gboolean use_ext_filter = FALSE; gchar *mimetype; ProbeResult *pr = NULL; + GList **list_hdr = NULL; + extern GHashTable *ext_hash; filename_proxy = g_strdup(filename); + /* Some URIs will end in ?<subsong> to determine the subsong requested. */ tmp_uri = g_strdup(filename); - tmp = strrchr(tmp_uri, '?'); if (tmp != NULL && g_ascii_isdigit(*(tmp + 1))) *tmp = '\0'; + /* Check for plugins with custom URI:// strings */ /* cue:// cdda:// tone:// tact:// */ if ((ip = uri_get_plugin(filename)) != NULL && ip->enabled) @@ -384,6 +447,8 @@ return NULL; } + + // open the file with vfs sub-system fd = vfs_buffered_file_new_from_uri(tmp_uri); g_free(tmp_uri); @@ -393,149 +458,90 @@ return NULL; } - ext = strrchr(filename_proxy, '.') + 1; - use_ext_filter = - (fd != NULL && (!g_strncasecmp(filename, "/", 1) || - !g_strncasecmp(filename, "file://", 7))) ? TRUE : FALSE; - + // apply mimetype check. note that stdio does not support mimetype check. mimetype = vfs_get_metadata(fd, "content-type"); - if ((ip = mime_get_plugin(mimetype)) != NULL && ip->enabled) - { - if (ip->probe_for_tuple != NULL) - { - Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd); + if ((ip = mime_get_plugin(mimetype)) != NULL && ip->enabled) { + while(1) { + if (!ip || !ip->enabled) + continue; - if (tuple != NULL) - { + pr = input_do_check_file(ip, fd, filename_proxy, loading); + + if(pr) { g_free(filename_proxy); vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - pr->tuple = tuple; - tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy)); - - return pr; - } - } - else if (fd && ip->is_our_file_from_vfs != NULL) - { - ret = ip->is_our_file_from_vfs(filename_proxy, fd); - - if (ret > 0) - { - g_free(filename_proxy); - vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - - return pr; - } - } - else if (ip->is_our_file != NULL) - { - ret = ip->is_our_file(filename_proxy); - - if (ret > 0) - { - g_free(filename_proxy); - vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - return pr; } } } - for (node = get_input_list(); node != NULL; node = g_list_next(node)) - { + + // apply ext_hash check + if(cfg.use_extension_probing) { + use_ext_filter = + (fd != NULL && (!g_strncasecmp(filename, "/", 1) || + !g_strncasecmp(filename, "file://", 7))) ? TRUE : FALSE; + } + + if(use_ext_filter) { + gchar *base, *lext; + gchar *tmp2 = g_filename_from_uri(filename_proxy, NULL, NULL); + gchar *realfn = g_strdup(tmp2 ? tmp2 : filename_proxy); + g_free(tmp2); + + base = g_path_get_basename(realfn); + g_free(realfn); + ext = strrchr(base, '.'); + + if(ext) { + lext = g_ascii_strdown(ext+1, -1); + list_hdr = g_hash_table_lookup(ext_hash, lext); + g_free(lext); + } + g_free(base); + + if(list_hdr) { + for(node = *list_hdr; node != NULL; node = g_list_next(node)) { + ip = INPUT_PLUGIN(node->data); + + if (!ip || !ip->enabled) + continue; + + pr = input_do_check_file(ip, fd, filename_proxy, loading); + + if(pr) { + g_free(filename_proxy); + vfs_fclose(fd); + return pr; + } + } + } + + return NULL; // no plugin found. + } + + + // do full scan when extension match isn't specified. + for (node = get_input_list(); node != NULL; node = g_list_next(node)) { ip = INPUT_PLUGIN(node->data); if (!ip || !ip->enabled) continue; - vfs_rewind(fd); - - if (cfg.use_extension_probing == TRUE && ip->vfs_extensions != NULL && - ext != NULL && ext != (gpointer) 0x1 && use_ext_filter == TRUE) - { - gint i; - gboolean is_our_ext = FALSE; - - for (i = 0; ip->vfs_extensions[i] != NULL; i++) - { - if (str_has_prefix_nocase(ext, ip->vfs_extensions[i])) - { - is_our_ext = TRUE; - break; - } - } - - /* not a plugin that supports this extension */ - if (is_our_ext == FALSE) - continue; - } - - if (fd && ip->probe_for_tuple != NULL) - { - Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd); - - if (tuple != NULL) - { - g_free(filename_proxy); - vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - pr->tuple = tuple; - tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy)); + pr = input_do_check_file(ip, fd, filename_proxy, loading); - return pr; - } - } - else if (fd && ip->is_our_file_from_vfs != NULL) - { - ret = ip->is_our_file_from_vfs(filename_proxy, fd); - - if (ret > 0) - { - g_free(filename_proxy); - vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - - return pr; - } + if(pr) { + g_free(filename_proxy); + vfs_fclose(fd); + return pr; } - else if (ip->is_our_file != NULL) - { - ret = ip->is_our_file(filename_proxy); - - if (ret > 0) - { - g_free(filename_proxy); - vfs_fclose(fd); - - pr = g_new0(ProbeResult, 1); - pr->ip = ip; - - return pr; - } - } - - if (ret <= -1) - break; } + + // all probing failed. return NULL g_free(filename_proxy); - vfs_fclose(fd); - return NULL; }