Commit aa4c7ce7 authored by Thomas Guillem's avatar Thomas Guillem

input: item: fix false positives when matching slaves

 - don't match 2 possible slaves between each others
 - The slave name len should not be twice longer than the item name len.
   (avoid matching "2016 - blabla.aac" with "20.mkv" for example)

The matching algorithm is still quite dumb and far from perfect. We should
detect item as slaves only if they have a language indication in their path
name.

Fixes #18913
parent 877b09d3
...@@ -1456,6 +1456,13 @@ static uint8_t rdh_get_slave_priority(input_item_t *p_item, ...@@ -1456,6 +1456,13 @@ static uint8_t rdh_get_slave_priority(input_item_t *p_item,
if (!psz_item_name || !psz_slave_name) if (!psz_item_name || !psz_slave_name)
goto done; goto done;
size_t i_item_len = strlen(psz_item_name);
size_t i_slave_len = strlen(psz_slave_name);
/* The slave name len should not be twice longer than the item name len. */
if (i_item_len > i_slave_len || i_slave_len > 2 * i_item_len)
goto done;
/* check if the names match exactly */ /* check if the names match exactly */
if (!strcmp(psz_item_name, psz_slave_name)) if (!strcmp(psz_item_name, psz_slave_name))
{ {
...@@ -1546,6 +1553,10 @@ static void rdh_attach_slaves(struct vlc_readdir_helper *p_rdh, ...@@ -1546,6 +1553,10 @@ static void rdh_attach_slaves(struct vlc_readdir_helper *p_rdh,
input_item_node_t *p_node = p_parent_node->pp_children[i]; input_item_node_t *p_node = p_parent_node->pp_children[i];
input_item_t *p_item = p_node->p_item; input_item_t *p_item = p_node->p_item;
enum slave_type unused;
if (input_item_slave_GetType(p_item->psz_name, &unused))
continue; /* don't match 2 possible slaves between each others */
for (size_t j = 0; j < p_rdh->i_slaves; j++) for (size_t j = 0; j < p_rdh->i_slaves; j++)
{ {
struct rdh_slave *p_rdh_slave = p_rdh->pp_slaves[j]; struct rdh_slave *p_rdh_slave = p_rdh->pp_slaves[j];
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <vlc_threads.h> #include <vlc_threads.h>
#define SLAVES_DIR SRCDIR "/samples/slaves" #define SLAVES_DIR SRCDIR "/samples/slaves"
#define MAIN_MEDIA_PATH SLAVES_DIR "/test.mp4"
static void static void
finished_event(const libvlc_event_t *p_ev, void *p_data) finished_event(const libvlc_event_t *p_ev, void *p_data)
...@@ -106,6 +105,7 @@ test_expected_slaves(libvlc_media_t *p_m, ...@@ -106,6 +105,7 @@ test_expected_slaves(libvlc_media_t *p_m,
static void static void
test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc, test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc,
const char *psz_main_media,
libvlc_media_slave_t *p_expected_slaves, libvlc_media_slave_t *p_expected_slaves,
unsigned i_expected_slaves) unsigned i_expected_slaves)
{ {
...@@ -115,7 +115,7 @@ test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc, ...@@ -115,7 +115,7 @@ test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc,
printf("Parse media dir to get subitems\n"); printf("Parse media dir to get subitems\n");
media_parse_sync(p_m); media_parse_sync(p_m);
char *psz_main_media_mrl = path_to_mrl(p_vlc, MAIN_MEDIA_PATH); char *psz_main_media_mrl = path_to_mrl(p_vlc, psz_main_media);
assert(psz_main_media_mrl != NULL); assert(psz_main_media_mrl != NULL);
printf("Main media mrl: '%s'\n", psz_main_media_mrl); printf("Main media mrl: '%s'\n", psz_main_media_mrl);
...@@ -159,17 +159,17 @@ main (void) ...@@ -159,17 +159,17 @@ main (void)
test_init(); test_init();
const char *pp_slave_paths[] = { const char *pp_slave_paths[] = {
SLAVES_DIR "/nomatch.srt",
SLAVES_DIR "/left-test.srt",
SLAVES_DIR "/test-right.srt",
SLAVES_DIR "/test.aac", SLAVES_DIR "/test.aac",
SLAVES_DIR "/test.rt.srt",
SLAVES_DIR "/lt-test.srt",
SLAVES_DIR "/nomatch.srt",
}; };
libvlc_media_slave_t p_expected_slaves[] = { libvlc_media_slave_t p_expected_slaves[] = {
{ NULL, libvlc_media_slave_type_subtitle, 0 /* none */ },
{ NULL, libvlc_media_slave_type_subtitle, 1 /* left */ },
{ NULL, libvlc_media_slave_type_subtitle, 2 /* right */ },
{ NULL, libvlc_media_slave_type_audio, 3 /* all */ }, { NULL, libvlc_media_slave_type_audio, 3 /* all */ },
{ NULL, libvlc_media_slave_type_subtitle, 2 /* right */ },
{ NULL, libvlc_media_slave_type_subtitle, 1 /* left */ },
{ NULL, libvlc_media_slave_type_subtitle, 0 /* none */ },
}; };
#define EXPECTED_SLAVES_COUNT (sizeof(p_expected_slaves) / sizeof(*p_expected_slaves)) #define EXPECTED_SLAVES_COUNT (sizeof(p_expected_slaves) / sizeof(*p_expected_slaves))
...@@ -194,16 +194,45 @@ main (void) ...@@ -194,16 +194,45 @@ main (void)
assert(p_expected_slaves[i].psz_uri != NULL); assert(p_expected_slaves[i].psz_uri != NULL);
} }
printf("== Test if a media has slaves from its parent ==\n"); printf("== Testing --sub-autodetect-fuzzy 1 (everything) ==\n");
test_media_has_slaves_from_parent(p_vlc, p_expected_slaves, test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4",
p_expected_slaves,
EXPECTED_SLAVES_COUNT); EXPECTED_SLAVES_COUNT);
libvlc_release(p_vlc); libvlc_release(p_vlc);
printf("== Test if a media doesn't have slaves from its parent ==\n"); printf("== Testing --sub-autodetect-fuzzy 2 (full, left, and right match) ==\n");
pp_args[2] = "2";
p_vlc = libvlc_new(ARGC - 1, pp_args);
assert(p_vlc != NULL);
test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4",
p_expected_slaves, 3);
printf("== Testing if the matching is not too permissive ==\n");
test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/t.mp4",
NULL, 0);
libvlc_release(p_vlc);
printf("== Testing --sub-autodetect-fuzzy 3 (full and left match) ==\n");
pp_args[2] = "3";
p_vlc = libvlc_new(ARGC - 1, pp_args);
assert(p_vlc != NULL);
test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4",
p_expected_slaves, 2);
libvlc_release(p_vlc);
printf("== Testing --sub-autodetect-fuzzy 4 (full match) ==\n");
pp_args[2] = "4";
p_vlc = libvlc_new(ARGC - 1, pp_args);
assert(p_vlc != NULL);
test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4",
p_expected_slaves, 1);
libvlc_release(p_vlc);
printf("== Testing --no-sub-autodetect-file (no match) ==\n");
pp_args[ARGC - 1] = "--no-sub-autodetect-file"; pp_args[ARGC - 1] = "--no-sub-autodetect-file";
p_vlc = libvlc_new(ARGC, pp_args); p_vlc = libvlc_new(ARGC, pp_args);
assert(p_vlc != NULL); assert(p_vlc != NULL);
test_media_has_slaves_from_parent(p_vlc, NULL, 0); test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4", NULL, 0);
libvlc_release(p_vlc); libvlc_release(p_vlc);
for (unsigned int i = 0; i < EXPECTED_SLAVES_COUNT; ++i) for (unsigned int i = 0; i < EXPECTED_SLAVES_COUNT; ++i)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment