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 *****************************************************************************/
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>
43 #include <vlc_es_out.h>
45 #include "../lib/libvlc_internal.h"
49 #include "demux-run.h"
55 struct es_out_id_t
*ids
;
60 struct es_out_id_t
*next
;
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
;
73 es_out_id_t
*id
= malloc(sizeof (*id
));
74 if (unlikely(id
== NULL
))
80 id
->decoder
= test_decoder_create((void *)out
->p_sys
, fmt
);
83 debug("[%p] Added ES\n", (void *)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
)
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
);
104 test_decoder_process(id
->decoder
, block
);
107 block_Release(block
);
111 static void IdDelete(es_out_id_t
*id
)
117 test_decoder_process(id
->decoder
, NULL
);
118 test_decoder_destroy(id
->decoder
);
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
;
136 debug("[%p] Deleted ES\n", (void *)id
);
141 static int EsOutControl(es_out_t
*out
, int query
, va_list args
)
147 case ES_OUT_RESTART_ES
:
149 case ES_OUT_SET_ES_DEFAULT
:
150 case ES_OUT_SET_ES_STATE
:
152 case ES_OUT_GET_ES_STATE
:
153 EsOutCheckId(out
, va_arg(args
, es_out_id_t
*));
154 *va_arg(args
, bool *) = true;
156 case ES_OUT_SET_ES_CAT_POLICY
:
158 case ES_OUT_SET_GROUP
:
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
:
170 case ES_OUT_GET_EMPTY
:
171 *va_arg(args
, bool *) = true;
173 case ES_OUT_SET_META
:
175 case ES_OUT_GET_PCR_SYSTEM
:
176 case ES_OUT_MODIFY_PCR_SYSTEM
:
184 static void EsOutDestroy(es_out_t
*out
)
186 struct test_es_out_t
*ctx
= (struct test_es_out_t
*)out
;
189 while ((id
= ctx
->ids
) != NULL
)
197 static es_out_t
*test_es_out_create(vlc_object_t
*parent
)
199 struct test_es_out_t
*ctx
= malloc(sizeof (*ctx
));
202 fprintf(stderr
, "Error: cannot create ES output.\n");
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
;
219 static unsigned demux_test_and_clear_flags(demux_t
*demux
, unsigned flags
)
222 if (demux_Control(demux
, DEMUX_TEST_AND_CLEAR_FLAGS
, &update
))
227 static void demux_get_title_list(demux_t
*demux
)
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
) )
248 input_attachment_t
**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
;
266 es_out_t
*out
= test_es_out_create(VLC_OBJECT(s
));
270 demux_t
*demux
= demux_New(VLC_OBJECT(s
), name
, "", s
, out
);
274 vlc_stream_Delete(s
);
275 debug("Error: cannot create demultiplexer: %s\n", name
);
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
);
293 double position
= 0.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
);
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
);
320 stream_t
*s
= vlc_access_NewMRL(VLC_OBJECT(vlc
->p_libvlc_int
), url
);
322 fprintf(stderr
, "Error: cannot create input stream: %s\n", url
);
324 int ret
= demux_process_stream(args
, s
);
329 int vlc_demux_process_path(const struct vlc_run_args
*args
, const char *path
)
331 char *url
= vlc_path2uri(path
, NULL
);
334 fprintf(stderr
, "Error: cannot convert path to URL: %s\n", path
);
338 int ret
= vlc_demux_process_url(args
, url
);
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
);
350 stream_t
*s
= vlc_stream_MemoryNew(VLC_OBJECT(vlc
->p_libvlc_int
),
351 (void *)buf
, length
, true);
353 fprintf(stderr
, "Error: cannot create input stream\n");
355 int ret
= demux_process_stream(args
, s
);
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
[];
367 #define DECODER_PLUGINS(f) \
388 #define DECODER_PLUGINS(f)
439 # define PLUGIN_TS(f) f(ts)
441 # define PLUGIN_TS(f)
445 # define PLUGIN_MKV(f) f(mkv)
447 # define PLUGIN_MKV(f)
450 #define DECL_PLUGIN(p) \
451 int vlc_entry__##p(int (*)(void *, void *, int, ...), void *);
453 #define FUNC_PLUGIN(p) \
458 __attribute__((visibility("default")))
459 vlc_plugin_cb vlc_static_modules
[] = { PLUGINS(FUNC_PLUGIN
) NULL
};
460 #endif /* HAVE_STATIC_MODULES */