Migrate file metadata encoding to DMAP common code

This commit is contained in:
Julien BLACHE 2011-04-02 15:07:26 +02:00
parent 07df6bb4aa
commit 718d1e9487
4 changed files with 162 additions and 145 deletions

View File

@ -366,3 +366,151 @@ dmap_send_error(struct evhttp_request *req, char *container, char *errmsg)
evbuffer_free(evbuf); evbuffer_free(evbuf);
} }
int
dmap_encode_file_metadata(struct evbuffer *songlist, struct evbuffer *song, struct db_media_file_info *dbmfi, const struct dmap_field **meta, int nmeta, int force_wav)
{
const struct dmap_field_map *dfm;
const struct dmap_field *df;
char **strval;
char *ptr;
int32_t val;
int want_mikd;
int want_asdk;
int i;
int ret;
want_mikd = 0;
want_asdk = 0;
i = -1;
while (1)
{
i++;
/* Specific meta tags requested (or default list) */
if (nmeta > 0)
{
if (i == nmeta)
break;
df = meta[i];
dfm = df->dfm;
}
/* No specific meta tags requested, send out everything */
else
{
/* End of list */
if (i == (sizeof(dmap_fields) / sizeof(dmap_fields[0])))
break;
df = &dmap_fields[i];
dfm = dmap_fields[i].dfm;
}
/* Not in struct media_file_info */
if (dfm->mfi_offset < 0)
continue;
/* Will be prepended to the list */
if (dfm == &dfm_dmap_mikd)
{
/* item kind */
want_mikd = 1;
continue;
}
else if (dfm == &dfm_dmap_asdk)
{
/* data kind */
want_asdk = 1;
continue;
}
DPRINTF(E_DBG, L_DAAP, "Investigating %s\n", df->desc);
strval = (char **) ((char *)dbmfi + dfm->mfi_offset);
if (!(*strval) || (**strval == '\0'))
continue;
/* Here's one exception ... codectype (ascd) is actually an integer */
if (dfm == &dfm_dmap_ascd)
{
dmap_add_literal(song, df->tag, *strval, 4);
continue;
}
val = 0;
if (force_wav)
{
switch (dfm->mfi_offset)
{
case dbmfi_offsetof(type):
ptr = "wav";
strval = &ptr;
break;
case dbmfi_offsetof(bitrate):
val = 0;
ret = safe_atoi32(dbmfi->samplerate, &val);
if ((ret < 0) || (val == 0))
val = 1411;
else
val = (val * 8) / 250;
ptr = NULL;
strval = &ptr;
break;
case dbmfi_offsetof(description):
ptr = "wav audio file";
strval = &ptr;
break;
default:
break;
}
}
dmap_add_field(song, df, *strval, val);
DPRINTF(E_DBG, L_DAAP, "Done with meta tag %s (%s)\n", df->desc, *strval);
}
val = 0;
if (want_mikd)
val += 9;
if (want_asdk)
val += 9;
dmap_add_container(songlist, "mlit", EVBUFFER_LENGTH(song) + val);
/* Prepend mikd & asdk if needed */
if (want_mikd)
{
/* dmap.itemkind must come first */
ret = safe_atoi32(dbmfi->item_kind, &val);
if (ret < 0)
val = 2; /* music by default */
dmap_add_char(songlist, "mikd", val);
}
if (want_asdk)
{
ret = safe_atoi32(dbmfi->data_kind, &val);
if (ret < 0)
val = 0;
dmap_add_char(songlist, "asdk", val);
}
ret = evbuffer_add_buffer(songlist, song);
if (ret < 0)
{
DPRINTF(E_LOG, L_DAAP, "Could not add song to song list\n");
return -1;
}
return 0;
}

View File

@ -5,6 +5,8 @@
#include <event.h> #include <event.h>
#include "evhttp/evhttp.h" #include "evhttp/evhttp.h"
#include "db.h"
enum dmap_type enum dmap_type
{ {
DMAP_TYPE_UBYTE = 0x01, DMAP_TYPE_UBYTE = 0x01,
@ -35,9 +37,6 @@ struct dmap_field {
}; };
extern const struct dmap_field_map dfm_dmap_mikd;
extern const struct dmap_field_map dfm_dmap_asdk;
extern const struct dmap_field_map dfm_dmap_ascd;
extern const struct dmap_field_map dfm_dmap_mimc; extern const struct dmap_field_map dfm_dmap_mimc;
extern const struct dmap_field_map dfm_dmap_aeSP; extern const struct dmap_field_map dfm_dmap_aeSP;
@ -78,4 +77,8 @@ dmap_add_field(struct evbuffer *evbuf, const struct dmap_field *df, char *strval
void void
dmap_send_error(struct evhttp_request *req, char *container, char *errmsg); dmap_send_error(struct evhttp_request *req, char *container, char *errmsg);
int
dmap_encode_file_metadata(struct evbuffer *songlist, struct evbuffer *song, struct db_media_file_info *dbmfi, const struct dmap_field **meta, int nmeta, int force_wav);
#endif /* !__DMAP_HELPERS_H__ */ #endif /* !__DMAP_HELPERS_H__ */

View File

@ -14,7 +14,7 @@
/* Non-static fields are exported by dmap_common.h */ /* Non-static fields are exported by dmap_common.h */
static const struct dmap_field_map dfm_dmap_miid = { dbmfi_offsetof(id), dbpli_offsetof(id), -1 }; static const struct dmap_field_map dfm_dmap_miid = { dbmfi_offsetof(id), dbpli_offsetof(id), -1 };
static const struct dmap_field_map dfm_dmap_minm = { dbmfi_offsetof(title), dbpli_offsetof(title), dbgri_offsetof(itemname) }; static const struct dmap_field_map dfm_dmap_minm = { dbmfi_offsetof(title), dbpli_offsetof(title), dbgri_offsetof(itemname) };
const struct dmap_field_map dfm_dmap_mikd = { dbmfi_offsetof(item_kind), -1, -1 }; static const struct dmap_field_map dfm_dmap_mikd = { dbmfi_offsetof(item_kind), -1, -1 };
static const struct dmap_field_map dfm_dmap_mper = { dbmfi_offsetof(id), dbpli_offsetof(id), dbgri_offsetof(persistentid) }; static const struct dmap_field_map dfm_dmap_mper = { dbmfi_offsetof(id), dbpli_offsetof(id), dbgri_offsetof(persistentid) };
static const struct dmap_field_map dfm_dmap_mcon = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_mcon = { -1, -1, -1 };
static const struct dmap_field_map dfm_dmap_mcti = { dbmfi_offsetof(id), -1, -1 }; static const struct dmap_field_map dfm_dmap_mcti = { dbmfi_offsetof(id), -1, -1 };
@ -89,7 +89,7 @@ static const struct dmap_field_map dfm_dmap_astc = { dbmfi_offsetof(total_tracks
static const struct dmap_field_map dfm_dmap_astn = { dbmfi_offsetof(track), -1, -1 }; static const struct dmap_field_map dfm_dmap_astn = { dbmfi_offsetof(track), -1, -1 };
static const struct dmap_field_map dfm_dmap_asur = { dbmfi_offsetof(rating), -1, -1 }; static const struct dmap_field_map dfm_dmap_asur = { dbmfi_offsetof(rating), -1, -1 };
static const struct dmap_field_map dfm_dmap_asyr = { dbmfi_offsetof(year), -1, -1 }; static const struct dmap_field_map dfm_dmap_asyr = { dbmfi_offsetof(year), -1, -1 };
const struct dmap_field_map dfm_dmap_asdk = { dbmfi_offsetof(data_kind), -1, -1 }; static const struct dmap_field_map dfm_dmap_asdk = { dbmfi_offsetof(data_kind), -1, -1 };
static const struct dmap_field_map dfm_dmap_asul = { dbmfi_offsetof(url), -1, -1 }; static const struct dmap_field_map dfm_dmap_asul = { dbmfi_offsetof(url), -1, -1 };
static const struct dmap_field_map dfm_dmap_aply = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_aply = { -1, -1, -1 };
static const struct dmap_field_map dfm_dmap_abpl = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_abpl = { -1, -1, -1 };
@ -99,7 +99,7 @@ static const struct dmap_field_map dfm_dmap_arif = { -1,
static const struct dmap_field_map dfm_dmap_aeNV = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_aeNV = { -1, -1, -1 };
const struct dmap_field_map dfm_dmap_aeSP = { -1, -1, -1 }; const struct dmap_field_map dfm_dmap_aeSP = { -1, -1, -1 };
static const struct dmap_field_map dfm_dmap_aePS = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_aePS = { -1, -1, -1 };
const struct dmap_field_map dfm_dmap_ascd = { dbmfi_offsetof(codectype), -1, -1 }; static const struct dmap_field_map dfm_dmap_ascd = { dbmfi_offsetof(codectype), -1, -1 };
static const struct dmap_field_map dfm_dmap_ascs = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_ascs = { -1, -1, -1 };
static const struct dmap_field_map dfm_dmap_agrp = { dbmfi_offsetof(grouping), -1, -1 }; static const struct dmap_field_map dfm_dmap_agrp = { dbmfi_offsetof(grouping), -1, -1 };
static const struct dmap_field_map dfm_dmap_aeSV = { -1, -1, -1 }; static const struct dmap_field_map dfm_dmap_aeSV = { -1, -1, -1 };

View File

@ -913,28 +913,16 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
struct db_media_file_info dbmfi; struct db_media_file_info dbmfi;
struct evbuffer *song; struct evbuffer *song;
struct evbuffer *songlist; struct evbuffer *songlist;
const struct dmap_field_map *dfm;
const struct dmap_field *dmap_fields;
const struct dmap_field *df;
const struct dmap_field **meta; const struct dmap_field **meta;
struct sort_ctx *sctx; struct sort_ctx *sctx;
const char *param; const char *param;
char *tag; char *tag;
char **strval;
char *ptr;
int nfields;
int nmeta; int nmeta;
int sort_headers; int sort_headers;
int nsongs; int nsongs;
int transcode; int transcode;
int want_mikd;
int want_asdk;
int32_t val;
int i;
int ret; int ret;
dmap_fields = dmap_get_fields_table(&nfields);
DPRINTF(E_DBG, L_DAAP, "Fetching song list for playlist %d\n", playlist); DPRINTF(E_DBG, L_DAAP, "Fetching song list for playlist %d\n", playlist);
if (playlist != -1) if (playlist != -1)
@ -1051,8 +1039,6 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
goto out_query_free; goto out_query_free;
} }
want_mikd = 0;
want_asdk = 0;
nsongs = 0; nsongs = 0;
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id)) while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
{ {
@ -1060,99 +1046,13 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
transcode = transcode_needed(req->input_headers, dbmfi.codectype); transcode = transcode_needed(req->input_headers, dbmfi.codectype);
i = -1; ret = dmap_encode_file_metadata(songlist, song, &dbmfi, meta, nmeta, transcode);
while (1) if (ret < 0)
{ {
i++; DPRINTF(E_LOG, L_DAAP, "Failed to encode song metadata\n");
/* Specific meta tags requested (or default list) */ ret = -100;
if (nmeta > 0) break;
{
if (i == nmeta)
break;
df = meta[i];
dfm = df->dfm;
}
/* No specific meta tags requested, send out everything */
else
{
/* End of list */
if (i == nfields)
break;
df = &dmap_fields[i];
dfm = dmap_fields[i].dfm;
}
/* Not in struct media_file_info */
if (dfm->mfi_offset < 0)
continue;
/* Will be prepended to the list */
if (dfm == &dfm_dmap_mikd)
{
/* item kind */
want_mikd = 1;
continue;
}
else if (dfm == &dfm_dmap_asdk)
{
/* data kind */
want_asdk = 1;
continue;
}
DPRINTF(E_DBG, L_DAAP, "Investigating %s\n", df->desc);
strval = (char **) ((char *)&dbmfi + dfm->mfi_offset);
if (!(*strval) || (**strval == '\0'))
continue;
/* Here's one exception ... codectype (ascd) is actually an integer */
if (dfm == &dfm_dmap_ascd)
{
dmap_add_literal(song, df->tag, *strval, 4);
continue;
}
val = 0;
if (transcode)
{
switch (dfm->mfi_offset)
{
case dbmfi_offsetof(type):
ptr = "wav";
strval = &ptr;
break;
case dbmfi_offsetof(bitrate):
val = 0;
ret = safe_atoi32(dbmfi.samplerate, &val);
if ((ret < 0) || (val == 0))
val = 1411;
else
val = (val * 8) / 250;
ptr = NULL;
strval = &ptr;
break;
case dbmfi_offsetof(description):
ptr = "wav audio file";
strval = &ptr;
break;
default:
break;
}
}
dmap_add_field(song, df, *strval, val);
DPRINTF(E_DBG, L_DAAP, "Done with meta tag %s (%s)\n", df->desc, *strval);
} }
/* Always include sort tags */ /* Always include sort tags */
@ -1177,40 +1077,6 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
} }
DPRINTF(E_DBG, L_DAAP, "Done with song\n"); DPRINTF(E_DBG, L_DAAP, "Done with song\n");
val = 0;
if (want_mikd)
val += 9;
if (want_asdk)
val += 9;
dmap_add_container(songlist, "mlit", EVBUFFER_LENGTH(song) + val);
/* Prepend mikd & asdk if needed */
if (want_mikd)
{
/* dmap.itemkind must come first */
ret = safe_atoi32(dbmfi.item_kind, &val);
if (ret < 0)
val = 2; /* music by default */
dmap_add_char(songlist, "mikd", val);
}
if (want_asdk)
{
ret = safe_atoi32(dbmfi.data_kind, &val);
if (ret < 0)
val = 0;
dmap_add_char(songlist, "asdk", val);
}
ret = evbuffer_add_buffer(songlist, song);
if (ret < 0)
{
DPRINTF(E_LOG, L_DAAP, "Could not add song to song list for DAAP song list reply\n");
ret = -100;
break;
}
} }
DPRINTF(E_DBG, L_DAAP, "Done with song list, %d songs\n", nsongs); DPRINTF(E_DBG, L_DAAP, "Done with song list, %d songs\n", nsongs);