1 /*****************************************************************************
2 * slaves.c: test libvlc_media_t and libvlc_media_player_t slaves API
3 *****************************************************************************
4 * Copyright © 2016 VLC authors, VideoLAN and VideoLabs
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
23 #include <vlc_common.h>
24 #include <vlc_threads.h>
26 #define SLAVES_DIR SRCDIR "/samples/slaves"
27 #define MAIN_MEDIA_PATH SLAVES_DIR "/test.mp4"
30 finished_event(const libvlc_event_t
*p_ev
, void *p_data
)
33 vlc_sem_t
*p_sem
= p_data
;
38 media_parse_sync(libvlc_media_t
*p_m
)
41 vlc_sem_init(&sem
, 0);
43 libvlc_event_manager_t
*p_em
= libvlc_media_event_manager(p_m
);
44 libvlc_event_attach(p_em
, libvlc_MediaParsedChanged
, finished_event
, &sem
);
46 int i_ret
= libvlc_media_parse_with_options(p_m
, libvlc_media_parse_local
, -1);
51 libvlc_event_detach(p_em
, libvlc_MediaParsedChanged
, finished_event
, &sem
);
53 vlc_sem_destroy (&sem
);
57 path_to_mrl(libvlc_instance_t
*p_vlc
, const char *psz_path
)
59 libvlc_media_t
*p_m
= libvlc_media_new_path(p_vlc
, psz_path
);
60 char *psz_mrl
= libvlc_media_get_mrl(p_m
);
61 libvlc_media_release(p_m
);
66 test_expected_slaves(libvlc_media_t
*p_m
,
67 libvlc_media_slave_t
*p_expected_slaves
,
68 unsigned int i_expected_slaves
)
70 printf("Check if slaves are correclty attached to media\n");
72 libvlc_media_slave_t
**pp_slaves
;
73 unsigned int i_slave_count
= libvlc_media_slaves_get(p_m
, &pp_slaves
);
74 assert(i_expected_slaves
== i_slave_count
);
76 if (i_expected_slaves
> 0)
78 bool *p_found_list
= calloc(i_expected_slaves
, sizeof(bool));
79 assert(p_found_list
!= NULL
);
80 for (unsigned int i
= 0; i
< i_slave_count
; ++i
)
82 libvlc_media_slave_t
*p_slave1
= pp_slaves
[i
];
83 for (unsigned int j
= 0; i
< i_expected_slaves
; ++j
)
85 libvlc_media_slave_t
*p_slave2
= &p_expected_slaves
[j
];
86 if (strcmp(p_slave1
->psz_uri
, p_slave2
->psz_uri
) == 0)
88 assert(p_found_list
[j
] == false);
89 assert(p_slave1
->i_type
== p_slave2
->i_type
);
90 assert(p_slave1
->i_priority
== p_slave2
->i_priority
);
91 p_found_list
[j
] = true;
96 for (unsigned int i
= 0; i
< i_expected_slaves
; ++i
)
98 printf("Check if slaves[%d] is found\n", i
);
99 assert(p_found_list
[i
]);
104 libvlc_media_slaves_release(pp_slaves
, i_slave_count
);
109 mediaplayer_play_sync(libvlc_media_player_t
*p_mp
)
112 vlc_sem_init(&sem
, 0);
114 libvlc_event_manager_t
*p_em
= libvlc_media_player_event_manager(p_mp
);
115 libvlc_event_attach(p_em
, libvlc_MediaPlayerPlaying
, finished_event
, &sem
);
116 libvlc_event_attach(p_em
, libvlc_MediaPlayerEndReached
, finished_event
, &sem
);
117 libvlc_event_attach(p_em
, libvlc_MediaPlayerEncounteredError
, finished_event
, &sem
);
119 int i_ret
= libvlc_media_player_play(p_mp
);
124 libvlc_event_detach(p_em
, libvlc_MediaPlayerPlaying
, finished_event
, &sem
);
125 libvlc_event_detach(p_em
, libvlc_MediaPlayerEndReached
, finished_event
, &sem
);
126 libvlc_event_detach(p_em
, libvlc_MediaPlayerEncounteredError
, finished_event
, &sem
);
128 libvlc_media_player_stop(p_mp
);
130 vlc_sem_destroy (&sem
);
134 test_media_has_slaves_from_player(libvlc_instance_t
*p_vlc
,
135 libvlc_media_slave_t
*p_expected_slaves
,
136 unsigned i_expected_slaves
)
138 /* This function test subtitles_Detect() when playing a local file */
139 libvlc_media_t
*p_m
= libvlc_media_new_path(p_vlc
, MAIN_MEDIA_PATH
);
142 libvlc_media_player_t
*p_mp
= libvlc_media_player_new_from_media(p_m
);
143 assert(p_mp
!= NULL
);
144 mediaplayer_play_sync(p_mp
);
146 test_expected_slaves(p_m
, p_expected_slaves
, i_expected_slaves
);
148 libvlc_media_release(p_m
);
149 libvlc_media_player_release(p_mp
);
154 test_media_has_slaves_from_parent(libvlc_instance_t
*p_vlc
,
155 libvlc_media_slave_t
*p_expected_slaves
,
156 unsigned i_expected_slaves
)
158 libvlc_media_t
*p_m
= libvlc_media_new_path(p_vlc
, SLAVES_DIR
);
161 printf("Parse media dir to get subitems\n");
162 media_parse_sync(p_m
);
164 char *psz_main_media_mrl
= path_to_mrl(p_vlc
, MAIN_MEDIA_PATH
);
165 assert(psz_main_media_mrl
!= NULL
);
166 printf("Main media mrl: '%s'\n", psz_main_media_mrl
);
168 printf("Fetch main media from subitems\n");
169 libvlc_media_list_t
*p_ml
= libvlc_media_subitems(p_m
);
170 assert(p_ml
!= NULL
);
171 libvlc_media_list_lock(p_ml
);
172 int i_count
= libvlc_media_list_count(p_ml
);
174 libvlc_media_t
*p_subm
= NULL
;
175 for (int i
= 0; i
< i_count
; ++i
)
177 p_subm
= libvlc_media_list_item_at_index(p_ml
, i
);
178 assert(p_subm
!= NULL
);
179 char *psz_mrl
= libvlc_media_get_mrl(p_subm
);
180 assert(psz_mrl
!= NULL
);
181 if (strcmp(psz_main_media_mrl
, psz_mrl
) == 0)
183 printf("Found main media\n");
188 libvlc_media_release(p_subm
);
191 free(psz_main_media_mrl
);
192 libvlc_media_list_unlock(p_ml
);
193 libvlc_media_list_release(p_ml
);
195 assert(p_subm
!= NULL
);
196 test_expected_slaves(p_subm
, p_expected_slaves
, i_expected_slaves
);
197 libvlc_media_release(p_subm
);
199 libvlc_media_release(p_m
);
207 const char *pp_slave_paths
[] = {
208 SLAVES_DIR
"/nomatch.srt",
209 SLAVES_DIR
"/left-test.srt",
210 SLAVES_DIR
"/test-right.srt",
211 SLAVES_DIR
"/test.aac",
214 libvlc_media_slave_t p_expected_slaves
[] = {
215 { NULL
, libvlc_media_slave_type_subtitle
, 0 /* none */ },
216 { NULL
, libvlc_media_slave_type_subtitle
, 1 /* left */ },
217 { NULL
, libvlc_media_slave_type_subtitle
, 2 /* right */ },
218 { NULL
, libvlc_media_slave_type_audio
, 3 /* all */ },
221 #define EXPECTED_SLAVES_COUNT (sizeof(p_expected_slaves) / sizeof(*p_expected_slaves))
222 static_assert((sizeof(pp_slave_paths
) / sizeof(*pp_slave_paths
)) == EXPECTED_SLAVES_COUNT
,
223 "pp_slave_paths and p_expected_slaves mismatch");
225 const char *pp_args
[] = {
226 "-v", "--sub-autodetect-fuzzy", "1",
227 "--no-video", "--no-audio",
228 "--codec", "none", /* to ensure we don't depend on codec modules */
229 NULL
/* "sub-autodetect-file" place holder */
231 #define ARGC (sizeof(pp_args) / sizeof(*pp_args))
233 libvlc_instance_t
*p_vlc
= libvlc_new(ARGC
- 1, pp_args
);
234 assert(p_vlc
!= NULL
);
236 /* Fill p_expected_slaves with correct VLC mrls */
237 for (unsigned int i
= 0; i
< EXPECTED_SLAVES_COUNT
; ++i
)
239 p_expected_slaves
[i
].psz_uri
= path_to_mrl(p_vlc
, pp_slave_paths
[i
]);
240 assert(p_expected_slaves
[i
].psz_uri
!= NULL
);
244 printf("== Test if a media has slaves from a media player ==\n");
245 test_media_has_slaves_from_player(p_vlc
, p_expected_slaves
,
246 EXPECTED_SLAVES_COUNT
- 1);
249 printf("== Test if a media has slaves from its parent ==\n");
250 test_media_has_slaves_from_parent(p_vlc
, p_expected_slaves
,
251 EXPECTED_SLAVES_COUNT
);
252 libvlc_release(p_vlc
);
254 printf("== Test if a media doesn't have slaves from its parent ==\n");
255 pp_args
[ARGC
- 1] = "--no-sub-autodetect-file";
256 p_vlc
= libvlc_new(ARGC
, pp_args
);
257 assert(p_vlc
!= NULL
);
258 test_media_has_slaves_from_parent(p_vlc
, NULL
, 0);
259 libvlc_release(p_vlc
);
261 for (unsigned int i
= 0; i
< EXPECTED_SLAVES_COUNT
; ++i
)
262 free(p_expected_slaves
[i
].psz_uri
);