demux-run: Re-add MKV to the list of fuzzer modules
[vlc.git] / test / src / input / demux-run.c
blob416436fcf141d5da453f9fea1d601477cf7909b6
1 /**
2 * @file demux-run.c
3 */
4 /*****************************************************************************
5 * Copyright © 2016 Rémi Denis-Courmont
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Rémi Denis-Courmont reserves the right to redistribute this file under
13 * the terms of the GNU Lesser General Public License as published by the
14 * the Free Software Foundation; either version 2.1 or the License, or
15 * (at his option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <limits.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
37 #include <vlc_common.h>
38 #include <vlc_access.h>
39 #include <vlc_block.h>
40 #include <vlc_demux.h>
41 #include <vlc_input.h>
42 #include <vlc_meta.h>
43 #include <vlc_es_out.h>
44 #include <vlc_url.h>
45 #include "../lib/libvlc_internal.h"
47 #include <vlc/vlc.h>
49 #include "demux-run.h"
50 #include "decoder.h"
52 struct test_es_out_t
54 struct es_out_t out;
55 struct es_out_id_t *ids;
58 struct es_out_id_t
60 struct es_out_id_t *next;
61 #ifdef HAVE_DECODERS
62 decoder_t *decoder;
63 #endif
66 static es_out_id_t *EsOutAdd(es_out_t *out, const es_format_t *fmt)
68 struct test_es_out_t *ctx = (struct test_es_out_t *) out;
70 if (fmt->i_group < 0)
71 return NULL;
73 es_out_id_t *id = malloc(sizeof (*id));
74 if (unlikely(id == NULL))
75 return NULL;
77 id->next = ctx->ids;
78 ctx->ids = id;
79 #ifdef HAVE_DECODERS
80 id->decoder = test_decoder_create((void *)out->p_sys, fmt);
81 #endif
83 debug("[%p] Added ES\n", (void *)id);
84 return id;
87 static void EsOutCheckId(es_out_t *out, es_out_id_t *id)
89 struct test_es_out_t *ctx = (struct test_es_out_t *) out;
91 for (es_out_id_t *ids = ctx->ids; ids != NULL; ids = ids->next)
92 if (ids == id)
93 return;
95 abort();
98 static int EsOutSend(es_out_t *out, es_out_id_t *id, block_t *block)
100 //debug("[%p] Sent ES: %zu\n", (void *)idd, block->i_buffer);
101 EsOutCheckId(out, id);
102 #ifdef HAVE_DECODERS
103 if (id->decoder)
104 test_decoder_process(id->decoder, block);
105 else
106 #endif
107 block_Release(block);
108 return VLC_SUCCESS;
111 static void IdDelete(es_out_id_t *id)
113 #ifdef HAVE_DECODERS
114 if (id->decoder)
116 /* Drain */
117 test_decoder_process(id->decoder, NULL);
118 test_decoder_destroy(id->decoder);
120 #endif
121 free(id);
124 static void EsOutDelete(es_out_t *out, es_out_id_t *id)
126 struct test_es_out_t *ctx = (struct test_es_out_t *) out;
127 es_out_id_t **pp = &ctx->ids;
129 while (*pp != id)
131 if (*pp == NULL)
132 abort();
133 pp = &((*pp)->next);
136 debug("[%p] Deleted ES\n", (void *)id);
137 *pp = id->next;
138 IdDelete(id);
141 static int EsOutControl(es_out_t *out, int query, va_list args)
143 switch (query)
145 case ES_OUT_SET_ES:
146 break;
147 case ES_OUT_RESTART_ES:
148 abort();
149 case ES_OUT_SET_ES_DEFAULT:
150 case ES_OUT_SET_ES_STATE:
151 break;
152 case ES_OUT_GET_ES_STATE:
153 EsOutCheckId(out, va_arg(args, es_out_id_t *));
154 *va_arg(args, bool *) = true;
155 break;
156 case ES_OUT_SET_ES_CAT_POLICY:
157 break;
158 case ES_OUT_SET_GROUP:
159 abort();
160 case ES_OUT_SET_PCR:
161 case ES_OUT_SET_GROUP_PCR:
162 case ES_OUT_RESET_PCR:
163 case ES_OUT_SET_ES_FMT:
164 case ES_OUT_SET_NEXT_DISPLAY_TIME:
165 case ES_OUT_SET_GROUP_META:
166 case ES_OUT_SET_GROUP_EPG:
167 case ES_OUT_DEL_GROUP:
168 case ES_OUT_SET_ES_SCRAMBLED_STATE:
169 break;
170 case ES_OUT_GET_EMPTY:
171 *va_arg(args, bool *) = true;
172 break;
173 case ES_OUT_SET_META:
174 break;
175 case ES_OUT_GET_PCR_SYSTEM:
176 case ES_OUT_MODIFY_PCR_SYSTEM:
177 abort();
178 default:
179 return VLC_EGENERIC;
181 return VLC_SUCCESS;
184 static void EsOutDestroy(es_out_t *out)
186 struct test_es_out_t *ctx = (struct test_es_out_t *)out;
187 es_out_id_t *id;
189 while ((id = ctx->ids) != NULL)
191 ctx->ids = id->next;
192 IdDelete(id);
194 free(ctx);
197 static es_out_t *test_es_out_create(vlc_object_t *parent)
199 struct test_es_out_t *ctx = malloc(sizeof (*ctx));
200 if (ctx == NULL)
202 fprintf(stderr, "Error: cannot create ES output.\n");
203 return NULL;
206 ctx->ids = NULL;
208 es_out_t *out = &ctx->out;
209 out->pf_add = EsOutAdd;
210 out->pf_send = EsOutSend;
211 out->pf_del = EsOutDelete;
212 out->pf_control = EsOutControl;
213 out->pf_destroy = EsOutDestroy;
214 out->p_sys = (void *)parent;
216 return out;
219 static unsigned demux_test_and_clear_flags(demux_t *demux, unsigned flags)
221 unsigned update;
222 if (demux_Control(demux, DEMUX_TEST_AND_CLEAR_FLAGS, &update))
223 return 0;
224 return update;
227 static void demux_get_title_list(demux_t *demux)
229 int title;
230 int title_offset;
231 int seekpoint_offset;
232 input_title_t **title_list;
234 if (demux_Control(demux, DEMUX_GET_TITLE_INFO, &title_list, &title,
235 &title_offset, &seekpoint_offset) == VLC_SUCCESS)
237 for (int i = 0; i < title; i++)
238 vlc_input_title_Delete(title_list[i]);
242 static void demux_get_meta(demux_t *demux)
244 vlc_meta_t *p_meta = vlc_meta_New();
245 if (unlikely(p_meta == NULL) )
246 return;
248 input_attachment_t **attachment;
249 int i_attachment;
251 demux_Control(demux, DEMUX_GET_META, p_meta);
252 demux_Control(demux, DEMUX_GET_ATTACHMENTS, &attachment, &i_attachment);
254 vlc_meta_Delete(p_meta);
257 static int demux_process_stream(const struct vlc_run_args *args, stream_t *s)
259 const char *name = args->name;
260 if (name == NULL)
261 name = "any";
263 if (s == NULL)
264 return -1;
266 es_out_t *out = test_es_out_create(VLC_OBJECT(s));
267 if (out == NULL)
268 return -1;
270 demux_t *demux = demux_New(VLC_OBJECT(s), name, "", s, out);
271 if (demux == NULL)
273 es_out_Delete(out);
274 vlc_stream_Delete(s);
275 debug("Error: cannot create demultiplexer: %s\n", name);
276 return -1;
279 uintmax_t i = 0;
280 int val;
282 while ((val = demux_Demux(demux)) == VLC_DEMUXER_SUCCESS)
284 if (args->test_demux_controls)
286 if (demux_test_and_clear_flags(demux, INPUT_UPDATE_TITLE_LIST))
287 demux_get_title_list(demux);
289 if (demux_test_and_clear_flags(demux, INPUT_UPDATE_META))
290 demux_get_meta(demux);
292 int seekpoint = 0;
293 double position = 0.0;
294 mtime_t time = 0;
295 mtime_t length = 0;
297 /* Call controls for increased code coverage */
298 demux_Control(demux, DEMUX_GET_SEEKPOINT, &seekpoint);
299 demux_Control(demux, DEMUX_GET_POSITION, &position);
300 demux_Control(demux, DEMUX_GET_TIME, &time);
301 demux_Control(demux, DEMUX_GET_LENGTH, &length);
303 i++;
306 demux_Delete(demux);
307 es_out_Delete(out);
309 debug("Completed with %ju iteration(s).\n", i);
311 return val == VLC_DEMUXER_EOF ? 0 : -1;
314 int vlc_demux_process_url(const struct vlc_run_args *args, const char *url)
316 libvlc_instance_t *vlc = libvlc_create(args);
317 if (vlc == NULL)
318 return -1;
320 stream_t *s = vlc_access_NewMRL(VLC_OBJECT(vlc->p_libvlc_int), url);
321 if (s == NULL)
322 fprintf(stderr, "Error: cannot create input stream: %s\n", url);
324 int ret = demux_process_stream(args, s);
325 libvlc_release(vlc);
326 return ret;
329 int vlc_demux_process_path(const struct vlc_run_args *args, const char *path)
331 char *url = vlc_path2uri(path, NULL);
332 if (url == NULL)
334 fprintf(stderr, "Error: cannot convert path to URL: %s\n", path);
335 return -1;
338 int ret = vlc_demux_process_url(args, url);
339 free(url);
340 return ret;
343 int vlc_demux_process_memory(const struct vlc_run_args *args,
344 const unsigned char *buf, size_t length)
346 libvlc_instance_t *vlc = libvlc_create(args);
347 if (vlc == NULL)
348 return -1;
350 stream_t *s = vlc_stream_MemoryNew(VLC_OBJECT(vlc->p_libvlc_int),
351 (void *)buf, length, true);
352 if (s == NULL)
353 fprintf(stderr, "Error: cannot create input stream\n");
355 int ret = demux_process_stream(args, s);
356 libvlc_release(vlc);
357 return ret;
360 #ifdef HAVE_STATIC_MODULES
361 # include <vlc_plugin.h>
363 typedef int (*vlc_plugin_cb)(int (*)(void *, void *, int, ...), void *);
364 extern vlc_plugin_cb vlc_static_modules[];
366 #ifdef HAVE_DECODERS
367 #define DECODER_PLUGINS(f) \
368 f(adpcm) \
369 f(aes3) \
370 f(araw) \
371 f(g711) \
372 f(lpcm) \
373 f(uleaddvaudio) \
374 f(rawvideo) \
375 f(cc) \
376 f(cvdsub) \
377 f(dvbsub) \
378 f(scte18) \
379 f(scte27) \
380 f(spudec) \
381 f(stl) \
382 f(subsdec) \
383 f(subsusf) \
384 f(svcdsub) \
385 f(textst) \
386 f(substx3g)
387 #else
388 #define DECODER_PLUGINS(f)
389 #endif
391 #define PLUGINS(f) \
392 f(xml) \
393 f(console) \
394 f(filesystem) \
395 f(xml) \
396 f(aiff) \
397 f(asf) \
398 f(au) \
399 f(avi) \
400 f(caf) \
401 f(es) \
402 f(flacsys) \
403 f(h26x) \
404 f(mjpeg) \
405 PLUGIN_MKV(f) \
406 f(mp4) \
407 f(nsc) \
408 f(nsv) \
409 f(ps) \
410 f(pva) \
411 f(sap) \
412 f(smf) \
413 f(subtitle) \
414 PLUGIN_TS(f) \
415 f(tta) \
416 f(ttml) \
417 f(ty) \
418 f(voc) \
419 f(wav) \
420 f(webvtt) \
421 f(xa) \
422 f(a52) \
423 f(copy) \
424 f(dts) \
425 f(flac) \
426 f(h264) \
427 f(hevc) \
428 f(mlp) \
429 f(mpeg4audio) \
430 f(mpeg4video) \
431 f(mpegaudio) \
432 f(mpegvideo) \
433 f(vc1) \
434 f(rawvid) \
435 f(rawaud) \
436 DECODER_PLUGINS(f)
438 #ifdef HAVE_DVBPSI
439 # define PLUGIN_TS(f) f(ts)
440 #else
441 # define PLUGIN_TS(f)
442 #endif
444 #ifdef HAVE_MATROSKA
445 # define PLUGIN_MKV(f) f(mkv)
446 #else
447 # define PLUGIN_MKV(f)
448 #endif
450 #define DECL_PLUGIN(p) \
451 int vlc_entry__##p(int (*)(void *, void *, int, ...), void *);
453 #define FUNC_PLUGIN(p) \
454 vlc_entry__##p,
456 PLUGINS(DECL_PLUGIN)
458 __attribute__((visibility("default")))
459 vlc_plugin_cb vlc_static_modules[] = { PLUGINS(FUNC_PLUGIN) NULL };
460 #endif /* HAVE_STATIC_MODULES */