* Add WAV MIME workaround for Marantz Receivers and Roku SoundBridge.

* Fix bitrate displayed on Microsoft PFS devices.
This commit is contained in:
Justin Maggard 2011-08-18 23:24:17 +00:00
parent c599ed3a9f
commit 546175743a
6 changed files with 55 additions and 24 deletions

6
NEWS
View File

@ -1,6 +1,10 @@
1.0.22 - Released 00-Month-0000 1.0.22 - Released 00-Month-0000
-------------------------------- --------------------------------
- Add bookmark support for Samsung TV's. - Add bookmark support for some Samsung TV's.
- Fix a memory leak when certain model Samsung TV's or Roku devices are on the network.
- Fix detection of Samsung Series D models.
- Add WAV MIME workaround for Marantz Receivers and Roku SoundBridge.
- Fix bitrate displayed on Microsoft PFS devices.
1.0.21 - Released 18-July-2011 1.0.21 - Released 18-July-2011
-------------------------------- --------------------------------

View File

@ -81,6 +81,7 @@ enum client_types {
ENetgearEVA2000, ENetgearEVA2000,
ESamsungSeriesA, ESamsungSeriesA,
ESamsungSeriesB, ESamsungSeriesB,
EMarantzDMP,
EStandardDLNA150 = 100 EStandardDLNA150 = 100
}; };

View File

@ -364,7 +364,7 @@ ParseUPnPClient(char *location)
int client; int client;
enum client_types type = 0; enum client_types type = 0;
uint32_t flags = 0; uint32_t flags = 0;
char *model, *serial; char *model, *serial, *name;
if (strncmp(location, "http://", 7) != 0) if (strncmp(location, "http://", 7) != 0)
return; return;
@ -448,13 +448,16 @@ close:
ParseNameValue(off, nread, &xml); ParseNameValue(off, nread, &xml);
model = GetValueFromNameValueList(&xml, "modelName"); model = GetValueFromNameValueList(&xml, "modelName");
serial = GetValueFromNameValueList(&xml, "serialNumber"); serial = GetValueFromNameValueList(&xml, "serialNumber");
name = GetValueFromNameValueList(&xml, "friendlyName");
if( model ) if( model )
{ {
DPRINTF(E_DEBUG, L_SSDP, "Model: %s\n", model); DPRINTF(E_DEBUG, L_SSDP, "Model: %s\n", model);
if( strstr(model, "Roku SoundBridge") ) if( strstr(model, "Roku SoundBridge") )
{ {
type = ERokuSoundBridge; type = ERokuSoundBridge;
flags |= FLAG_MS_PFS;
flags |= FLAG_AUDIO_ONLY; flags |= FLAG_AUDIO_ONLY;
flags |= FLAG_MIME_WAV_WAV;
} }
else if( strcmp(model, "Samsung DTV DMR") == 0 && serial ) else if( strcmp(model, "Samsung DTV DMR") == 0 && serial )
{ {
@ -468,12 +471,21 @@ close:
flags |= FLAG_NO_RESIZE; flags |= FLAG_NO_RESIZE;
} }
} }
else
{
if( name && (strcmp(name, "marantz DMP") == 0) )
{
type = EMarantzDMP;
flags |= FLAG_DLNA;
flags |= FLAG_MIME_WAV_WAV;
}
}
} }
ClearNameValueList(&xml); ClearNameValueList(&xml);
if( !type ) if( !type )
return; return;
client = SearchClientCache(dest.sin_addr, 1);
/* Add this client to the cache if it's not there already. */ /* Add this client to the cache if it's not there already. */
client = SearchClientCache(dest.sin_addr, 1);
if( client < 0 ) if( client < 0 )
{ {
for( client=0; client<CLIENT_CACHE_SLOTS; client++ ) for( client=0; client<CLIENT_CACHE_SLOTS; client++ )
@ -506,7 +518,7 @@ ProcessSSDPRequest(int s, unsigned short port)
socklen_t len_r; socklen_t len_r;
struct sockaddr_in sendername; struct sockaddr_in sendername;
int i; int i;
char *st = NULL, *mx = NULL, *man = NULL, *mx_end = NULL, *loc = NULL, *srv = NULL; char *st = NULL, *mx = NULL, *man = NULL, *mx_end = NULL;
int man_len = 0; int man_len = 0;
len_r = sizeof(struct sockaddr_in); len_r = sizeof(struct sockaddr_in);
@ -521,7 +533,8 @@ ProcessSSDPRequest(int s, unsigned short port)
if(memcmp(bufr, "NOTIFY", 6) == 0) if(memcmp(bufr, "NOTIFY", 6) == 0)
{ {
int loc_len = 0, srv_len = 0; char *loc = NULL, *srv = NULL, *nts = NULL, *nt = NULL;
int loc_len = 0;
//DEBUG DPRINTF(E_DEBUG, L_SSDP, "Received SSDP notify:\n%.*s", n, bufr); //DEBUG DPRINTF(E_DEBUG, L_SSDP, "Received SSDP notify:\n%.*s", n, bufr);
for(i=0; i < n; i++) for(i=0; i < n; i++)
{ {
@ -540,32 +553,34 @@ ProcessSSDPRequest(int s, unsigned short port)
if(strncasecmp(bufr+i, "SERVER:", 7) == 0) if(strncasecmp(bufr+i, "SERVER:", 7) == 0)
{ {
srv = bufr+i+7; srv = bufr+i+7;
srv_len = 0;
while(*srv == ' ' || *srv == '\t') srv++; while(*srv == ' ' || *srv == '\t') srv++;
while(srv[srv_len]!='\r' && srv[srv_len]!='\n') srv_len++;
} }
else if(strncasecmp(bufr+i, "LOCATION:", 9) == 0) else if(strncasecmp(bufr+i, "LOCATION:", 9) == 0)
{ {
loc = bufr+i+9; loc = bufr+i+9;
loc_len = 0;
while(*loc == ' ' || *loc == '\t') loc++; while(*loc == ' ' || *loc == '\t') loc++;
while(loc[loc_len]!='\r' && loc[loc_len]!='\n') loc_len++; while(loc[loc_len]!='\r' && loc[loc_len]!='\n') loc_len++;
loc[loc_len] = '\0';
} }
else if(strncasecmp(bufr+i, "NTS:", 4) == 0) else if(strncasecmp(bufr+i, "NTS:", 4) == 0)
{ {
man = bufr+i+4; nts = bufr+i+4;
man_len = 0; while(*nts == ' ' || *nts == '\t') nts++;
while(*man == ' ' || *man == '\t') man++; }
while(man[man_len]!='\r' && man[man_len]!='\n') man_len++; else if(strncasecmp(bufr+i, "NT:", 3) == 0)
{
nt = bufr+i+3;
while(*nt == ' ' || *nt == '\t') nt++;
} }
} }
if( !loc || !srv || !man || (strncmp(man, "ssdp:alive", man_len) != 0) ) if( !loc || !srv || !nt || !nts || (strncmp(nts, "ssdp:alive", 10) != 0) ||
(strncmp(nt, "urn:schemas-upnp-org:device:MediaRenderer", 41) != 0) )
{ {
return; return;
} }
if( strncmp(srv, "Allegro-Software-RomPlug", 24) == 0 || loc[loc_len] = '\0';
strstr(loc, "SamsungMRDesc.xml") ) if( (strncmp(srv, "Allegro-Software-RomPlug", 24) == 0) || /* Roku */
(strstr(loc, "SamsungMRDesc.xml") != NULL) || /* Samsung TV */
(strstrc(srv, "DigiOn DiXiM", '\r') != NULL) ) /* Marantz Receiver */
{ {
/* Check if the client is already in cache */ /* Check if the client is already in cache */
i = SearchClientCache(sendername.sin_addr, 1); i = SearchClientCache(sendername.sin_addr, 1);

View File

@ -56,7 +56,7 @@
#include <sqlite3.h> #include <sqlite3.h>
#define MINIDLNA_VERSION "1.0.21" #define MINIDLNA_VERSION "1.0.21.2"
#ifdef NETGEAR #ifdef NETGEAR
# define SERVER_NAME "ReadyDLNA" # define SERVER_NAME "ReadyDLNA"

View File

@ -109,10 +109,11 @@ struct upnphttp {
#define FLAG_MIME_AVI_DIVX 0x00200000 #define FLAG_MIME_AVI_DIVX 0x00200000
#define FLAG_MIME_AVI_AVI 0x00400000 #define FLAG_MIME_AVI_AVI 0x00400000
#define FLAG_MIME_FLAC_FLAC 0x00800000 #define FLAG_MIME_FLAC_FLAC 0x00800000
#define FLAG_NO_RESIZE 0x01000000 #define FLAG_MIME_WAV_WAV 0x01000000
#define FLAG_MS_PFS 0x02000000 // Microsoft PlaysForSure client #define FLAG_NO_RESIZE 0x02000000
#define FLAG_SAMSUNG 0x04000000 #define FLAG_MS_PFS 0x04000000 // Microsoft PlaysForSure client
#define FLAG_AUDIO_ONLY 0x08000000 #define FLAG_SAMSUNG 0x08000000
#define FLAG_AUDIO_ONLY 0x10000000
#define FLAG_FREE_OBJECT_ID 0x00000001 #define FLAG_FREE_OBJECT_ID 0x00000001
#define FLAG_ROOT_CONTAINER 0x00000002 #define FLAG_ROOT_CONTAINER 0x00000002

View File

@ -605,7 +605,10 @@ add_res(char *size, char *duration, char *bitrate, char *sampleFrequency,
strcatf(args->str, "duration=\"%s\" ", duration); strcatf(args->str, "duration=\"%s\" ", duration);
} }
if( bitrate && (args->filter & FILTER_RES_BITRATE) ) { if( bitrate && (args->filter & FILTER_RES_BITRATE) ) {
strcatf(args->str, "bitrate=\"%s\" ", bitrate); int br = atoi(bitrate);
if(args->flags & FLAG_MS_PFS)
br /= 8;
strcatf(args->str, "bitrate=\"%d\" ", br);
} }
if( sampleFrequency && (args->filter & FILTER_RES_SAMPLEFREQUENCY) ) { if( sampleFrequency && (args->filter & FILTER_RES_SAMPLEFREQUENCY) ) {
strcatf(args->str, "sampleFrequency=\"%s\" ", sampleFrequency); strcatf(args->str, "sampleFrequency=\"%s\" ", sampleFrequency);
@ -737,6 +740,13 @@ callback(void *args, int argc, char **argv, char **azColName)
strcpy(mime+6, "flac"); strcpy(mime+6, "flac");
} }
} }
else if( strcmp(mime+6, "x-wav") == 0 )
{
if( passed_args->flags & FLAG_MIME_WAV_WAV )
{
strcpy(mime+6, "wav");
}
}
} }
ret = strcatf(str, "&lt;item id=\"%s\" parentID=\"%s\" restricted=\"1\"", id, parent); ret = strcatf(str, "&lt;item id=\"%s\" parentID=\"%s\" restricted=\"1\"", id, parent);