Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (7)
Showing
with 208 additions and 152 deletions
......@@ -236,12 +236,12 @@ vlc_media_tree_Find(vlc_media_tree_t *tree, const input_item_t *media,
* \param tree the media tree (not necessarily locked)
* \param parser a valid preparser
* \param media the media to preparse
* \param id a task identifier, cancel it via vlc_preparser_Cancel()
* \returns VLC_PREPARSER_REQ_ID_INVALID in case of error, or a valid id if the
* item was scheduled for preparsing. Cancel it vlc_preparser_Cancel().
*/
VLC_API void
VLC_API vlc_preparser_req_id
vlc_media_tree_Preparse(vlc_media_tree_t *tree, vlc_preparser_t *parser,
input_item_t *media, void *id);
input_item_t *media);
/**
* Media source.
......
......@@ -42,6 +42,9 @@
* It will also issue art fetching requests.
*/
typedef struct vlc_preparser_t vlc_preparser_t;
typedef size_t vlc_preparser_req_id;
#define VLC_PREPARSER_REQ_ID_INVALID 0
typedef enum input_item_meta_request_option_t
{
......@@ -84,22 +87,25 @@ VLC_API vlc_preparser_t *vlc_preparser_New( vlc_object_t *obj,
* @param cbs_userdata opaque pointer used by the callbacks
* @param id unique id provided by the caller. This is can be used to cancel
* the request with vlc_preparser_Cancel()
* @returns VLC_SUCCESS if the item was scheduled for preparsing, an error code
* otherwise
* If this returns an error, the on_preparse_ended will *not* be invoked
* @return VLC_PREPARSER_REQ_ID_INVALID in case of error, or a valid id if the
* item was scheduled for preparsing. If this returns an
* error, the on_preparse_ended will *not* be invoked
*/
VLC_API int vlc_preparser_Push( vlc_preparser_t *preparser, input_item_t *item,
input_item_meta_request_option_t option,
const input_item_parser_cbs_t *cbs,
void *cbs_userdata, void *id );
VLC_API vlc_preparser_req_id
vlc_preparser_Push( vlc_preparser_t *preparser, input_item_t *item,
input_item_meta_request_option_t option,
const input_item_parser_cbs_t *cbs, void *cbs_userdata );
/**
* This function cancel all preparsing requests for a given id
*
* @param preparser the preparser object
* @param id unique id given to vlc_preparser_Push()
* @param id unique id returned by vlc_preparser_Push(),
* VLC_PREPARSER_REQ_ID_INVALID to cancels all tasks
* @return number of tasks cancelled
*/
VLC_API void vlc_preparser_Cancel( vlc_preparser_t *preparser, void *id );
VLC_API size_t vlc_preparser_Cancel( vlc_preparser_t *preparser,
vlc_preparser_req_id id );
/**
* This function destroys the preparser object and thread.
......
......@@ -27,7 +27,9 @@
#include <vlc_tick.h>
typedef struct vlc_thumbnailer_t vlc_thumbnailer_t;
typedef struct vlc_thumbnailer_request_t vlc_thumbnailer_request_t;
typedef size_t vlc_thumbnailer_req_id;
#define VLC_THUMBNAILER_REQ_ID_INVALID 0
/**
* \brief vlc_thumbnailer_cb defines a callback invoked on thumbnailing completion or error
......@@ -71,17 +73,15 @@ enum vlc_thumbnailer_seek_speed
* \param timeout A timeout value, or VLC_TICK_INVALID to disable timeout
* \param cb A user callback to be called on completion (success & error)
* \param user_data An opaque value, provided as pf_cb's first parameter
* \return An opaque request object, or NULL in case of failure
* \returns > 0 if the item was scheduled for thumbnailing, 0 in case of error.
*
* If this function returns a valid request object, the callback is guaranteed
* to be called, even in case of later failure (except if destroyed early by
* If this function returns a valid id, the callback is guaranteed
* to be called, even in case of later failure (except if cancelled early by
* the user).
* The returned request object must be freed with
* vlc_thumbnailer_DestroyRequest().
* The provided input_item will be held by the thumbnailer and can safely be
* released safely after calling this function.
*/
VLC_API vlc_thumbnailer_request_t*
VLC_API vlc_thumbnailer_req_id
vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer,
vlc_tick_t time,
enum vlc_thumbnailer_seek_speed speed,
......@@ -96,17 +96,15 @@ vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer,
* \param timeout A timeout value, or VLC_TICK_INVALID to disable timeout
* \param cb A user callback to be called on completion (success & error)
* \param user_data An opaque value, provided as pf_cb's first parameter
* \return An opaque request object, or NULL in case of failure
*
* If this function returns a valid request object, the callback is guaranteed
* to be called, even in case of later failure (except if destroyed early by
* the user).
* The returned request object must be freed with
* vlc_thumbnailer_DestroyRequest().
* @return VLC_THUMBNAILER_REQ_ID_INVALID in case of error, or a valid id if
* the item was scheduled for preparsing. If this function returns a valid id,
* the callback is guaranteed to be called, even in case of later failure
* (except if cancelled early by the user).
* The provided input_item will be held by the thumbnailer and can safely be
* released after calling this function.
* released safely after calling this function.
*/
VLC_API vlc_thumbnailer_request_t*
VLC_API vlc_thumbnailer_req_id
vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer,
double pos,
enum vlc_thumbnailer_seek_speed speed,
......@@ -114,16 +112,14 @@ vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer,
vlc_thumbnailer_cb cb, void* user_data );
/**
* \brief vlc_thumbnailer_DestroyRequest Destroy a thumbnail request
* \brief vlc_thumbnailer_Camcel Cancel a thumbnail request
* \param thumbnailer A thumbnailer object
* \param request An opaque thumbnail request object
*
* The request can be destroyed before receiving a callback (in that case, the
* callback won't be called) or after (to release resources).
* \param id unique id returned by vlc_thumbnailer_Request*(),
* VLC_THUMBNAILER_REQ_ID_INVALID to cancels all tasks
* \return number of tasks cancelled
*/
VLC_API void
vlc_thumbnailer_DestroyRequest( vlc_thumbnailer_t* thumbnailer,
vlc_thumbnailer_request_t* request );
VLC_API size_t
vlc_thumbnailer_Cancel( vlc_thumbnailer_t* thumbnailer, vlc_thumbnailer_req_id id );
/**
* \brief vlc_thumbnailer_Release releases a thumbnailer and cancel all pending requests
......
......@@ -39,7 +39,6 @@
#include <vlc_url.h>
#include <vlc_thumbnailer.h>
#include <vlc_atomic.h>
#include <vlc_preparser.h>
#include "../src/libvlc.h"
......@@ -372,6 +371,7 @@ libvlc_media_t * libvlc_media_new_from_input_item(input_item_t *p_input_item )
p_md->p_input_item->libvlc_owner = p_md;
atomic_init(&p_md->parsed_status, libvlc_media_parsed_status_none);
p_md->id = VLC_PREPARSER_REQ_ID_INVALID;
libvlc_event_manager_init( &p_md->event_manager, p_md );
......@@ -742,7 +742,6 @@ int libvlc_media_parse_request(libvlc_instance_t *inst, libvlc_media_t *media,
input_item_t *item = media->p_input_item;
input_item_meta_request_option_t parse_scope = 0;
int ret;
unsigned int ref = atomic_load_explicit(&media->worker_count,
memory_order_relaxed);
do
......@@ -816,9 +815,9 @@ int libvlc_media_parse_request(libvlc_instance_t *inst, libvlc_media_t *media,
vlc_preparser_SetTimeout(parser, VLC_TICK_FROM_MS(timeout));
ret = vlc_preparser_Push(parser, item, parse_scope,
&preparser_callbacks, media, media);
if (ret != VLC_SUCCESS)
media->id = vlc_preparser_Push(parser, item, parse_scope,
&preparser_callbacks, media);
if (media->id == VLC_PREPARSER_REQ_ID_INVALID)
{
atomic_fetch_sub_explicit(&media->worker_count, 1,
memory_order_relaxed);
......@@ -833,7 +832,11 @@ libvlc_media_parse_stop(libvlc_instance_t *inst, libvlc_media_t *media)
{
vlc_preparser_t *parser = libvlc_get_preparser(inst);
assert(parser != NULL);
vlc_preparser_Cancel(parser, media);
if (media->id != VLC_PREPARSER_REQ_ID_INVALID)
{
vlc_preparser_Cancel(parser, media->id);
media->id = VLC_PREPARSER_REQ_ID_INVALID;
}
}
// Get Parsed status for media descriptor object
......@@ -921,7 +924,7 @@ struct libvlc_media_thumbnail_request_t
unsigned int height;
bool crop;
libvlc_picture_type_t type;
vlc_thumbnailer_request_t* req;
vlc_thumbnailer_req_id id;
};
static void media_on_thumbnail_ready( void* data, picture_t* thumbnail )
......@@ -967,14 +970,14 @@ libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst,
req->type = picture_type;
req->crop = crop;
libvlc_media_retain( md );
req->req = vlc_thumbnailer_RequestByTime( thumb,
req->id = vlc_thumbnailer_RequestByTime( thumb,
vlc_tick_from_libvlc_time( time ),
speed == libvlc_media_thumbnail_seek_fast ?
VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE,
md->p_input_item,
timeout > 0 ? vlc_tick_from_libvlc_time( timeout ) : VLC_TICK_INVALID,
media_on_thumbnail_ready, req );
if ( req->req == NULL )
if ( req->id == VLC_PREPARSER_REQ_ID_INVALID )
{
free( req );
libvlc_media_release( md );
......@@ -1010,13 +1013,13 @@ libvlc_media_thumbnail_request_by_pos( libvlc_instance_t *inst,
req->crop = crop;
req->type = picture_type;
libvlc_media_retain( md );
req->req = vlc_thumbnailer_RequestByPos( thumb, pos,
req->id = vlc_thumbnailer_RequestByPos( thumb, pos,
speed == libvlc_media_thumbnail_seek_fast ?
VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE,
md->p_input_item,
timeout > 0 ? vlc_tick_from_libvlc_time( timeout ) : VLC_TICK_INVALID,
media_on_thumbnail_ready, req );
if ( req->req == NULL )
if ( req->id == VLC_PREPARSER_REQ_ID_INVALID )
{
free( req );
libvlc_media_release( md );
......@@ -1032,7 +1035,7 @@ void libvlc_media_thumbnail_request_destroy( libvlc_media_thumbnail_request_t *r
vlc_thumbnailer_t *thumb = libvlc_get_thumbnailer(req->instance);
assert(thumb != NULL);
vlc_thumbnailer_DestroyRequest( thumb, req->req );
vlc_thumbnailer_Cancel( thumb, req->id );
libvlc_media_release( req->md );
libvlc_release(req->instance);
free( req );
......
......@@ -30,6 +30,7 @@
#include <vlc_common.h>
#include <vlc_input.h>
#include <vlc_player.h>
#include <vlc_preparser.h>
#include <vlc_atomic.h>
struct libvlc_media_t
......@@ -48,6 +49,7 @@ struct libvlc_media_t
atomic_uint worker_count;
_Atomic libvlc_media_parsed_status_t parsed_status;
vlc_preparser_req_id id;
};
/* Media Descriptor */
......
......@@ -317,7 +317,7 @@ static const char *const myFoldersDescription = "My Folders";
}
vlc_media_tree_Preparse(_p_mediaSource->tree, _p_preparser,
inputNode.inputItem.vlcInputItem, NULL);
inputNode.inputItem.vlcInputItem);
}
- (void)clearChildNodesForNode:(nonnull input_item_node_t*)inputNode
......
......@@ -95,7 +95,7 @@ class NetworkMediaModelPrivate
public:
NetworkMediaModelPrivate(NetworkMediaModel* pub)
: LocalListBaseModelPrivate<NetworkMediaItemPtr>(pub)
, m_preparseSem(1)
, m_preparseSem(1), m_parserId(VLC_PREPARSER_REQ_ID_INVALID)
{}
public:
......@@ -409,7 +409,8 @@ public:
input_item_node_t* mediaNode = nullptr;
input_item_node_t* parent = nullptr;
vlc_media_tree_Lock(tree);
vlc_preparser_Cancel( parser, this );
if (m_parserId != VLC_PREPARSER_REQ_ID_INVALID)
vlc_preparser_Cancel( parser, m_parserId );
std::vector<SharedInputItem> itemList;
q->m_path = {QVariant::fromValue(PathNode(q->m_treeItem, q->m_name))};
if (vlc_media_tree_Find( tree, q->m_treeItem.media.get(), &mediaNode, &parent))
......@@ -437,7 +438,7 @@ public:
}
m_preparseSem.acquire();
vlc_media_tree_Preparse( tree, parser, q->m_treeItem.media.get(), this );
m_parserId = vlc_media_tree_Preparse( tree, parser, q->m_treeItem.media.get() );
m_listener = std::move( l );
......@@ -466,6 +467,8 @@ public:
std::unique_ptr<MediaTreeListener> m_listener;
QHash<QString, NetworkMediaItemPtr> m_items;
std::unique_ptr<MLMediaStore> m_MLMedias;
private:
vlc_preparser_req_id m_parserId;
};
// NetworkMediaModel::ListenerCb implementation
......@@ -497,7 +500,11 @@ NetworkMediaModel::~NetworkMediaModel()
auto parser = m_ctx->getNetworkPreparser();
if (likely(parser != NULL))
{
vlc_preparser_Cancel( parser, this );
if (d->m_parserId != VLC_PREPARSER_REQ_ID_INVALID)
{
vlc_preparser_Cancel( parser, d->m_parserId );
d->m_parserId = VLC_PREPARSER_REQ_ID_INVALID;
}
//wait for the callback call on cancel
d->m_preparseSem.acquire();
}
......
......@@ -1968,7 +1968,7 @@ void PlayerController::requestArtUpdate( input_item_t *p_item )
META_REQUEST_OPTION_FETCH_LOCAL;
vlc_preparser_Push( d->m_preparser, p_item, fetch_options,
&art_fetcher_cbs, d, nullptr );
&art_fetcher_cbs, d );
}
void PlayerControllerPrivate::onArtFetchEnded(input_item_t *p_item, bool)
......
......@@ -70,18 +70,22 @@ bool Thumbnailer::generate( const medialibrary::IMedia&, const std::string& mrl,
{
vlc::threads::mutex_locker lock( m_mutex );
m_currentContext = &ctx;
ctx.request = vlc_thumbnailer_RequestByPos( m_thumbnailer.get(), position,
VLC_THUMBNAILER_SEEK_FAST, item.get(),
VLC_TICK_FROM_SEC( 3 ),
&onThumbnailComplete, &ctx );
vlc_thumbnailer_req_id requestId =
vlc_thumbnailer_RequestByPos( m_thumbnailer.get(), position,
VLC_THUMBNAILER_SEEK_FAST, item.get(),
VLC_TICK_FROM_SEC( 3 ),
&onThumbnailComplete, &ctx );
if (requestId == VLC_THUMBNAILER_REQ_ID_INVALID)
{
m_currentContext = nullptr;
return false;
}
while ( ctx.done == false )
m_cond.wait( m_mutex );
m_currentContext = nullptr;
}
vlc_thumbnailer_DestroyRequest(m_thumbnailer.get(), ctx.request);
if ( ctx.thumbnail == nullptr )
return false;
......
......@@ -41,7 +41,6 @@
struct vlc_event_t;
struct vlc_object_t;
struct vlc_thumbnailer_t;
struct vlc_thumbnailer_request_t;
class Logger;
......@@ -129,7 +128,6 @@ class Thumbnailer : public medialibrary::IThumbnailer
Thumbnailer* thumbnailer;
bool done;
picture_t* thumbnail;
vlc_thumbnailer_request_t* request;
};
public:
Thumbnailer(vlc_medialibrary_module_t* ml);
......
......@@ -32,6 +32,12 @@ struct vlc_thumbnailer_t
{
vlc_object_t* parent;
vlc_executor_t *executor;
vlc_mutex_t lock;
vlc_cond_t cond_ended;
vlc_thumbnailer_req_id current_id;
struct vlc_list submitted_tasks; /**< list of struct task */
};
struct seek_target
......@@ -48,13 +54,8 @@ struct seek_target
};
};
/* We may not rename vlc_thumbnailer_request_t because it is exposed in the
* public API */
typedef struct vlc_thumbnailer_request_t task_t;
struct vlc_thumbnailer_request_t
typedef struct task
{
vlc_atomic_rc_t rc;
vlc_thumbnailer_t *thumbnailer;
struct seek_target seek_target;
......@@ -68,8 +69,6 @@ struct vlc_thumbnailer_request_t
vlc_thumbnailer_cb cb;
void* userdata;
vlc_mutex_t lock;
vlc_cond_t cond_ended;
enum
{
RUNNING,
......@@ -78,8 +77,11 @@ struct vlc_thumbnailer_request_t
} status;
picture_t *pic;
vlc_thumbnailer_req_id id;
struct vlc_runnable runnable; /**< to be passed to the executor */
};
struct vlc_list node; /**< node of vlc_thumbnailer_t.submitted_tasks */
} task_t;
static void RunnableRun(void *);
......@@ -92,7 +94,6 @@ TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item,
if (!task)
return NULL;
vlc_atomic_rc_init(&task->rc);
task->thumbnailer = thumbnailer;
task->item = item;
task->seek_target = seek_target;
......@@ -101,8 +102,6 @@ TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item,
task->userdata = userdata;
task->timeout = timeout;
vlc_mutex_init(&task->lock);
vlc_cond_init(&task->cond_ended);
task->status = RUNNING;
task->pic = NULL;
......@@ -115,10 +114,8 @@ TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item,
}
static void
TaskRelease(task_t *task)
TaskDestroy(task_t *task)
{
if (!vlc_atomic_rc_dec(&task->rc))
return;
input_item_Release(task->item);
free(task);
}
......@@ -140,14 +137,15 @@ on_thumbnailer_input_event( input_thread_t *input,
return;
task_t *task = userdata;
vlc_thumbnailer_t *thumbnailer = task->thumbnailer;
vlc_mutex_lock(&task->lock);
vlc_mutex_lock(&thumbnailer->lock);
if (task->status != RUNNING)
{
/* We may receive a THUMBNAIL_READY event followed by an
* INPUT_EVENT_STATE (end of stream), we must only consider the first
* one. */
vlc_mutex_unlock(&task->lock);
vlc_mutex_unlock(&thumbnailer->lock);
return;
}
......@@ -156,8 +154,8 @@ on_thumbnailer_input_event( input_thread_t *input,
if (event->type == INPUT_EVENT_THUMBNAIL_READY)
task->pic = picture_Hold(event->thumbnail);
vlc_cond_signal(&task->cond_ended);
vlc_mutex_unlock(&task->lock);
vlc_cond_signal(&thumbnailer->cond_ended);
vlc_mutex_unlock(&thumbnailer->lock);
}
static void
......@@ -200,11 +198,11 @@ RunnableRun(void *userdata)
goto error;
}
vlc_mutex_lock(&task->lock);
vlc_mutex_lock(&thumbnailer->lock);
if (task->timeout == VLC_TICK_INVALID)
{
while (task->status == RUNNING)
vlc_cond_wait(&task->cond_ended, &task->lock);
vlc_cond_wait(&thumbnailer->cond_ended, &thumbnailer->lock);
}
else
{
......@@ -212,13 +210,15 @@ RunnableRun(void *userdata)
int timeout = 0;
while (task->status == RUNNING && timeout == 0)
timeout =
vlc_cond_timedwait(&task->cond_ended, &task->lock, deadline);
vlc_cond_timedwait(&thumbnailer->cond_ended, &thumbnailer->lock, deadline);
}
picture_t* pic = task->pic;
task->pic = NULL;
bool notify = task->status != INTERRUPTED;
vlc_mutex_unlock(&task->lock);
vlc_list_remove(&task->node);
vlc_mutex_unlock(&thumbnailer->lock);
if (notify)
NotifyThumbnail(task, pic);
......@@ -230,20 +230,10 @@ RunnableRun(void *userdata)
input_Close(input);
error:
TaskRelease(task);
TaskDestroy(task);
}
static void
Interrupt(task_t *task)
{
/* Wake up RunnableRun() which will call input_Stop() */
vlc_mutex_lock(&task->lock);
task->status = INTERRUPTED;
vlc_cond_signal(&task->cond_ended);
vlc_mutex_unlock(&task->lock);
}
static task_t *
static vlc_thumbnailer_req_id
RequestCommon(vlc_thumbnailer_t *thumbnailer, struct seek_target seek_target,
enum vlc_thumbnailer_seek_speed speed, input_item_t *item,
vlc_tick_t timeout, vlc_thumbnailer_cb cb, void *userdata)
......@@ -252,16 +242,22 @@ RequestCommon(vlc_thumbnailer_t *thumbnailer, struct seek_target seek_target,
task_t *task = TaskNew(thumbnailer, item, seek_target, fast_seek, cb,
userdata, timeout);
if (!task)
return NULL;
return 0;
vlc_mutex_lock(&thumbnailer->lock);
vlc_thumbnailer_req_id id = task->id = thumbnailer->current_id++;
static_assert(VLC_THUMBNAILER_REQ_ID_INVALID == 0, "Invalid id should be 0");
if (unlikely(thumbnailer->current_id == 0)) /* unsigned wrapping */
++thumbnailer->current_id;
vlc_list_append(&task->node, &thumbnailer->submitted_tasks);
vlc_mutex_unlock(&thumbnailer->lock);
/* One ref for the executor */
vlc_atomic_rc_inc(&task->rc);
vlc_executor_Submit(thumbnailer->executor, &task->runnable);
return task;
return id;
}
task_t *
vlc_thumbnailer_req_id
vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer,
vlc_tick_t time,
enum vlc_thumbnailer_seek_speed speed,
......@@ -276,7 +272,7 @@ vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer,
userdata);
}
task_t *
vlc_thumbnailer_req_id
vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer,
double pos, enum vlc_thumbnailer_seek_speed speed,
input_item_t *item, vlc_tick_t timeout,
......@@ -290,20 +286,36 @@ vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer,
userdata);
}
void vlc_thumbnailer_DestroyRequest( vlc_thumbnailer_t* thumbnailer, task_t* task )
size_t vlc_thumbnailer_Cancel( vlc_thumbnailer_t* thumbnailer, vlc_thumbnailer_req_id id )
{
bool canceled = vlc_executor_Cancel(thumbnailer->executor, &task->runnable);
if (canceled)
vlc_mutex_lock(&thumbnailer->lock);
task_t *task;
size_t count = 0;
vlc_list_foreach(task, &thumbnailer->submitted_tasks, node)
{
/* Release the executor reference (since it won't run) */
bool ret = vlc_atomic_rc_dec(&task->rc);
/* Assert that only the caller got the reference */
assert(!ret); (void) ret;
if (id == VLC_THUMBNAILER_REQ_ID_INVALID || task->id == id)
{
count++;
bool canceled =
vlc_executor_Cancel(thumbnailer->executor, &task->runnable);
if (canceled)
{
vlc_list_remove(&task->node);
TaskDestroy(task);
}
else
{
/* The task will be finished and destroyed after run() */
task->status = INTERRUPTED;
vlc_cond_signal(&thumbnailer->cond_ended);
}
}
}
else
Interrupt(task);
TaskRelease(task);
vlc_mutex_unlock(&thumbnailer->lock);
return count;
}
vlc_thumbnailer_t *vlc_thumbnailer_Create( vlc_object_t* parent)
......@@ -320,6 +332,10 @@ vlc_thumbnailer_t *vlc_thumbnailer_Create( vlc_object_t* parent)
}
thumbnailer->parent = parent;
thumbnailer->current_id = 1;
vlc_mutex_init(&thumbnailer->lock);
vlc_cond_init(&thumbnailer->cond_ended);
vlc_list_init(&thumbnailer->submitted_tasks);
return thumbnailer;
}
......
......@@ -833,7 +833,7 @@ vlc_encoder_Destroy
vlc_thumbnailer_Create
vlc_thumbnailer_RequestByTime
vlc_thumbnailer_RequestByPos
vlc_thumbnailer_DestroyRequest
vlc_thumbnailer_Cancel
vlc_thumbnailer_Release
vlc_player_AddAssociatedMedia
vlc_player_AddListener
......
......@@ -338,20 +338,19 @@ static const input_item_parser_cbs_t preparser_callbacks = {
.on_subtree_added = media_subtree_changed,
};
void
vlc_preparser_req_id
vlc_media_tree_Preparse(vlc_media_tree_t *tree, vlc_preparser_t *parser,
input_item_t *media, void* id)
input_item_t *media)
{
#ifdef TEST_MEDIA_SOURCE
VLC_UNUSED(tree);
VLC_UNUSED(parser);
VLC_UNUSED(media);
VLC_UNUSED(id);
VLC_UNUSED(preparser_callbacks);
#else
vlc_preparser_Push(parser, media, META_REQUEST_OPTION_PARSE |
META_REQUEST_OPTION_DO_INTERACT |
META_REQUEST_OPTION_PARSE_SUBITEMS,
&preparser_callbacks, tree, id);
return vlc_preparser_Push(parser, media, META_REQUEST_OPTION_PARSE |
META_REQUEST_OPTION_DO_INTERACT |
META_REQUEST_OPTION_PARSE_SUBITEMS,
&preparser_callbacks, tree);
#endif
}
......@@ -155,6 +155,6 @@ vlc_playlist_AutoPreparse(vlc_playlist_t *playlist, input_item_t *input,
options |= META_REQUEST_OPTION_PARSE_SUBITEMS;
vlc_preparser_Push(playlist->parser, input, options,
&preparser_callbacks, playlist, NULL);
&preparser_callbacks, playlist);
}
}
......@@ -40,6 +40,7 @@ struct vlc_preparser_t
atomic_bool deactivated;
vlc_mutex_t lock;
vlc_preparser_req_id current_id;
struct vlc_list submitted_tasks; /**< list of struct task */
};
......@@ -50,7 +51,7 @@ struct task
input_item_meta_request_option_t options;
const input_item_parser_cbs_t *cbs;
void *userdata;
void *id;
vlc_preparser_req_id id;
vlc_tick_t timeout;
input_item_parser_id_t *parser;
......@@ -69,8 +70,7 @@ static void RunnableRun(void *);
static struct task *
TaskNew(vlc_preparser_t *preparser, input_item_t *item,
input_item_meta_request_option_t options,
const input_item_parser_cbs_t *cbs, void *userdata,
void *id, vlc_tick_t timeout)
const input_item_parser_cbs_t *cbs, void *userdata, vlc_tick_t timeout)
{
assert(timeout >= 0);
......@@ -83,7 +83,6 @@ TaskNew(vlc_preparser_t *preparser, input_item_t *item,
task->options = options;
task->cbs = cbs;
task->userdata = userdata;
task->id = id;
task->timeout = timeout;
input_item_Hold(item);
......@@ -106,12 +105,24 @@ TaskDelete(struct task *task)
free(task);
}
static void
static vlc_preparser_req_id
PreparserGetNextTaskIdLocked(vlc_preparser_t *preparser, struct task *task)
{
vlc_preparser_req_id id = task->id = preparser->current_id++;
static_assert(VLC_PREPARSER_REQ_ID_INVALID == 0, "Invalid id should be 0");
if (unlikely(preparser->current_id == 0)) /* unsigned wrapping */
++preparser->current_id;
return id;
}
static vlc_preparser_req_id
PreparserAddTask(vlc_preparser_t *preparser, struct task *task)
{
vlc_mutex_lock(&preparser->lock);
vlc_preparser_req_id id = PreparserGetNextTaskIdLocked(preparser, task);
vlc_list_append(&task->node, &preparser->submitted_tasks);
vlc_mutex_unlock(&preparser->lock);
return id;
}
static void
......@@ -352,16 +363,18 @@ vlc_preparser_t* vlc_preparser_New( vlc_object_t *parent, unsigned max_threads,
vlc_mutex_init(&preparser->lock);
vlc_list_init(&preparser->submitted_tasks);
preparser->current_id = 1;
return preparser;
}
int vlc_preparser_Push( vlc_preparser_t *preparser,
input_item_t *item, input_item_meta_request_option_t i_options,
const input_item_parser_cbs_t *cbs, void *cbs_userdata, void *id )
vlc_preparser_req_id vlc_preparser_Push( vlc_preparser_t *preparser, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_item_parser_cbs_t *cbs,
void *cbs_userdata )
{
if( atomic_load( &preparser->deactivated ) )
return VLC_EGENERIC;
return 0;
assert(i_options & META_REQUEST_OPTION_PARSE
|| i_options & META_REQUEST_OPTION_FETCH_ANY);
......@@ -372,34 +385,44 @@ int vlc_preparser_Push( vlc_preparser_t *preparser,
|| preparser->fetcher != NULL);
struct task *task =
TaskNew(preparser, item, i_options, cbs, cbs_userdata, id,
TaskNew(preparser, item, i_options, cbs, cbs_userdata,
preparser->default_timeout);
if( !task )
return VLC_ENOMEM;
return 0;
if (preparser->executor != NULL)
{
PreparserAddTask(preparser, task);
vlc_preparser_req_id id = PreparserAddTask(preparser, task);
vlc_executor_Submit(preparser->executor, &task->runnable);
return VLC_SUCCESS;
return id;
}
return Fetch(task);
/* input_fetcher is not cancellable (for now) but we need to generate a new
* id anyway. */
vlc_mutex_lock(&preparser->lock);
vlc_preparser_req_id id = PreparserGetNextTaskIdLocked(preparser, task);
vlc_mutex_unlock(&preparser->lock);
int ret = Fetch(task);
return ret == VLC_SUCCESS ? id : 0;
}
void vlc_preparser_Cancel( vlc_preparser_t *preparser, void *id )
size_t vlc_preparser_Cancel( vlc_preparser_t *preparser, vlc_preparser_req_id id )
{
if (preparser->executor == NULL)
return; /* TODO: the fetcher should be cancellable too */
return 0; /* TODO: the fetcher should be cancellable too */
vlc_mutex_lock(&preparser->lock);
struct task *task;
size_t count = 0;
vlc_list_foreach(task, &preparser->submitted_tasks, node)
{
if (!id || task->id == id)
if (id == VLC_PREPARSER_REQ_ID_INVALID || task->id == id)
{
count++;
bool canceled =
vlc_executor_Cancel(preparser->executor, &task->runnable);
if (canceled)
......@@ -415,12 +438,14 @@ void vlc_preparser_Cancel( vlc_preparser_t *preparser, void *id )
}
vlc_mutex_unlock(&preparser->lock);
return count;
}
void vlc_preparser_Deactivate( vlc_preparser_t* preparser )
{
atomic_store( &preparser->deactivated, true );
vlc_preparser_Cancel(preparser, NULL);
vlc_preparser_Cancel(preparser, 0);
}
void vlc_preparser_SetTimeout( vlc_preparser_t *preparser,
......@@ -432,7 +457,7 @@ void vlc_preparser_SetTimeout( vlc_preparser_t *preparser,
void vlc_preparser_Delete( vlc_preparser_t *preparser )
{
/* In case vlc_preparser_Deactivate() has not been called */
vlc_preparser_Cancel(preparser, NULL);
vlc_preparser_Cancel(preparser, 0);
if (preparser->executor != NULL)
vlc_executor_Delete(preparser->executor);
......
......@@ -247,13 +247,14 @@ static void test_input_metadata_timeout(libvlc_instance_t *vlc, int timeout,
1, VLC_TICK_FROM_MS(timeout),
options);
assert(parser != NULL);
i_ret = vlc_preparser_Push(parser, p_item, options, &cbs, &sem, parser);
assert(i_ret == 0);
vlc_preparser_req_id id = vlc_preparser_Push(parser, p_item, options, &cbs, &sem);
assert(id != VLC_PREPARSER_REQ_ID_INVALID);
if (wait_and_cancel > 0)
{
vlc_tick_sleep( VLC_TICK_FROM_MS(wait_and_cancel) );
vlc_preparser_Cancel(parser, parser);
size_t count = vlc_preparser_Cancel(parser, id);
assert(count == 1);
}
vlc_sem_wait(&sem);
......
......@@ -135,27 +135,26 @@ static void test_thumbnails( libvlc_instance_t* p_vlc )
vlc_mutex_lock( &ctx.lock );
vlc_thumbnailer_request_t* p_req;
vlc_thumbnailer_req_id id;
if ( test_params[i].b_use_pos )
{
p_req = vlc_thumbnailer_RequestByPos( p_thumbnailer, test_params[i].f_pos,
id = vlc_thumbnailer_RequestByPos( p_thumbnailer, test_params[i].f_pos,
test_params[i].b_fast_seek ?
VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE,
p_item, test_params[i].i_timeout, thumbnailer_callback, &ctx );
}
else
{
p_req = vlc_thumbnailer_RequestByTime( p_thumbnailer, test_params[i].i_time,
id = vlc_thumbnailer_RequestByTime( p_thumbnailer, test_params[i].i_time,
test_params[i].b_fast_seek ?
VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE,
p_item, test_params[i].i_timeout, thumbnailer_callback, &ctx );
}
assert( p_req != NULL );
assert( id != VLC_THUMBNAILER_REQ_ID_INVALID );
while ( ctx.b_done == false )
vlc_cond_wait( &ctx.cond, &ctx.lock );
vlc_thumbnailer_DestroyRequest( p_thumbnailer, p_req );
vlc_mutex_unlock( &ctx.lock );
input_item_Release( p_item );
......@@ -184,11 +183,11 @@ static void test_cancel_thumbnail( libvlc_instance_t* p_vlc )
input_item_t* p_item = input_item_New( psz_mrl, "mock item" );
assert( p_item != NULL );
vlc_thumbnailer_request_t* p_req = vlc_thumbnailer_RequestByTime( p_thumbnailer,
vlc_thumbnailer_req_id id = vlc_thumbnailer_RequestByTime( p_thumbnailer,
VLC_TICK_INVALID, VLC_THUMBNAILER_SEEK_PRECISE, p_item,
VLC_TICK_INVALID, thumbnailer_callback_cancel, NULL );
vlc_thumbnailer_DestroyRequest( p_thumbnailer, p_req );
vlc_thumbnailer_Cancel( p_thumbnailer, id );
/* Check that thumbnailer_callback_cancel is not called, even after the
* normal termination of the parsing. */
......