From aa4c7ce7952252d0196cb539b582313ca3f93d99 Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Mon, 6 Nov 2017 15:39:07 +0100 Subject: [PATCH] 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 --- src/input/item.c | 11 ++++ test/libvlc/slaves.c | 53 ++++++++++++++----- .../slaves/{left-test.srt => lt-test.srt} | 0 test/samples/slaves/{test-right.srt => t.mp4} | 0 test/samples/slaves/test.rt.srt | 0 5 files changed, 52 insertions(+), 12 deletions(-) rename test/samples/slaves/{left-test.srt => lt-test.srt} (100%) rename test/samples/slaves/{test-right.srt => t.mp4} (100%) create mode 100644 test/samples/slaves/test.rt.srt diff --git a/src/input/item.c b/src/input/item.c index 0327e21f03..11cfccf8f7 100644 --- a/src/input/item.c +++ b/src/input/item.c @@ -1456,6 +1456,13 @@ static uint8_t rdh_get_slave_priority(input_item_t *p_item, if (!psz_item_name || !psz_slave_name) 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 */ if (!strcmp(psz_item_name, psz_slave_name)) { @@ -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_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++) { struct rdh_slave *p_rdh_slave = p_rdh->pp_slaves[j]; diff --git a/test/libvlc/slaves.c b/test/libvlc/slaves.c index e36e301d6c..7b2c24fa43 100644 --- a/test/libvlc/slaves.c +++ b/test/libvlc/slaves.c @@ -24,7 +24,6 @@ #include #define SLAVES_DIR SRCDIR "/samples/slaves" -#define MAIN_MEDIA_PATH SLAVES_DIR "/test.mp4" static void finished_event(const libvlc_event_t *p_ev, void *p_data) @@ -106,6 +105,7 @@ test_expected_slaves(libvlc_media_t *p_m, static void test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc, + const char *psz_main_media, libvlc_media_slave_t *p_expected_slaves, unsigned i_expected_slaves) { @@ -115,7 +115,7 @@ test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc, printf("Parse media dir to get subitems\n"); 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); printf("Main media mrl: '%s'\n", psz_main_media_mrl); @@ -159,17 +159,17 @@ main (void) test_init(); 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.rt.srt", + SLAVES_DIR "/lt-test.srt", + SLAVES_DIR "/nomatch.srt", }; 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_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)) @@ -194,16 +194,45 @@ main (void) assert(p_expected_slaves[i].psz_uri != NULL); } - printf("== Test if a media has slaves from its parent ==\n"); - test_media_has_slaves_from_parent(p_vlc, p_expected_slaves, + printf("== Testing --sub-autodetect-fuzzy 1 (everything) ==\n"); + test_media_has_slaves_from_parent(p_vlc, SLAVES_DIR "/test.mp4", + p_expected_slaves, EXPECTED_SLAVES_COUNT); 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"; p_vlc = libvlc_new(ARGC, pp_args); 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); for (unsigned int i = 0; i < EXPECTED_SLAVES_COUNT; ++i) diff --git a/test/samples/slaves/left-test.srt b/test/samples/slaves/lt-test.srt similarity index 100% rename from test/samples/slaves/left-test.srt rename to test/samples/slaves/lt-test.srt diff --git a/test/samples/slaves/test-right.srt b/test/samples/slaves/t.mp4 similarity index 100% rename from test/samples/slaves/test-right.srt rename to test/samples/slaves/t.mp4 diff --git a/test/samples/slaves/test.rt.srt b/test/samples/slaves/test.rt.srt new file mode 100644 index 0000000000..e69de29bb2