dirac: remove Dirac packetizer
[vlc.git] / test / src / input / demux-run.c
blob7c40c5d5565518cf8f1216ed34c4e83b61cf9440
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) == VLC_SUCCESS)
223 return update;
224 unsigned ret = demux->info.i_update & flags;
225 demux->info.i_update &= ~flags;
226 return ret;
229 static void demux_get_title_list(demux_t *demux)
231 int title;
232 int title_offset;
233 int seekpoint_offset;
234 input_title_t **title_list;
236 if (demux_Control(demux, DEMUX_GET_TITLE_INFO, &title_list, &title,
237 &title_offset, &seekpoint_offset) == VLC_SUCCESS)
239 for (int i = 0; i < title; i++)
240 vlc_input_title_Delete(title_list[i]);
244 static void demux_get_meta(demux_t *demux)
246 vlc_meta_t *p_meta = vlc_meta_New();
247 if (unlikely(p_meta == NULL) )
248 return;
250 input_attachment_t **attachment;
251 int i_attachment;
253 demux_Control(demux, DEMUX_GET_META, p_meta);
254 demux_Control(demux, DEMUX_GET_ATTACHMENTS, &attachment, &i_attachment);
256 vlc_meta_Delete(p_meta);
259 static int demux_process_stream(const struct vlc_run_args *args, stream_t *s)
261 const char *name = args->name;
262 if (name == NULL)
263 name = "any";
265 if (s == NULL)
266 return -1;
268 es_out_t *out = test_es_out_create(VLC_OBJECT(s));
269 if (out == NULL)
270 return -1;
272 demux_t *demux = demux_New(VLC_OBJECT(s), name, "", s, out);
273 if (demux == NULL)
275 es_out_Delete(out);
276 vlc_stream_Delete(s);
277 debug("Error: cannot create demultiplexer: %s\n", name);
278 return -1;
281 uintmax_t i = 0;
282 int val;
284 while ((val = demux_Demux(demux)) == VLC_DEMUXER_SUCCESS)
286 if (args->test_demux_controls)
288 if (demux_test_and_clear_flags(demux, INPUT_UPDATE_TITLE_LIST))
289 demux_get_title_list(demux);
291 if (demux_test_and_clear_flags(demux, INPUT_UPDATE_META))
292 demux_get_meta(demux);
294 int seekpoint = 0;
295 double position = 0.0;
296 mtime_t time = 0;
297 mtime_t length = 0;
299 /* Call controls for increased code coverage */
300 demux_Control(demux, DEMUX_GET_SEEKPOINT, &seekpoint);
301 demux_Control(demux, DEMUX_GET_POSITION, &position);
302 demux_Control(demux, DEMUX_GET_TIME, &time);
303 demux_Control(demux, DEMUX_GET_LENGTH, &length);
305 i++;
308 demux_Delete(demux);
309 es_out_Delete(out);
311 debug("Completed with %ju iteration(s).\n", i);
313 return val == VLC_DEMUXER_EOF ? 0 : -1;
316 int vlc_demux_process_url(const struct vlc_run_args *args, const char *url)
318 libvlc_instance_t *vlc = libvlc_create(args);
319 if (vlc == NULL)
320 return -1;
322 stream_t *s = vlc_access_NewMRL(VLC_OBJECT(vlc->p_libvlc_int), url);
323 if (s == NULL)
324 fprintf(stderr, "Error: cannot create input stream: %s\n", url);
326 int ret = demux_process_stream(args, s);
327 libvlc_release(vlc);
328 return ret;
331 int vlc_demux_process_path(const struct vlc_run_args *args, const char *path)
333 char *url = vlc_path2uri(path, NULL);
334 if (url == NULL)
336 fprintf(stderr, "Error: cannot convert path to URL: %s\n", path);
337 return -1;
340 int ret = vlc_demux_process_url(args, url);
341 free(url);
342 return ret;
345 int vlc_demux_process_memory(const struct vlc_run_args *args,
346 const unsigned char *buf, size_t length)
348 libvlc_instance_t *vlc = libvlc_create(args);
349 if (vlc == NULL)
350 return -1;
352 stream_t *s = vlc_stream_MemoryNew(VLC_OBJECT(vlc->p_libvlc_int),
353 (void *)buf, length, true);
354 if (s == NULL)
355 fprintf(stderr, "Error: cannot create input stream\n");
357 int ret = demux_process_stream(args, s);
358 libvlc_release(vlc);
359 return ret;
362 #ifdef HAVE_STATIC_MODULES
363 # include <vlc_plugin.h>
365 typedef int (*vlc_plugin_cb)(int (*)(void *, void *, int, ...), void *);
366 extern vlc_plugin_cb vlc_static_modules[];
368 #ifdef HAVE_DECODERS
369 #define DECODER_PLUGINS(f) \
370 f(adpcm) \
371 f(aes3) \
372 f(araw) \
373 f(g711) \
374 f(lpcm) \
375 f(uleaddvaudio) \
376 f(rawvideo) \
377 f(cc) \
378 f(cvdsub) \
379 f(dvbsub) \
380 f(scte18) \
381 f(scte27) \
382 f(spudec) \
383 f(stl) \
384 f(subsdec) \
385 f(subsusf) \
386 f(svcdsub) \
387 f(textst) \
388 f(substx3g)
389 #else
390 #define DECODER_PLUGINS(f)
391 #endif
393 #define PLUGINS(f) \
394 f(xml) \
395 f(console) \
396 f(filesystem) \
397 f(xml) \
398 f(aiff) \
399 f(asf) \
400 f(au) \
401 f(avi) \
402 f(caf) \
403 f(es) \
404 f(flacsys) \
405 f(h26x) \
406 f(mjpeg) \
407 f(mkv) \
408 f(mp4) \
409 f(nsc) \
410 f(nsv) \
411 f(ps) \
412 f(pva) \
413 f(sap) \
414 f(smf) \
415 f(subtitle) \
416 PLUGIN_TS(f) \
417 f(tta) \
418 f(ttml) \
419 f(ty) \
420 f(voc) \
421 f(wav) \
422 f(webvtt) \
423 f(xa) \
424 f(a52) \
425 f(copy) \
426 f(dts) \
427 f(flac) \
428 f(h264) \
429 f(hevc) \
430 f(mlp) \
431 f(mpeg4audio) \
432 f(mpeg4video) \
433 f(mpegaudio) \
434 f(mpegvideo) \
435 f(vc1) \
436 f(rawvid) \
437 f(rawaud) \
438 DECODER_PLUGINS(f)
440 #ifdef HAVE_DVBPSI
441 # define PLUGIN_TS(f) f(ts)
442 #else
443 # define PLUGIN_TS(f)
444 #endif
446 #define DECL_PLUGIN(p) \
447 int vlc_entry__##p(int (*)(void *, void *, int, ...), void *);
449 #define FUNC_PLUGIN(p) \
450 vlc_entry__##p,
452 PLUGINS(DECL_PLUGIN)
454 __attribute__((visibility("default")))
455 vlc_plugin_cb vlc_static_modules[] = { PLUGINS(FUNC_PLUGIN) NULL };
456 #endif /* HAVE_STATIC_MODULES */