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
) == VLC_SUCCESS
)
224 unsigned ret
= demux
->info
.i_update
& flags
;
225 demux
->info
.i_update
&= ~flags
;
229 static void demux_get_title_list(demux_t
*demux
)
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
) )
250 input_attachment_t
**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
;
268 es_out_t
*out
= test_es_out_create(VLC_OBJECT(s
));
272 demux_t
*demux
= demux_New(VLC_OBJECT(s
), name
, "", s
, out
);
276 vlc_stream_Delete(s
);
277 debug("Error: cannot create demultiplexer: %s\n", name
);
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
);
295 double position
= 0.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
);
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
);
322 stream_t
*s
= vlc_access_NewMRL(VLC_OBJECT(vlc
->p_libvlc_int
), url
);
324 fprintf(stderr
, "Error: cannot create input stream: %s\n", url
);
326 int ret
= demux_process_stream(args
, s
);
331 int vlc_demux_process_path(const struct vlc_run_args
*args
, const char *path
)
333 char *url
= vlc_path2uri(path
, NULL
);
336 fprintf(stderr
, "Error: cannot convert path to URL: %s\n", path
);
340 int ret
= vlc_demux_process_url(args
, url
);
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
);
352 stream_t
*s
= vlc_stream_MemoryNew(VLC_OBJECT(vlc
->p_libvlc_int
),
353 (void *)buf
, length
, true);
355 fprintf(stderr
, "Error: cannot create input stream\n");
357 int ret
= demux_process_stream(args
, s
);
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
[];
369 #define DECODER_PLUGINS(f) \
390 #define DECODER_PLUGINS(f)
441 # define PLUGIN_TS(f) f(ts)
443 # define PLUGIN_TS(f)
446 #define DECL_PLUGIN(p) \
447 int vlc_entry__##p(int (*)(void *, void *, int, ...), void *);
449 #define FUNC_PLUGIN(p) \
454 __attribute__((visibility("default")))
455 vlc_plugin_cb vlc_static_modules
[] = { PLUGINS(FUNC_PLUGIN
) NULL
};
456 #endif /* HAVE_STATIC_MODULES */