ogg voribs comment parsing on the fly in the decoder
git-svn-id: https://svn.musicpd.org/mpd/trunk@1279 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
187eba5754
commit
fe0b751c82
33
src/decode.c
33
src/decode.c
@ -118,6 +118,8 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
|
|||||||
DECODE_METADATA_LENGTH); \
|
DECODE_METADATA_LENGTH); \
|
||||||
pc->metadata[DECODE_METADATA_LENGTH-1] = '\0'; \
|
pc->metadata[DECODE_METADATA_LENGTH-1] = '\0'; \
|
||||||
pc->title = dc->title; \
|
pc->title = dc->title; \
|
||||||
|
pc->artist = dc->artist; \
|
||||||
|
pc->album = dc->album; \
|
||||||
} \
|
} \
|
||||||
pc->metadataState = PLAYER_METADATA_STATE_READ; \
|
pc->metadataState = PLAYER_METADATA_STATE_READ; \
|
||||||
pc->totalTime = dc->totalTime; \
|
pc->totalTime = dc->totalTime; \
|
||||||
@ -265,6 +267,8 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
|||||||
dc->metadataSet = 0;
|
dc->metadataSet = 0;
|
||||||
memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
|
memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
|
||||||
dc->title = -1;
|
dc->title = -1;
|
||||||
|
dc->album = -1;
|
||||||
|
dc->artist = -1;
|
||||||
|
|
||||||
strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN);
|
strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN);
|
||||||
dc->utf8url[MAXPATHLEN] = '\0';
|
dc->utf8url[MAXPATHLEN] = '\0';
|
||||||
@ -595,4 +599,31 @@ void decode() {
|
|||||||
|
|
||||||
decodeParent(pc, dc, cb);
|
decodeParent(pc, dc, cb);
|
||||||
}
|
}
|
||||||
/* vim:set shiftwidth=8 tabstop=8 expandtab: */
|
|
||||||
|
/* this is stuff for inputPlugins to use! */
|
||||||
|
#define copyStringToMetadata(string, element) { \
|
||||||
|
if(string && (slen = strlen(string)) && \
|
||||||
|
pos < DECODE_METADATA_LENGTH-1) \
|
||||||
|
{ \
|
||||||
|
strncpy(dc->metadata+pos, string, \
|
||||||
|
DECODE_METADATA_LENGTH-1-pos); \
|
||||||
|
element = pos; \
|
||||||
|
pos += slen; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyMpdTagToDecoderControlMetadata(DecoderControl * dc, MpdTag * tag) {
|
||||||
|
int pos = 0;
|
||||||
|
int slen;
|
||||||
|
|
||||||
|
if(dc->metadataSet) return;
|
||||||
|
if(!tag) return;
|
||||||
|
|
||||||
|
memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
|
||||||
|
|
||||||
|
copyStringToMetadata(tag->title, dc->title);
|
||||||
|
copyStringToMetadata(tag->artist, dc->artist);
|
||||||
|
copyStringToMetadata(tag->album, dc->album);
|
||||||
|
|
||||||
|
dc->metadataSet = 1;
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define DECODE_H
|
#define DECODE_H
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
#include "tag.h"
|
||||||
|
|
||||||
#include "mpd_types.h"
|
#include "mpd_types.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
@ -63,11 +64,15 @@ typedef struct _DecoderControl {
|
|||||||
volatile mpd_sint8 metadataSet;
|
volatile mpd_sint8 metadataSet;
|
||||||
char metadata[DECODE_METADATA_LENGTH];
|
char metadata[DECODE_METADATA_LENGTH];
|
||||||
volatile mpd_sint16 title;
|
volatile mpd_sint16 title;
|
||||||
|
volatile mpd_sint16 artist;
|
||||||
|
volatile mpd_sint16 album;
|
||||||
} DecoderControl;
|
} DecoderControl;
|
||||||
|
|
||||||
void decodeSigHandler(int sig);
|
void decodeSigHandler(int sig);
|
||||||
|
|
||||||
void decode();
|
void decode();
|
||||||
|
|
||||||
|
void copyMpdTagToDecoderControlMetadata(DecoderControl * dc, MpdTag * tag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
||||||
|
@ -165,6 +165,61 @@ float ogg_getReplayGainScale(char ** comments) {
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MpdTag * oggCommentsParse(char ** comments) {
|
||||||
|
MpdTag * ret = NULL;
|
||||||
|
char * temp;
|
||||||
|
|
||||||
|
while(*comments) {
|
||||||
|
if((temp = ogg_parseComment(*comments,"artist"))) {
|
||||||
|
if(!ret) ret = newMpdTag();
|
||||||
|
if(!ret->artist) {
|
||||||
|
ret->artist = strdup(temp);
|
||||||
|
stripReturnChar(ret->artist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((temp = ogg_parseComment(*comments,"title"))) {
|
||||||
|
if(!ret) ret = newMpdTag();
|
||||||
|
if(!ret->title) {
|
||||||
|
ret->title = strdup(temp);
|
||||||
|
stripReturnChar(ret->title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((temp = ogg_parseComment(*comments,"album"))) {
|
||||||
|
if(!ret) ret = newMpdTag();
|
||||||
|
if(!ret->album) {
|
||||||
|
ret->album = strdup(temp);
|
||||||
|
stripReturnChar(ret->album);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((temp = ogg_parseComment(*comments,"tracknumber"))) {
|
||||||
|
if(!ret) ret = newMpdTag();
|
||||||
|
if(!ret->track) {
|
||||||
|
ret->track = strdup(temp);
|
||||||
|
stripReturnChar(ret->track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comments++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void putOggCommentsIntoDecoderControlMetadata(DecoderControl * dc,
|
||||||
|
char ** comments)
|
||||||
|
{
|
||||||
|
MpdTag * tag;
|
||||||
|
|
||||||
|
if(dc->metadataSet) return;
|
||||||
|
|
||||||
|
tag = oggCommentsParse(comments);
|
||||||
|
if(!tag) return;
|
||||||
|
|
||||||
|
copyMpdTagToDecoderControlMetadata(dc, tag);
|
||||||
|
|
||||||
|
freeMpdTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
|
int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
|
||||||
{
|
{
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
@ -215,6 +270,8 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
|
|||||||
|
|
||||||
comments = ov_comment(&vf, -1)->user_comments;
|
comments = ov_comment(&vf, -1)->user_comments;
|
||||||
|
|
||||||
|
putOggCommentsIntoDecoderControlMetadata(dc, comments);
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc->state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
replayGainScale = ogg_getReplayGainScale(comments);
|
replayGainScale = ogg_getReplayGainScale(comments);
|
||||||
@ -281,8 +338,6 @@ MpdTag * oggTagDup(char * file) {
|
|||||||
MpdTag * ret = NULL;
|
MpdTag * ret = NULL;
|
||||||
FILE * fp;
|
FILE * fp;
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
char ** comments;
|
|
||||||
char * temp;
|
|
||||||
|
|
||||||
fp = fopen(file,"r");
|
fp = fopen(file,"r");
|
||||||
if(!fp) return NULL;
|
if(!fp) return NULL;
|
||||||
@ -291,40 +346,11 @@ MpdTag * oggTagDup(char * file) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = newMpdTag();
|
ret = oggCommentsParse(ov_comment(&vf,-1)->user_comments);
|
||||||
|
|
||||||
|
if(!ret) ret = newMpdTag();
|
||||||
ret->time = (int)(ov_time_total(&vf,-1)+0.5);
|
ret->time = (int)(ov_time_total(&vf,-1)+0.5);
|
||||||
|
|
||||||
comments = ov_comment(&vf,-1)->user_comments;
|
|
||||||
|
|
||||||
while(*comments) {
|
|
||||||
if((temp = ogg_parseComment(*comments,"artist"))) {
|
|
||||||
if(!ret->artist) {
|
|
||||||
ret->artist = strdup(temp);
|
|
||||||
stripReturnChar(ret->artist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((temp = ogg_parseComment(*comments,"title"))) {
|
|
||||||
if(!ret->title) {
|
|
||||||
ret->title = strdup(temp);
|
|
||||||
stripReturnChar(ret->title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((temp = ogg_parseComment(*comments,"album"))) {
|
|
||||||
if(!ret->album) {
|
|
||||||
ret->album = strdup(temp);
|
|
||||||
stripReturnChar(ret->album);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((temp = ogg_parseComment(*comments,"tracknumber"))) {
|
|
||||||
if(!ret->track) {
|
|
||||||
ret->track = strdup(temp);
|
|
||||||
stripReturnChar(ret->track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comments++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ov_clear(&vf);
|
ov_clear(&vf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -56,6 +56,8 @@ static void resetPlayerMetadata() {
|
|||||||
if(pc->metadataState == PLAYER_METADATA_STATE_READ) {
|
if(pc->metadataState == PLAYER_METADATA_STATE_READ) {
|
||||||
pc->metadataState = PLAYER_METADATA_STATE_WRITE;
|
pc->metadataState = PLAYER_METADATA_STATE_WRITE;
|
||||||
pc->title = -1;
|
pc->title = -1;
|
||||||
|
pc->artist = -1;
|
||||||
|
pc->album = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +491,12 @@ Song * playerCurrentDecodeSong() {
|
|||||||
if(pc->title >= 0) {
|
if(pc->title >= 0) {
|
||||||
song->tag->title = strdup(pc->title + pc->metadata);
|
song->tag->title = strdup(pc->title + pc->metadata);
|
||||||
}
|
}
|
||||||
|
if(pc->artist >= 0) {
|
||||||
|
song->tag->artist = strdup(pc->artist + pc->metadata);
|
||||||
|
}
|
||||||
|
if(pc->album >= 0) {
|
||||||
|
song->tag->album = strdup(pc->album + pc->metadata);
|
||||||
|
}
|
||||||
validateUtf8Tag(song->tag);
|
validateUtf8Tag(song->tag);
|
||||||
resetPlayerMetadata();
|
resetPlayerMetadata();
|
||||||
return song;
|
return song;
|
||||||
|
@ -87,6 +87,8 @@ typedef struct _PlayerControl {
|
|||||||
volatile mpd_sint8 metadataState;
|
volatile mpd_sint8 metadataState;
|
||||||
char metadata[DECODE_METADATA_LENGTH];
|
char metadata[DECODE_METADATA_LENGTH];
|
||||||
volatile mpd_sint16 title;
|
volatile mpd_sint16 title;
|
||||||
|
volatile mpd_sint16 artist;
|
||||||
|
volatile mpd_sint16 album;
|
||||||
} PlayerControl;
|
} PlayerControl;
|
||||||
|
|
||||||
void clearPlayerPid();
|
void clearPlayerPid();
|
||||||
|
@ -118,6 +118,8 @@ void initPlayerData() {
|
|||||||
playerData_pd->playerControl.totalPlayTime = 0;
|
playerData_pd->playerControl.totalPlayTime = 0;
|
||||||
playerData_pd->playerControl.decode_pid = 0;
|
playerData_pd->playerControl.decode_pid = 0;
|
||||||
playerData_pd->playerControl.title = -1;
|
playerData_pd->playerControl.title = -1;
|
||||||
|
playerData_pd->playerControl.artist = -1;
|
||||||
|
playerData_pd->playerControl.album = -1;
|
||||||
playerData_pd->playerControl.metadataState =
|
playerData_pd->playerControl.metadataState =
|
||||||
PLAYER_METADATA_STATE_WRITE;
|
PLAYER_METADATA_STATE_WRITE;
|
||||||
|
|
||||||
@ -130,6 +132,8 @@ void initPlayerData() {
|
|||||||
memset(playerData_pd->decoderControl.metadata, 0,
|
memset(playerData_pd->decoderControl.metadata, 0,
|
||||||
DECODE_METADATA_LENGTH);
|
DECODE_METADATA_LENGTH);
|
||||||
playerData_pd->decoderControl.title = -1;
|
playerData_pd->decoderControl.title = -1;
|
||||||
|
playerData_pd->decoderControl.artist = -1;
|
||||||
|
playerData_pd->decoderControl.album = -1;
|
||||||
playerData_pd->decoderControl.metadataSet = 0;
|
playerData_pd->decoderControl.metadataSet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user