* Be more flexible when it comes to album art resolutions. This is really just a recommendation and not an absolute requirement for DLNA compliance.

This commit is contained in:
Justin Maggard 2009-02-04 02:25:24 +00:00
parent 48a742181d
commit a1d385241d
6 changed files with 77 additions and 43 deletions

View File

@ -38,6 +38,24 @@ static void libjpeg_error_handler(j_common_ptr cinfo)
return;
}
int
check_res(int width, int height, char * dlna_pn)
{
if( (width <= 0) || (height <= 0) )
return 0;
if( width <= 160 && height <= 160 )
strcpy(dlna_pn, "JPEG_TN");
else if( width <= 640 && height <= 480 )
strcpy(dlna_pn, "JPEG_SM");
else if( width <= 1024 && height <= 768 )
strcpy(dlna_pn, "JPEG_MED");
else if( width <= 4096 && height <= 4096 )
strcpy(dlna_pn, "JPEG_LRG");
else
return 0;
return 1;
}
#ifdef HAVE_LIBID3TAG
#include <id3tag.h>
@ -101,9 +119,9 @@ jpeg_memory_src(j_decompress_ptr cinfo, unsigned char const *buffer, size_t bufs
src->pub.bytes_in_buffer = bufsize;
}
/* And our main album art function */
/* And our main album art functions */
int
check_embedded_art(const char * path)
check_embedded_art(const char * path, char * dlna_pn)
{
struct id3_file *file;
struct id3_tag *pid3tag;
@ -148,21 +166,22 @@ check_embedded_art(const char * path)
}
id3_file_close(file);
/* It's not a valid DLNA_PN JPEG_TN unless it's JPEG <= 160x160 */
return( (width > 0 && width <= 160) && (height > 0 && height <= 160) );
return( check_res(width, height, dlna_pn) );
}
#endif // HAVE_LIBID3TAG
char *
check_for_album_file(char * dir)
check_for_album_file(char * dir, char * dlna_pn)
{
char * file = malloc(PATH_MAX);
char * album_art_names[] =
{
"Cover.jpg", "cover.jpg",
"Album.jpg", "album.jpg",
"Folder.jpg", "folder.jpg",
"Thumb.jpg", "thumb.jpg",
"AlbumArtSmall.jpg", "albumartsmall.jpg",
"Cover.jpg", "cover.jpg",
"AlbumArt.jpg", "albumart.jpg",
"Album.jpg", "album.jpg",
"Folder.jpg", "folder.jpg",
"Thumb.jpg", "thumb.jpg",
0
};
struct jpeg_decompress_struct cinfo;
@ -191,8 +210,10 @@ check_for_album_file(char * dir)
jpeg_destroy_decompress(&cinfo);
fclose(infile);
if( (width > 0 && width <= 160) && (height > 0 && height <= 160) )
if( check_res(width, height, dlna_pn) )
return(file);
else
return(NULL);
}
}
free(file);
@ -200,7 +221,7 @@ check_for_album_file(char * dir)
}
sqlite_int64
find_album_art(const char * path)
find_album_art(const char * path, char * dlna_pn)
{
char * album_art = NULL;
char * sql;
@ -210,9 +231,9 @@ find_album_art(const char * path)
char * mypath = strdup(path);
#ifdef HAVE_LIBID3TAG
if( check_embedded_art(path) || (album_art = check_for_album_file(dirname(mypath))) )
if( check_embedded_art(path, dlna_pn) || (album_art = check_for_album_file(dirname(mypath), dlna_pn)) )
#else
if( (album_art = check_for_album_file(dirname(mypath))) )
if( (album_art = check_for_album_file(dirname(mypath), dlna_pn)) )
#endif
{
sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path);

View File

@ -11,6 +11,6 @@
#define __ALBUMART_H__
sqlite_int64
find_album_art(const char * path);
find_album_art(const char * path, char * dlna_pn);
#endif

View File

@ -100,17 +100,18 @@ get_fourcc(const char *s)
}
sqlite_int64
GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art)
GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art, const char * art_dlna_pn)
{
char * sql;
int ret;
sql = sqlite3_mprintf( "INSERT into DETAILS"
" (TITLE, CREATOR, ARTIST, GENRE, ALBUM_ART) "
" (TITLE, CREATOR, ARTIST, GENRE, ALBUM_ART, ART_DLNA_PN) "
"VALUES"
" ('%q', %Q, %Q, %Q, %lld);",
" ('%q', %Q, %Q, %Q, %lld, %Q);",
name, artist, artist, genre,
album_art ? strtoll(album_art, NULL, 10) : 0);
album_art ? strtoll(album_art, NULL, 10) : 0,
art_dlna_pn);
if( sql_exec(db, sql) != SQLITE_OK )
ret = 0;
@ -136,6 +137,8 @@ GetAudioMetadata(const char * path, char * name)
char *zErrMsg = NULL;
char *title, *artist, *album, *genre, *comment;
int free_flags = 0;
sqlite_int64 album_art;
char art_dlna_pn[9];
if ( stat(path, &file) == 0 )
size = file.st_size;
@ -248,11 +251,13 @@ GetAudioMetadata(const char * path, char * name)
strcpy(mime, "audio/mp4");
}
album_art = find_album_art(path, art_dlna_pn);
sql = sqlite3_mprintf( "INSERT into DETAILS"
" (PATH, SIZE, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE,"
" TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, TRACK, DLNA_PN, MIME, ALBUM_ART) "
" TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, TRACK, DLNA_PN, MIME, ALBUM_ART, ART_DLNA_PN) "
"VALUES"
" (%Q, %llu, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, '%s', '%s', %lld);",
" (%Q, %llu, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, '%s', '%s', %lld, %Q);",
path, size, duration, taglib_audioproperties_channels(properties),
taglib_audioproperties_bitrate(properties)*1024,
taglib_audioproperties_samplerate(properties),
@ -264,7 +269,7 @@ GetAudioMetadata(const char * path, char * name)
comment,
taglib_tag_track(tag),
dlna_pn, mime,
find_album_art(path) );
album_art, album_art?art_dlna_pn:NULL );
taglib_tag_free_strings();
taglib_file_free(audio_file);

View File

@ -44,7 +44,7 @@ char *
modifyString(char * string, const char * before, const char * after, short like);
sqlite_int64
GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art);
GetFolderMetadata(const char * name, const char * artist, const char * genre, const char * album_art, const char * art_dlna_pn);
sqlite_int64
GetAudioMetadata(const char * path, char * name);

View File

@ -79,7 +79,7 @@ get_next_available_id(const char * table, const char * parentID)
long long int
insert_container(const char * tmpTable, const char * item, const char * rootParent, const char *subParent,
const char *class, const char *artist, const char *genre, const char *album_art)
const char *class, const char *artist, const char *genre, const char *album_art, const char *art_dlna_pn)
{
char **result;
char *sql;
@ -100,7 +100,7 @@ insert_container(const char * tmpTable, const char * item, const char * rootPare
else
{
parentID = get_next_available_id("OBJECTS", rootParent);
detailID = GetFolderMetadata(item, artist, genre, album_art);
detailID = GetFolderMetadata(item, artist, genre, album_art, art_dlna_pn);
sql = sqlite3_mprintf( "INSERT into OBJECTS"
" (OBJECT_ID, PARENT_ID, DETAIL_ID, CLASS, NAME) "
"VALUES"
@ -147,7 +147,7 @@ insert_containers(const char * name, const char *path, const char * refID, const
{
strncpy(date_taken, date, 10);
}
container = insert_container("DATES", date_taken, "3$12", NULL, "album.photoAlbum", NULL, NULL, NULL);
container = insert_container("DATES", date_taken, "3$12", NULL, "album.photoAlbum", NULL, NULL, NULL, NULL);
parentID = container>>32;
objectID = container;
sql = sqlite3_mprintf( "INSERT into OBJECTS"
@ -160,12 +160,12 @@ insert_containers(const char * name, const char *path, const char * refID, const
}
if( cam && date )
{
container = insert_container("CAMS", cam, "3$13", NULL, "storageFolder", NULL, NULL, NULL);
container = insert_container("CAMS", cam, "3$13", NULL, "storageFolder", NULL, NULL, NULL, NULL);
parentID = container>>32;
//objectID = container;
char parent[64];
sprintf(parent, "3$13$%X", parentID);
long long int subcontainer = insert_container("CAMDATE", date_taken, parent, cam, "storageFolder", NULL, NULL, NULL);
long long int subcontainer = insert_container("CAMDATE", date_taken, parent, cam, "storageFolder", NULL, NULL, NULL, NULL);
int subParentID = subcontainer>>32;
int subObjectID = subcontainer;
sql = sqlite3_mprintf( "INSERT into OBJECTS"
@ -187,8 +187,8 @@ insert_containers(const char * name, const char *path, const char * refID, const
}
else if( strstr(class, "audioItem") )
{
char *artist = cols ? result[7+cols]:NULL, *album = cols ? result[8+cols]:NULL;
char *genre = cols ? result[9+cols]:NULL, *album_art = cols ? result[19+cols]:NULL;
char *artist = cols ? result[7+cols]:NULL, *album = cols ? result[8+cols]:NULL, *genre = cols ? result[9+cols]:NULL;
char *album_art = cols ? result[19+cols]:NULL, *art_dlna_pn = cols ? result[20+cols]:NULL;
static char last_artist[1024] = "0";
static int last_artist_parentID, last_artist_objectID;
static char last_album[1024];
@ -207,7 +207,7 @@ insert_containers(const char * name, const char *path, const char * refID, const
else
{
strcpy(last_artist, artist);
container = insert_container("ARTISTS", artist, "1$6", NULL, "person.musicArtist", NULL, genre, NULL);
container = insert_container("ARTISTS", artist, "1$6", NULL, "person.musicArtist", NULL, genre, NULL, NULL);
parentID = container>>32;
objectID = container;
last_artist_objectID = objectID;
@ -231,7 +231,7 @@ insert_containers(const char * name, const char *path, const char * refID, const
else
{
strcpy(last_album, album);
container = insert_container("ALBUMS", album, "1$7", NULL, "album.musicAlbum", artist, genre, album_art);
container = insert_container("ALBUMS", album, "1$7", NULL, "album.musicAlbum", artist, genre, album_art, art_dlna_pn);
parentID = container>>32;
objectID = container;
last_album_objectID = objectID;
@ -255,7 +255,7 @@ insert_containers(const char * name, const char *path, const char * refID, const
else
{
strcpy(last_genre, genre);
container = insert_container("GENRES", genre, "1$5", NULL, "genre.musicGenre", NULL, NULL, NULL);
container = insert_container("GENRES", genre, "1$5", NULL, "genre.musicGenre", NULL, NULL, NULL, NULL);
parentID = container>>32;
objectID = container;
last_genre_objectID = objectID;
@ -361,7 +361,7 @@ insert_directory(const char * name, const char * path, const char * base, const
return 1;
}
detailID = GetFolderMetadata(name, NULL, NULL, NULL);
detailID = GetFolderMetadata(name, NULL, NULL, NULL, NULL);
sql = sqlite3_mprintf( "INSERT into OBJECTS"
" (OBJECT_ID, PARENT_ID, REF_ID, DETAIL_ID, CLASS, NAME) "
"VALUES"
@ -513,7 +513,8 @@ CreateDatabase(void)
"CREATOR TEXT, "
"DLNA_PN TEXT, "
"MIME TEXT, "
"ALBUM_ART INTEGER DEFAULT 0"
"ALBUM_ART INTEGER DEFAULT 0, "
"ART_DLNA_PN TEXT DEFAULT NULL"
");");
if( ret != SQLITE_OK )
goto sql_failed;
@ -529,7 +530,7 @@ CreateDatabase(void)
sprintf(sql_buf, "INSERT into OBJECTS (OBJECT_ID, PARENT_ID, DETAIL_ID, CLASS, NAME)"
" values "
"('%s', '%s', %lld, 'container.storageFolder', '%s')",
containers[i], containers[i+1], GetFolderMetadata(containers[i+2], NULL, NULL, NULL), containers[i+2]);
containers[i], containers[i+1], GetFolderMetadata(containers[i+2], NULL, NULL, NULL, NULL), containers[i+2]);
ret = sql_exec(db, sql_buf);
if( ret != SQLITE_OK )
goto sql_failed;

View File

@ -209,8 +209,8 @@ static int callback(void *args, int argc, char **argv, char **azColName)
struct Response { char *resp; int returned; int requested; int total; char *filter; } *passed_args = (struct Response *)args;
char *id = argv[1], *parent = argv[2], *refID = argv[3], *class = argv[4], *detailID = argv[5], *size = argv[9], *title = argv[10],
*duration = argv[11], *bitrate = argv[12], *sampleFrequency = argv[13], *artist = argv[14], *album = argv[15],
*genre = argv[16], *comment = argv[17], *nrAudioChannels = argv[18], *track = argv[19], *date = argv[20],
*resolution = argv[21], *tn = argv[22], *creator = argv[23], *dlna_pn = argv[24], *mime = argv[25], *album_art = argv[26];
*genre = argv[16], *comment = argv[17], *nrAudioChannels = argv[18], *track = argv[19], *date = argv[20], *resolution = argv[21],
*tn = argv[22], *creator = argv[23], *dlna_pn = argv[24], *mime = argv[25], *album_art = argv[26], *art_dlna_pn = argv[27];
char dlna_buf[64];
char str_buf[4096];
char **result;
@ -269,10 +269,12 @@ static int callback(void *args, int argc, char **argv, char **azColName)
strcat(passed_args->resp, str_buf);
}
if( album_art && atoi(album_art) && (!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI")) ) {
sprintf(str_buf, "&lt;upnp:albumArtURI %s"
"&gt;http://%s:%d/AlbumArt/%s.jpg&lt;/upnp:albumArtURI&gt;",
(!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID")) ?
"dlna:profileID=\"JPEG_TN\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"" : "",
strcat(passed_args->resp, "&lt;upnp:albumArtURI ");
if( !passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID") ) {
sprintf(str_buf, "dlna:profileID=\"%s\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"", art_dlna_pn);
strcat(passed_args->resp, str_buf);
}
sprintf(str_buf, "&gt;http://%s:%d/AlbumArt/%s.jpg&lt;/upnp:albumArtURI&gt;",
lan_addr[0].str, runtime_vars.port, album_art);
strcat(passed_args->resp, str_buf);
}
@ -368,8 +370,13 @@ static int callback(void *args, int argc, char **argv, char **azColName)
strcat(passed_args->resp, str_buf);
}
if( album_art && atoi(album_art) && (!passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI")) ) {
sprintf(str_buf, "&lt;upnp:albumArtURI dlna:profileID=\"JPEG_TN\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\""
"&gt;http://%s:%d/AlbumArt/%s.jpg&lt;/upnp:albumArtURI&gt;", lan_addr[0].str, runtime_vars.port, album_art);
strcat(passed_args->resp, "&lt;upnp:albumArtURI ");
if( !passed_args->filter || strstr(passed_args->filter, "upnp:albumArtURI@dlna:profileID") ) {
sprintf(str_buf, "dlna:profileID=\"%s\" xmlns:dlna=\"urn:schemas-dlnaorg:metadata-1-0/\"", art_dlna_pn);
strcat(passed_args->resp, str_buf);
}
sprintf(str_buf, "&gt;http://%s:%d/AlbumArt/%s.jpg&lt;/upnp:albumArtURI&gt;",
lan_addr[0].str, runtime_vars.port, album_art);
strcat(passed_args->resp, str_buf);
}
sprintf(str_buf, "&lt;/container&gt;");