Support for multiple wma composers
This commit is contained in:
parent
0725c9ae13
commit
c5ef4021a3
122
src/scan-wma.c
122
src/scan-wma.c
|
@ -251,6 +251,13 @@ typedef struct tag_wma_stream_properties {
|
||||||
unsigned short int flags;
|
unsigned short int flags;
|
||||||
unsigned int reserved;
|
unsigned int reserved;
|
||||||
} _PACKED WMA_STREAM_PROP;
|
} _PACKED WMA_STREAM_PROP;
|
||||||
|
|
||||||
|
typedef struct tag_wma_header_extension {
|
||||||
|
unsigned char reserved_1[16];
|
||||||
|
unsigned short int reserved_2;
|
||||||
|
unsigned int data_size;
|
||||||
|
} _PACKED WMA_HEADER_EXT;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -262,10 +269,11 @@ unsigned int wma_convert_int(unsigned char *src);
|
||||||
unsigned long long wma_convert_ll(unsigned char *src);
|
unsigned long long wma_convert_ll(unsigned char *src);
|
||||||
char *wma_utf16toutf8(unsigned char *utf16, int len);
|
char *wma_utf16toutf8(unsigned char *utf16, int len);
|
||||||
int wma_parse_content_description(int fd,int size, MP3FILE *pmp3);
|
int wma_parse_content_description(int fd,int size, MP3FILE *pmp3);
|
||||||
int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3);
|
int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3, int extended);
|
||||||
int wma_parse_file_properteis(int fd,int size, MP3FILE *pmp3);
|
int wma_parse_file_properteis(int fd,int size, MP3FILE *pmp3);
|
||||||
int wma_parse_audio_media(int fd, int size, MP3FILE *pmp3);
|
int wma_parse_audio_media(int fd, int size, MP3FILE *pmp3);
|
||||||
int wma_parse_stream_properties(int fd, int size, MP3FILE *pmp3);
|
int wma_parse_stream_properties(int fd, int size, MP3FILE *pmp3);
|
||||||
|
int wma_parse_header_extension(int fd, int size, MP3FILE *pmp3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read an unsigned short int from the fd
|
* read an unsigned short int from the fd
|
||||||
|
@ -335,6 +343,54 @@ int wma_file_read_bytes(int fd,int len, unsigned char **data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wma_parse_header_extension(int fd, int size, MP3FILE *pmp3) {
|
||||||
|
WMA_HEADER_EXT he;
|
||||||
|
WMA_SUBHEADER sh;
|
||||||
|
WMA_GUID *pguid;
|
||||||
|
long bytes_left;
|
||||||
|
|
||||||
|
if(r_read(fd,&he,sizeof(he)) != sizeof(he))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bytes_left = he.data_size;
|
||||||
|
DPRINTF(E_DBG,L_SCAN,"Found header ext of %ld (%ld) bytes\n",he.data_size,size);
|
||||||
|
|
||||||
|
while(bytes_left) {
|
||||||
|
/* read in a subheader */
|
||||||
|
if(r_read(fd,&sh,sizeof(sh)) != sizeof(sh))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pguid = wma_find_guid(sh.objectid);
|
||||||
|
if(!pguid) {
|
||||||
|
DPRINTF(E_DBG,L_SCAN," Unknown ext subheader: %02hhx%02hhx"
|
||||||
|
"%02hhx%02hhx-"
|
||||||
|
"%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
|
||||||
|
"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx\n",
|
||||||
|
sh.objectid[3],sh.objectid[2],
|
||||||
|
sh.objectid[1],sh.objectid[0],
|
||||||
|
sh.objectid[5],sh.objectid[4],
|
||||||
|
sh.objectid[7],sh.objectid[6],
|
||||||
|
sh.objectid[8],sh.objectid[9],
|
||||||
|
sh.objectid[10],sh.objectid[11],
|
||||||
|
sh.objectid[12],sh.objectid[13],
|
||||||
|
sh.objectid[14],sh.objectid[15]);
|
||||||
|
} else {
|
||||||
|
DPRINTF(E_DBG,L_SCAN," Found ext subheader: %s\n", pguid->name);
|
||||||
|
if(strcmp(pguid->name,"ASF_Metadata_Library_Object")==0) {
|
||||||
|
if(!wma_parse_extended_content_description(fd,size,pmp3,1))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG,L_SCAN," Size: %ld\n",sh.size);
|
||||||
|
|
||||||
|
bytes_left -= sh.size;
|
||||||
|
lseek(fd,sh.size - sizeof(sh),SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* another try to get stream codec type
|
* another try to get stream codec type
|
||||||
|
@ -417,13 +473,16 @@ int wma_parse_audio_media(int fd, int size, MP3FILE *pmp3) {
|
||||||
* @param size size of the content description block
|
* @param size size of the content description block
|
||||||
* @param pmp3 the mp3 struct we are filling with gleaned data
|
* @param pmp3 the mp3 struct we are filling with gleaned data
|
||||||
*/
|
*/
|
||||||
int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3, int extended) {
|
||||||
unsigned short descriptor_count;
|
unsigned short descriptor_count;
|
||||||
int index;
|
int index;
|
||||||
unsigned short descriptor_name_len;
|
unsigned short descriptor_name_len;
|
||||||
char *descriptor_name;
|
char *descriptor_name;
|
||||||
unsigned short descriptor_value_type;
|
unsigned short descriptor_value_type;
|
||||||
|
unsigned int descriptor_value_int;
|
||||||
unsigned short descriptor_value_len;
|
unsigned short descriptor_value_len;
|
||||||
|
unsigned short language_list_index;
|
||||||
|
unsigned short stream_number;
|
||||||
|
|
||||||
char *descriptor_byte_value=NULL;
|
char *descriptor_byte_value=NULL;
|
||||||
unsigned int descriptor_int_value; /* bool and dword */
|
unsigned int descriptor_int_value; /* bool and dword */
|
||||||
|
@ -444,15 +503,27 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
|
|
||||||
for(index = 0; index < descriptor_count; index++) {
|
for(index = 0; index < descriptor_count; index++) {
|
||||||
DPRINTF(E_DBG,L_SCAN,"Reading descr %d of %d\n",index,descriptor_count);
|
DPRINTF(E_DBG,L_SCAN,"Reading descr %d of %d\n",index,descriptor_count);
|
||||||
if(!wma_file_read_short(fd,&descriptor_name_len)) return -1;
|
if(!extended) {
|
||||||
if(!wma_file_read_utf16(fd,descriptor_name_len,&descriptor_name)) return -1;
|
if(!wma_file_read_short(fd,&descriptor_name_len)) return FALSE;
|
||||||
if(!wma_file_read_short(fd,&descriptor_value_type)) {
|
if(!wma_file_read_utf16(fd,descriptor_name_len,&descriptor_name))
|
||||||
free(descriptor_name);
|
return FALSE;
|
||||||
return FALSE;
|
if(!wma_file_read_short(fd,&descriptor_value_type)) {
|
||||||
}
|
free(descriptor_name);
|
||||||
if(!wma_file_read_short(fd,&descriptor_value_len)) {
|
return FALSE;
|
||||||
free(descriptor_name);
|
}
|
||||||
return FALSE;
|
if(!wma_file_read_short(fd,&descriptor_value_len)) {
|
||||||
|
free(descriptor_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
descriptor_value_int = descriptor_value_len;
|
||||||
|
} else {
|
||||||
|
if(!wma_file_read_short(fd,&language_list_index)) return FALSE;
|
||||||
|
if(!wma_file_read_short(fd,&stream_number)) return FALSE;
|
||||||
|
if(!wma_file_read_short(fd,&descriptor_name_len)) return FALSE;
|
||||||
|
if(!wma_file_read_short(fd,&descriptor_value_type)) return FALSE;
|
||||||
|
if(!wma_file_read_int(fd,&descriptor_value_int)) return FALSE;
|
||||||
|
if(!wma_file_read_utf16(fd,descriptor_name_len,&descriptor_name))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG,L_SCAN,"Found descriptor: %s\n", descriptor_name);
|
DPRINTF(E_DBG,L_SCAN,"Found descriptor: %s\n", descriptor_name);
|
||||||
|
@ -460,7 +531,7 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
/* see what kind it is */
|
/* see what kind it is */
|
||||||
switch(descriptor_value_type) {
|
switch(descriptor_value_type) {
|
||||||
case 0x0000: /* string */
|
case 0x0000: /* string */
|
||||||
if(!wma_file_read_utf16(fd,descriptor_value_len,
|
if(!wma_file_read_utf16(fd,descriptor_value_int,
|
||||||
&descriptor_byte_value)) {
|
&descriptor_byte_value)) {
|
||||||
fail=1;
|
fail=1;
|
||||||
}
|
}
|
||||||
|
@ -468,11 +539,11 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
DPRINTF(E_DBG,L_SCAN,"Type: string, value: %s\n",descriptor_byte_value);
|
DPRINTF(E_DBG,L_SCAN,"Type: string, value: %s\n",descriptor_byte_value);
|
||||||
break;
|
break;
|
||||||
case 0x0001: /* byte array */
|
case 0x0001: /* byte array */
|
||||||
if(descriptor_value_len > 4096) {
|
if(descriptor_value_int > 4096) {
|
||||||
lseek(fd,descriptor_value_len,SEEK_CUR);
|
lseek(fd,descriptor_value_int,SEEK_CUR);
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
} else {
|
} else {
|
||||||
if(!wma_file_read_bytes(fd,descriptor_value_len,
|
if(!wma_file_read_bytes(fd,descriptor_value_int,
|
||||||
(unsigned char **)&descriptor_byte_value)){
|
(unsigned char **)&descriptor_byte_value)){
|
||||||
fail=1;
|
fail=1;
|
||||||
}
|
}
|
||||||
|
@ -498,8 +569,20 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
snprintf(numbuff,sizeof(numbuff)-1,"%d",descriptor_short_value);
|
snprintf(numbuff,sizeof(numbuff)-1,"%d",descriptor_short_value);
|
||||||
descriptor_byte_value = strdup(numbuff);
|
descriptor_byte_value = strdup(numbuff);
|
||||||
break;
|
break;
|
||||||
|
case 0x0006: /* guid */
|
||||||
|
lseek(fd,16,SEEK_CUR); /* skip it */
|
||||||
|
if(descriptor_name)
|
||||||
|
free(descriptor_name);
|
||||||
|
descriptor_name = strdup("");
|
||||||
|
descriptor_byte_value = NULL;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
DPRINTF(E_LOG,L_SCAN,"Badly formatted wma file\n");
|
||||||
|
if(descriptor_name)
|
||||||
|
free(descriptor_name);
|
||||||
|
if(descriptor_byte_value)
|
||||||
|
free(descriptor_byte_value);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fail) {
|
if(fail) {
|
||||||
|
@ -925,17 +1008,20 @@ int scan_get_wmainfo(char *filename, MP3FILE *pmp3) {
|
||||||
|
|
||||||
pguid = wma_find_guid(subhdr.objectid);
|
pguid = wma_find_guid(subhdr.objectid);
|
||||||
if(pguid) {
|
if(pguid) {
|
||||||
DPRINTF(E_DBG,L_SCAN,"Found subheader: %s\n",pguid->name);
|
DPRINTF(E_DBG,L_SCAN,"0x%08X: Found subheader: %s\n",
|
||||||
|
offset,pguid->name);
|
||||||
if(strcmp(pguid->name,"ASF_Content_Description_Object")==0) {
|
if(strcmp(pguid->name,"ASF_Content_Description_Object")==0) {
|
||||||
res &= wma_parse_content_description(wma_fd,(int)subhdr.size,pmp3);
|
res &= wma_parse_content_description(wma_fd,(int)subhdr.size,pmp3);
|
||||||
} else if (strcmp(pguid->name,"ASF_Extended_Content_Description_Object")==0) {
|
} else if (strcmp(pguid->name,"ASF_Extended_Content_Description_Object")==0) {
|
||||||
res &= wma_parse_extended_content_description(wma_fd,(int)subhdr.size,pmp3);
|
res &= wma_parse_extended_content_description(wma_fd,(int)subhdr.size,pmp3,0);
|
||||||
} else if (strcmp(pguid->name,"ASF_File_Properties_Object")==0) {
|
} else if (strcmp(pguid->name,"ASF_File_Properties_Object")==0) {
|
||||||
res &= wma_parse_file_properties(wma_fd,(int)subhdr.size,pmp3);
|
res &= wma_parse_file_properties(wma_fd,(int)subhdr.size,pmp3);
|
||||||
} else if (strcmp(pguid->name,"ASF_Audio_Media")==0) {
|
} else if (strcmp(pguid->name,"ASF_Audio_Media")==0) {
|
||||||
res &= wma_parse_audio_media(wma_fd,(int)subhdr.size,pmp3);
|
res &= wma_parse_audio_media(wma_fd,(int)subhdr.size,pmp3);
|
||||||
} else if (strcmp(pguid->name,"ASF_Stream_Properties_Object")==0) {
|
} else if (strcmp(pguid->name,"ASF_Stream_Properties_Object")==0) {
|
||||||
res &= wma_parse_stream_properties(wma_fd,(int)subhdr.size,pmp3);
|
res &= wma_parse_stream_properties(wma_fd,(int)subhdr.size,pmp3);
|
||||||
|
} else if(strcmp(pguid->name,"ASF_Header_Extension_Object")==0) {
|
||||||
|
res &= wma_parse_header_extension(wma_fd,(int)subhdr.size,pmp3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(E_DBG,L_SCAN,"Unknown subheader: %02hhx%02hhx%02hhx%02hhx-"
|
DPRINTF(E_DBG,L_SCAN,"Unknown subheader: %02hhx%02hhx%02hhx%02hhx-"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS := $(CFLAGS) -g -I/opt/local/include -DHAVE_CONFIG_H -I. -I.. -DHOST='"foo"' -DHAVE_SQL -DHAVE_CONFIG_H
|
CFLAGS := $(CFLAGS) -g -I/sw/include -DHAVE_CONFIG_H -I. -I.. -DHOST='"foo"' -DHAVE_SQL -DHAVE_CONFIG_H
|
||||||
LDFLAGS := $(LDFLAGS) -L/opt/local/lib -lid3tag -logg -lvorbisfile -lFLAC -lvorbis -ltag_c -lsqlite -lsqlite3 -lm -framework CoreFoundation
|
LDFLAGS := $(LDFLAGS) -L/sw/lib -lid3tag -logg -lvorbisfile -lFLAC -lvorbis -ltag_c -lsqlite -lsqlite3 -lm -framework CoreFoundation
|
||||||
TARGET = scanner
|
TARGET = scanner
|
||||||
OBJECTS=scanner-driver.o restart.o err.o scan-aif.o scan-wma.o scan-aac.o scan-wav.o scan-flac.o scan-ogg.o scan-mp3.o scan-url.o scan-mpc.o os-unix.o conf.o ll.o xml-rpc.o webserver.o uici.o rend-win32.o configfile.o db-generic.o db-sql-sqlite3.o db-sql-sqlite2.o db-sql.o smart-parser.o plugin.o dispatch.o dynamic-art.o db-sql-updates.o
|
OBJECTS=scanner-driver.o restart.o err.o scan-aif.o scan-wma.o scan-aac.o scan-wav.o scan-flac.o scan-ogg.o scan-mp3.o scan-url.o scan-mpc.o os-unix.o conf.o ll.o xml-rpc.o webserver.o uici.o rend-win32.o configfile.o db-generic.o db-sql-sqlite3.o db-sql-sqlite2.o db-sql.o smart-parser.o plugin.o dispatch.o dynamic-art.o db-sql-updates.o
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue