Commit 81257945 authored by Romain Vimont's avatar Romain Vimont
Browse files

preparser: provide events in callbacks

The input thread used by the preparser is not exposed to the caller.
Add a "callbacks" parameter to receive preparsing events.
parent 9da71939
......@@ -39,6 +39,7 @@
typedef struct input_item_opaque input_item_opaque_t;
typedef struct input_item_slave input_item_slave_t;
typedef struct input_preparser_callbacks_t input_preparser_callbacks_t;
struct info_t
{
......@@ -379,7 +380,7 @@ typedef enum input_item_meta_request_option_t
META_REQUEST_OPTION_DO_INTERACT = 0x04
} input_item_meta_request_option_t;
/* status of the vlc_InputItemPreparseEnded event */
/* status of the on_preparse_ended() callback */
enum input_item_preparse_status
{
ITEM_PREPARSE_SKIPPED,
......@@ -388,8 +389,15 @@ enum input_item_preparse_status
ITEM_PREPARSE_DONE
};
typedef struct input_preparser_callbacks_t {
void (*on_preparse_ended)(input_item_t *, enum input_item_preparse_status status, void *userdata);
void (*on_subtree_added)(input_item_t *, input_item_node_t *subtree, void *userdata);
} input_preparser_callbacks_t;
VLC_API int libvlc_MetadataRequest( libvlc_int_t *, input_item_t *,
input_item_meta_request_option_t,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int, void * );
VLC_API int libvlc_ArtRequest(libvlc_int_t *, input_item_t *,
input_item_meta_request_option_t );
......
......@@ -811,7 +811,7 @@ static int media_parse(libvlc_media_t *media, bool b_async,
parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
if (parse_flag & libvlc_media_do_interact)
parse_scope |= META_REQUEST_OPTION_DO_INTERACT;
ret = libvlc_MetadataRequest(libvlc, item, parse_scope, timeout, media);
ret = libvlc_MetadataRequest(libvlc, item, parse_scope, NULL, NULL, timeout, media);
if (ret != VLC_SUCCESS)
return ret;
}
......
......@@ -198,7 +198,8 @@
[_imageWell setImage: [NSImage imageNamed: @"noart.png"]];
} else {
if (!input_item_IsPreparsed(p_item))
libvlc_MetadataRequest(getIntf()->obj.libvlc, p_item, META_REQUEST_OPTION_NONE, -1, NULL);
libvlc_MetadataRequest(getIntf()->obj.libvlc, p_item, META_REQUEST_OPTION_NONE,
NULL, NULL, -1, NULL);
/* fill uri info */
char *psz_url = vlc_uri_decode(input_item_GetURI(p_item));
......
......@@ -472,6 +472,8 @@ static void GetFilenames( libvlc_int_t *p_vlc, unsigned n,
int vlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
......@@ -485,7 +487,7 @@ int vlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
item->b_preparse_interact = true;
vlc_mutex_unlock( &item->lock );
}
input_preparser_Push( priv->parser, item, i_options, timeout, id );
input_preparser_Push( priv->parser, item, i_options, cbs, cbs_userdata, timeout, id );
return VLC_SUCCESS;
}
......@@ -497,6 +499,8 @@ int vlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
*/
int libvlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
......@@ -509,7 +513,7 @@ int libvlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
item->i_preparse_depth = 1;
vlc_mutex_unlock( &item->lock );
return vlc_MetadataRequest(libvlc, item, i_options, timeout, id);
return vlc_MetadataRequest(libvlc, item, i_options, cbs, cbs_userdata, timeout, id);
}
/**
......
......@@ -204,6 +204,8 @@ void intf_DestroyAll( libvlc_int_t * );
int vlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id);
/*
......
......@@ -744,7 +744,8 @@ static void playlist_Preparse( playlist_t *p_playlist,
if( sys->b_preparse && !input_item_IsPreparsed( input )
&& (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) )
vlc_MetadataRequest( p_playlist->obj.libvlc, input, 0, -1, p_item );
vlc_MetadataRequest( p_playlist->obj.libvlc, input, 0,
NULL, NULL, -1, p_item );
free( psz_artist );
free( psz_album );
}
......
......@@ -24,6 +24,7 @@
#endif
#include <vlc_common.h>
#include <vlc_atomic.h>
#include "misc/background_worker.h"
#include "input/input_interface.h"
......@@ -39,15 +40,55 @@ struct input_preparser_t
atomic_bool deactivated;
};
typedef struct input_preparser_req_t
{
input_item_t *item;
const input_preparser_callbacks_t *cbs;
void *userdata;
vlc_atomic_rc_t rc;
} input_preparser_req_t;
typedef struct input_preparser_task_t
{
input_preparser_req_t *req;
input_preparser_t* preparser;
input_thread_t* input;
atomic_int state;
atomic_bool done;
} input_preparser_task_t;
static input_preparser_req_t *ReqCreate(input_item_t *item,
const input_preparser_callbacks_t *cbs,
void *userdata)
{
input_preparser_req_t *req = malloc(sizeof(*req));
if (unlikely(!req))
return NULL;
req->item = item;
req->cbs = cbs;
req->userdata = userdata;
vlc_atomic_rc_init(&req->rc);
input_item_Hold(item);
return req;
}
static void ReqHold(input_preparser_req_t *req)
{
vlc_atomic_rc_inc(&req->rc);
}
static void ReqRelease(input_preparser_req_t *req)
{
if (vlc_atomic_rc_dec(&req->rc))
{
input_item_Release(req->item);
free(req);
}
}
static void InputEvent( input_thread_t *input, void *task_,
const struct vlc_input_event *event )
{
......@@ -64,13 +105,21 @@ static void InputEvent( input_thread_t *input, void *task_,
atomic_store( &task->done, true );
background_worker_RequestProbe( task->preparser->worker );
break;
case INPUT_EVENT_SUBITEMS:
{
input_preparser_req_t *req = task->req;
if (req->cbs && req->cbs->on_subtree_added)
req->cbs->on_subtree_added(req->item, event->subitems, req->userdata);
break;
}
default: ;
}
}
static int PreparserOpenInput( void* preparser_, void* item_, void** out )
static int PreparserOpenInput( void* preparser_, void* req_, void** out )
{
input_preparser_t* preparser = preparser_;
input_preparser_req_t *req = req_;
input_preparser_task_t* task = malloc( sizeof *task );
if( unlikely( !task ) )
......@@ -81,10 +130,12 @@ static int PreparserOpenInput( void* preparser_, void* item_, void** out )
task->preparser = preparser_;
task->input = input_CreatePreparser( preparser->owner, InputEvent,
task, item_ );
task, req->item );
if( !task->input )
goto error;
task->req = req;
if( input_Start( task->input ) )
{
input_Close( task->input );
......@@ -97,7 +148,10 @@ static int PreparserOpenInput( void* preparser_, void* item_, void** out )
error:
free( task );
input_item_SignalPreparseEnded( item_, ITEM_PREPARSE_FAILED );
/* TODO remove legacy input_item_SignalPreparseEnded() */
input_item_SignalPreparseEnded(req->item, ITEM_PREPARSE_FAILED);
if (req->cbs && req->cbs->on_preparse_ended)
req->cbs->on_preparse_ended(req->item, ITEM_PREPARSE_FAILED, req->userdata);
return VLC_EGENERIC;
}
......@@ -111,6 +165,7 @@ static int PreparserProbeInput( void* preparser_, void* task_ )
static void PreparserCloseInput( void* preparser_, void* task_ )
{
input_preparser_task_t* task = task_;
input_preparser_req_t *req = task->req;
input_preparser_t* preparser = preparser_;
input_thread_t* input = task->input;
......@@ -141,11 +196,14 @@ static void PreparserCloseInput( void* preparser_, void* task_ )
}
input_item_SetPreparsed( item, true );
/* TODO remove legacy input_item_SignalPreparseEnded() */
input_item_SignalPreparseEnded( item, status );
if (req->cbs && req->cbs->on_preparse_ended)
req->cbs->on_preparse_ended(req->item, status, req->userdata);
}
static void InputItemRelease( void* item ) { input_item_Release( item ); }
static void InputItemHold( void* item ) { input_item_Hold( item ); }
static void ReqHoldVoid(void *item) { ReqHold(item); }
static void ReqReleaseVoid(void *item) { ReqRelease(item); }
input_preparser_t* input_preparser_New( vlc_object_t *parent )
{
......@@ -157,8 +215,9 @@ input_preparser_t* input_preparser_New( vlc_object_t *parent )
.pf_start = PreparserOpenInput,
.pf_probe = PreparserProbeInput,
.pf_stop = PreparserCloseInput,
.pf_release = InputItemRelease,
.pf_hold = InputItemHold };
.pf_release = ReqReleaseVoid,
.pf_hold = ReqHoldVoid
};
if( likely( preparser ) )
......@@ -182,6 +241,7 @@ input_preparser_t* input_preparser_New( vlc_object_t *parent )
void input_preparser_Push( input_preparser_t *preparser,
input_item_t *item, input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs, void *cbs_userdata,
int timeout, void *id )
{
if( atomic_load( &preparser->deactivated ) )
......@@ -202,12 +262,24 @@ void input_preparser_Push( input_preparser_t *preparser,
break;
/* fallthrough */
default:
/* TODO remove legacy input_item_SignalPreparseEnded() */
input_item_SignalPreparseEnded( item, ITEM_PREPARSE_SKIPPED );
if (cbs && cbs->on_preparse_ended)
cbs->on_preparse_ended(item, ITEM_PREPARSE_SKIPPED, cbs_userdata);
return;
}
if( background_worker_Push( preparser->worker, item, id, timeout ) )
struct input_preparser_req_t *req = ReqCreate(item, cbs, cbs_userdata);
if (background_worker_Push(preparser->worker, req, id, timeout))
{
/* TODO remove legacy input_item_SignalPreparseEnded() */
input_item_SignalPreparseEnded( item, ITEM_PREPARSE_FAILED );
if (req->cbs && cbs->on_preparse_ended)
cbs->on_preparse_ended(item, ITEM_PREPARSE_FAILED, cbs_userdata);
}
ReqRelease(req);
}
void input_preparser_fetcher_Push( input_preparser_t *preparser,
......
......@@ -45,8 +45,6 @@ input_preparser_t *input_preparser_New( vlc_object_t * );
*
* The input item is retained until the preparsing is done or until the
* preparser object is deleted.
* Listen to vlc_InputItemPreparseEnded event to get notified when item is
* preparsed.
*
* @param timeout maximum time allowed to preparse the item. If -1, the default
* "preparse-timeout" option will be used as a timeout. If 0, it will wait
......@@ -56,6 +54,8 @@ input_preparser_t *input_preparser_New( vlc_object_t * );
*/
void input_preparser_Push( input_preparser_t *, input_item_t *,
input_item_meta_request_option_t,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id );
void input_preparser_fetcher_Push( input_preparser_t *, input_item_t *,
......
......@@ -158,7 +158,8 @@ static void test_input_metadata_timeout(libvlc_instance_t *vlc, int timeout,
input_item_preparse_timeout, &sem);
assert(i_ret == 0);
i_ret = libvlc_MetadataRequest(vlc->p_libvlc_int, p_item,
META_REQUEST_OPTION_SCOPE_LOCAL, timeout, vlc);
META_REQUEST_OPTION_SCOPE_LOCAL,
NULL, NULL, timeout, vlc);
assert(i_ret == 0);
if (wait_and_cancel > 0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment