Project

General

Profile

probe.cc.diff

Jim Turner, August 07, 2022 04:50

View differences:

src/libaudcore/probe.cc
109 109
            ext_matches.append(plugin);
110 110
    }
111 111

  
112
    if (ext_matches.len() == 1)
112
    /* NOTE:Must not return Vorbis plugin without probing first, since not all .ogg entries are Vorbis! */
113
    if (ext_matches.len() == 1 && !strstr(aud_plugin_get_name(ext_matches[0]), "Ogg Vorbis Decoder"))
113 114
    {
114 115
        AUDINFO("Matched %s by extension.\n",
115 116
                aud_plugin_get_name(ext_matches[0]));
......
131 132

  
132 133
    String mime = file.get_metadata("content-type");
133 134

  
135
    /* NOTE: Ogg-memed (ogg-wrapped) data requires careful handling, since flac or vorbis can grab the
136
       entry but later fail to play (long after we're done probing)!  We can test vorbis here "by content"
137
       but flac can play flac data embedded in ogg files, but will fail these "by content".  However,
138
       other stuff, ie. opus can be embedded in ogg files, which both will grab(mime), then fail to play,
139
       so we must do a special probe of these here too and "fall through", which allows ffaudio to catch
140
       and play later!  We prefer to try & match the "good" ones w/flac or vorbis if possible as they are
141
       generally preffered (higher priority) over ffaudio.
142
    */
134 143
    if (mime)
135 144
    {
136
        for (PluginHandle * plugin : (ext_matches.len() ? ext_matches : list))
145
        const char * mime_is_oggish = strstr_nocase(mime, "ogg"); // MUST CHECK BOTH FLAC & VORBIS FOR OGG MIMES!
146
        for (PluginHandle * plugin : (!mime_is_oggish && ext_matches.len() ? ext_matches : list))
137 147
        {
138 148
            if (!aud_plugin_get_enabled(plugin))
139 149
                continue;
......
142 152
            {
143 153
                AUDINFO("Matched %s by MIME type %s.\n",
144 154
                        aud_plugin_get_name(plugin), (const char *)mime);
145
                return plugin;
155
                if (!mime_is_oggish)  // Not an ogg mimetype, so we'll use first matching plugin.
156
                    return plugin;
157
                else if (strstr(aud_plugin_get_name(plugin), "FLAC Decoder")) // Trying flac decoder for ogg:
158
                {
159
                    /* Must probe flac here b/c flac's "our_file()" can fail some valid ogg-wrapped flac! */
160
                    char buf[35];
161
                    if (!file.fseek(0, VFS_SEEK_SET) && file.fread(buf, 1, sizeof buf) == sizeof buf
162
                            && (!strncmp(buf+29, "FLAC", 4) || !strncmp(buf+29, "Flac", 4)
163
                            || !strncmp(buf+29, "flac", 4)))  // Need a "strncmp_nocase()" here!
164
                        return plugin;  // will use flac plugin.
165
                }
166
                else if (strstr(aud_plugin_get_name(plugin), "Ogg Vorbis Decoder")) // Trying vorbis decoder for ogg:
167
                {
168
                    /* We now test vorbis in it's "our_file" fn as it should only grab valid vorbis data. */
169
                    auto ip = (InputPlugin *)aud_plugin_get_header(plugin);
170
                    if (ip && ip->is_our_file(filename, file))
171
                        return plugin;  // will use vorbis plugin.
172
                }
146 173
            }
147 174
        }
148 175
    }