[vlc-devel] [PATCH 01/20] input: item: add input_item_Parse
Thomas Guillem
thomas at gllm.fr
Fri May 31 15:59:27 CEST 2019
This function doesn't use a background thread, contrary to
libvlc_MetadataRequest(). It will be used by the Medialibray that has its own
background thread.
---
include/vlc_input_item.h | 60 +++++++++++++++++++++++++++++++++++
src/input/item.c | 67 ++++++++++++++++++++++++++++++++++++++++
src/libvlccore.sym | 2 ++
3 files changed, 129 insertions(+)
diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 5ae437c13f..272f774306 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -371,6 +371,66 @@ VLC_API input_item_t *input_item_Hold(input_item_t *);
/** Releases an input item, i.e. decrements its reference counter. */
VLC_API void input_item_Release(input_item_t *);
+/**
+ * input item parser opaque structure
+ */
+typedef struct input_item_parser_t input_item_parser_t;
+
+/**
+ * input item parser callbacks
+ */
+typedef struct input_item_parser_cbs_t
+{
+ /**
+ * Event received when the parser ends
+ *
+ * @note this callback is mandatory.
+ *
+ * @param item the parsed item
+ * @param ret VLC_SUCCESS in case of success, an error otherwise
+ * @param userdata user data set by input_item_Parse()
+ */
+ void (*on_ended)(input_item_t *item, int ret, void *userdata);
+
+ /**
+ * Event received when a new subtree is added
+ *
+ * @note this callback is optional.
+ *
+ * @param item the parsed item
+ * @param subtree sub items of the current item
+ * @param userdata user data set by input_item_Parse()
+ */
+ void (*on_subtree_added)(input_item_t *item, input_item_node_t *subtree, void *userdata);
+} input_item_parser_cbs_t;
+
+/**
+ * Parse an item
+ *
+ * @note the parsing is done asynchronously. The user can call
+ * input_item_parser_Release() before receiving the on_ended() event in order
+ * to interrupt it.
+ *
+ * @param item the item to parse
+ * @param parent the parent obj
+ * @param cbs callbacks to be notified of the end of the parsing
+ * @param userdata opaque data user by parser callbacks
+ *
+ * @return a parser instance or NULL in case of error, the parser needs to be
+ * released with input_item_parser_Release()
+ */
+VLC_API input_item_parser_t *
+input_item_Parse(input_item_t *item, vlc_object_t *parent,
+ const input_item_parser_cbs_t *cbs, void *userdata) VLC_USED;
+
+/**
+ * Release (and interrupt if needed) a parser
+ *
+ * @param parser the parser returned by input_item_Parse
+ */
+VLC_API void
+input_item_parser_Release(input_item_parser_t *parser);
+
typedef enum input_item_meta_request_option_t
{
META_REQUEST_OPTION_NONE = 0x00,
diff --git a/src/input/item.c b/src/input/item.c
index 830c79895f..ce58b90122 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -1325,6 +1325,73 @@ void input_item_UpdateTracksInfo(input_item_t *item, const es_format_t *fmt)
vlc_mutex_unlock( &item->lock );
}
+struct input_item_parser_t
+{
+ input_thread_t *input;
+ input_state_e state;
+ const input_item_parser_cbs_t *cbs;
+ void *userdata;
+};
+
+static void
+input_item_parser_InputEvent(input_thread_t *input,
+ const struct vlc_input_event *event, void *parser_)
+{
+ input_item_parser_t *parser = parser_;
+
+ switch (event->type)
+ {
+ case INPUT_EVENT_STATE:
+ parser->state = event->state;
+ break;
+ case INPUT_EVENT_DEAD:
+ {
+ int ret = parser->state == END_S ? VLC_SUCCESS : VLC_EGENERIC;
+ parser->cbs->on_ended(input_GetItem(input), ret, parser->userdata);
+ break;
+ }
+ case INPUT_EVENT_SUBITEMS:
+ if (parser->cbs->on_subtree_added)
+ parser->cbs->on_subtree_added(input_GetItem(input),
+ event->subitems, parser->userdata);
+ break;
+ default:
+ break;
+ }
+}
+
+input_item_parser_t *
+input_item_Parse(input_item_t *item, vlc_object_t *obj,
+ const input_item_parser_cbs_t *cbs, void *userdata)
+{
+ assert(cbs && cbs->on_ended);
+ input_item_parser_t *parser = malloc(sizeof(*parser));
+ if (!parser)
+ return NULL;
+
+ parser->state = INIT_S;
+ parser->cbs = cbs;
+ parser->userdata = userdata;
+ parser->input = input_CreatePreparser(obj, input_item_parser_InputEvent,
+ parser, item);
+ if (!parser->input || input_Start(parser->input))
+ {
+ if (parser->input)
+ input_Close(parser->input);
+ free(parser);
+ return NULL;
+ }
+ return parser;
+}
+
+void
+input_item_parser_Release(input_item_parser_t *parser)
+{
+ input_Stop(parser->input);
+ input_Close(parser->input);
+ free(parser);
+}
+
static int rdh_compar_type(input_item_t *p1, input_item_t *p2)
{
if (p1->i_type != p2->i_type)
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 87190a3573..ae7cc6d8b4 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -207,6 +207,8 @@ input_item_WriteMeta
input_item_slave_GetType
input_item_slave_New
input_item_AddSlave
+input_item_Parse
+input_item_parser_Release
input_Read
input_resource_New
input_resource_Release
--
2.20.1
More information about the vlc-devel
mailing list