Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
643b7e3b
Commit
643b7e3b
authored
Dec 22, 2008
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up/document a bit art fetcher code.
parent
ab0e40f0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
126 deletions
+195
-126
src/playlist/art.c
src/playlist/art.c
+1
-65
src/playlist/art.h
src/playlist/art.h
+0
-1
src/playlist/fetcher.c
src/playlist/fetcher.c
+171
-47
src/playlist/fetcher.h
src/playlist/fetcher.h
+23
-13
No files found.
src/playlist/art.c
View file @
643b7e3b
...
...
@@ -160,6 +160,7 @@ static char *ArtCacheName( input_item_t *p_item, const char *psz_type )
return
psz_filename
;
}
/* */
int
playlist_FindArtInCache
(
input_item_t
*
p_item
)
{
char
*
psz_path
=
ArtCachePath
(
p_item
);
...
...
@@ -200,71 +201,6 @@ int playlist_FindArtInCache( input_item_t *p_item )
return
b_found
?
VLC_SUCCESS
:
VLC_EGENERIC
;
}
/**
* Download the art using the URL or an art downloaded
* This function should be called only if data is not already in cache
*/
int
playlist_DownloadArt
(
playlist_t
*
p_playlist
,
input_item_t
*
p_item
)
{
char
*
psz_arturl
=
input_item_GetArtURL
(
p_item
);
assert
(
*
psz_arturl
);
if
(
!
strncmp
(
psz_arturl
,
"file://"
,
7
)
)
{
msg_Dbg
(
p_playlist
,
"Album art is local file, no need to cache"
);
free
(
psz_arturl
);
return
VLC_SUCCESS
;
}
if
(
!
strncmp
(
psz_arturl
,
"APIC"
,
4
)
)
{
msg_Warn
(
p_playlist
,
"APIC fetch not supported yet"
);
goto
error
;
}
stream_t
*
p_stream
=
stream_UrlNew
(
p_playlist
,
psz_arturl
);
if
(
!
p_stream
)
goto
error
;
uint8_t
*
p_data
=
NULL
;
int
i_data
=
0
;
for
(
;;
)
{
int
i_read
=
65536
;
if
(
i_data
+
i_read
<=
i_data
)
/* Protect gainst overflow */
break
;
p_data
=
realloc
(
p_data
,
i_data
+
i_read
);
if
(
!
p_data
)
break
;
i_read
=
stream_Read
(
p_stream
,
&
p_data
[
i_data
],
i_read
);
if
(
i_read
<=
0
)
break
;
i_data
+=
i_read
;
}
stream_Delete
(
p_stream
);
if
(
p_data
&&
i_data
>
0
)
{
char
*
psz_type
=
strrchr
(
psz_arturl
,
'.'
);
if
(
psz_type
&&
strlen
(
psz_type
)
>
5
)
psz_type
=
NULL
;
/* remove extension if it's > to 4 characters */
playlist_SaveArt
(
p_playlist
,
p_item
,
p_data
,
i_data
,
psz_type
);
}
free
(
p_data
);
free
(
psz_arturl
);
return
VLC_SUCCESS
;
error:
free
(
psz_arturl
);
return
VLC_EGENERIC
;
}
/* */
int
playlist_SaveArt
(
playlist_t
*
p_playlist
,
input_item_t
*
p_item
,
...
...
src/playlist/art.h
View file @
643b7e3b
...
...
@@ -36,7 +36,6 @@ typedef struct
int
playlist_FindArtInCache
(
input_item_t
*
);
int
playlist_DownloadArt
(
playlist_t
*
,
input_item_t
*
);
int
playlist_SaveArt
(
playlist_t
*
,
input_item_t
*
,
const
uint8_t
*
p_buffer
,
int
i_buffer
,
const
char
*
psz_type
);
#endif
...
...
src/playlist/fetcher.c
View file @
643b7e3b
/*****************************************************************************
*
preparse.c: Prepars
er thread.
*
fetcher.c: Art fetch
er thread.
*****************************************************************************
* Copyright © 1999-2009 the VideoLAN team
* $Id$
...
...
@@ -27,16 +27,38 @@
#include <vlc_common.h>
#include <vlc_playlist.h>
#include <vlc_stream.h>
#include "art.h"
#include "fetcher.h"
#include "playlist_internal.h"
/*****************************************************************************
* Structures/definitions
*****************************************************************************/
struct
playlist_fetcher_t
{
playlist_t
*
p_playlist
;
vlc_thread_t
thread
;
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
int
i_art_policy
;
int
i_waiting
;
input_item_t
**
pp_waiting
;
DECL_ARRAY
(
playlist_album_t
)
albums
;
};
static
void
*
Thread
(
void
*
);
/*****************************************************************************
* Public functions
*****************************************************************************/
playlist_fetcher_t
*
playlist_fetcher_New
(
playlist_t
*
p_playlist
)
{
// Secondary Preparse
playlist_fetcher_t
*
p_fetcher
=
malloc
(
sizeof
(
*
p_fetcher
)
);
if
(
!
p_fetcher
)
return
NULL
;
...
...
@@ -46,7 +68,7 @@ playlist_fetcher_t *playlist_fetcher_New( playlist_t *p_playlist )
vlc_cond_init
(
&
p_fetcher
->
wait
);
p_fetcher
->
i_waiting
=
0
;
p_fetcher
->
pp_waiting
=
NULL
;
p_fetcher
->
i_art_policy
=
var_
Create
GetInteger
(
p_playlist
,
"album-art"
);
p_fetcher
->
i_art_policy
=
var_GetInteger
(
p_playlist
,
"album-art"
);
ARRAY_INIT
(
p_fetcher
->
albums
);
if
(
vlc_clone
(
&
p_fetcher
->
thread
,
Thread
,
p_fetcher
,
...
...
@@ -87,6 +109,10 @@ void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher )
free
(
p_fetcher
);
}
/*****************************************************************************
* Privates functions
*****************************************************************************/
/**
* This function locates the art associated to an input item.
* Return codes:
...
...
@@ -211,12 +237,130 @@ static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item )
return
i_ret
;
}
/**
* Download the art using the URL or an art downloaded
* This function should be called only if data is not already in cache
*/
static
int
DownloadArt
(
playlist_t
*
p_playlist
,
input_item_t
*
p_item
)
{
char
*
psz_arturl
=
input_item_GetArtURL
(
p_item
);
assert
(
*
psz_arturl
);
if
(
!
strncmp
(
psz_arturl
,
"file://"
,
7
)
)
{
msg_Dbg
(
p_playlist
,
"Album art is local file, no need to cache"
);
free
(
psz_arturl
);
return
VLC_SUCCESS
;
}
if
(
!
strncmp
(
psz_arturl
,
"APIC"
,
4
)
)
{
msg_Warn
(
p_playlist
,
"APIC fetch not supported yet"
);
goto
error
;
}
stream_t
*
p_stream
=
stream_UrlNew
(
p_playlist
,
psz_arturl
);
if
(
!
p_stream
)
goto
error
;
uint8_t
*
p_data
=
NULL
;
int
i_data
=
0
;
for
(
;;
)
{
int
i_read
=
65536
;
if
(
i_data
+
i_read
<=
i_data
)
/* Protect gainst overflow */
break
;
p_data
=
realloc
(
p_data
,
i_data
+
i_read
);
if
(
!
p_data
)
break
;
i_read
=
stream_Read
(
p_stream
,
&
p_data
[
i_data
],
i_read
);
if
(
i_read
<=
0
)
break
;
i_data
+=
i_read
;
}
stream_Delete
(
p_stream
);
if
(
p_data
&&
i_data
>
0
)
{
char
*
psz_type
=
strrchr
(
psz_arturl
,
'.'
);
if
(
psz_type
&&
strlen
(
psz_type
)
>
5
)
psz_type
=
NULL
;
/* remove extension if it's > to 4 characters */
playlist_SaveArt
(
p_playlist
,
p_item
,
p_data
,
i_data
,
psz_type
);
}
free
(
p_data
);
free
(
psz_arturl
);
return
VLC_SUCCESS
;
error:
free
(
psz_arturl
);
return
VLC_EGENERIC
;
}
static
int
InputEvent
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
VLC_UNUSED
(
p_this
);
VLC_UNUSED
(
psz_cmd
);
VLC_UNUSED
(
oldval
);
playlist_fetcher_t
*
p_fetcher
=
p_data
;
if
(
newval
.
i_int
==
INPUT_EVENT_ITEM_META
)
vlc_cond_signal
(
&
p_fetcher
->
wait
);
return
VLC_SUCCESS
;
}
/* Check if it is not yet preparsed and if so wait for it
* (at most 0.5s)
* (This can happen if we fetch art on play)
* FIXME this doesn't work if we need to fetch meta before art...
*/
static
void
WaitPreparsed
(
playlist_fetcher_t
*
p_fetcher
,
input_item_t
*
p_item
)
{
playlist_t
*
p_playlist
=
p_fetcher
->
p_playlist
;
if
(
input_item_IsPreparsed
(
p_item
)
)
return
;
input_thread_t
*
p_input
=
playlist_CurrentInput
(
p_playlist
);
if
(
!
p_input
)
return
;
if
(
input_GetItem
(
p_input
)
!=
p_item
)
goto
exit
;
var_AddCallback
(
p_input
,
"intf-event"
,
InputEvent
,
p_fetcher
);
const
mtime_t
i_deadline
=
mdate
()
+
500
*
1000
;
while
(
!
p_input
->
b_eof
&&
!
p_input
->
b_error
&&
!
input_item_IsPreparsed
(
p_item
)
)
{
/* A bit weird, but input_item_IsPreparsed does held the protected value */
vlc_mutex_lock
(
&
p_fetcher
->
lock
);
vlc_cond_timedwait
(
&
p_fetcher
->
wait
,
&
p_fetcher
->
lock
,
i_deadline
);
vlc_mutex_unlock
(
&
p_fetcher
->
lock
);
if
(
i_deadline
<=
mdate
()
)
break
;
}
var_DelCallback
(
p_input
,
"intf-event"
,
InputEvent
,
p_fetcher
);
exit:
vlc_object_release
(
p_input
);
}
static
void
*
Thread
(
void
*
p_data
)
{
playlist_fetcher_t
*
p_fetcher
=
p_data
;
playlist_t
*
p_playlist
=
p_fetcher
->
p_playlist
;
playlist_private_t
*
p_sys
=
pl_priv
(
p_playlist
);
for
(
;;
)
{
...
...
@@ -238,51 +382,31 @@ static void *Thread( void *p_data )
/* */
int
canc
=
vlc_savecancel
();
{
int
i_ret
;
/* Check if it is not yet preparsed and if so wait for it
* (at most 0.5s)
* (This can happen if we fetch art on play)
* FIXME this doesn't work if we need to fetch meta before art...
*/
for
(
i_ret
=
0
;
i_ret
<
10
&&
!
input_item_IsPreparsed
(
p_item
);
i_ret
++
)
{
bool
b_break
;
PL_LOCK
;
b_break
=
(
!
p_sys
->
p_input
||
input_GetItem
(
p_sys
->
p_input
)
!=
p_item
||
p_sys
->
p_input
->
b_die
||
p_sys
->
p_input
->
b_eof
||
p_sys
->
p_input
->
b_error
);
PL_UNLOCK
;
if
(
b_break
)
break
;
msleep
(
50000
);
}
i_ret
=
FindArt
(
p_fetcher
,
p_item
);
if
(
i_ret
==
1
)
{
PL_DEBUG
(
"downloading art for %s"
,
p_item
->
psz_name
);
if
(
playlist_DownloadArt
(
p_playlist
,
p_item
)
)
input_item_SetArtNotFound
(
p_item
,
true
);
else
{
input_item_SetArtFetched
(
p_item
,
true
);
var_SetInteger
(
p_playlist
,
"item-change"
,
p_item
->
i_id
);
}
}
else
if
(
i_ret
==
0
)
/* Was in cache */
{
PL_DEBUG
(
"found art for %s in cache"
,
p_item
->
psz_name
);
input_item_SetArtFetched
(
p_item
,
true
);
var_SetInteger
(
p_playlist
,
"item-change"
,
p_item
->
i_id
);
}
else
{
PL_DEBUG
(
"art not found for %s"
,
p_item
->
psz_name
);
input_item_SetArtNotFound
(
p_item
,
true
);
}
vlc_gc_decref
(
p_item
);
/* Wait that the input item is preparsed if it is being played */
WaitPreparsed
(
p_fetcher
,
p_item
);
/* Find art, and download it if needed */
int
i_ret
=
FindArt
(
p_fetcher
,
p_item
);
if
(
i_ret
==
1
)
i_ret
=
DownloadArt
(
p_playlist
,
p_item
);
/* */
char
*
psz_name
=
input_item_GetName
(
p_item
);
if
(
!
i_ret
)
/* Art is now in cache */
{
PL_DEBUG
(
"found art for %s in cache"
,
psz_name
);
input_item_SetArtFetched
(
p_item
,
true
);
var_SetInteger
(
p_playlist
,
"item-change"
,
p_item
->
i_id
);
}
else
{
PL_DEBUG
(
"art not found for %s"
,
psz_name
);
input_item_SetArtNotFound
(
p_item
,
true
);
}
free
(
psz_name
);
vlc_gc_decref
(
p_item
);
vlc_restorecancel
(
canc
);
int
i_activity
=
var_GetInteger
(
p_playlist
,
"activity"
);
...
...
src/playlist/fetcher.h
View file @
643b7e3b
...
...
@@ -25,22 +25,32 @@
#ifndef _PLAYLIST_FETCHER_H
#define _PLAYLIST_FETCHER_H 1
typedef
struct
{
playlist_t
*
p_playlist
;
vlc_thread_t
thread
;
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
int
i_art_policy
;
int
i_waiting
;
input_item_t
**
pp_waiting
;
DECL_ARRAY
(
playlist_album_t
)
albums
;
}
playlist_fetcher_t
;
/**
* Fetcher opaque structure.
*
* The fether object will retreive the art album data for any given input
* item in an asynchronous way.
*/
typedef
struct
playlist_fetcher_t
playlist_fetcher_t
;
/**
* This function creates the fetcher object and thread.
*/
playlist_fetcher_t
*
playlist_fetcher_New
(
playlist_t
*
);
/**
* This function enqueues the provided item to be art fetched.
*
* The input item is retained until the art fetching is done or until the
* fetcher object is destroyed.
*/
void
playlist_fetcher_Push
(
playlist_fetcher_t
*
,
input_item_t
*
);
/**
* This function destroys the fetcher object and thread.
*
* All pending input items will be released.
*/
void
playlist_fetcher_Delete
(
playlist_fetcher_t
*
);
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment