diff --git a/NEWS b/NEWS index 5017bfa..45ae6d4 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,16 @@ - Add support for other operating systems. - Switch to autoconf from our little genconfig.sh. +1.0.24 - Released 14-Feb-2012 +-------------------------------- +- Fix playlist browsing with no SortOrder specified. +- Fix inotify detection of caption file removal. +- Handle an empty DeviceID from Zyxel media player SOAP request. +- Fix false positives in playlist caching optimization when we have duplicate file names in different directories. +- Trim the camera model name extracted from EXIF tags. +- Add support for user-configurable log level settings. +- Add DLNA.ORG_FLAGS support. + 1.0.23 - Released 23-Jan-2012 -------------------------------- - Enable the subtitle menu on some Samsung TV's. diff --git a/metadata.c b/metadata.c index 6489101..523abf3 100644 --- a/metadata.c +++ b/metadata.c @@ -417,7 +417,7 @@ GetAudioMetadata(const char * path, char * name) } if( song.dlna_pn ) - asprintf(&m.dlna_pn, "%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", song.dlna_pn); + m.dlna_pn = strdup(song.dlna_pn); if( song.year ) asprintf(&m.date, "%04d-01-01", song.year); asprintf(&m.duration, "%d:%02d:%02d.%03d", @@ -511,7 +511,7 @@ GetAudioMetadata(const char * path, char * name) " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) " "VALUES" " (%Q, %lld, %ld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);", - path, file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date, + path, (long long)file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date, m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track, m.dlna_pn, song.mime?song.mime:m.mime, album_art); if( ret != SQLITE_OK ) @@ -686,11 +686,11 @@ no_exifdata: return 0; } if( width <= 640 && height <= 480 ) - asprintf(&m.dlna_pn, "JPEG_SM;%s", dlna_no_conv); + m.dlna_pn = strdup("JPEG_SM"); else if( width <= 1024 && height <= 768 ) - asprintf(&m.dlna_pn, "JPEG_MED;%s", dlna_no_conv); + m.dlna_pn = strdup("JPEG_MED"); else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) ) - asprintf(&m.dlna_pn, "JPEG_LRG;%s", dlna_no_conv); + m.dlna_pn = strdup("JPEG_LRG"); asprintf(&m.resolution, "%dx%d", width, height); ret = sql_exec(db, "INSERT into DETAILS" @@ -698,7 +698,7 @@ no_exifdata: " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) " "VALUES" " (%Q, '%q', %lld, %ld, %Q, %Q, %Q, %d, %Q, %Q, %Q);", - path, name, file.st_size, file.st_mtime, m.date, m.resolution, + path, name, (long long)file.st_size, file.st_mtime, m.date, m.resolution, m.rotation, thumb, m.creator, m.dlna_pn, m.mime); if( ret != SQLITE_OK ) { @@ -942,7 +942,7 @@ GetVideoMetadata(const char * path, char * name) if( (vc->width == 352) && (vc->height <= 288) ) { - asprintf(&m.dlna_pn, "MPEG1;%s", dlna_no_conv); + m.dlna_pn = strdup("MPEG1"); } asprintf(&m.mime, "video/mpeg"); } @@ -1019,8 +1019,6 @@ GetVideoMetadata(const char * path, char * name) free(m.dlna_pn); m.dlna_pn = NULL; } - if( m.dlna_pn ) - sprintf(m.dlna_pn+off, ";%s", dlna_no_conv); break; case CODEC_ID_H264: m.dlna_pn = malloc(128); @@ -1325,8 +1323,6 @@ GetVideoMetadata(const char * path, char * name) free(m.dlna_pn); m.dlna_pn = NULL; } - if( m.dlna_pn ) - sprintf(m.dlna_pn+off, ";%s", dlna_no_conv); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basepath); break; case CODEC_ID_MPEG4: @@ -1390,8 +1386,6 @@ GetVideoMetadata(const char * path, char * name) m.dlna_pn = NULL; } } - if( m.dlna_pn ) - sprintf(m.dlna_pn+off, ";%s", dlna_no_conv); } break; case CODEC_ID_WMV3: @@ -1501,8 +1495,6 @@ GetVideoMetadata(const char * path, char * name) break; } } - if( m.dlna_pn ) - sprintf(m.dlna_pn+off, ";%s", dlna_no_conv); break; case CODEC_ID_MSMPEG4V3: asprintf(&m.mime, "video/x-msvideo"); @@ -1611,7 +1603,7 @@ video_no_dlna: " TITLE, CREATOR, ARTIST, GENRE, COMMENT, DLNA_PN, MIME, ALBUM_ART) " "VALUES" " (%Q, %lld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, '%q', %Q, %Q, %Q, %Q, %Q, '%q', %lld);", - path, file.st_size, file.st_mtime, m.duration, + path, (long long)file.st_size, file.st_mtime, m.duration, m.date, m.channels, m.bitrate, m.frequency, m.resolution, m.title, m.creator, m.artist, m.genre, m.comment, m.dlna_pn, m.mime, album_art); diff --git a/sql.c b/sql.c index 3b85404..df69158 100644 --- a/sql.c +++ b/sql.c @@ -210,12 +210,15 @@ db_upgrade(sqlite3 *db) if (db_vers == DB_VERSION) return 0; + if (db_vers > DB_VERSION) + return -2; if (db_vers < 1) return -1; if (db_vers < 5) return 5; if (db_vers < 6) { + DPRINTF(E_WARN, L_DB_SQL, "Updating DB version to v%d.\n", 6); ret = sql_exec(db, "CREATE TABLE BOOKMARKS (" "ID INTEGER PRIMARY KEY, " "SEC INTEGER)"); @@ -224,11 +227,18 @@ db_upgrade(sqlite3 *db) } if (db_vers < 7) { - DPRINTF(E_WARN, L_DB_SQL, "Updating DB version to v%d.\n", DB_VERSION); + DPRINTF(E_WARN, L_DB_SQL, "Updating DB version to v%d.\n", 7); ret = sql_exec(db, "ALTER TABLE DETAILS ADD rotation INTEGER"); if( ret != SQLITE_OK ) return 7; } + if (db_vers < 8) + { + DPRINTF(E_WARN, L_DB_SQL, "Updating DB version to v%d.\n", 8); + ret = sql_exec(db, "UPDATE DETAILS set DLNA_PN = replace(DLNA_PN, ';DLNA.ORG_OP=01;DLNA.ORG_CI=0', '')"); + if( ret != SQLITE_OK ) + return 8; + } sql_exec(db, "PRAGMA user_version = %d", DB_VERSION); return 0; diff --git a/upnpglobalvars.c b/upnpglobalvars.c index 1c20572..b543a95 100644 --- a/upnpglobalvars.c +++ b/upnpglobalvars.c @@ -85,7 +85,6 @@ const char * minissdpdsocketpath = "/var/run/minissdpd.sock"; /* UPnP-A/V [DLNA] */ sqlite3 * db; -char dlna_no_conv[] = "DLNA.ORG_OP=01;DLNA.ORG_CI=0"; char friendly_name[FRIENDLYNAME_MAX_LEN]; char db_path[PATH_MAX] = {'\0'}; char log_path[PATH_MAX] = {'\0'}; diff --git a/upnpglobalvars.h b/upnpglobalvars.h index 51a0f5f..9dae331 100644 --- a/upnpglobalvars.h +++ b/upnpglobalvars.h @@ -66,7 +66,7 @@ #define CLIENT_CACHE_SLOTS 20 #define USE_FORK 1 -#define DB_VERSION 7 +#define DB_VERSION 8 #ifdef ENABLE_NLS #define _(string) gettext(string) @@ -80,80 +80,80 @@ #define RESOURCE_PROTOCOL_INFO_VALUES \ "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN," \ - "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_60_AC3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HP_HD_AC3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AC3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AC3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_HD_NA_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_CIF15_AAC_520;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_CIF30_AAC_940;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L31_HD_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L32_HD_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L3L_SD_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_VGA_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_60_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_60_AC3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HP_HD_AC3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AC3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AC3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AC3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_HD_NA;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_HD_NA_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPLL_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAPRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMALSL;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMALSL_MULT5;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_MULT5_ISO;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ - "http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_CI=0," \ + "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM," \ + "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED," \ + "http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_60_AC3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HP_HD_AC3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AC3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AC3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_HD_NA_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO," \ + "http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_CIF15_AAC_520," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_CIF30_AAC_940," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L31_HD_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L32_HD_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_BL_L3L_SD_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC," \ + "http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_VGA_AAC," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_60_AC3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_60_AC3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HP_HD_AC3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AC3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AC3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AC3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AC3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_HD_NA," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_HD_NA_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA," \ + "http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPLL_BASE," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_BASE," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_MP3," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL," \ + "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO," \ + "http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC," \ + "http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR," \ + "http-get:*:audio/mpeg:DLNA.ORG_PN=MP3," \ + "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE," \ + "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL," \ + "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAPRO," \ + "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMALSL," \ + "http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMALSL_MULT5," \ + "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320," \ + "http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_ISO_320," \ + "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO," \ + "http-get:*:audio/mp4:DLNA.ORG_PN=AAC_MULT5_ISO," \ + "http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM," \ "http-get:*:image/jpeg:*," \ "http-get:*:video/avi:*," \ "http-get:*:video/divx:*," \ @@ -170,7 +170,15 @@ "http-get:*:audio/x-flac:*," \ "http-get:*:application/ogg:*" -/* statup time */ +#define DLNA_FLAG_DLNA_V1_5 0x00100000 +#define DLNA_FLAG_HTTP_STALLING 0x00200000 +#define DLNA_FLAG_TM_B 0x00400000 +#define DLNA_FLAG_TM_I 0x00800000 +#define DLNA_FLAG_TM_S 0x01000000 +#define DLNA_FLAG_LOP_BYTES 0x20000000 +#define DLNA_FLAG_LOP_NPT 0x40000000 + +/* startup time */ extern time_t startup_time; extern struct runtime_vars_s runtime_vars; @@ -216,7 +224,6 @@ extern const char * minissdpdsocketpath; /* UPnP-A/V [DLNA] */ extern sqlite3 *db; -extern char dlna_no_conv[]; #define FRIENDLYNAME_MAX_LEN (64) extern char friendly_name[]; extern char db_path[]; diff --git a/upnphttp.c b/upnphttp.c index 36c5d6a..7a46de5 100644 --- a/upnphttp.c +++ b/upnphttp.c @@ -59,15 +59,16 @@ #include #include #include +#include +#include #include "config.h" +#include "upnpglobalvars.h" #include "upnphttp.h" #include "upnpdescgen.h" #include "minidlnapath.h" #include "upnpsoap.h" #include "upnpevents.h" - -#include "upnpglobalvars.h" #include "utils.h" #include "getifaddr.h" #include "image_utils.h" @@ -1413,9 +1414,8 @@ SendResp_albumArt(struct upnphttp * h, char * object) "realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n" "contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN\r\n" "Server: " MINIDLNA_SERVER_STRING "\r\n" - "transferMode.dlna.org: %s\r\n\r\n", - (intmax_t)size, date, - (h->reqflags & FLAG_XFERBACKGROUND) ? "Background" : "Interactive"); + "transferMode.dlna.org: Interactive\r\n\r\n", + (intmax_t)size, date); if( send_data(h, header, ret, MSG_MORE) == 0 ) { @@ -1527,16 +1527,15 @@ SendResp_thumbnail(struct upnphttp * h, char * object) strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime)); ret = snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n" "Content-Type: image/jpeg\r\n" - "Content-Length: %d\r\n" + "Content-Length: %jd\r\n" "Connection: close\r\n" "Date: %s\r\n" "EXT:\r\n" "realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n" - "contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN\r\n" + "contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN;DLNA.ORG_CI=1\r\n" "Server: " MINIDLNA_SERVER_STRING "\r\n" - "transferMode.dlna.org: %s\r\n\r\n", - ed->size, date, - (h->reqflags & FLAG_XFERBACKGROUND) ? "Background" : "Interactive"); + "transferMode.dlna.org: Interactive\r\n\r\n", + (intmax_t)ed->size, date); if( send_data(h, header, ret, MSG_MORE) == 0 ) { @@ -1555,7 +1554,8 @@ SendResp_resizedimg(struct upnphttp * h, char * object) struct string_s str; char **result; char date[30]; - char dlna_pn[4]; + char dlna_pn[22]; + uint32_t dlna_flags = DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B|DLNA_FLAG_TM_I; time_t curtime = time(NULL); int width=640, height=480, dstw, dsth, size; int srcw, srch; @@ -1676,11 +1676,11 @@ SendResp_resizedimg(struct upnphttp * h, char * object) } if( dstw <= 640 && dsth <= 480 ) - strcpy(dlna_pn, "SM"); + strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_SM;"); else if( dstw <= 1024 && dsth <= 768 ) - strcpy(dlna_pn, "MED"); + strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_MED;"); else - strcpy(dlna_pn, "LRG"); + strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_LRG;"); if( srcw>>4 >= dstw && srch>>4 >= dsth) scale = 8; @@ -1700,17 +1700,15 @@ SendResp_resizedimg(struct upnphttp * h, char * object) "Date: %s\r\n" "EXT:\r\n" "realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n" - "contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_%s;DLNA.ORG_CI=1\r\n" + "contentFeatures.dlna.org: %sDLNA.ORG_CI=%X;DLNA.ORG_FLAGS=%08X%024X\r\n" "Server: " MINIDLNA_SERVER_STRING "\r\n", - date, dlna_pn); - if( h->reqflags & FLAG_XFERINTERACTIVE ) - { - strcatf(&str, "transferMode.dlna.org: Interactive\r\n"); - } - else if( h->reqflags & FLAG_XFERBACKGROUND ) - { + date, dlna_pn, 1, dlna_flags, 0); +#if USE_FORK + if( (h->reqflags & FLAG_XFERBACKGROUND) && (setpriority(PRIO_PROCESS, 0, 19) == 0) ) strcatf(&str, "transferMode.dlna.org: Background\r\n"); - } + else +#endif + strcatf(&str, "transferMode.dlna.org: Interactive\r\n"); if( strcmp(h->HttpVer, "HTTP/1.0") == 0 ) { @@ -1789,6 +1787,7 @@ SendResp_dlnafile(struct upnphttp * h, char * object) off_t total, offset, size; sqlite_int64 id; int sendfh; + uint32_t dlna_flags = DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B; static struct { sqlite_int64 id; enum client_types client; char path[PATH_MAX]; @@ -1800,6 +1799,17 @@ SendResp_dlnafile(struct upnphttp * h, char * object) #endif id = strtoll(object, NULL, 10); + if( h->reqflags & FLAG_MS_PFS ) + { + if( strstr(object, "?albumArt=true") ) + { + char *art; + art = sql_get_text_field(db, "SELECT ALBUM_ART from DETAILS where ID = '%lld'", id); + SendResp_albumArt(h, art); + sqlite3_free(art); + return; + } + } if( id != last_file.id || h->req_client != last_file.client ) { snprintf(buf, sizeof(buf), "SELECT PATH, MIME, DLNA_PN from DETAILS where ID = '%lld'", id); @@ -1845,9 +1855,7 @@ SendResp_dlnafile(struct upnphttp * h, char * object) } } if( result[5] ) - snprintf(last_file.dlna, sizeof(last_file.dlna), "DLNA.ORG_PN=%s", result[5]); - else if( h->reqflags & FLAG_DLNA ) - strcpy(last_file.dlna, dlna_no_conv); + snprintf(last_file.dlna, sizeof(last_file.dlna), "DLNA.ORG_PN=%s;", result[5]); else last_file.dlna[0] = '\0'; sqlite3_free_table(result); @@ -1945,22 +1953,26 @@ SendResp_dlnafile(struct upnphttp * h, char * object) strcatf(&str, "Content-Length: %jd\r\n", (intmax_t)total); } - if( h->reqflags & FLAG_XFERSTREAMING ) - { +#if USE_FORK + if( (h->reqflags & FLAG_XFERBACKGROUND) && (setpriority(PRIO_PROCESS, 0, 19) == 0) ) + strcatf(&str, "transferMode.dlna.org: Background\r\n"); + else +#endif + if( strncmp(last_file.mime, "image", 5) == 0 ) + strcatf(&str, "transferMode.dlna.org: Interactive\r\n"); + else strcatf(&str, "transferMode.dlna.org: Streaming\r\n"); - } - else if( h->reqflags & FLAG_XFERBACKGROUND ) + + switch( *last_file.mime ) { - if( strncmp(last_file.mime, "image", 5) == 0 ) - strcatf(&str, "transferMode.dlna.org: Background\r\n"); - } - else //if( h->reqflags & FLAG_XFERINTERACTIVE ) - { - if( (strncmp(last_file.mime, "video", 5) == 0) || - (strncmp(last_file.mime, "audio", 5) == 0) ) - strcatf(&str, "transferMode.dlna.org: Streaming\r\n"); - else - strcatf(&str, "transferMode.dlna.org: Interactive\r\n"); + case 'i': + dlna_flags |= DLNA_FLAG_TM_I; + break; + case 'a': + case 'v': + default: + dlna_flags |= DLNA_FLAG_TM_S; + break; } if( h->reqflags & FLAG_CAPTION ) @@ -1976,9 +1988,9 @@ SendResp_dlnafile(struct upnphttp * h, char * object) "Date: %s\r\n" "EXT:\r\n" "realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n" - "contentFeatures.dlna.org: %s\r\n" + "contentFeatures.dlna.org: %sDLNA.ORG_OP=%02X;DLNA.ORG_CI=%X;DLNA.ORG_FLAGS=%08X%024X\r\n" "Server: " MINIDLNA_SERVER_STRING "\r\n\r\n", - date, last_file.dlna); + date, last_file.dlna, 1, 0, dlna_flags, 0); //DEBUG DPRINTF(E_DEBUG, L_HTTP, "RESPONSE: %s\n", str.data); if( send_data(h, str.data, str.off, MSG_MORE) == 0 ) diff --git a/upnphttp.h b/upnphttp.h index 64df2a5..dfa0329 100644 --- a/upnphttp.h +++ b/upnphttp.h @@ -1,7 +1,27 @@ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ +/* MiniDLNA project * - * Copyright (c) 2006, Thomas Bernard + * http://sourceforge.net/projects/minidlna/ + * + * MiniDLNA media server + * Copyright (C) 2008-2012 Justin Maggard + * + * This file is part of MiniDLNA. + * + * MiniDLNA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MiniDLNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MiniDLNA. If not, see . + * + * Portions of the code from the MiniUPnP project: + * + * Copyright (c) 2006-2007, Thomas Bernard * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,7 +56,7 @@ #include "config.h" /* server: HTTP header returned in all HTTP responses : */ -#define MINIDLNA_SERVER_STRING OS_VERSION " DLNADOC/1.50 UPnP/1.0 MiniDLNA/1.0" +#define MINIDLNA_SERVER_STRING OS_VERSION " DLNADOC/1.50 UPnP/1.0 " SERVER_NAME "/" MINIDLNA_VERSION /* states : diff --git a/upnpsoap.c b/upnpsoap.c index 378bdbb..64982fb 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -654,10 +654,12 @@ add_resized_res(int srcw, int srch, int reqw, int reqh, char *dlna_pn, } strcatf(args->str, "resolution=\"%dx%d\" ", dstw, dsth); } - strcatf(args->str, "protocolInfo=\"http-get:*:image/jpeg:DLNA.ORG_PN=%s;DLNA.ORG_CI=1\">" + strcatf(args->str, "protocolInfo=\"http-get:*:image/jpeg:" + "DLNA.ORG_PN=%s;DLNA.ORG_CI=1;DLNA.ORG_FLAGS=%08X%024X\">" "http://%s:%d/Resized/%s.jpg?width=%d,height=%d" "</res>", - dlna_pn, lan_addr[args->iface].str, runtime_vars.port, + dlna_pn, DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B|DLNA_FLAG_TM_I, 0, + lan_addr[args->iface].str, runtime_vars.port, detailID, dstw, dsth); } @@ -720,7 +722,7 @@ callback(void *args, int argc, char **argv, char **azColName) *duration = argv[7], *bitrate = argv[8], *sampleFrequency = argv[9], *artist = argv[10], *album = argv[11], *genre = argv[12], *comment = argv[13], *nrAudioChannels = argv[14], *track = argv[15], *date = argv[16], *resolution = argv[17], *tn = argv[18], *creator = argv[19], *dlna_pn = argv[20], *mime = argv[21], *album_art = argv[22]; - char dlna_buf[96]; + char dlna_buf[128]; char ext[5]; struct string_s *str = passed_args->str; int ret = 0; @@ -755,22 +757,17 @@ callback(void *args, int argc, char **argv, char **azColName) } passed_args->returned++; - if( dlna_pn ) - sprintf(dlna_buf, "DLNA.ORG_PN=%s", dlna_pn); - else if( passed_args->flags & FLAG_DLNA ) - strcpy(dlna_buf, dlna_no_conv); - else - strcpy(dlna_buf, "*"); - if( runtime_vars.root_container && strcmp(parent, runtime_vars.root_container) == 0 ) parent = "0"; if( strncmp(class, "item", 4) == 0 ) { + uint32_t dlna_flags = DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B; char *alt_title = NULL; /* We may need special handling for certain MIME types */ if( *mime == 'v' ) { + dlna_flags |= DLNA_FLAG_TM_S; if( passed_args->flags & FLAG_MIME_AVI_DIVX ) { if( strcmp(mime, "video/x-msvideo") == 0 ) @@ -826,6 +823,7 @@ callback(void *args, int argc, char **argv, char **azColName) } else if( *mime == 'a' ) { + dlna_flags |= DLNA_FLAG_TM_S; if( strcmp(mime+6, "x-flac") == 0 ) { if( passed_args->flags & FLAG_MIME_FLAC_FLAC ) @@ -841,6 +839,22 @@ callback(void *args, int argc, char **argv, char **azColName) } } } + else + dlna_flags |= DLNA_FLAG_TM_I; + + if( dlna_pn ) + snprintf(dlna_buf, sizeof(dlna_buf), "DLNA.ORG_PN=%s;" + "DLNA.ORG_OP=01;" + "DLNA.ORG_CI=0;" + "DLNA.ORG_FLAGS=%08X%024X", + dlna_pn, dlna_flags, 0); + else if( passed_args->flags & FLAG_DLNA ) + snprintf(dlna_buf, sizeof(dlna_buf), "DLNA.ORG_OP=01;" + "DLNA.ORG_CI=0;" + "DLNA.ORG_FLAGS=%08X%024X", + dlna_flags, 0); + else + strcpy(dlna_buf, "*"); ret = strcatf(str, "<item id=\"%s\" parentID=\"%s\" restricted=\"1\"", id, parent); if( refID && (passed_args->filter & FILTER_REFID) ) { @@ -942,7 +956,7 @@ callback(void *args, int argc, char **argv, char **azColName) ret = strcatf(str, "<res protocolInfo=\"http-get:*:%s:%s\">" "http://%s:%d/Thumbnails/%s.jpg" "</res>", - mime, "DLNA.ORG_PN=JPEG_TN", lan_addr[passed_args->iface].str, + mime, "DLNA.ORG_PN=JPEG_TN;DLNA.ORG_CI=1", lan_addr[passed_args->iface].str, runtime_vars.port, detailID); } } @@ -955,7 +969,7 @@ callback(void *args, int argc, char **argv, char **azColName) strncmp(dlna_pn, "AVC_TS_MP_HD_AC3", 16) == 0 || strncmp(dlna_pn, "AVC_TS_HP_HD_AC3", 16) == 0)) { - sprintf(dlna_buf, "DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); + sprintf(dlna_buf, "DLNA.ORG_PN=%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", "MPEG_PS_NTSC"); add_res(size, duration, bitrate, sampleFrequency, nrAudioChannels, resolution, dlna_buf, mime, detailID, ext, passed_args); } @@ -967,13 +981,13 @@ callback(void *args, int argc, char **argv, char **azColName) { if( strncmp(dlna_pn, "MPEG_TS_SD_NA", 13) != 0 ) { - sprintf(dlna_buf, "DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); + sprintf(dlna_buf, "DLNA.ORG_PN=%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", "MPEG_TS_SD_NA"); add_res(size, duration, bitrate, sampleFrequency, nrAudioChannels, resolution, dlna_buf, mime, detailID, ext, passed_args); } if( strncmp(dlna_pn, "MPEG_TS_SD_EU", 13) != 0 ) { - sprintf(dlna_buf, "DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); + sprintf(dlna_buf, "DLNA.ORG_PN=%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", "MPEG_TS_SD_EU"); add_res(size, duration, bitrate, sampleFrequency, nrAudioChannels, resolution, dlna_buf, mime, detailID, ext, passed_args); } @@ -988,13 +1002,13 @@ callback(void *args, int argc, char **argv, char **azColName) strcpy(mime+6, "avi"); if( !dlna_pn || strncmp(dlna_pn, "MPEG_PS_NTSC", 12) != 0 ) { - sprintf(dlna_buf, "DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); + sprintf(dlna_buf, "DLNA.ORG_PN=%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", "MPEG_PS_NTSC"); add_res(size, duration, bitrate, sampleFrequency, nrAudioChannels, resolution, dlna_buf, mime, detailID, ext, passed_args); } if( !dlna_pn || strncmp(dlna_pn, "MPEG_PS_PAL", 11) != 0 ) { - sprintf(dlna_buf, "DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=01;DLNA.ORG_CI=0"); + sprintf(dlna_buf, "DLNA.ORG_PN=%s;DLNA.ORG_OP=01;DLNA.ORG_CI=0", "MPEG_PS_PAL"); add_res(size, duration, bitrate, sampleFrequency, nrAudioChannels, resolution, dlna_buf, mime, detailID, ext, passed_args); }