summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
Diffstat (limited to 'inc')
-rw-r--r--inc/avdetector.h124
-rw-r--r--inc/config.h74
-rw-r--r--inc/database.h1024
-rw-r--r--inc/filehandle.h108
-rw-r--r--inc/livereceiver.h105
-rw-r--r--inc/menusetup.h103
-rw-r--r--inc/metadata.h189
-rw-r--r--inc/object.h1576
-rw-r--r--inc/profiles.h32
-rw-r--r--inc/profiles/aac.h36
-rw-r--r--inc/profiles/ac3.h24
-rw-r--r--inc/profiles/amr.h17
-rw-r--r--inc/profiles/atrac3plus.h16
-rw-r--r--inc/profiles/container.h47
-rw-r--r--inc/profiles/jpeg.h24
-rw-r--r--inc/profiles/lpcm.h16
-rw-r--r--inc/profiles/mpa.h25
-rw-r--r--inc/profiles/mpeg1.h16
-rw-r--r--inc/profiles/mpeg2.h68
-rw-r--r--inc/profiles/mpeg4_p10.h153
-rw-r--r--inc/profiles/mpeg4_p2.h80
-rw-r--r--inc/profiles/png.h22
-rw-r--r--inc/profiles/profile_data.h213
-rw-r--r--inc/profiles/wma.h18
-rw-r--r--inc/profiles/wmv9.h24
-rw-r--r--inc/recplayer.h53
-rw-r--r--inc/resources.h318
-rw-r--r--inc/search.h156
-rw-r--r--inc/server.h221
-rw-r--r--inc/upnp/connectionmanager.h99
-rw-r--r--inc/upnp/contentdirectory.h56
-rw-r--r--inc/upnp/dlna.h97
-rw-r--r--inc/upnp/service.h119
-rw-r--r--inc/util.h148
-rw-r--r--inc/webserver.h160
35 files changed, 5561 insertions, 0 deletions
diff --git a/inc/avdetector.h b/inc/avdetector.h
new file mode 100644
index 0000000..923608f
--- /dev/null
+++ b/inc/avdetector.h
@@ -0,0 +1,124 @@
+/*
+ * File: avdetector.h
+ * Author: savop
+ *
+ * Created on 26. Oktober 2009, 13:02
+ */
+
+#ifndef _AVDETECTOR_H
+#define _AVDETECTOR_H
+
+#include "profiles.h"
+#include <vdr/recording.h>
+#include <vdr/channels.h>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+
+/**
+ * The audio/video detector
+ *
+ * This is the audio video detector, which analizes the audio and video stream
+ * of a file to gather more information about the resource. This is also
+ * required for determination of a suitable DLNA profile.
+ */
+class cAudioVideoDetector {
+private:
+ void init();
+ void uninit();
+ int detectChannelProperties();
+ int detectFileProperties();
+ int detectRecordingProperties();
+ /**
+ * Detect video properties
+ *
+ * This detects video properties of a video stream
+ *
+ * @return returns
+ * - \bc 0, if the detection was successful
+ * - \bc <0, otherwise
+ */
+ int analyseVideo(AVFormatContext* FormatCtx);
+ /**
+ * Detect audio properties
+ *
+ * This detects audio properties of a video or audio stream
+ *
+ * @return returns
+ * - \bc 0, if the detection was successful
+ * - \bc <0, otherwise
+ */
+ int analyseAudio(AVFormatContext* FormatCtx);
+ /**
+ * Detect DLNA profile
+ *
+ * This detects the matching DLNA profile for the video or audio item
+ *
+ * @return returns
+ * - \bc 0, if the detection was successful
+ * - \bc <0, otherwise
+ */
+ int detectDLNAProfile(AVFormatContext* FormatCtx);
+ UPNP_RESOURCE_TYPES mResourceType;
+ union {
+ const cChannel* Channel;
+ const cRecording* Recording;
+ const char* Filename;
+ } mResource;
+ int mWidth;
+ int mHeight;
+ int mBitrate;
+ int mBitsPerSample;
+ int mColorDepth;
+ off64_t mDuration;
+ off64_t mSize;
+ int mSampleFrequency;
+ int mNrAudioChannels;
+ DLNAProfile* mDLNAProfile;
+public:
+ cAudioVideoDetector(const char* Filename);
+ cAudioVideoDetector(const cChannel* Channel);
+ cAudioVideoDetector(const cRecording* Recording);
+ virtual ~cAudioVideoDetector();
+ /**
+ * Detect resource properties of the file
+ *
+ * This detects the resource properties of a file. If the returned value
+ * is 0, no erros occured while detection and the properties are properly
+ * set. Otherwise, in case of an error, the properties may have
+ * unpredictable values.
+ *
+ * @return returns
+ * - \bc 0, if the detection was successful
+ * - \bc <0, otherwise
+ */
+ int detectProperties();
+ DLNAProfile* getDLNAProfile() const { return this->mDLNAProfile; }
+ const char* getContentType() const { return (this->mDLNAProfile) ? this->mDLNAProfile->mime : NULL; }
+ const char* getProtocolInfo() const;
+ int getWidth() const { return this->mWidth; }
+ int getHeight() const { return this->mHeight; }
+ int getBitrate() const { return this->mBitrate; }
+ int getBitsPerSample() const { return this->mBitsPerSample; }
+ int getSampleFrequency() const { return this->mSampleFrequency; }
+ int getNumberOfAudioChannels() const { return this->mNrAudioChannels; }
+ int getColorDepth() const { return this->mColorDepth; }
+ off64_t getFileSize() const { return this->mSize; }
+ off64_t getDuration() const { return this->mDuration; }
+};
+
+class cCodecToolKit {
+public:
+ static AVCodecContext* getFirstCodecContext(AVFormatContext* FormatCtx, CodecType Type);
+ static AVStream* getFirstStream(AVFormatContext* FormatCtx, CodecType Type);
+ static bool matchesAcceptedBitrates(AcceptedBitrates Bitrates, AVCodecContext* Codec);
+ static bool matchesAcceptedSystemBitrate(AcceptedBitrates Bitrate, AVFormatContext* Format);
+ static bool matchesAcceptedAudioChannels(AcceptedAudioChannels Channels, AVCodecContext* Codec);
+ static bool matchesAcceptedSamplingRates(AcceptedSamplingRates SamplingRates, AVCodecContext* Codec);
+ static bool matchesAcceptedResolutions(AcceptedResolution *Resolutions, int Count, AVStream* Stream);
+};
+
+#endif /* _AVDETECTOR_H */
+
diff --git a/inc/config.h b/inc/config.h
new file mode 100644
index 0000000..10f92e7
--- /dev/null
+++ b/inc/config.h
@@ -0,0 +1,74 @@
+/*
+ * File: config.h
+ * Author: savop
+ *
+ * Created on 15. August 2009, 13:03
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+#include <vdr/tools.h>
+#include "../common.h"
+
+/**
+ * The configuration settings
+ *
+ * This holds the configurations for the server. It holds information about the
+ * network settings as well as some status flags.
+ */
+class cUPnPConfig {
+private:
+ static cUPnPConfig* mInstance;
+ cString mParsedArgs;
+ cUPnPConfig();
+public:
+ static int verbosity; ///< the verbosity of the plugin, the higher the more messages
+ ///< are printed.
+ char* mInterface; ///< the network interface, which the server is bound to
+ char* mAddress; ///< the IP address which is used by the server
+ int mPort; ///< the port which the server is listening on
+ int mEnable; ///< indicates, if the server is enabled or not
+ int mAutoSetup; ///< indicates, if the settings are automatically detected
+ char* mDatabaseFolder; ///< the directory where the metadata.db is located
+ char* mHTTPFolder; ///< the directory where the HTTP data is located
+public:
+ virtual ~cUPnPConfig();
+ /**
+ * Get the configuration
+ *
+ * This returns the instance of the current configuration settings.
+ *
+ * @return the configuration object
+ */
+ static cUPnPConfig* get();
+ /**
+ * Parse setup variable
+ *
+ * This parses the setup variable with the according value. The value is a
+ * string representation and must be converted into the according data type.
+ *
+ * @return returns
+ * - \bc true, if parsing was successful
+ * - \bc false, otherwise
+ * @param Name the name of the variable
+ * @param Value the according value of the variable
+ */
+ bool parseSetup(const char* Name, const char* Value);
+ /**
+ * Processes the commandline arguments
+ *
+ * This processes the commandline arguments which the user specified at the
+ * start of the plugin.
+ *
+ * @return returns
+ * - \bc true, if processing was successful
+ * - \bc false, otherwise
+ * @param argc the number of arguments in the list
+ * @param argv the arguments as a char array
+ */
+ bool processArgs(int argc, char* argv[]);
+};
+
+#endif /* _CONFIG_H */
+
diff --git a/inc/database.h b/inc/database.h
new file mode 100644
index 0000000..5bb595f
--- /dev/null
+++ b/inc/database.h
@@ -0,0 +1,1024 @@
+/*
+ * File: database.h
+ * Author: savop
+ *
+ * Created on 3. September 2009, 22:20
+ */
+
+#ifndef _DATABASE_H
+#define _DATABASE_H
+
+#include <sqlite3.h>
+#include <vdr/tools.h>
+#include "../common.h"
+
+#define SQLITE_CASCADE_DELETES
+
+#define PK_OBJECTS TOSTRING(1)
+#define PK_RESOURCES TOSTRING(2)
+#define PK_SEARCHCLASSES TOSTRING(3)
+
+#define SQLITE_FIRST_CUSTOMID TOSTRING(100)
+
+#define SQLITE_COLUMN_NAME_LENGTH 64
+
+#define SQLITE_TABLE_RESOURCES "Resources"
+#define SQLITE_TABLE_OBJECTS "Objects"
+#define SQLITE_TABLE_ITEMS "Items"
+#define SQLITE_TABLE_CONTAINERS "Containers"
+#define SQLITE_TABLE_VIDEOITEMS "VideoItems"
+#define SQLITE_TABLE_AUDIOITEMS "AudioItems"
+#define SQLITE_TABLE_IMAGEITEMS "ImageItems"
+#define SQLITE_TABLE_VIDEOBROADCASTS "VideoBroadcasts"
+#define SQLITE_TABLE_AUDIOBROADCASTS "AudioBroadcasts"
+#define SQLITE_TABLE_MOVIES "Movies"
+#define SQLITE_TABLE_PHOTOS "Photos"
+#define SQLITE_TABLE_ALBUMS "Albums"
+#define SQLITE_TABLE_PLAYLISTS "Playlists"
+#define SQLITE_TABLE_SEARCHCLASS "SearchClass"
+#define SQLITE_TABLE_PRIMARY_KEYS "PrimaryKeys"
+#define SQLITE_TABLE_SYSTEM "System"
+#define SQLITE_TABLE_ITEMFINDER "ItemFinder"
+
+#define SQLITE_TYPE_TEXT "TEXT"
+#define SQLITE_TYPE_INTEGER "INTEGER"
+#define SQLITE_TYPE_BOOL SQLITE_TYPE_INTEGER
+#define SQLITE_TYPE_DATE SQLITE_TYPE_TEXT
+#define SQLITE_TYPE_ULONG SQLITE_TYPE_INTEGER
+#define SQLITE_TYPE_LONG SQLITE_TYPE_INTEGER
+#define SQLITE_TYPE_UINTEGER SQLITE_TYPE_INTEGER
+
+#define SQLITE_TRANSACTION_BEGIN "BEGIN IMMEDIATE TRANSACTION "
+#define SQLITE_TRANSACTION_END "COMMIT TRANSACTION"
+#define SQLITE_TRANSACTION_TYPE "ROLLBACK"
+
+#define SQLITE_CONFLICT_CLAUSE "ON CONFLICT " SQLITE_TRANSACTION_TYPE
+#define SQLITE_PRIMARY_KEY SQLITE_TYPE_INTEGER " PRIMARY KEY"
+#define SQLITE_NOT_NULL "NOT NULL"
+#define SQLITE_UNIQUE "UNIQUE"
+
+#define SQLITE_COL_OBJECTID "ObjectID"
+#define SQLITE_COL_PARENTID "ParentID"
+#define SQLITE_COL_TITLE "Title"
+#define SQLITE_COL_CREATOR "Creator"
+#define SQLITE_COL_CLASS "Class"
+#define SQLITE_COL_RESTRICTED "Restricted"
+#define SQLITE_COL_WRITESTATUS "WriteStatus"
+#define SQLITE_COL_REFERENCEID "RefID"
+#define SQLITE_COL_CLASSDERIVED "IncludeDerived"
+#define SQLITE_COL_SEARCHABLE "Searchable"
+#define SQLITE_COL_CONTAINER_UID "UpdateID"
+#define SQLITE_COL_RESOURCEID "ResourceID"
+#define SQLITE_COL_PROTOCOLINFO "ProtocolInfo"
+#define SQLITE_COL_CONTENTTYPE "ContentType"
+#define SQLITE_COL_RESOURCETYPE "ResourceType"
+#define SQLITE_COL_RESOURCE "Resource"
+#define SQLITE_COL_SIZE "Size"
+#define SQLITE_COL_DURATION "Duration"
+#define SQLITE_COL_BITRATE "Bitrate"
+#define SQLITE_COL_SAMPLEFREQUENCE "SampleFreq"
+#define SQLITE_COL_BITSPERSAMPLE "BitsPerSample"
+#define SQLITE_COL_NOAUDIOCHANNELS "NoAudioChannels"
+#define SQLITE_COL_COLORDEPTH "ColorDepth"
+#define SQLITE_COL_RESOLUTION "Resolution"
+#define SQLITE_COL_GENRE "Genre"
+#define SQLITE_COL_LONGDESCRIPTION "LongDescription"
+#define SQLITE_COL_PRODUCER "Producer"
+#define SQLITE_COL_RATING "Rating"
+#define SQLITE_COL_ACTOR "Actor"
+#define SQLITE_COL_DIRECTOR "Director"
+#define SQLITE_COL_DESCRIPTION "Description"
+#define SQLITE_COL_PUBLISHER "Publisher"
+#define SQLITE_COL_LANGUAGE "Language"
+#define SQLITE_COL_RELATION "Relation"
+#define SQLITE_COL_STORAGEMEDIUM "StorageMedium"
+#define SQLITE_COL_DVDREGIONCODE "DVDRegionCode"
+#define SQLITE_COL_CHANNELNAME "Channelname"
+#define SQLITE_COL_SCHEDULEDSTARTTIME "ScheduledStartTime"
+#define SQLITE_COL_SCHEDULEDENDTIME "ScheduledEndTime"
+#define SQLITE_COL_ICON "Icon"
+#define SQLITE_COL_REGION "Region"
+#define SQLITE_COL_CHANNELNR "ChannelNr"
+#define SQLITE_COL_RIGHTS "Rights"
+#define SQLITE_COL_RADIOCALLSIGN "CallSign"
+#define SQLITE_COL_RADIOSTATIONID "StationID"
+#define SQLITE_COL_RADIOBAND "Band"
+#define SQLITE_COL_CONTRIBUTOR "Contributor"
+#define SQLITE_COL_DATE "Date"
+#define SQLITE_COL_ALBUM "Album"
+#define SQLITE_COL_ARTIST "Artist"
+#define SQLITE_COL_DLNA_CONTAINERTYPE "DLNAContainer"
+#define SQLITE_COL_CHILDCOUNT "ChildCount"
+#define SQLITE_COL_ITEMFINDER "ItemFastID"
+
+#define SQLITE_UPNP_OBJECTID SQLITE_COL_OBJECTID " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL " " SQLITE_CONFLICT_CLAUSE " "\
+ SQLITE_UNIQUE " " SQLITE_CONFLICT_CLAUSE
+
+#define SQLITE_INSERT_TRIGGER(TableA,TableB,Class) "CREATE TRIGGER IF NOT EXISTS "\
+ TableA "_I_" TableB " "\
+ "BEFORE INSERT ON "\
+ TableB " "\
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "((SELECT " SQLITE_COL_OBJECTID " FROM " TableA " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID " "\
+ ") IS NULL) "\
+ "OR "\
+ "((SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID " "\
+ "AND " SQLITE_COL_CLASS " LIKE '" Class "%%') IS NULL) "\
+ ") THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", "\
+ "'INSERT on table " TableB " failed due constraint violation "\
+ "on foreign key " SQLITE_COL_OBJECTID "'"\
+ ") "\
+ "END; END;"
+
+#define SQLITE_UPDATE_TRIGGER(TableA,TableB,Class) "CREATE TRIGGER IF NOT EXISTS "\
+ TableA "_U_" TableB " "\
+ "BEFORE UPDATE ON "\
+ TableB " "\
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "((SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID " "\
+ "AND " SQLITE_COL_CLASS " LIKE '" Class "%%') IS NULL)"\
+ ") THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", "\
+ "'UPDATE on table " TableB " failed due constraint violation "\
+ "on foreign key " SQLITE_COL_OBJECTID "'"\
+ ") "\
+ "END; END;"
+
+#define SQLITE_INSERT_REFERENCE_TRIGGER(Table,Column) "CREATE TRIGGER IF NOT EXISTS "\
+ Table "_I_" Table " "\
+ "BEFORE INSERT ON " \
+ Table " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ( "\
+ "((SELECT " SQLITE_COL_OBJECTID " FROM " Table " "\
+ "WHERE " SQLITE_COL_OBJECTID " = NEW." Column ") IS NULL) "\
+ "AND "\
+ "(NEW." Column "!=-1)"\
+ ")THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", 'INSERT on table " Table " "\
+ "violates foreign key \"" Column "\"') "\
+ "END; END;"
+
+#define SQLITE_UPDATE_REFERENCE_TRIGGER(Table,Column) "CREATE TRIGGER IF NOT EXISTS "\
+ Table "_U_" Table " "\
+ "BEFORE INSERT ON " \
+ Table " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ( "\
+ "((SELECT " SQLITE_COL_OBJECTID " FROM " Table " "\
+ "WHERE " SQLITE_COL_OBJECTID " = NEW." Column ") IS NULL) "\
+ "AND "\
+ "(NEW." Column "!=-1)"\
+ ")THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", 'UPDATE on table " Table " "\
+ "violates foreign key \"" Column "\"') "\
+ "END; END;"
+
+#define SQLITE_DELETE_REFERENCE_TRIGGER(Table,Column) "CREATE TRIGGER IF NOT EXISTS "\
+ Table "_D_" Table " " \
+ "BEFORE DELETE ON " \
+ Table " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " Column " FROM " Table " "\
+ "WHERE " Column " = OLD." SQLITE_COL_OBJECTID ") IS NOT NULL"\
+ ")THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", 'DELETE on table " Table " "\
+ "violates foreign key \"" Column "\"') "\
+ "END; END;"
+
+#ifdef SQLITE_CASCADE_DELETES
+#define SQLITE_DELETE_TRIGGER(TableA,TableB) "CREATE TRIGGER IF NOT EXISTS "\
+ TableA "_D_" TableB " "\
+ "BEFORE DELETE ON "\
+ TableA " "\
+ "FOR EACH ROW BEGIN "\
+ "DELETE FROM " TableB " "\
+ "WHERE " SQLITE_COL_OBJECTID "=OLD." SQLITE_COL_OBJECTID "; "\
+ "END;"
+
+#define SQLITE_DELETE_PARENT_TRIGGER "CREATE TRIGGER IF NOT EXISTS "\
+ SQLITE_TABLE_OBJECTS "_D_" SQLITE_TABLE_OBJECTS " " \
+ "BEFORE DELETE ON " \
+ SQLITE_TABLE_OBJECTS " " \
+ "FOR EACH ROW BEGIN "\
+ "DELETE FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_PARENTID "=OLD." SQLITE_COL_OBJECTID "; "\
+ "END;"
+#else
+#define SQLITE_DELETE_TRIGGER(TableA,TableB) "CREATE TRIGGER IF NOT EXISTS "\
+ TableA "_D_" TableB " "\
+ "BEFORE DELETE ON "\
+ TableA " "\
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " SQLITE_COL_OBJECTID " FROM " TableB " "\
+ "WHERE " SQLITE_COL_OBJECTID "=OLD." SQLITE_COL_OBJECTID ") IS NOT NULL"\
+ ") THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ", "\
+ "'DELETE on table " TableA " failed due constraint violation "\
+ "on foreign key " SQLITE_COL_OBJECTID "'"\
+ ") "\
+ "END; END;"
+
+#define SQLITE_DELETE_PARENT_TRIGGER SQLITE_DELETE_REFERENCE_TRIGGER(SQLITE_TABLE_OBJECTS, SQLITE_COL_PARENTID)
+#endif
+
+/**********************************************\
+* *
+* Primary keys *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_PRIMARY_KEYS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_PRIMARY_KEYS \
+ "("\
+ "KeyID " SQLITE_PRIMARY_KEY " " SQLITE_NOT_NULL ","\
+ "Key " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL\
+ ");"\
+ "INSERT OR IGNORE INTO "\
+ SQLITE_TABLE_PRIMARY_KEYS \
+ "(KeyID, Key) VALUES ("\
+ PK_OBJECTS "," SQLITE_FIRST_CUSTOMID\
+ ");"\
+ "INSERT OR IGNORE INTO "\
+ SQLITE_TABLE_PRIMARY_KEYS \
+ "(KeyID, Key) VALUES ("\
+ PK_RESOURCES ",0"\
+ ");"\
+ "INSERT OR IGNORE INTO "\
+ SQLITE_TABLE_PRIMARY_KEYS \
+ "(KeyID, Key) VALUES ("\
+ PK_SEARCHCLASSES ",0"\
+ ");"
+
+#define SQLITE_TRIGGER_UPDATE_OBJECTID "CREATE TRIGGER IF NOT EXISTS "\
+ SQLITE_TABLE_OBJECTS "_PK_UPDATE "\
+ "AFTER INSERT ON "\
+ SQLITE_TABLE_OBJECTS " "\
+ "BEGIN "\
+ "UPDATE " SQLITE_TABLE_PRIMARY_KEYS " SET Key=Key+1 WHERE KeyID=" PK_OBJECTS "; "\
+ "END;"
+
+/**********************************************\
+* *
+* System settings *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_SYSTEM "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_SYSTEM " "\
+ "("\
+ "Key " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL " " SQLITE_UNIQUE ","\
+ "Value " SQLITE_TYPE_TEXT " "\
+ ");"
+
+#define SQLITE_TRIGGER_UPDATE_SYSTEM "CREATE TRIGGER IF NOT EXISTS "\
+ SQLITE_TABLE_SYSTEM "_VALUE_UPDATE "\
+ "BEFORE UPDATE "\
+ "ON " SQLITE_TABLE_SYSTEM " "\
+ "WHEN ((SELECT Key FROM " SQLITE_TABLE_SYSTEM " WHERE Key=NEW.Key) IS NULL) "\
+ "BEGIN INSERT INTO " SQLITE_TABLE_SYSTEM " (Key) VALUES (NEW.Key); END;"
+
+/**********************************************\
+* *
+* Fast item finder *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_ITEMFINDER "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_ITEMFINDER " "\
+ "("\
+ SQLITE_UPNP_OBJECTID ","\
+ SQLITE_COL_ITEMFINDER " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL " " SQLITE_UNIQUE \
+ ");"
+
+#define SQLITE_TRIGGER_D_OBJECTS_ITEMFINDER SQLITE_DELETE_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_ITEMFINDER)
+
+/**********************************************\
+* *
+* Objects *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_OBJECTS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_OBJECTS \
+ "(" \
+ SQLITE_COL_OBJECTID " " SQLITE_PRIMARY_KEY " " SQLITE_NOT_NULL " " SQLITE_CONFLICT_CLAUSE "," \
+ SQLITE_COL_PARENTID " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL " " SQLITE_CONFLICT_CLAUSE "," \
+ SQLITE_COL_TITLE " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_CREATOR " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_CLASS " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_RESTRICTED " " SQLITE_TYPE_BOOL " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_WRITESTATUS " " SQLITE_TYPE_INTEGER \
+ ");"
+
+// Trigger for foreign key ParentID
+
+#define SQLITE_TRIGGER_D_OBJECTS_OBJECTS SQLITE_DELETE_PARENT_TRIGGER
+
+#define SQLITE_TRIGGER_I_OBJECTS_OBJECTS SQLITE_INSERT_REFERENCE_TRIGGER(SQLITE_TABLE_OBJECTS, SQLITE_COL_PARENTID)\
+ "CREATE TRIGGER IF NOT EXISTS "\
+ SQLITE_TABLE_OBJECTS "_PI_" SQLITE_TABLE_OBJECTS " "\
+ "BEFORE INSERT ON "\
+ SQLITE_TABLE_OBJECTS " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "((SELECT " SQLITE_COL_PARENTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_PARENTID "=-1) IS NOT NULL) "\
+ "AND "\
+ "(NEW." SQLITE_COL_PARENTID "=-1)"\
+ ") THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ","\
+ "'INSERT on table " SQLITE_TABLE_OBJECTS " violates constraint. "\
+ SQLITE_COL_PARENTID " must uniquely be -1') "\
+ "END; END;"
+
+#define SQLITE_TRIGGER_U_OBJECTS_OBJECTS SQLITE_UPDATE_REFERENCE_TRIGGER(SQLITE_TABLE_OBJECTS, SQLITE_COL_PARENTID)\
+ "CREATE TRIGGER IF NOT EXISTS "\
+ SQLITE_TABLE_OBJECTS "_PU_" SQLITE_TABLE_OBJECTS " "\
+ "BEFORE UPDATE ON "\
+ SQLITE_TABLE_OBJECTS " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "((SELECT " SQLITE_COL_PARENTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_PARENTID "=-1 "\
+ "AND " SQLITE_COL_OBJECTID "!=NEW." SQLITE_COL_OBJECTID " ) IS NOT NULL) "\
+ "AND "\
+ "(NEW." SQLITE_COL_PARENTID "=-1) AND (OLD." SQLITE_COL_PARENTID "!=-1) "\
+ ") THEN "\
+ "RAISE(" SQLITE_TRANSACTION_TYPE ","\
+ "'UPDATE on table " SQLITE_TABLE_OBJECTS " violates constraint. "\
+ SQLITE_COL_PARENTID " must uniquely be -1') "\
+ "END; END;"
+
+/**********************************************\
+* *
+* Items *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_ITEMS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_ITEMS \
+ "(" \
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_REFERENCEID " " SQLITE_TYPE_INTEGER " DEFAULT -1" \
+ ");"
+
+// Trigger for foreign key ObjectID
+
+#define SQLITE_TRIGGER_D_OBJECT_ITEMS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_ITEMS)
+
+#define SQLITE_TRIGGER_I_OBJECT_ITEMS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_ITEMS,\
+ UPNP_CLASS_ITEM)
+
+#define SQLITE_TRIGGER_U_OBJECT_ITEMS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_ITEMS,\
+ UPNP_CLASS_ITEM)
+
+// Trigger for Reference items
+
+#define SQLITE_TRIGGER_I_ITEMS_ITEMS SQLITE_INSERT_REFERENCE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_COL_REFERENCEID)
+
+#define SQLITE_TRIGGER_U_ITEMS_ITEMS SQLITE_UPDATE_REFERENCE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_COL_REFERENCEID)
+
+#define SQLITE_TRIGGER_D_ITEMS_ITEMS SQLITE_DELETE_REFERENCE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_COL_REFERENCEID)
+
+/**********************************************\
+* *
+* Containers *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_CONTAINER "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_CONTAINERS \
+ "(" \
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_SEARCHABLE " " SQLITE_TYPE_INTEGER ","\
+ SQLITE_COL_CONTAINER_UID " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL ","\
+ SQLITE_COL_DLNA_CONTAINERTYPE " " SQLITE_TYPE_TEXT \
+ ");"
+
+#define SQLITE_TRIGGER_D_OBJECT_CONTAINERS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_CONTAINERS)
+
+#define SQLITE_TRIGGER_I_OBJECT_CONTAINERS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_CONTAINERS,\
+ UPNP_CLASS_CONTAINER)
+
+#define SQLITE_TRIGGER_U_OBJECT_CONTAINERS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_OBJECTS,\
+ SQLITE_TABLE_CONTAINERS,\
+ UPNP_CLASS_CONTAINER)
+
+/**********************************************\
+* *
+* Video items *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_VIDEOITEMS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_VIDEOITEMS \
+ "(" \
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_GENRE " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_LONGDESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_PRODUCER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_RATING " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_ACTOR " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DIRECTOR " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_PUBLISHER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_LANGUAGE " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_RELATION " " SQLITE_TYPE_TEXT \
+ ");"
+
+#define SQLITE_TRIGGER_D_ITEMS_VIDEOITEMS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_TABLE_VIDEOITEMS)
+
+#define SQLITE_TRIGGER_U_ITEMS_VIDEOITEMS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_VIDEOITEMS, \
+ UPNP_CLASS_VIDEO)
+
+#define SQLITE_TRIGGER_I_ITEMS_VIDEOITEMS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_VIDEOITEMS, \
+ UPNP_CLASS_VIDEO)
+
+/**********************************************\
+* *
+* Audio items *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_AUDIOITEMS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_AUDIOITEMS \
+ "(" \
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_GENRE " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_LONGDESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_PUBLISHER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_RELATION " " SQLITE_TYPE_TEXT \
+ ");"
+
+#define SQLITE_TRIGGER_D_ITEMS_AUDIOITEMS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_TABLE_AUDIOITEMS)
+
+#define SQLITE_TRIGGER_U_ITEMS_AUDIOITEMS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_AUDIOITEMS, \
+ UPNP_CLASS_AUDIO)
+
+#define SQLITE_TRIGGER_I_ITEMS_AUDIOITEMS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_AUDIOITEMS, \
+ UPNP_CLASS_AUDIO)
+
+/**********************************************\
+* *
+* Image items *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_IMAGEITEMS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_IMAGEITEMS \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_LONGDESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_PUBLISHER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_STORAGEMEDIUM " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RATING " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_DATE " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RIGHTS " " SQLITE_TYPE_TEXT\
+ ");"
+
+#define SQLITE_TRIGGER_D_ITEMS_IMAGEITEMS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_ITEMS, SQLITE_TABLE_IMAGEITEMS)
+
+#define SQLITE_TRIGGER_U_ITEMS_IMAGEITEMS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_IMAGEITEMS, \
+ UPNP_CLASS_IMAGE)
+
+#define SQLITE_TRIGGER_I_ITEMS_IMAGEITEMS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_ITEMS, \
+ SQLITE_TABLE_IMAGEITEMS, \
+ UPNP_CLASS_IMAGE)
+
+/**********************************************\
+* *
+* Video broadcasts *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_VIDEOBROADCASTS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_VIDEOBROADCASTS \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_ICON " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_REGION " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_CHANNELNR " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_CHANNELNAME " " SQLITE_TYPE_TEXT " " SQLITE_UNIQUE \
+ ");"
+
+#define SQLITE_TRIGGER_D_VIDEOITEMS_VIDEOBROADCASTS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_VIDEOITEMS, SQLITE_TABLE_VIDEOBROADCASTS)
+
+#define SQLITE_TRIGGER_U_VIDEOITEMS_VIDEOBROADCASTS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_VIDEOITEMS,\
+ SQLITE_TABLE_VIDEOBROADCASTS,\
+ UPNP_CLASS_VIDEOBC)
+
+#define SQLITE_TRIGGER_I_VIDEOITEMS_VIDEOBROADCASTS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_VIDEOITEMS,\
+ SQLITE_TABLE_VIDEOBROADCASTS,\
+ UPNP_CLASS_VIDEOBC)
+
+/**********************************************\
+* *
+* Audio broadcasts *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_AUDIOBROADCASTS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_AUDIOBROADCASTS \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_REGION " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RADIOCALLSIGN " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RADIOSTATIONID " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RADIOBAND " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_CHANNELNR " " SQLITE_TYPE_INTEGER \
+ ");"
+
+#define SQLITE_TRIGGER_D_AUDIOITEMS_AUDIOBROADCASTS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_AUDIOITEMS, SQLITE_TABLE_AUDIOBROADCASTS)
+
+#define SQLITE_TRIGGER_I_AUDIOITEMS_AUDIOBROADCASTS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_AUDIOITEMS,\
+ SQLITE_TABLE_AUDIOBROADCASTS,\
+ UPNP_CLASS_AUDIOBC)
+
+#define SQLITE_TRIGGER_U_AUDIOITEMS_AUDIOBROADCASTS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_AUDIOITEMS,\
+ SQLITE_TABLE_AUDIOBROADCASTS,\
+ UPNP_CLASS_AUDIOBC)
+
+/**********************************************\
+* *
+* Movies *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_MOVIES "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_MOVIES \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_STORAGEMEDIUM " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DVDREGIONCODE " " SQLITE_TYPE_INTEGER "," \
+ SQLITE_COL_CHANNELNAME " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_SCHEDULEDSTARTTIME " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_SCHEDULEDENDTIME " " SQLITE_TYPE_TEXT\
+ ");"
+
+#define SQLITE_TRIGGER_D_VIDEOITEMS_MOVIES SQLITE_DELETE_TRIGGER(SQLITE_TABLE_VIDEOITEMS, SQLITE_TABLE_MOVIES)
+
+
+#define SQLITE_TRIGGER_I_VIDEOITEMS_MOVIES SQLITE_INSERT_TRIGGER(SQLITE_TABLE_VIDEOITEMS,\
+ SQLITE_TABLE_MOVIES,\
+ UPNP_CLASS_MOVIE)
+
+#define SQLITE_TRIGGER_U_VIDEOITEMS_MOVIES SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_VIDEOITEMS,\
+ SQLITE_TABLE_MOVIES,\
+ UPNP_CLASS_MOVIE)
+
+/**********************************************\
+* *
+* Photos *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_PHOTOS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_PHOTOS \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_ALBUM " " SQLITE_TYPE_TEXT\
+ ");"
+
+#define SQLITE_TRIGGER_D_IMAGEITEMS_PHOTOS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_IMAGEITEMS, SQLITE_TABLE_PHOTOS)
+
+#define SQLITE_TRIGGER_I_IMAGEITEMS_PHOTOS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_IMAGEITEMS,\
+ SQLITE_TABLE_PHOTOS,\
+ UPNP_CLASS_PHOTO)
+
+#define SQLITE_TRIGGER_U_IMAGEITEMS_PHOTOS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_IMAGEITEMS,\
+ SQLITE_TABLE_PHOTOS,\
+ UPNP_CLASS_PHOTO)
+
+/**********************************************\
+* *
+* Albums *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_ALBUMS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_ALBUMS \
+ "("\
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_STORAGEMEDIUM " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_LONGDESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_PUBLISHER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_CONTRIBUTOR " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_DATE " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_RELATION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_RIGHTS " " SQLITE_TYPE_TEXT \
+ ");"
+
+#define SQLITE_TRIGGER_D_CONTAINERS_ALBUMS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_CONTAINERS, SQLITE_TABLE_ALBUMS)
+
+#define SQLITE_TRIGGER_U_CONTAINERS_ALBUMS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_CONTAINERS,\
+ SQLITE_TABLE_ALBUMS,\
+ UPNP_CLASS_ALBUM)
+
+#define SQLITE_TRIGGER_I_CONTAINERS_ALBUMS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_CONTAINERS,\
+ SQLITE_TABLE_ALBUMS,\
+ UPNP_CLASS_ALBUM)
+
+/**********************************************\
+* *
+* Playlists *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_PLAYLISTS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_PLAYLISTS \
+ "(" \
+ SQLITE_UPNP_OBJECTID "," \
+ SQLITE_COL_ARTIST " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_GENRE " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_LONGDESCRIPTION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DESCRIPTION " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_PRODUCER " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_STORAGEMEDIUM " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_CONTRIBUTOR " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_DATE " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_LANGUAGE " " SQLITE_TYPE_TEXT ","\
+ SQLITE_COL_RIGHTS " " SQLITE_TYPE_TEXT\
+ ");"
+
+#define SQLITE_TRIGGER_D_CONTAINERS_PLAYLISTS SQLITE_DELETE_TRIGGER(SQLITE_TABLE_CONTAINERS, SQLITE_TABLE_PLAYLISTS)
+
+#define SQLITE_TRIGGER_I_CONTAINERS_PLAYLISTS SQLITE_INSERT_TRIGGER(SQLITE_TABLE_CONTAINERS,\
+ SQLITE_TABLE_PLAYLISTS,\
+ UPNP_CLASS_PLAYLISTCONT)
+
+#define SQLITE_TRIGGER_U_CONTAINERS_PLAYLISTS SQLITE_UPDATE_TRIGGER(SQLITE_TABLE_CONTAINERS,\
+ SQLITE_TABLE_PLAYLISTS,\
+ UPNP_CLASS_PLAYLISTCONT)
+
+/**********************************************\
+* *
+* Search classes *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_SEARCHCLASS "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_SEARCHCLASS \
+ "(" \
+ SQLITE_COL_OBJECTID " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_CLASS " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_CLASSDERIVED " " SQLITE_TYPE_BOOL \
+ ");"
+
+#define SQLITE_TRIGGER_D_CONTAINERS_SEARCHCLASSES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_CONTAINERS "_D_" SQLITE_TABLE_SEARCHCLASS " " \
+ "BEFORE DELETE ON " \
+ SQLITE_TABLE_CONTAINERS " " \
+ "FOR EACH ROW BEGIN "\
+ "DELETE FROM " SQLITE_TABLE_SEARCHCLASS " "\
+ "WHERE " SQLITE_COL_OBJECTID "= OLD." SQLITE_COL_OBJECTID "; " \
+ "END;"
+
+#define SQLITE_TRIGGER_U_CONTAINERS_SEARCHCLASSES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_CONTAINERS "_U_" SQLITE_TABLE_SEARCHCLASS " " \
+ "BEFORE UPDATE ON " \
+ SQLITE_TABLE_SEARCHCLASS " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_CONTAINERS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID ") IS NULL "\
+ ") THEN "\
+ "RAISE (" SQLITE_TRANSACTION_TYPE ", 'UPDATE on table " SQLITE_TABLE_SEARCHCLASS " "\
+ "violates foreign key constraint \"" SQLITE_COL_OBJECTID "\"') " \
+ "END; END;"
+
+#define SQLITE_TRIGGER_I_CONTAINERS_SEARCHCLASSES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_CONTAINERS "_I_" SQLITE_TABLE_SEARCHCLASS " " \
+ "BEFORE INSERT ON " \
+ SQLITE_TABLE_SEARCHCLASS " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_CONTAINERS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID ") IS NULL "\
+ ") THEN "\
+ "RAISE (" SQLITE_TRANSACTION_TYPE ", 'INSERT on table " SQLITE_TABLE_SEARCHCLASS " "\
+ "violates foreign key constraint \"" SQLITE_COL_OBJECTID "\"') " \
+ "END; END;"
+
+/**********************************************\
+* *
+* Resources *
+* *
+\**********************************************/
+
+#define SQLITE_CREATE_TABLE_RESOURCES "CREATE TABLE IF NOT EXISTS "\
+ SQLITE_TABLE_RESOURCES \
+ "(" \
+ SQLITE_COL_RESOURCEID " " SQLITE_PRIMARY_KEY " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_OBJECTID " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_PROTOCOLINFO " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_CONTENTTYPE " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_RESOURCETYPE " " SQLITE_TYPE_INTEGER " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_RESOURCE " " SQLITE_TYPE_TEXT " " SQLITE_NOT_NULL "," \
+ SQLITE_COL_SIZE " " SQLITE_TYPE_ULONG "," \
+ SQLITE_COL_DURATION " " SQLITE_TYPE_TEXT "," \
+ SQLITE_COL_BITRATE " " SQLITE_TYPE_UINTEGER "," \
+ SQLITE_COL_SAMPLEFREQUENCE " " SQLITE_TYPE_UINTEGER "," \
+ SQLITE_COL_BITSPERSAMPLE " " SQLITE_TYPE_UINTEGER "," \
+ SQLITE_COL_NOAUDIOCHANNELS " " SQLITE_TYPE_UINTEGER "," \
+ SQLITE_COL_COLORDEPTH " " SQLITE_TYPE_UINTEGER "," \
+ SQLITE_COL_RESOLUTION " " SQLITE_TYPE_TEXT \
+ ");"
+
+#define SQLITE_TRIGGER_D_OBJECT_RESOURCES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_OBJECTS "_D_" SQLITE_TABLE_RESOURCES " " \
+ "BEFORE DELETE ON " \
+ SQLITE_TABLE_OBJECTS " " \
+ "FOR EACH ROW BEGIN "\
+ "DELETE FROM " SQLITE_TABLE_RESOURCES " "\
+ "WHERE " SQLITE_COL_OBJECTID "= OLD." SQLITE_COL_OBJECTID "; " \
+ "END;"
+
+#define SQLITE_TRIGGER_I_OBJECT_RESOURCES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_OBJECTS "_I_" SQLITE_TABLE_RESOURCES " " \
+ "BEFORE INSERT ON " \
+ SQLITE_TABLE_RESOURCES " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID ") IS NULL"\
+ ") THEN "\
+ "RAISE (" SQLITE_TRANSACTION_TYPE ", 'INSERT on table " SQLITE_TABLE_RESOURCES " "\
+ "violates foreign key constraint \"" SQLITE_COL_OBJECTID "\"') " \
+ "END; END;"
+
+#define SQLITE_TRIGGER_U_OBJECT_RESOURCES "CREATE TRIGGER IF NOT EXISTS " \
+ SQLITE_TABLE_OBJECTS "_U_" SQLITE_TABLE_RESOURCES " " \
+ "BEFORE UPDATE ON " \
+ SQLITE_TABLE_RESOURCES " " \
+ "FOR EACH ROW BEGIN "\
+ "SELECT CASE "\
+ "WHEN ("\
+ "(SELECT " SQLITE_COL_OBJECTID " FROM " SQLITE_TABLE_OBJECTS " "\
+ "WHERE " SQLITE_COL_OBJECTID "=NEW." SQLITE_COL_OBJECTID ") IS NULL"\
+ ") THEN "\
+ "RAISE (" SQLITE_TRANSACTION_TYPE ", 'INSERT on table " SQLITE_TABLE_RESOURCES " "\
+ "violates foreign key constraint \"" SQLITE_COL_OBJECTID "\"') " \
+ "END; END;"
+
+class cSQLiteDatabase;
+
+/**
+ * Result row of a SQL SELECT request
+ *
+ * This is a single row of a {\c SQL SELECT} request.
+ *
+ * @see cRows
+ */
+class cRow : public cListObject {
+ friend class cSQLiteDatabase;
+private:
+ int currentCol;
+ int ColCount;
+ char** Columns;
+ char** Values;
+ cRow();
+public:
+ virtual ~cRow();
+ /**
+ * Number of columns in this row
+ *
+ * @return the number of rows
+ */
+ int Count(){ return this->ColCount; }
+ /**
+ * Fetches a Column
+ *
+ * This will fetch a column of this row and stores the name of the column
+ * in the first parameter and the value in the second parameter.
+ *
+ * @return returns
+ * - \bc true, if more columns to come
+ * - \bc false, if the column is its last in this row.
+ */
+ bool fetchColumn(
+ cString* Column, /**< The name of the current column */
+ cString* Value /**< The value of the current value */
+ );
+
+ /**
+ * Fetches a Column
+ *
+ * This will fetch a column of this row and stores the name of the column
+ * in the first parameter and the value in the second parameter.
+ *
+ * @return returns
+ * - \bc true, if more columns to come
+ * - \bc false, if the column is its last in this row.
+ */
+ bool fetchColumn(
+ char** Column, /**< The name of the current column */
+ char** Value /**< The value of the current column */
+ );
+};
+
+/**
+ * Result rows of a SQL SELECT request
+ *
+ * Contains the rows of a SQL SELECT request
+ *
+ * @see cRow
+ */
+class cRows : public cList<cRow> {
+ friend class cSQLiteDatabase;
+private:
+ cRow* mLastRow;
+ cRows();
+public:
+ virtual ~cRows();
+ /**
+ * Fetches a row from the result
+ *
+ * This fetches the next row in the resultset by storing the contents of
+ * that row in the first parameter.
+ *
+ * @return returns
+ * - \bc true, if more rows to come
+ * - \bc false, if the row is its last in this resultset.
+ */
+ bool fetchRow(
+ cRow** Row /**< The Pointer of the row */
+ );
+};
+
+/**
+ * SQLite Database
+ *
+ * This is a wrapper class for a SQLite3 database connection
+ * It supports simple execution functions.
+ *
+ * On requests with returns any results a instance of \c cRows* will be created.
+ */
+class cSQLiteDatabase {
+ friend class cStatement;
+private:
+ bool mAutoCommit;
+ bool mActiveTransaction;
+ cRow* mLastRow;
+ cRows* mRows;
+ sqlite3* mDatabase;
+ static cSQLiteDatabase* mInstance;
+ cSQLiteDatabase();
+ int initialize();
+ int initializeTables();
+ int initializeTriggers();
+ static int getResultRow(void* DB, int NumCols, char** Values, char** ColNames);
+ int exec(const char* Statement);
+public:
+ /**
+ * Prints a SQLite escaped text
+ *
+ * Returns a formated text with special characters to escape SQLite special
+ * characters like "'". Additionally to the well known characters of \a printf
+ * the following are allowed:
+ *
+ * - \bc q, like s, escapes single quotes in strings
+ * - \bc Q, like q, surrounds the escaped string with additional
+ * single quotes
+ * - \bc z, frees the string after reading and coping it
+ *
+ * @see sprintf()
+ * @return the formated string
+ */
+ static const char* sprintf(
+ const char* Format, /**< The format string */
+ ... /**< optional properties which will be passed to sprintf */
+ );
+ virtual ~cSQLiteDatabase();
+ /**
+ * Returns the instance of the database
+ *
+ * Returns the instance of the SQLite database. This will create a single
+ * instance of none is existing on the very first call. A subsequent call
+ * will return the same instance.
+ *
+ * @return the database instance
+ */
+ static cSQLiteDatabase* getInstance();
+ /**
+ * Row count of the last result
+ *
+ * Returns the row count of the last {\c SQL SELECT} request.
+ *
+ * @see cRows
+ * @return the result row count
+ */
+ int getResultCount() const { return this->mRows->Count(); }
+ /**
+ * The last \c INSERT RowID
+ *
+ * Returns the primary key of the last inserted row.
+ * This will only work if there are no successive calls to the database.
+ *
+ * @return the last insert RowID
+ */
+ long getLastInsertRowID() const;
+ /**
+ * Result set of the last request
+ *
+ * Returns the result rows of the SQL SELECT request.
+ * This might be NULL, if the last statement was not a SELECT.
+ *
+ * @see cRows
+ * @return the result rows of the last \c SELECT statement.
+ */
+ cRows* getResultRows() const { return this->mRows; }
+ /**
+ * Executes a SQL statement
+ *
+ * This will execute the statement in the first parameter. If it is followed
+ * by any optional parameters it will be formated using the same function as
+ * in \c cSQLiteDatabase::sprintf().
+ *
+ * \sa cSQLiteDatabase::sprintf().
+ *
+ * @return returns an integer representing
+ * - \bc -1, in case of an error
+ * - \bc 0, when the statement was executed successfuly
+ */
+ int execStatement(
+ const char* Statement , /**< Statement to be executed */
+ ... /**< optional parameters passed to the format string */
+ );
+ /**
+ * Starts a transaction
+ *
+ * This starts a new transaction and commits or rolls back a previous.
+ *
+ * @see cSQLiteDatabase::setAutoCommit
+ * @see cSQLiteDatabase::commitTransaction
+ */
+ void startTransaction();
+ /**
+ * Commits a transaction
+ *
+ * This function commits the transaction and writes all changes to the
+ * database
+ *
+ * @see cSQLiteDatabase::startTransaction
+ */
+ void commitTransaction();
+ /**
+ * Performs a rollback on a transaction
+ *
+ * This function performs a rollback. No changes will be made to the
+ * database
+ *
+ * @see cSQLiteDatabase::rollbackTransaction
+ */
+ void rollbackTransaction();
+ /**
+ * Set the commit behavior
+ *
+ * This function sets the auto commit behavior on new transactions with
+ * \sa cSQLiteDatabase::startTransaction.
+ *
+ * - \bc true, commits the last transaction before starting a
+ * new one
+ * - \bc false, performs a rollback on the old transaction
+ *
+ */
+ void setAutoCommit(
+ bool Commit=true /**< Switches the behavior of auto commit */
+ ){ this->mAutoCommit = Commit; }
+};
+
+#endif /* _DATABASE_H */ \ No newline at end of file
diff --git a/inc/filehandle.h b/inc/filehandle.h
new file mode 100644
index 0000000..1dc57bf
--- /dev/null
+++ b/inc/filehandle.h
@@ -0,0 +1,108 @@
+/*
+ * File: filehandle.h
+ * Author: savop
+ *
+ * Created on 15. Oktober 2009, 10:49
+ */
+
+#ifndef _FILEHANDLE_H
+#define _FILEHANDLE_H
+
+#include <upnp/upnp.h>
+#include "../common.h"
+
+/**
+ * Interface for File Handles
+ *
+ * This class is a pure virtual class to act as an interface for file handles
+ * used by the webserver.
+ */
+class cFileHandle {
+public:
+ /**
+ * Opens the file
+ *
+ * Opens the file at the given mode. These can be:
+ * - \b UPNP_READ, to read from the file
+ * - \b UPNP_WRITE, to write to the file
+ *
+ * @param mode The file mode, i.e. one of the following
+ * - \b UPNP_READ
+ * - \b UPNP_WRITE
+ */
+ virtual void open(
+ UpnpOpenFileMode mode ///< The file mode, i.e. one of the following
+ ///< - \b UPNP_READ
+ ///< - \b UPNP_WRITE
+ ) = 0;
+ /**
+ * Reads from the file
+ *
+ * Reads from the file a certain amount of bytes and stores them in a buffer
+ *
+ * @return returns
+ * - \b <0, in case of an error
+ * - \b 0, when reading was successful
+ *
+ * @param buf The char buffer
+ * @param buflen The size of the buffer
+ */
+ virtual int read(
+ char* buf, ///< The char buffer
+ size_t buflen ///< The size of the buffer
+ ) = 0;
+ /**
+ * Writes to the file
+ *
+ * Writes to the file a certain amount of bytes which are stored in a buffer
+ *
+ * @return returns
+ * - \b <0, in case of an error
+ * - \b 0, when reading was successful
+ *
+ * @param buf The char buffer
+ * @param buflen The size of the buffer
+ */
+ virtual int write(
+ char* buf, ///< The char buffer
+ size_t buflen ///< The size of the buffer
+ ) = 0;
+ /**
+ * Seeks in the file
+ *
+ * Seeks in the file where the offset is the relativ position depending on
+ * the second parameter. This means, in case of
+ *
+ * - \b SEEK_SET, the offset is relative to the beginning of the file
+ * - \b SEEK_CUR, it is relative to the current position or
+ * - \b SEEK_END, relative to the end of the file.
+ *
+ * @return returns
+ * - \b <0, in case of an error
+ * - \b 0, when reading was successful
+ *
+ * @param offset The byte offset in the file
+ * @param whence one of the following
+ * - \b SEEK_SET,
+ * - \b SEEK_CUR,
+ * - \b SEEK_END
+ */
+ virtual int seek(
+ off_t offset, ///< The byte offset in the file
+ int whence ///< one of the following
+ ///< - \b SEEK_SET,
+ ///< - \b SEEK_CUR,
+ ///< - \b SEEK_END
+ ) = 0;
+ /**
+ * Closes the open file
+ *
+ * This will close open file handles and frees the memory obtained by it.
+ */
+ virtual void close() = 0;
+ virtual ~cFileHandle(){};
+private:
+};
+
+#endif /* _FILEHANDLE_H */
+
diff --git a/inc/livereceiver.h b/inc/livereceiver.h
new file mode 100644
index 0000000..379f453
--- /dev/null
+++ b/inc/livereceiver.h
@@ -0,0 +1,105 @@
+/*
+ * File: livereceiver.h
+ * Author: savop
+ *
+ * Created on 4. Juni 2009, 13:28
+ */
+
+#ifndef _LIVERECEIVER_H
+#define _LIVERECEIVER_H
+
+#include "../common.h"
+#include "filehandle.h"
+#include <vdr/thread.h>
+#include <vdr/receiver.h>
+#include <vdr/ringbuffer.h>
+
+#define RECEIVER_WAIT_ON_NODATA 50 // 50 ms
+#define RECEIVER_WAIT_ON_NODATA_TIMEOUT 1000 * 2 // 2s
+#define RECEIVER_MIN_BUFFER_FILLAGE 20 // 20%
+
+/**
+ * A receiver for live TV
+ *
+ * This is a receiver object which is attached to a VDR tv card device.
+ * It is receiving transport stream packages and generates a single MPEG2
+ * transport stream which can be distributed through the network.
+ *
+ */
+class cLiveReceiver : public cReceiver, public cThread, public cFileHandle {
+public:
+ /**
+ * Creates a new receiver instance
+ *
+ * This will create a new instance of a live receiver for the specified
+ * channel at the specified priority level.
+ *
+ * A negativ priority means that the receiver may being detached from a
+ * device.
+ *
+ * The receiver must be free'd with delete after it is not used anylonger.
+ *
+ * @return returns a new liveReceiver instance
+ */
+ static cLiveReceiver* newInstance(
+ cChannel *Channel, ///< the channel which shall be tuned
+ int Priority ///< the priority level
+ );
+ virtual ~cLiveReceiver(void);
+ /*! @copydoc cFileHandle::open(UpnpOpenFileMode) */
+ virtual void open(UpnpOpenFileMode mode);
+ /*! @copydoc cFileHandle::read(char*,size_t) */
+ virtual int read(char* buf, size_t buflen);
+ /*! @copydoc cFileHandle::write(char*,size_t) */
+ virtual int write(char* buf, size_t buflen);
+ /*! @copydoc cFileHandle::seek(off_t,int) */
+ virtual int seek(off_t offset, int whence);
+ /*! @copydoc cFileHandle::close() */
+ virtual void close();
+protected:
+ /**
+ * Receives data from VDR
+ *
+ * This is the interface for receiving packet data from the VDR. It buffers
+ * the incoming transport stream packets in a linear ringbuffer and returns
+ * immediatelly
+ */
+ virtual void Receive(
+ uchar *Data, ///< The data received from VDR
+ int Length ///< The length of the data packet, usually 188 bytes
+ );
+ /**
+ * Activates the receiver
+ *
+ * This activates the receiver which initializes internal data structures to
+ * be prepared for receiving data from the VDR
+ *
+ * If the parameter is \bc true, the receiver will be activated. If it is
+ * \bc false, the receiver will be deactivated and stops its threads.
+ */
+ virtual void Activate(
+ bool On ///< Activates the receiver thread
+ );
+ /**
+ * The receiver thread action
+ *
+ * This actually is the receiver thread, which runs consequitivelly and
+ * buffers any received video data from the interal incoming buffer to the
+ * internal outgoing buffer.
+ *
+ * While doing so, it tries to syncronize with the stream and creates new
+ * MPEG2-TS PATs and PMTs for a single MPEG2-TS stream
+ */
+ virtual void Action(void);
+private:
+ cLiveReceiver(cChannel *Channel, cDevice *Device);
+ cDevice *mDevice;
+ cChannel *mChannel;
+ cRingBufferLinear *mLiveBuffer;
+ cRingBufferLinear *mOutputBuffer;
+ cFrameDetector *mFrameDetector;
+ cPatPmtGenerator mPatPmtGenerator;
+};
+
+#endif /* _LIVERECEIVER_H */
+
diff --git a/inc/menusetup.h b/inc/menusetup.h
new file mode 100644
index 0000000..1db0480
--- /dev/null
+++ b/inc/menusetup.h
@@ -0,0 +1,103 @@
+/*
+ * File: menusetup.h
+ * Author: savop
+ *
+ * Created on 19. April 2009, 16:50
+ */
+
+#ifndef _CMENUSETUPUPNP_H
+#define _CMENUSETUPUPNP_H
+
+#include <vdr/plugin.h>
+#include "server.h"
+#include "config.h"
+
+/**
+ * The VDR setup page
+ *
+ * This class shows and manages the settings within the VDR setup OSD
+ *
+ */
+class cMenuSetupUPnP : public cMenuSetupPage {
+public:
+ cMenuSetupUPnP();
+// virtual ~cMenuSetupUPnP();
+ /**
+ * Processes a keystroke
+ *
+ * This processes a keystroke which is done by the user and updates the
+ * menu accordingly
+ *
+ * It returns the current state of the VDR after pressing a key
+ *
+ * @return The current state of the VDR
+ */
+ virtual eOSState ProcessKey(
+ eKeys Key ///< Key, pressed by the user
+ );
+protected:
+ /**
+ * Stores the setup information
+ *
+ * This stores the setup information in the configuration file
+ */
+ virtual void Store(void);
+ /**
+ * Update the menu
+ *
+ * This updates the menu osd and refreshes the screen.
+ */
+ void Update(void);
+ /**
+ * Loads the setup information
+ *
+ * This loads the setup information from the configuration file
+ */
+ void Load(void);
+private:
+ const char* const* getInterfaceList(int *count);
+ int getInterfaceIndex(const char* Interface);
+ const char* getInterface(int Index);
+ cOsdItem *mCtrlBind;
+ cOsdItem *mCtrlEnabled;
+ cOsdItem *mCtrlPort;
+ cOsdItem *mCtrlAutoMode;
+ cUPnPServer* mUpnpServer;
+ /**
+ * Is the server enabled or not
+ *
+ * The server can be switched on or off. If it is turned off, the server
+ * will close open transmissions and ports
+ *
+ */
+ int mEnable;
+ int mAutoSetup;
+ /**
+ * The port to listen to (Default: 0 autodetect)
+ *
+ * The port the server is bound to. The default setting is 0.
+ * So, the server will determine automatically a free random port between
+ * 49152 and 65535. If a server should use a specific port it can be set
+ * to one out of that range.
+ *
+ */
+ int mPort;
+ int mDetectPort;
+ /**
+ * The Interface the server is bound to
+ *
+ * If multiple interfaces exist the server can be bound to a specific
+ * one
+ *
+ */
+ int mInterfaceIndex;
+ /**
+ * The socket address of the server
+ *
+ * The IP address and the port of the server
+ */
+ char *mAddress;
+};
+
+#endif /* _CMENUSETUPUPNP_H */
+
diff --git a/inc/metadata.h b/inc/metadata.h
new file mode 100644
index 0000000..e6200e1
--- /dev/null
+++ b/inc/metadata.h
@@ -0,0 +1,189 @@
+/*
+ * File: metadata.h
+ * Author: savop
+ *
+ * Created on 28. Mai 2009, 21:14
+ */
+
+#ifndef _METADATA_H
+#define _METADATA_H
+
+#include <vdr/tools.h>
+#include <vdr/channels.h>
+#include <vdr/recording.h>
+#include "../common.h"
+#include "database.h"
+#include "object.h"
+#include "resources.h"
+
+/**
+ * The result set of a request
+ *
+ * This contains the results of a previous \e Browse or \e Search request.
+ */
+struct cUPnPResultSet {
+ int mNumberReturned; ///< The number of returned matches
+ int mTotalMatches; ///< The total amount of matches
+ const char* mResult; ///< The DIDL-Lite fragment
+};
+
+/**
+ * The media database
+ *
+ * This class is the global object manager. It holds every object in a local cache.
+ * Only this class is allowed to create new objects.
+ *
+ * @see cUPnPClassObject
+ */
+class cMediaDatabase : public cThread {
+ friend class cUPnPServer;
+ friend class cUPnPObjectMediator;
+private:
+ unsigned int mSystemUpdateID;
+ cUPnPObjectFactory* mFactory;
+ cHash<cUPnPClassObject>* mObjects;
+ cSQLiteDatabase* mDatabase;
+ cUPnPObjectID mLastInsertObjectID;
+ cUPnPObjectID getNextObjectID();
+ void cacheObject(cUPnPClassObject* Object);
+ int prepareDatabase();
+#ifndef WITHOUT_TV
+ int loadChannels();
+ void updateChannelEPG();
+#endif
+#ifndef WITHOUT_RECORDS
+ int loadRecordings();
+ void updateRecordings();
+#endif
+ bool init();
+ void updateSystemID();
+ virtual void Action();
+public:
+ /**
+ * Returns the SystemUpdateID
+ *
+ * This returns the \e SystemUpdateID. This changes whenever anything changed
+ * within the content directory. This value will be sent through the UPnP
+ * network every 2 seconds.
+ *
+ * @return the SystemUpdateID
+ */
+ unsigned int getSystemUpdateID();
+ /**
+ * Returns a CSV list with ContainerUpdateIDs
+ *
+ * This list contains an unordered list of ordered pairs of ContainerID and
+ * its ContainerUpdateID. It contains only recent changes which are not yet
+ * beeing evented. This means that evented updates will be removed from list.
+ *
+ * @return CSV list of ContainerUpdateIDs
+ */
+ const char* getContainerUpdateIDs();
+ /**
+ * Constructor
+ *
+ * This creates an instance of the media database.
+ */
+ cMediaDatabase();
+ virtual ~cMediaDatabase();
+ /**
+ * Add a Fastfind
+ *
+ * This creates a \e Fastfind entry. It is a string which can be used to
+ * relocate a objectID. Usually this is a file name or another ID with which
+ * the related object can be found.
+ *
+ * @return returns
+ * - \bc -1, if the creation was successful
+ * - \bc 0, otherwise
+ */
+ int addFastFind(
+ cUPnPClassObject* Object, ///< the object, which should be registered
+ const char* FastFind ///< the string with which the object shall be
+ ///< relocated
+ );
+ /**
+ * Finds a object by Fastfind
+ *
+ * This returns the object via the \e Fastfind string. The object must be
+ * previosly registered via \c cMediaDatabase::addFastFind().
+ *
+ * It tries to find the object in the internal object cache. If this fails,
+ * the object will be loaded from the database.
+ *
+ * @see cMediaDatabase::addFastFind
+ * @return The object associated with FastFind
+ */
+ cUPnPClassObject* getObjectByFastFind(
+ const char* FastFind ///< the string with which the object shall be
+ ///< relocated
+ );
+ /**
+ * Finds a object by its ObjectID
+ *
+ * This returns the object via its \e ObjectID.
+ *
+ * It tries to find the object in the internal object cache. If this fails,
+ * the object will be loaded from the database.
+ *
+ * @return The object associated with FastFind
+ */
+ cUPnPClassObject* getObjectByID(
+ cUPnPObjectID ID ///< The ObjectID of the requested object
+ );
+ /**
+ * Performs a browse on the database
+ *
+ * This performs a browse request on the database and returns a structure
+ * containing the matching count and DIDL-Lite fragement which is sent to
+ * the control point.
+ *
+ * @return returns an integer representing one of the following:
+ * - \bc UPNP_CDS_E_INVALID_SORT_CRITERIA, when the sort criteria is malformed
+ * - \bc UPNP_CDS_E_CANT_PROCESS_REQUEST, when there is an internal error while
+ * processing the request
+ * - \bc UPNP_CDS_E_NO_SUCH_OBJECT, when the requested ObjectID does not exist
+ * - \bc UPNP_SOAP_E_ACTION_FAILED, when the action failed due any reasons
+ * - \bc UPNP_E_SUCCESS, if the request was successful
+ */
+ int browse(
+ OUT cUPnPResultSet** Results, ///< the result of the request
+ IN const char* ID, ///< the objectID of the request
+ IN bool BrowseMetadata, ///< \b true to browse metadata, \b false otherwise
+ IN const char* Filter = "*", ///< the filter applied to the returned metadata
+ IN unsigned int Offset = 0, ///< the starting offset
+ IN unsigned int Count = 0, ///< maximum count returned
+ IN const char* SortCriteria = "" ///< sorts the results before returning them
+ );
+ /**
+ * Performs a search on the database
+ *
+ * This performs a search request on the database and returns a structure
+ * containing the matching count and DIDL-Lite fragement which is sent to
+ * the control point.
+ *
+ * @note
+ * The submitted ID must be a ContainerID. Searches are performed only
+ * in this container.
+ *
+ * @return returns an integer representing one of the following:
+ * - \bc UPNP_CDS_E_INVALID_SORT_CRITERIA, when the sort criteria is malformed
+ * - \bc UPNP_CDS_E_CANT_PROCESS_REQUEST, when there is an internal error while
+ * processing the request
+ * - \bc UPNP_CDS_E_NO_SUCH_OBJECT, when the requested ObjectID does not exist
+ * - \bc UPNP_SOAP_E_ACTION_FAILED, when the action failed due any reasons
+ * - \bc UPNP_E_SUCCESS, if the request was successful
+ */
+ int search(
+ OUT cUPnPResultSet** Results, ///< the result of the request
+ IN const char* ID, ///< the ContainerID
+ IN const char* Search, ///< the search string
+ IN const char* Filter = "*", ///< the filter applied to the returned metadata
+ IN unsigned int Offset = 0, ///< the starting offset
+ IN unsigned int Count = 0, ///< maximum count returned
+ IN const char* SortCriteria = "" ///< sorts the results before returning them
+ );
+};
+
+#endif /* _METADATA_H */
+
diff --git a/inc/object.h b/inc/object.h
new file mode 100644
index 0000000..bceb3f1
--- /dev/null
+++ b/inc/object.h
@@ -0,0 +1,1576 @@
+/*
+ * File: object.h
+ * Author: savop
+ *
+ * Created on 11. September 2009, 20:39
+ */
+
+#ifndef _OBJECT_H
+#define _OBJECT_H
+
+#include "database.h"
+#include "../common.h"
+#include "util.h"
+#include <string.h>
+#include <vdr/tools.h>
+#include <map>
+#include <vector>
+#include <upnp/ixml.h>
+
+/**
+ * UPnP Object ID
+ *
+ * This is a UPnP Object ID representation.
+ */
+struct cUPnPObjectID {
+ int _ID; ///< The UPnP Object ID
+ /**
+ * Constructor
+ *
+ * Creates invalid ID
+ */
+ cUPnPObjectID():_ID(-1){}
+ /**
+ * Constructor
+ *
+ * Creates from long integer
+ */
+ cUPnPObjectID(
+ long ID ///< new ID
+ ){ _ID = (int)ID; }
+ /**
+ * Constructor
+ *
+ * Creates from integer
+ */
+ cUPnPObjectID(
+ int ID ///< new ID
+ ){ _ID = ID; }
+ /** Set the object ID */
+ cUPnPObjectID &operator=(
+ long ID ///< new ID
+ ){ _ID = ID; return *this; }
+ /** @overload cUPnPObjectID &operator=(long ID) */
+ cUPnPObjectID &operator=(
+ int ID ///< new ID
+ ){ _ID = ID; return *this; }
+ /** @overload cUPnPObjectID &operator=(long ID) */
+ cUPnPObjectID &operator=(
+ const cUPnPObjectID& ID ///< new ID
+ ){ if(this != &ID){ _ID = ID._ID; } return *this; }
+ /** Pre increment the ID */
+ cUPnPObjectID &operator++(){ _ID++; return *this; }
+ /** Post increment the ID */
+ cUPnPObjectID operator++(int){ cUPnPObjectID old = *this; _ID++; return old; }
+ /** Post decrement the ID */
+ cUPnPObjectID operator--(int){ cUPnPObjectID old = *this; _ID--; return old; }
+ /** Pre decrement the ID */
+ cUPnPObjectID &operator--(){ _ID--; return *this; }
+ /** Not equal */
+ bool operator!=(
+ long ID ///< compare with this ID
+ ){ return _ID != ID; }
+ /** Equal */
+ bool operator==(
+ long ID ///< compare with this ID
+ ){ return _ID == ID; }
+ /** @overload bool operator!=(long ID) */
+ bool operator!=(
+ int ID ///< compare with this ID
+ ){ return _ID != ID; }
+ /** @overload bool operator==(long ID) */
+ bool operator==(
+ int ID ///< compare with this ID
+ ){ return _ID == ID; }
+ /** @overload bool operator!=(long ID) */
+ bool operator!=(
+ const cUPnPObjectID& ID ///< compare with this ID
+ ){ return *this == ID; }
+ /** @overload bool operator==(long ID) */
+ bool operator==(
+ const cUPnPObjectID& ID ///< compare with this ID
+ ){ return *this == ID; }
+ /** Casts to unsigned int */
+ operator unsigned int(){ return (unsigned int)_ID; }
+ /** Casts to int */
+ operator int(){ return _ID; }
+ /** Casts to long */
+ operator long(){ return (long)_ID; }
+ /** Casts to string */
+ const char* operator*(){ char* buf; return asprintf(&buf,"%d",_ID)?buf:NULL; }
+};
+
+/**
+ * Structure of a UPnP Class
+ *
+ * This represents a UPnP Class
+ */
+struct cClass {
+ cString ID; ///< The upnp class ID
+ bool includeDerived; ///< flag, to indicate if derived classes are allowed
+ /**
+ * Compares two classes
+ *
+ * @param cmp the other class to compare with
+ */
+ bool operator==(const cClass &cmp){ return (!strcasecmp(cmp.ID,ID) && includeDerived==cmp.includeDerived); }
+ /*! @copydoc operator==(const cClass &cmp) */
+ bool operator!=(const cClass &cmp){ return !(*this==cmp); }
+};
+
+class cUPnPClassObject;
+class cUPnPObjectMediator;
+class cUPnPContainerMediator;
+class cUPnPClassContainer;
+class cUPnPResource;
+
+/**
+ * List of UPnP Objects
+ *
+ * This is a cList of UPnP Objects
+ * The list can be sorted by using a specific property
+ */
+class cUPnPObjects : public cList<cUPnPClassObject> {
+public:
+ cUPnPObjects();
+ virtual ~cUPnPObjects();
+ /**
+ * Sorts the list
+ *
+ * This sorts the list by a specific property and a certain direction
+ */
+ void SortBy(
+ const char* Property, ///< the property used for sorting
+ bool Descending = false ///< the direction of the sort
+ );
+};
+
+/**
+ * The UPnP class Object
+ *
+ * This is a UPnP class Object representation with all its properties.
+ */
+class cUPnPClassObject : public cListObject {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPClassContainer;
+private:
+ cUPnPObjectID mLastID;
+ bool mDeleted; // is this Objected marked as deleted, NOT used yet.
+protected:
+ time_t mLastModified; ///< The last modification of this property
+ cUPnPObjectID mID; ///< The object ID
+ cUPnPClassObject* mParent; ///< The parent object
+ cString mClass; ///< Class (Who am I?)
+ cString mTitle; ///< Object title
+ cString mCreator; ///< Creator of this object
+ bool mRestricted; ///< Ability of changing metadata?
+ int mWriteStatus; ///< Ability of writing resources?
+ cList<cUPnPResource>* mResources; ///< The resources of this object
+ cHash<cUPnPResource>* mResourcesID; ///< The resources of this object as hashmap
+ IXML_Document* mDIDLFragment; ///< The DIDL fragment of the object
+ cString mSortCriteria; ///< The sort criteria to sort with
+ bool mSortDescending; ///< The direction of the sort
+ cUPnPClassObject();
+ /**
+ * Set the Object ID
+ *
+ * This is only allowed by mediators and the media database. Manually editing
+ * the object ID may result in unpredictable behavior.
+ *
+ * @param ID the ObjectID of this object
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ */
+ int setID(cUPnPObjectID ID);
+ /**
+ * Set the Parent Object
+ *
+ * This is only allowed by mediators and the media database. Manually editing
+ * the parent may result in unpredictable behavior.
+ *
+ * @param Parent the parent of this object
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ */
+ int setParent(cUPnPClassContainer* Parent);
+ /**
+ * Set the object class
+ *
+ * This is only allowed by mediators and the media database. Manually editing
+ * the object class may result in unpredictable behavior.
+ *
+ * @param Class the class of this object
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ */
+ int setClass(const char* Class);
+ /**
+ * Set the modification time
+ *
+ * This sets the last modification time to the current timestamp. This is
+ * used to indicate when the object was updated the last time.
+ */
+ void setModified(void){ this->mLastModified = time(NULL); }
+public:
+ /**
+ * Last modified
+ *
+ * Returns when the object was modified the last time.
+ *
+ * @return last modification timestamp
+ */
+ time_t modified() const { return this->mLastModified; }
+ virtual ~cUPnPClassObject();
+ /**
+ * Compares a object
+ *
+ * This compares a given object with this object
+ * It uses the SortCriteria to compare them.
+ *
+ * @return returns
+ * - \bc >0, if the object comes after this one
+ * - \bc 0, if the objects have the same property
+ * - \bc <0, if the object comes before this one
+ * @param ListObject the object to compare with
+ */
+ virtual int Compare(const cListObject& ListObject) const;
+ /**
+ * Get the properties of the object
+ *
+ * This returns a property list with all the properties which can be obtained
+ * or set with \c getProperty or \c setProperty.
+ *
+ * @return a stringlist with the properties
+ */
+ virtual cStringList* getPropertyList();
+ /**
+ * Gets a property
+ *
+ * Returns the value of a specified property. The value is converted into a
+ * string.
+ *
+ * @return returns
+ * - \bc true, if the property exists
+ * - \bc false, otherwise
+ * @param Property the property which should be returned
+ * @param Value the value of that property
+ */
+ virtual bool getProperty(const char* Property, char** Value) const ;
+ /**
+ * Sets a property
+ *
+ * Sets the value of a specified property. The value is converted from string
+ * into the propper data type
+ *
+ * @return returns
+ * - \bc true, if the property exists
+ * - \bc false, otherwise
+ * @param Property the property which should be set
+ * @param Value the value of that property
+ */
+ virtual bool setProperty(const char* Property, const char* Value);
+ /**
+ * Converts to container
+ *
+ * This will convert the object into a container if it is one. If not, it
+ * returns \bc NULL.
+ *
+ * @return returns
+ * - \bc NULL, if it is not a container
+ * - a container representation of this object
+ */
+ virtual cUPnPClassContainer* getContainer(){ return NULL; }
+ /**
+ * Create the DIDL fragment
+ *
+ * This creates the DIDL-Lite fragment of the object. The DIDL is written to the
+ * specified \em IXML document. The details of the output can be controlled via
+ * the filter stringlist
+ *
+ * @return the DIDL fragment of the object
+ * @param Document the IXML document where to write the contents
+ * @param Filter the string list with the filter criteria
+ */
+ virtual IXML_Node* createDIDLFragment(IXML_Document* Document, cStringList* Filter) = 0;
+ /**
+ * Is this a container?
+ *
+ * Returns if this object is a container or not
+ *
+ * @return returns
+ * - \bc true, if it is a container
+ * - \bc false, otherwise
+ */
+ bool isContainer(){ return this->getContainer()==NULL?false:true; }
+ /**
+ * Set the sort criteria
+ *
+ * This sets a certain criteria which the object can be compared with.
+ *
+ * @param Property the property to sort after
+ * @param Descending sort the objects in descending order
+ */
+ void setSortCriteria(const char* Property, bool Descending = false);
+ /**
+ * Clears the sort criteria
+ *
+ * Clears the property of the sort criteria and sets the descending flag to
+ * false.
+ */
+ void clearSortCriteria();
+ /******* Setter *******/
+ /**
+ * Set the title
+ *
+ * This sets the title of the object. It is a required metadata information.
+ * It must not be \bc NULL or an empty string.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Title the title of the object
+ */
+ int setTitle(const char* Title);
+ /**
+ * Set the creator
+ *
+ * The creator of an object is primarily the creator or owner of the object
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Creator the creator of the object
+ */
+ int setCreator(const char* Creator);
+ /**
+ * Set the restriction
+ *
+ * This sets the restriction flag. If the object is restricted, no modifications
+ * to its metadata by the user are allowed.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Restricted \bc true, to disallow modification, \bc false to allow it
+ */
+ int setRestricted(bool Restricted);
+ /**
+ * Set the write status
+ *
+ * This sets the write status of a resource. With this indicator, you can set
+ * the modifiabilty of resources by a control point.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Status the write status
+ */
+ int setWriteStatus(int Status);
+ /**
+ * Set the resources
+ *
+ * This sets the list of resources of an object. The list usally contain a
+ * single resource. However, multiple resources a also very common.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Resources the resource list of this object
+ */
+ int setResources(cList<cUPnPResource>* Resources);
+ /**
+ * Add resource to list
+ *
+ * This adds the specified resource to the resource list of the object
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Resource the resource to be added
+ */
+ int addResource(cUPnPResource* Resource);
+ /**
+ * Remove resource from list
+ *
+ * This removes the specified resource from the resource list of the object
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Resource the resource to be removed
+ */
+ int removeResource(cUPnPResource* Resource);
+ /******* Getter *******/
+ /**
+ * Get the object ID
+ *
+ * This returns the object ID of the object.
+ *
+ * @return the object ID
+ */
+ cUPnPObjectID getID() const { return this->mID; }
+ /**
+ * Get the parent ID
+ *
+ * This returns the ID of the parent container object, associated with this object.
+ * It is \bc -1, if the object is the root object.
+ *
+ * @return the parent ID
+ */
+ cUPnPObjectID getParentID() const { return this->mParent?this->mParent->getID():cUPnPObjectID(-1); }
+ /**
+ * Get the parent object
+ *
+ * This returns the parent container object, associated with this object. It is
+ * \bc NULL, if the object is the root object.
+ *
+ * @return the parent object
+ */
+ cUPnPClassContainer* getParent() const { return (cUPnPClassContainer*)this->mParent; }
+ /**
+ * Get the title
+ *
+ * This returns the title of the object. This may be the title of an item or
+ * the folder name in case of a container.
+ *
+ * @return the title of the object
+ */
+ const char* getTitle() const { return this->mTitle; }
+ /**
+ * Get the object class
+ *
+ * This returns the object class of the object. The classes are defined by
+ * the UPnP Working Committee. However, custom classes which are derived from
+ * a standardized class are also possible.
+ *
+ * @return the class of the object
+ */
+ const char* getClass() const { return this->mClass; }
+ /**
+ * Get the creator
+ *
+ * This returns the creator of the object. Usually, this is the primary
+ * content creator or the owner of the object
+ *
+ * @return the creator of the object
+ */
+ const char* getCreator() const { return this->mCreator; }
+ /**
+ * Is the resource restricted?
+ *
+ * Returns \bc true, if the object is restricted or \bc false, otherwise.
+ * When the object is restricted, then modifications to the metadata of the
+ * object are disallowed.
+ *
+ * @return returns
+ * - \bc true, if the object is restricted
+ * - \bc false, otherwise
+ */
+ bool isRestricted() const { return this->mRestricted; }
+ /**
+ * Get write status
+ *
+ * This returns the write status of the object. It gives information, if the
+ * resource is modifiable.
+ *
+ * @return the write status
+ */
+ int getWriteStatus() const { return this->mWriteStatus; }
+ /**
+ * Get a resource by its ID
+ *
+ * Returns the resource with the specified resource ID.
+ *
+ * @return the resource by ID
+ * @param ResourceID the resource ID of the demanded resource
+ */
+ cUPnPResource* getResource(unsigned int ResourceID) const { return this->mResourcesID->Get(ResourceID); }
+ /**
+ * Get the resources
+ *
+ * This returns a list with resources associated with this object.
+ *
+ * @return the resources of this object
+ */
+ cList<cUPnPResource>* getResources() const { return this->mResources; }
+};
+
+/**
+ * The UPnP class Item
+ *
+ * This is a UPnP class Item representation with all its properties.
+ */
+class cUPnPClassItem : public cUPnPClassObject {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPItemMediator;
+protected:
+// cUPnPObjectID mReferenceID;
+ cUPnPClassItem* mReference; ///< The reference item
+ /**
+ * Constructor of an item
+ *
+ * This creates a new instance of an item
+ */
+ cUPnPClassItem();
+public:
+ virtual ~cUPnPClassItem(){};
+ virtual cStringList* getPropertyList();
+ virtual IXML_Node* createDIDLFragment(IXML_Document* Document, cStringList* Filter);
+ virtual bool setProperty(const char* Property, const char* Value);
+ virtual bool getProperty(const char* Property, char** Value) const;
+ /******** Setter ********/
+ /**
+ * Set a reference item
+ *
+ * This sets a reference item. Its comparable with symlinks in *nix systems
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Reference the reference item
+ */
+ int setReference(cUPnPClassItem* Reference);
+ /******** Getter ********/
+ /**
+ * Get the referenced item
+ *
+ * This returns the referenced item of this item
+ *
+ * @return the referenced item
+ */
+ cUPnPClassItem* getReference() const { return this->mReference; }
+ /**
+ * Get the reference ID
+ *
+ * This returns the object ID of the referenced item or \b -1, if
+ * no reference exists.
+ *
+ * @return the reference ID
+ */
+ cUPnPObjectID getReferenceID() const { return this->mReference?this->mReference->getID():cUPnPObjectID(-1); }
+};
+
+typedef std::vector<cClass> tClassVector;
+
+/**
+ * The UPnP class Container
+ *
+ * This is a UPnP class Container representation with all its properties.
+ */
+class cUPnPClassContainer : public cUPnPClassObject {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPContainerMediator;
+protected:
+ cString mContainerType; ///< DLNA container type
+ tClassVector mSearchClasses; ///< Classes which are searchable
+ tClassVector mCreateClasses; ///< Classes which are creatable
+ bool mSearchable; ///< Is the Container searchable?
+ unsigned int mUpdateID; ///< The containerUpdateID
+ cUPnPObjects* mChildren; ///< List of children
+ cHash<cUPnPClassObject>* mChildrenID; ///< List of children as hash map
+ /**
+ * Update the container
+ *
+ * This performs an update, which acutally increases the containerUpdateID.
+ */
+ void update();
+ /**
+ * Sets the containerUpdateID
+ *
+ * This method should only be used when the containerUpdateID is loaded from
+ * the database.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param UID the containerUpdateID
+ */
+ int setUpdateID(unsigned int UID);
+ /**
+ * Constructor of a container
+ *
+ * This creates a new instance of a container
+ */
+ cUPnPClassContainer();
+public:
+ virtual ~cUPnPClassContainer();
+ virtual cStringList* getPropertyList();
+ virtual IXML_Node* createDIDLFragment(IXML_Document* Document, cStringList* Filter);
+ virtual bool setProperty(const char* Property, const char* Value);
+ virtual bool getProperty(const char* Property, char** Value) const;
+ virtual cUPnPClassContainer* getContainer(){ return this; }
+ /**
+ * Add a child
+ *
+ * This adds the specified child to this container. The parent container of the
+ * child will be set to this container.
+ *
+ * @param Object the child to be added
+ */
+ void addObject(cUPnPClassObject* Object);
+ /**
+ * Remove a child
+ *
+ * This removes the specified child from the list of children. The child will
+ * also loose its parent container, so that there is no link between left.
+ *
+ * @param Object the child to be removed
+ */
+ void removeObject(cUPnPClassObject* Object);
+ /**
+ * Get a child by ID
+ *
+ * Returns the child, which is specified by the \c ObjectID.
+ *
+ * @return the child with the specified ID
+ * @param ID the \c ObjectID of the child
+ */
+ cUPnPClassObject* getObject(cUPnPObjectID ID) const;
+ /**
+ * Get the list of children
+ *
+ * This returns a list of the children of the container.
+ *
+ * @return the list of children
+ */
+ cUPnPObjects* getObjectList() const { return this->mChildren; }
+ /**
+ * Add a search class
+ *
+ * This adds a search class to the search classes vector
+ *
+ * @return returns
+ * - \bc 0, if adding was successful
+ * - \bc <0, otherwise
+ * @param SearchClass the new class to be added
+ */
+ int addSearchClass(cClass SearchClass);
+ /**
+ * Remove a search class
+ *
+ * This removes a search class from the search classes vector
+ *
+ * @return returns
+ * - \bc 0, if deleting was successful
+ * - \bc <0, otherwise
+ * @param SearchClass the class to be deleted
+ */
+ int delSearchClass(cClass SearchClass);
+ /**
+ * Add a create class
+ *
+ * This adds a create class to the create classes vector
+ *
+ * @return returns
+ * - \bc 0, if adding was successful
+ * - \bc <0, otherwise
+ * @param CreateClass the new class to be added
+ */
+ int addCreateClass(cClass CreateClass);
+ /**
+ * Remove a create class
+ *
+ * This removes a create class from the create classes vector
+ *
+ * @return returns
+ * - \bc 0, if deleting was successful
+ * - \bc <0, otherwise
+ * @param CreateClass the class to be deleted
+ */
+ int delCreateClass(cClass CreateClass);
+ /******** Setter ********/
+ /**
+ * Set the DLNA container type
+ *
+ * This sets the DLNA container type. It must be a valid container type value.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Type the DLNA container type
+ */
+ int setContainerType(const char* Type);
+ /**
+ * Sets the search classes
+ *
+ * This sets the search classes, which allows the user to search only for
+ * these classes in the current container and its children. If the vector
+ * is empty the search can return any match. If the additional flag \bc
+ * derived is set, then also any derived classes are matched.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param SearchClasses a vector container the allowed search classes
+ */
+ int setSearchClasses(std::vector<cClass> SearchClasses);
+ /**
+ * Sets the create classes
+ *
+ * This sets the create classes, which allows the user to create new objects
+ * in this container, if \em restricted is \bc false.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param CreateClasses a vector containing the create classes
+ */
+ int setCreateClasses(std::vector<cClass> CreateClasses);
+ /**
+ * Sets the searchable flag
+ *
+ * This sets the searchable flag, which allows or disallows search on this
+ * container.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Searchable \bc true, to enable or \bc false, to disable searching
+ */
+ int setSearchable(bool Searchable);
+ /******** Getter ********/
+ /**
+ * Get the DLNA container type
+ *
+ * This returns the DLNA container type. Currently there are only these possible
+ * values beside \bc NULL:
+ * - \bc TUNER_1_0
+ *
+ * @return the DLNA container type
+ */
+ const char* getContainerType() const { return this->mContainerType; }
+ /**
+ * Get the search classes
+ *
+ * This returns a vector container all possible search classes. This are classes,
+ * which can be used for searching in this container.
+ *
+ * @return a vector with all search classes
+ */
+ const std::vector<cClass>* getSearchClasses() const { return &(this->mSearchClasses); }
+ /**
+ * Get the create classes
+ *
+ * This returns a vector containing all possible create classes. This are classes,
+ * which can be created in this container. For instance a TV container can only create
+ * items of the class VideoBroadcast. The vector is empty when creation of new items
+ * by the user is not allowed.
+ *
+ * @return a vector with create classes
+ */
+ const std::vector<cClass>* getCreateClasses() const { return &(this->mCreateClasses); }
+ /**
+ * Is this container searchable
+ *
+ * This returns \bc true, if the container can be search via \em Search or
+ * \bc false, otherwise.
+ *
+ * @return returns
+ * - \bc true, if the container is searchable
+ * - \bc false, otherwise
+ */
+ bool isSearchable() const { return this->mSearchable; }
+ /**
+ * Get the number of children
+ *
+ * This returns the total number of children of this container
+ *
+ * @return the number of childen
+ */
+ unsigned int getChildCount() const { return this->mChildren->Count(); }
+ /**
+ * Get the containerUpdateID
+ *
+ * This returns the containerUpdateID
+ *
+ * @return the containerUpdateID of this container
+ */
+ unsigned int getUpdateID() const { return this->mUpdateID; }
+ /**
+ * Has the container been updated?
+ *
+ * This returns \bc true, if the container was recently updated or
+ * \bc false, otherwise
+ *
+ * @return returns
+ * - \bc true, if the container was updated
+ * - \bc false, otherwise
+ */
+ bool isUpdated();
+};
+
+/**
+ * The UPnP class VideoItem
+ *
+ * This is a UPnP class VideoItem representation with all its properties.
+ */
+class cUPnPClassVideoItem : public cUPnPClassItem {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPVideoItemMediator;
+protected:
+ cString mGenre; ///< Genre of the video
+ cString mDescription; ///< Description
+ cString mLongDescription; ///< a longer description
+ cString mPublishers; ///< CSV of Publishers
+ cString mLanguage; ///< RFC 1766 Language code
+ cString mRelations; ///< Relation to other contents
+ cString mProducers; ///< CSV of Producers
+ cString mRating; ///< Rating (for parential control)
+ cString mActors; ///< CSV of Actors
+ cString mDirectors; ///< CSV of Directors
+ /**
+ * Constructor of a video item
+ *
+ * This creates a new instance of a video item
+ */
+ cUPnPClassVideoItem();
+public:
+ virtual ~cUPnPClassVideoItem();
+ //virtual cString createDIDLFragment(cStringList* Filter);
+ virtual cStringList* getPropertyList();
+ virtual bool setProperty(const char* Property, const char* Value);
+ virtual bool getProperty(const char* Property, char** Value) const;
+ /******** Setter ********/
+ /**
+ * Set a long description
+ *
+ * A long description may hold information about the content or the story
+ * of a video
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param LongDescription the content or story of a video
+ */
+ int setLongDescription(const char* LongDescription);
+ /**
+ * Set a description
+ *
+ * A description may hold short information about the content or the story
+ * of a video. Unlike a long description, this contains just a very short
+ * brief like a subtitle or the episode title.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Description the description of a video
+ */
+ int setDescription(const char* Description);
+ /**
+ * Set the publishers
+ *
+ * This is a CSV list of publishers, who distributes the video.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Publishers a CSV list of publishers
+ */
+ int setPublishers(const char* Publishers);
+ /**
+ * Set a genre
+ *
+ * This is a CSV list of genre of a video. This may be something like
+ * "Western" or "SciFi". Actually, there is no standardized rule for
+ * a genre name, which results in an ambiguous definition of certain
+ * genre, like Thriller and Horror.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Genre a CSV list of genre
+ */
+ int setGenre(const char* Genre);
+ /**
+ * Set the language
+ *
+ * This sets the language of a video. It is defined by RFC 1766.
+ * A valid language definition is \em "de-DE" or \em "en-US".
+ *
+ * @see http://www.ietf.org/rfc/rfc1766.txt
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Language the language (RFC 1766)
+ */
+ int setLanguage(const char* Language);
+ /**
+ * Sets a relation URL
+ *
+ * This sets a CSV list of relation URLs, where to find additional
+ * information about the movie. The URLs may not contain commas and they
+ * must be properly escaped as in RFC 2396
+ *
+ * @see http://www.ietf.org/rfc/rfc2396.txt
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Relations a CSV list with relations
+ */
+ int setRelations(const char* Relations);
+ /**
+ * Sets the directors
+ *
+ * This sets a CSV list of directors.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Directors a CSV list of directors
+ */
+ int setDirectors(const char* Directors);
+ /**
+ * Sets the actors
+ *
+ * This sets a CSV list of actors in a video. This usually contain the main actors.
+ * However, also other actors appearing in the video can be mentioned here.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Actors a CSV list of actors
+ */
+ int setActors(const char* Actors);
+ /**
+ * Sets the producers
+ *
+ * This sets a CSV list of producers of a video. These are the people who are
+ * involed in the production of a video
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Producers a CSV list of producers
+ */
+ int setProducers(const char* Producers);
+ /**
+ * Sets the rating
+ *
+ * This is a rating, which can be used for parential control issues.
+ *
+ * @see http://en.wikipedia.org/wiki/Motion_picture_rating_system
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Rating the rating of a video
+ */
+ int setRating(const char* Rating);
+ /******** Getter ********/
+ /**
+ * Get the genres
+ *
+ * This returns a CSV list of genre
+ *
+ * @return the genre of a video
+ */
+ const char* getGenre() const { return this->mGenre; }
+ /**
+ * Get the long description
+ *
+ * This returns the long description of a video
+ *
+ * @return the long description of a video
+ */
+ const char* getLongDescription() const { return this->mLongDescription; }
+ /**
+ * Get the description
+ *
+ * This returns the description of a video
+ *
+ * @return the description of a video
+ */
+ const char* getDescription() const { return this->mDescription; }
+ /**
+ * Get the publishers
+ *
+ * This returns a CSV list of publishers of the video
+ *
+ * @return a CSV list of publishers
+ */
+ const char* getPublishers() const { return this->mPublishers; }
+ /**
+ * Get the language
+ *
+ * This returns the language of the video
+ *
+ * @return the language
+ */
+ const char* getLanguage() const { return this->mLanguage; }
+ /**
+ * Get the relations
+ *
+ * This returns a CSV list of relation URLs.
+ *
+ * @return a CSV list of relation URLs
+ */
+ const char* getRelations() const { return this->mRelations; }
+ /**
+ * Get the actors
+ *
+ * This returns a CSV list of actors in the video
+ *
+ * @return a CSV list of actors
+ */
+ const char* getActors() const { return this->mActors; }
+ /**
+ * Get the producers
+ *
+ * This returns a CSV list of producers of a video
+ *
+ * @return a CSV list of producers
+ */
+ const char* getProducers() const { return this->mProducers; }
+ /**
+ * Get the directors
+ *
+ * This returns a CSV list of directors
+ *
+ * @return a CSV list of directors
+ */
+ const char* getDirectors() const { return this->mDirectors; }
+ /**
+ * Get the rating
+ *
+ * This returns the rating used for parental control.
+ *
+ * @return the rating of a video
+ */
+ const char* getRating() const { return this->mRating; }
+};
+
+/**
+ * The UPnP class Movie
+ *
+ * This is a UPnP class Movie representation with all its properties.
+ */
+class cUPnPClassMovie : public cUPnPClassVideoItem {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPMovieMediator;
+protected:
+ int mDVDRegionCode; ///< The Region code of the movie (0 - 8)
+ cString mStorageMedium; ///< The storage medium where the movie is stored
+ /**
+ * Constructor of a movie
+ *
+ * This creates a new instance of a movie
+ */
+ cUPnPClassMovie();
+public:
+ virtual ~cUPnPClassMovie();
+ //virtual cString createDIDLFragment(cStringList* Filter);
+ virtual cStringList* getPropertyList();
+ virtual bool setProperty(const char* Property, const char* Value);
+ virtual bool getProperty(const char* Property, char** Value) const;
+ /******** Setter ********/
+ /**
+ * Sets the DVD region code
+ *
+ * For more information on this, see http://en.wikipedia.org/wiki/DVD_region_code
+ *
+ * The integer representation for \em ALL is 9.
+ *
+ * @see http://en.wikipedia.org/wiki/DVD_region_code
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param RegionCode the region code of this movie
+ */
+ int setDVDRegionCode(int RegionCode);
+ /**
+ * Sets the storage medium
+ *
+ * This will set the storage medium, where the movie resides. Valid media
+ * are defined in \link common.h \endlink
+ *
+ * @see common.h
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param StorageMedium the medium where the movie is located
+ */
+ int setStorageMedium(const char* StorageMedium);
+ /******** Getter ********/
+ /**
+ * Get the DVD region code
+ *
+ * This returns the DVD region code. For more information,
+ * see http://en.wikipedia.org/wiki/DVD_region_code
+ *
+ * The integer representation for \em ALL is 9.
+ *
+ * @see http://en.wikipedia.org/wiki/DVD_region_code
+ * @return the DVD region code
+ */
+ int getDVDRegionCode() const { return this->mDVDRegionCode; }
+ /**
+ * Get the storage medium
+ *
+ * This returns the storage medium, where the movie resides.
+ *
+ * @return the storage medium
+ */
+ const char* getStorageMedium() const { return this->mStorageMedium; }
+};
+
+/**
+ * The UPnP class VideoBroadcast
+ *
+ * This is a UPnP class VideoBroadcast representation with all its properties.
+ */
+class cUPnPClassVideoBroadcast : public cUPnPClassVideoItem {
+ friend class cMediaDatabase;
+ friend class cUPnPObjectMediator;
+ friend class cUPnPVideoBroadcastMediator;
+protected:
+ cString mIcon; ///< The channel icon of the channel
+ cString mRegion; ///< The region where the channel can be received
+ int mChannelNr; ///< The channel number
+ cString mChannelName; ///< The channel name or provider name
+ /**
+ * Constructor of a video broadcast
+ *
+ * This creates a new instance of a video broadcast
+ */
+ cUPnPClassVideoBroadcast();
+public:
+ virtual ~cUPnPClassVideoBroadcast();
+ //virtual cString createDIDLFragment(cStringList* Filter);
+ virtual cStringList* getPropertyList();
+ virtual bool setProperty(const char* Property, const char* Value);
+ virtual bool getProperty(const char* Property, char** Value) const;
+ /******** Setter ********/
+ /**
+ * Set the channel icon
+ *
+ * This sets the channel icon of this channel. The resource must be a valid
+ * URI which can be obtained via the internal webserver
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param IconURI the URI to the icon file
+ */
+ int setIcon(const char* IconURI);
+ /**
+ * Set the channel region
+ *
+ * This sets the region of a channel, where it can be received
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param Region the location where the channel can be received
+ */
+ int setRegion(const char* Region);
+ /**
+ * Set channel number
+ *
+ * This sets the channel number, so that it can be used for directly navigation
+ * or channel up and down navigation respectively.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param ChannelNr the channel number
+ */
+ int setChannelNr(int ChannelNr);
+ /**
+ * Set the channel name
+ *
+ * This sets the channel name or the provider of the channel.
+ *
+ * @return returns
+ * - \bc 0, if setting was successful
+ * - \bc <0, otherwise
+ * @param ChannelName the channel name
+ */
+ int setChannelName(const char* ChannelName);
+ /******** Getter ********/
+ /**
+ * Get the channel icon
+ *
+ * This returns the channel icon of the channel.
+ *
+ * @return the channel icon
+ */
+ const char* getIcon() const { return this->mIcon; }
+ /**
+ * Get the region
+ *
+ * This returns the region, where the channel can be received
+ *
+ * @return the channel region
+ */
+ const char* getRegion() const { return this->mRegion; }
+ /**
+ * Get the channel number
+ *
+ * This returns the channel number
+ *
+ * @return the channel number
+ */
+ int getChannelNr() const { return this->mChannelNr; }
+ /**
+ * Get the channel name
+ *
+ * This returns the channel name or provider name respectively
+ *
+ * @return the channel name
+ */
+ const char* getChannelName() const { return this->mChannelName; }
+};
+
+/**
+ * Mediator interface
+ *
+ * This is an interface for mediators used to communicate with the database.
+ * A mediator is applied to get, create, save or delete an UPnP object.
+ */
+class cMediatorInterface {
+public:
+ virtual ~cMediatorInterface(){};
+ /**
+ * Creates an object
+ *
+ * This creates a new UPnP object with the specific title and the restriction.
+ *
+ * @return the newly created object
+ * @param Title the title of that object
+ * @param Restricted the restriction of the object
+ */
+ virtual cUPnPClassObject* createObject(const char* Title, bool Restricted) = 0;
+ /**
+ * Get an object
+ *
+ * Retrieves a UPnP object from the database and stores its information in the
+ * object. The object is obtained via its object ID.
+ *
+ * @return the object, found in the database
+ * @param ID the object ID
+ */
+ virtual cUPnPClassObject* getObject(cUPnPObjectID ID) = 0;
+ /**
+ * Saves the object
+ *
+ * This saves the object in the database by updating the values in the database
+ * with those in the object.
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param Object the object to be saved
+ */
+ virtual int saveObject(cUPnPClassObject* Object) = 0;
+ /**
+ * Deletes the object
+ *
+ * This deletes the object in the database by removing all its children and then
+ * deleting the contents from the database
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param Object the object to be deleted
+ */
+ virtual int deleteObject(cUPnPClassObject* Object) = 0;
+ /**
+ * Clears the object
+ *
+ * This clears the object, i.e. all its children will be removed and deleted
+ * from the database
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param Object the object to be cleared
+ */
+ virtual int clearObject(cUPnPClassObject* Object) = 0;
+};
+
+typedef std::map<const char*, cMediatorInterface*, strCmp> tMediatorMap;
+
+/**
+ * The object factory
+ *
+ * This factory can create, delete, clear or save UPnP objects. It uses mediators
+ * to communicate with the persistance database to load or persist the objects.
+ *
+ * If a new type of object shall be stored in the database an according mediator
+ * is needed, which knows the internal database structure. It must implement the
+ * cMediatorInterface class to work with this factory.
+ */
+class cUPnPObjectFactory {
+private:
+ static cUPnPObjectFactory* mInstance;
+ cSQLiteDatabase* mDatabase;
+ tMediatorMap mMediators;
+ cMediatorInterface* findMediatorByID(cUPnPObjectID ID);
+ cMediatorInterface* findMediatorByClass(const char* Class);
+ cUPnPObjectFactory();
+public:
+ /**
+ * Return the instance of the factory
+ *
+ * This returns the instance of the factory. When the media database is
+ * initialized successfully, it usally has all known mediators already
+ * registered.
+ *
+ * @return the instance of the factory
+ */
+ static cUPnPObjectFactory* getInstance();
+ /**
+ * Register a mediator
+ *
+ * This registers a new mediator by the associated class. The mediator
+ * must implement the cMediatorInterface class to be used with this
+ * factory.
+ *
+ * @param UPnPClass the class of which the mediator is associated to
+ * @param Mediator the mediator itself
+ */
+ void registerMediator(const char* UPnPClass, cMediatorInterface* Mediator);
+ /**
+ * Unregisters a mediator
+ *
+ * This unregisters a mediator if it is not needed anylonger. If the optional
+ * parameter \c freeMediator is set, the object instance will be free'd after
+ * removing it from the list.
+ *
+ * @param UPnPClass the class of the associated mediator
+ * @param freeMediator flag to indicate if the mediator shall be free'd after removing
+ */
+ void unregisterMediator(const char* UPnPClass, bool freeMediator=true);
+ /**
+ * @copydoc cMediatorInterface::createObject(const char* Title, bool Restricted)
+ *
+ * @param UPnPClass the class of the new object
+ */
+ cUPnPClassObject* createObject(const char* UPnPClass, const char* Title, bool Restricted=true);
+ /*! @copydoc cMediatorInterface::getObject(cUPnPObjectID ID) */
+ cUPnPClassObject* getObject(cUPnPObjectID ID);
+ /*! @copydoc cMediatorInterface::saveObject(cUPnPClassObject* Object) */
+ int saveObject(cUPnPClassObject* Object);
+ /*! @copydoc cMediatorInterface::deleteObject(cUPnPClassObject* Object) */
+ int deleteObject(cUPnPClassObject* Object);
+ /*! @copydoc cMediatorInterface::clearObject(cUPnPClassObject* Object) */
+ int clearObject(cUPnPClassObject* Object);
+};
+
+class cMediaDatabase;
+
+/**
+ * Object Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPObjectMediator : public cMediatorInterface {
+protected:
+ cSQLiteDatabase* mDatabase; ///< the SQLite 3 database wrapper
+ cMediaDatabase* mMediaDatabase; ///< the media database
+ /**
+ * Constructor of object mediator
+ *
+ * This constructs a new object mediator. This is actually not allowed because
+ * it is prohibited to create instances of the UPnP class Object
+ */
+ cUPnPObjectMediator(
+ cMediaDatabase* MediaDatabase ///< the media database
+ );
+ /**
+ * Initializes an object
+ *
+ * This initializes an object, which means, that it will be created in the database with
+ * the required details.
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ */
+ virtual int initializeObject(
+ cUPnPClassObject* Object, ///< the object to be initialized
+ const char* Class, ///< the class of the object
+ const char* Title, ///< the title of the object
+ bool Restricted ///< restriction of the object
+ );
+ /**
+ * Store the object in the database
+ *
+ * This stores the information of an object in the database
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param Object the object to be saved
+ */
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ /**
+ * Loads an object from database
+ *
+ * This loads an object from the database
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param Object the object to be loaded
+ * @param ID the object ID of that object
+ */
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ virtual ~cUPnPObjectMediator();
+ /*! @copydoc cMediatorInterface::createObject(const char* Title, bool Restricted) */
+ virtual cUPnPClassObject* createObject(const char* Title, bool Restricted);
+ /*! @copydoc cMediatorInterface::getObject(cUPnPObjectID ID) */
+ virtual cUPnPClassObject* getObject(cUPnPObjectID ID);
+ /*! @copydoc cMediatorInterface::saveObject(cUPnPClassObject* Object) */
+ virtual int saveObject(cUPnPClassObject* Object);
+ /*! @copydoc cMediatorInterface::deleteObject(cUPnPClassObject* Object) */
+ virtual int deleteObject(cUPnPClassObject* Object);
+ /*! @copydoc cMediatorInterface::clearObject(cUPnPClassObject* Object) */
+ virtual int clearObject(cUPnPClassObject* Object);
+};
+
+/**
+ * Item Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPItemMediator : public cUPnPObjectMediator {
+protected:
+ /*! @copydoc cUPnPObjectMediator::objectToDatabase(cUPnPClassObject* Object) */
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ /*! @copydoc cUPnPObjectMediator::databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID) */
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ /**
+ * Constructor of item mediator
+ *
+ * This creates a new item mediator with which it is possible to create new
+ * instances of Item objects.
+ *
+ * @param MediaDatabase the media database
+ */
+ cUPnPItemMediator(cMediaDatabase* MediaDatabase);
+ virtual ~cUPnPItemMediator(){};
+ /*! @copydoc cUPnPObjectMediator::createObject(const char* Title, bool Restricted) */
+ virtual cUPnPClassItem* createObject(const char* Title, bool Restricted);
+ /*! @copydoc cUPnPObjectMediator::getObject(cUPnPObjectID ID) */
+ virtual cUPnPClassItem* getObject(cUPnPObjectID ID);
+};
+
+/**
+ * VideoItem Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPVideoItemMediator : public cUPnPItemMediator {
+protected:
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ /**
+ * Constructor of videoitem mediator
+ *
+ * This creates a new videoitem mediator with which it is possible to create new
+ * instances of VideoItem objects.
+ *
+ * @param MediaDatabase the media database
+ */
+ cUPnPVideoItemMediator(cMediaDatabase* MediaDatabase);
+ virtual ~cUPnPVideoItemMediator(){};
+ virtual cUPnPClassVideoItem* createObject(const char* Title, bool Restricted);
+ virtual cUPnPClassVideoItem* getObject(cUPnPObjectID ID);
+};
+
+/**
+ * VideoBroadcast Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPVideoBroadcastMediator : public cUPnPVideoItemMediator {
+protected:
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ /**
+ * Constructor of video broadcast mediator
+ *
+ * This creates a new video broadcast mediator with which it is possible to create new
+ * instances of VideoBroadcast objects.
+ *
+ * @param MediaDatabase the media database
+ */
+ cUPnPVideoBroadcastMediator(cMediaDatabase* MediaDatabase);
+ virtual ~cUPnPVideoBroadcastMediator(){};
+ virtual cUPnPClassVideoBroadcast* createObject(const char* Title, bool Restricted);
+ virtual cUPnPClassVideoBroadcast* getObject(cUPnPObjectID ID);
+};
+
+/**
+ * Movie Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPMovieMediator : public cUPnPVideoItemMediator {
+protected:
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ /**
+ * Constructor of movie mediator
+ *
+ * This creates a new movie mediator with which it is possible to create new
+ * instances of Movie objects.
+ *
+ * @param MediaDatabase the media database
+ */
+ cUPnPMovieMediator(cMediaDatabase* MediaDatabase);
+ virtual ~cUPnPMovieMediator(){};
+ virtual cUPnPClassMovie* createObject(const char* Title, bool Restricted);
+ virtual cUPnPClassMovie* getObject(cUPnPObjectID ID);
+};
+
+/**
+ * Container Mediator
+ *
+ * This is the interface between the objects and the database. It is possible to
+ * create new objects, stores objects in the database as well as removing them from
+ * it.
+ */
+class cUPnPContainerMediator : public cUPnPObjectMediator {
+protected:
+ virtual int objectToDatabase(cUPnPClassObject* Object);
+ virtual int databaseToObject(cUPnPClassObject* Object, cUPnPObjectID ID);
+public:
+ /**
+ * Constructor of container mediator
+ *
+ * This creates a new container mediator with which it is possible to create new
+ * instances of Container objects.
+ *
+ * @param MediaDatabase the media database
+ */
+ cUPnPContainerMediator(cMediaDatabase* MediaDatabase);
+ virtual ~cUPnPContainerMediator(){};
+ virtual cUPnPClassContainer* createObject(const char* Title, bool Restricted);
+ virtual cUPnPClassContainer* getObject(cUPnPObjectID ID);
+};
+
+#endif /* _OBJECT_H */
+
diff --git a/inc/profiles.h b/inc/profiles.h
new file mode 100644
index 0000000..c50e4ee
--- /dev/null
+++ b/inc/profiles.h
@@ -0,0 +1,32 @@
+/*
+ * File: profiles.h
+ * Author: savop
+ *
+ * Created on 8. Dezember 2009, 12:45
+ */
+
+#ifndef _PROFILES_H
+#define _PROFILES_H
+
+#include "../common.h"
+
+#include "profiles/aac.h"
+#include "profiles/ac3.h"
+#include "profiles/amr.h"
+#include "profiles/atrac3plus.h"
+#include "profiles/jpeg.h"
+#include "profiles/lpcm.h"
+#include "profiles/mpa.h"
+#include "profiles/mpeg1.h"
+#include "profiles/mpeg2.h"
+#include "profiles/mpeg4_p2.h"
+#include "profiles/mpeg4_p10.h"
+#include "profiles/png.h"
+
+#ifdef WITH_WINDOWS_MEDIA
+ #include "profiles/wma.h"
+ #include "profiles/wmv9.h"
+#endif
+
+#endif /* _PROFILES_H */
+
diff --git a/inc/profiles/aac.h b/inc/profiles/aac.h
new file mode 100644
index 0000000..e3f4dab
--- /dev/null
+++ b/inc/profiles/aac.h
@@ -0,0 +1,36 @@
+/*
+ * File: profiles_aac.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:31
+ */
+
+#ifndef _PROFILES_AAC_H
+#define _PROFILES_AAC_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_AAC_ADTS; ///< AAC ADTS
+extern DLNAProfile DLNA_PROFILE_AAC_ADTS_320; ///< AAC ADTS
+extern DLNAProfile DLNA_PROFILE_AAC_ISO; ///< AAC ISO (iTunes)
+extern DLNAProfile DLNA_PROFILE_AAC_ISO_320; ///< AAC ISO
+extern DLNAProfile DLNA_PROFILE_AAC_LTP_ISO; ///< AAC LTP ISO
+extern DLNAProfile DLNA_PROFILE_AAC_LTP_MULT5_ISO; ///< AAC LTP Multi 5.1 ISO
+extern DLNAProfile DLNA_PROFILE_AAC_LTP_MULT7_ISO; ///< AAC LTP Multi 7.1 ISO
+extern DLNAProfile DLNA_PROFILE_AAC_MULT5_ADTS; ///< AAC Multi 5.1 ADTS
+extern DLNAProfile DLNA_PROFILE_AAC_MULT5_ISO; ///< AAC Multi 5.1 ISO
+
+extern DLNAProfile DLNA_PROFILE_HEAAC_L2_ADTS; ///< AAC Radio Broadcasts ADTS L2
+extern DLNAProfile DLNA_PROFILE_HEAAC_L2_ISO; ///< AAC Radio Broadcasts ISO L2
+extern DLNAProfile DLNA_PROFILE_HEAAC_L3_ADTS; ///< AAC Radio Broadcasts ADTS L3
+extern DLNAProfile DLNA_PROFILE_HEAAC_L3_ISO; ///< AAC Radio Broadcasts ISO L3
+extern DLNAProfile DLNA_PROFILE_HEAAC_MULT5_ADTS; ///< AAC Music Track 5.1 ADTS
+extern DLNAProfile DLNA_PROFILE_HEAAC_MULT5_ISO; ///< AAC Music Track 5.1 ISO
+extern DLNAProfile DLNA_PROFILE_HEAAC_L2_ADTS_320; ///< AAC Radio Broadcasts ADTS 320 L2
+extern DLNAProfile DLNA_PROFILE_HEAAC_L2_ISO_320; ///< AAC Radio Broadcasts ISO 320 L2
+
+extern DLNAProfile DLNA_PROFILE_BSAC_ISO; ///< BSAC ISO
+extern DLNAProfile DLNA_PROFILE_BSAC_MULT5_ISO; ///< BSAC ISO 5.1
+
+#endif /* _PROFILES_AAC_H */
+
diff --git a/inc/profiles/ac3.h b/inc/profiles/ac3.h
new file mode 100644
index 0000000..1d1ccf2
--- /dev/null
+++ b/inc/profiles/ac3.h
@@ -0,0 +1,24 @@
+/*
+ * File: profiles_ac3.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:04
+ */
+
+#ifndef _PROFILES_AC3_H
+#define _PROFILES_AC3_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_AC3; ///< DLNA AC3
+
+class cAC3Profiler : public cDLNAProfiler, public cAudioProfiler {
+public:
+ virtual DLNAProfile* probeDLNAProfile(AVFormatContext* FormatCtx);
+ virtual AudioPortionProfile probeAudioProfile(AVFormatContext* FormatCtx);
+};
+
+extern cAC3Profiler AC3Profiler;
+
+#endif /* _PROFILES_AC3_H */
+
diff --git a/inc/profiles/amr.h b/inc/profiles/amr.h
new file mode 100644
index 0000000..73cc9ee
--- /dev/null
+++ b/inc/profiles/amr.h
@@ -0,0 +1,17 @@
+/*
+ * File: profiles_amr.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:05
+ */
+
+#ifndef _PROFILES_AMR_H
+#define _PROFILES_AMR_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_AMR_3GPP; ///< AMR 3GPP, cell phones
+extern DLNAProfile DLNA_PROFILE_AMR_WBPlus; ///< AMR WB+
+
+#endif /* _PROFILES_AMR_H */
+
diff --git a/inc/profiles/atrac3plus.h b/inc/profiles/atrac3plus.h
new file mode 100644
index 0000000..64f7c15
--- /dev/null
+++ b/inc/profiles/atrac3plus.h
@@ -0,0 +1,16 @@
+/*
+ * File: profiles_atrac3plus.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:06
+ */
+
+#ifndef _PROFILES_ATRAC3PLUS_H
+#define _PROFILES_ATRAC3PLUS_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_ATRAC3Plus; ///< Atrac 3+
+
+#endif /* _PROFILES_ATRAC3PLUS_H */
+
diff --git a/inc/profiles/container.h b/inc/profiles/container.h
new file mode 100644
index 0000000..26cec8e
--- /dev/null
+++ b/inc/profiles/container.h
@@ -0,0 +1,47 @@
+/*
+ * File: container.h
+ * Author: savop
+ *
+ * Created on 8. Januar 2010, 10:45
+ */
+
+#ifndef _CONTAINER_H
+#define _CONTAINER_H
+
+#include "profile_data.h"
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+
+class cContainerDetector {
+public:
+ static VideoContainerProfile detect(AVFormatContext* Ctx);
+private:
+ /**
+ * MPEG1
+ */
+ static VideoContainerProfile detectMPEG1Container(AVFormatContext* Ctx);
+ /**
+ * MPEG2-PS
+ * MPEG2-TS
+ * MPEG2-TS-DLNA
+ * MPEG2-TS-DLNA-T
+ */
+ static VideoContainerProfile detectMPEG2Container(AVFormatContext* Ctx);
+ /**
+ * 3GPP
+ * MP4
+ */
+ static VideoContainerProfile detectMP4Container(AVFormatContext* Ctx);
+#ifdef WITH_WINDOWS_MEDIA
+ /**
+ * ASF
+ */
+ static VideoContainerProfile detectWMFContainer(AVFormatContext* Ctx);
+#endif
+};
+
+#endif /* _CONTAINER_H */
+
diff --git a/inc/profiles/jpeg.h b/inc/profiles/jpeg.h
new file mode 100644
index 0000000..42d2420
--- /dev/null
+++ b/inc/profiles/jpeg.h
@@ -0,0 +1,24 @@
+/*
+ * File: profiles_jpeg.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 12:59
+ */
+
+#ifndef _PROFILES_JPEG_H
+#define _PROFILES_JPEG_H
+
+#include "profile_data.h"
+
+/* Images */
+extern DLNAProfile DLNA_PROFILE_JPEG_SM; ///< JPEG small resolution
+extern DLNAProfile DLNA_PROFILE_JPEG_MED; ///< JPEG medium resolution
+extern DLNAProfile DLNA_PROFILE_JPEG_LRG; ///< JPEG high resolution
+
+/* Icons */
+extern DLNAIconProfile DLNA_ICON_JEPG_TN; ///< DLNA jpeg thumbnail profile of images
+extern DLNAIconProfile DLNA_ICON_JPEG_SM_24; ///< DLNA icon profile of small jpeg images
+extern DLNAIconProfile DLNA_ICON_JPEG_LRG_24; ///< DLNA icon profile of large jpeg images
+
+#endif /* _PROFILES_JPEG_H */
+
diff --git a/inc/profiles/lpcm.h b/inc/profiles/lpcm.h
new file mode 100644
index 0000000..0643b77
--- /dev/null
+++ b/inc/profiles/lpcm.h
@@ -0,0 +1,16 @@
+/*
+ * File: profiles_lpcm.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:07
+ */
+
+#ifndef _PROFILES_LPCM_H
+#define _PROFILES_LPCM_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_LPCM; ///< LPCM Audio
+
+#endif /* _PROFILES_LPCM_H */
+
diff --git a/inc/profiles/mpa.h b/inc/profiles/mpa.h
new file mode 100644
index 0000000..9110bc0
--- /dev/null
+++ b/inc/profiles/mpa.h
@@ -0,0 +1,25 @@
+/*
+ * File: profiles_mp3.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:08
+ */
+
+#ifndef _PROFILES_MP3_H
+#define _PROFILES_MP3_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_MP3; ///< DLNA MP3
+extern DLNAProfile DLNA_PROFILE_MP3X; ///< MP3x
+
+class cMPEGAudioProfiler : public cDLNAProfiler, public cAudioProfiler {
+public:
+ virtual AudioPortionProfile probeAudioProfile(AVFormatContext* FormatCtx);
+ virtual DLNAProfile* probeDLNAProfile(AVFormatContext* FormatCtx);
+};
+
+extern cMPEGAudioProfiler MPEGAudioProfiler;
+
+#endif /* _PROFILES_MP3_H */
+
diff --git a/inc/profiles/mpeg1.h b/inc/profiles/mpeg1.h
new file mode 100644
index 0000000..7e7637e
--- /dev/null
+++ b/inc/profiles/mpeg1.h
@@ -0,0 +1,16 @@
+/*
+ * File: profiles_mpeg1.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:34
+ */
+
+#ifndef _PROFILES_MPEG1_H
+#define _PROFILES_MPEG1_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_MPEG1; ///< MPEG 1
+
+#endif /* _PROFILES_MPEG1_H */
+
diff --git a/inc/profiles/mpeg2.h b/inc/profiles/mpeg2.h
new file mode 100644
index 0000000..6abbbb5
--- /dev/null
+++ b/inc/profiles/mpeg2.h
@@ -0,0 +1,68 @@
+/*
+ * File: profiles_mpeg2.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:35
+ */
+
+#ifndef _PROFILES_MPEG2_H
+#define _PROFILES_MPEG2_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_MPEG_PS_NTSC; ///< MPEG 2 PS NTSC
+extern DLNAProfile DLNA_PROFILE_MPEG_PS_NTSC_XAC3; ///< MPEG 2 PS NTSC AC3
+extern DLNAProfile DLNA_PROFILE_MPEG_PS_PAL; ///< MPEG 2 PS PAL
+extern DLNAProfile DLNA_PROFILE_MPEG_PS_PAL_XAC3; ///< MPEG 2 PS PAL AC3
+
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA; ///< MPEG 2 TS North America
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA_T; ///< MPEG 2 TS North America with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA_ISO; ///< MPEG 2 TS North America without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA; ///< MPEG 2 TS North America HD
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA_T; ///< MPEG 2 TS North America with time stamp HD
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA_ISO; ///< MPEG 2 TS North America without time stamp HD
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA_XAC3; ///< MPEG 2 TS North America AC3
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA_XAC3_T; ///< MPEG 2 TS North America AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_NA_XAC3_ISO; ///< MPEG 2 TS North America AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA_XAC3; ///< MPEG 2 TS North America AC3 HD
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA_XAC3_T; ///< MPEG 2 TS North America AC3 with time stamp HD
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_NA_XAC3_ISO; ///< MPEG 2 TS North America AC3 without time stamp HD
+
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_EU; ///< MPEG 2 TS Europe
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_EU_T; ///< MPEG 2 TS Europe with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_EU_ISO; ///< MPEG 2 TS Europe without time stamp
+
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO; ///< MPEG 2 TS Korea
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO_T; ///< MPEG 2 TS Korea with time stamp
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO_ISO; ///< MPEG 2 TS Korea without time stamp
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO; ///< MPEG 2 TS Korea HD
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO_T; ///< MPEG 2 TS Korea with time stamp HD
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO_ISO; ///< MPEG 2 TS Korea without time stamp HD
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO_XAC3; ///< MPEG 2 TS Korea AC3
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO_XAC3_T; ///< MPEG 2 TS Korea AC3 with time stamp
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_SD_KO_XAC3_ISO; ///< MPEG 2 TS Korea AC3 without time stamp
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO_XAC3; ///< MPEG 2 TS Korea AC3 HD
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO_XAC3_T; ///< MPEG 2 TS Korea AC3 with time stamp HD
+//extern DLNAProfile DLNA_PROFILE_MPEG_TS_HD_KO_XAC3_ISO; ///< MPEG 2 TS Korea AC3 without time stamp HD
+
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_MP_LL_AAC; ///< Low Level with AAC Audio
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_MP_LL_AAC_T; ///< Low level with AAC Audio with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG_TS_MP_LL_AAC_ISO; ///< Low level with AAC Audio without time stamp
+
+//extern DLNAProfile DLNA_PROFILE_MPEG_ES_PAL; ///< PAL ES over RTP
+//extern DLNAProfile DLNA_PROFILE_MPEG_ES_NTSC; ///< NTSC ES over RTP
+//extern DLNAProfile DLNA_PROFILE_MPEG_ES_PAL_XAC3; ///< PAL AC3 ES over RTP
+//extern DLNAProfile DLNA_PROFILE_MPEG_ES_NTSC_XAC3; ///< NTSC AC3 ES over RTP
+
+class cMPEG2Profiler : public cDLNAProfiler, public cVideoProfiler, public cAudioProfiler {
+public:
+ virtual VideoContainerProfile probeContainerProfile(AVFormatContext* FormatCtx);
+ virtual VideoPortionProfile probeVideoProfile(AVFormatContext* FormatCtx);
+ virtual AudioPortionProfile probeAudioProfile(AVFormatContext* FormatCtx);
+ virtual DLNAProfile* probeDLNAProfile(AVFormatContext* FormatCtx);
+};
+
+extern cMPEG2Profiler MPEG2Profiler;
+
+#endif /* _PROFILES_MPEG2_H */
+
diff --git a/inc/profiles/mpeg4_p10.h b/inc/profiles/mpeg4_p10.h
new file mode 100644
index 0000000..f58ac43
--- /dev/null
+++ b/inc/profiles/mpeg4_p10.h
@@ -0,0 +1,153 @@
+/*
+ * File: profiles_mpeg4_p10.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:38
+ */
+
+#ifndef _PROFILES_MPEG4_P10_H
+#define _PROFILES_MPEG4_P10_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_MULT5; ///< AVC main profile AAC 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_MULT5_T; ///< AVC main profile AAC 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_MULT5_ISO; ///< AVC main profile AAC 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_HEAAC_L2; ///< AVC main profile HEAAC L2
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_HEAAC_L2_T; ///< AVC main profile HEAAC L2 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_HEAAC_L2_ISO; ///< AVC main profile HEAAC L2 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_MPEG1_L3; ///< AVC main profile MP3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_MPEG1_L3_T; ///< AVC main profile MP3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_MPEG1_L3_ISO; ///< AVC main profile MP3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AC3; ///< AVC main profile AC3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AC3_T; ///< AVC main profile AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AC3_ISO; ///< AVC main profile AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP; ///< AVC main profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_T; ///< AVC main profile AAC LTP with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_ISO; ///< AVC main profile AAC LTP without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT5; ///< AVC main profile AAC LTP 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT5_T; ///< AVC main profile AAC LTP 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT5_ISO; ///< AVC main profile AAC LTP 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT7; ///< AVC main profile AAC LTP 7.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT7_T; ///< AVC main profile AAC LTP 7.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_AAC_LTP_MULT7_ISO; ///< AVC main profile AAC LTP 7.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_BSAC; ///< AVC main profile BSAC
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_BSAC_T; ///< AVC main profile BSAC with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_SD_BSAC_ISO; ///< AVC main profile BSAC without time stamp
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_AAC_MULT5; ///< AVC main profile MP4 AAC 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_HEAAC_L2; ///< AVC main profile MP4 HEAAC L2
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_MPEG1_L3; ///< AVC main profile MP4 MP3
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_AC3; ///< AVC main profile MP4 AC3
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_AAC_LTP; ///< AVC main profile MP4 AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_AAC_LTP_MULT5; ///< AVC main profile MP4 AAC LTP 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_AAC_LTP_MULT7; ///< AVC main profile MP4 AAC LTP 7.1
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_ATRAC3plus; ///< AVC main profile MP4 ATRAC3+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_MP_SD_BSAC; ///< AVC main profile MP4 BSAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BP_L3L_SD_AAC; ///< AVC baseline profile MP4 AAC
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BP_L3L_SD_HEAAC; ///< AVC baseline profile MP4 HEAAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BP_L3_SD_AAC; ///< AVC baseline profile standard MP4 AAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_MULT5; ///< AVC CIF30 baseline profile AAC 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_MULT5_T; ///< AVC CIF30 baseline profile AAC 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_MULT5_ISO; ///< AVC CIF30 baseline profile AAC 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_HEAAC_L2; ///< AVC CIF30 baseline profile HEAAC L2
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_HEAAC_L2_T; ///< AVC CIF30 baseline profile HEAAC L2 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_HEAAC_L2_ISO; ///< AVC CIF30 baseline profile HEAAC L2 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_MPEG1_L3; ///< AVC CIF30 baseline profile MP3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_MPEG1_L3_T; ///< AVC CIF30 baseline profile MP3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_MPEG1_L3_ISO; ///< AVC CIF30 baseline profile MP3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AC3; ///< AVC CIF30 baseline profile AC3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AC3_T; ///< AVC CIF30 baseline profile AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AC3_ISO; ///< AVC CIF30 baseline profile AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP; ///< AVC CIF30 baseline profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP_T; ///< AVC CIF30 baseline profile AAC LTP with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP_ISO; ///< AVC CIF30 baseline profile AAC LTP without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP_MULT5; ///< AVC CIF30 baseline profile AAC LTP 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP_MULT5_T; ///< AVC CIF30 baseline profile AAC LTP 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_LTP_MULT5_ISO; ///< AVC CIF30 baseline profile AAC LTP 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_940; ///< AVC CIF30 baseline profile AAC 940
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_940_T; ///< AVC CIF30 baseline profile AAC 940 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF30_AAC_940_ISO; ///< AVC CIF30 baseline profile AAC 940 without time stamp
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_AAC_MULT5; ///< AVC CIF30 baseline profile MP4 AAC 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_HEAAC_L2; ///< AVC CIF30 baseline profile MP4 HEAAC L2
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_MPEG1_L3; ///< AVC CIF30 baseline profile MP4 MP3
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_AC3; ///< AVC CIF30 baseline profile MP4 AC3
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_AAC_LTP; ///< AVC CIF30 baseline profile MP4 AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_AAC_LTP_MULT5; ///< AVC CIF30 baseline profile MP4 AAC LTP 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_BSAC; ///< AVC CIF30 baseline profile BSAC
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF30_BSAC_MULT5; ///< AVC CIF30 baseline profile BSAC 5.1
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_L2_CIF30_AAC; ///< AVC CIF30 baseline profile L2 AAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_HEAAC; ///< AVC CIF15 baseline profile HEAAC
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_AMR; ///< AVC CIF15 baseline profile AMR
+
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_MULT5; ///< AVC main profile AAC 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_MULT5_T; ///< AVC main profile AAC 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_MULT5_ISO; ///< AVC main profile AAC 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_HEAAC_L2; ///< AVC main profile HEAAC L2
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_HEAAC_L2_T; ///< AVC main profile HEAAC L2 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_HEAAC_L2_ISO; ///< AVC main profile HEAAC L2 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_MPEG1_L3; ///< AVC main profile MP3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_MPEG1_L3_T; ///< AVC main profile MP3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_MPEG1_L3_ISO; ///< AVC main profile MP3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AC3; ///< AVC main profile AC3
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AC3_T; ///< AVC main profile AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AC3_ISO; ///< AVC main profile AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC; ///< AVC main profile AAC
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_T; ///< AVC main profile AAC with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_ISO; ///< AVC main profile AAC without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP; ///< AVC main profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_T; ///< AVC main profile AAC LTP with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_ISO; ///< AVC main profile AAC LTP without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT5; ///< AVC main profile AAC LTP 5.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT5_T; ///< AVC main profile AAC LTP 5.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT5_ISO; ///< AVC main prpfile AAC LTP 5.1 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT7; ///< AVC main profile AAC LTP 7.1
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT7_T; ///< AVC main profile AAC LTP 7.1 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_MP_HD_AAC_LTP_MULT7_ISO; ///< AVC main prpfile AAC LTP 7.1 without time stamp
+
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC; ///< AVC baseline profile AAC
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_T; ///< AVC baseline profile AAC with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_ISO; ///< AVC baseline profile AAC without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_540; ///< AVC baseline profile AAC 540
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_540_T; ///< AVC baseline profile AAC 540 with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_540_ISO; ///< AVC baseline profile AAC 540 without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_LTP; ///< AVC baseline profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_LTP_T; ///< AVC baseline profile AAC LTP with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_AAC_LTP_IS0; ///< AVC baseline profile AAC LTP without time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_BSAC; ///< AVC baseline profile BSAC
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_BSAC_T; ///< AVC baseline profile BSAC with time stamp
+extern DLNAProfile DLNA_PROFILE_AVC_TS_BL_CIF15_BSAC_ISO; ///< AVC baseline profile BSAC without time stamp
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_AAC; ///< AVC baseline profile AAC
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_AAC_520; ///< AVC baseline profile AAC 520
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_AAC_LTP; ///< AVC baseline profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_AAC_LTP_520; ///< AVC baseline profile AAC LTP 520
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_CIF15_BSAC; ///< AVC baseline profile BSAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_L12_CIF15_HEAAC; ///< AVC baseline profile HEAAC
+
+extern DLNAProfile DLNA_PROFILE_AVC_MP4_BL_L1B_QCIF15_HEAAC; ///< AVC baseline profile QCIF15
+
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_CIF30_AMR_WBplus; ///< AVC 3GPP baseline profile CIF30 AMR WB+
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_CIF15_AMR_WBplus; ///< AVC 3GPP baseline profile CIF15 AMR WB+
+
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_QCIF15_AAC; ///< AVC 3GPP baseline profile QCIF15 AAC
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_QCIF15_AAC_LTP; ///< AVC 3GPP baseline profile QCIF15 AAC LTP
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_QCIF15_HEAAC; ///< AVC 3GPP baseline profile QCIF15 HEAAC
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_QCIF15_AMR_WBplus; ///< AVC 3GPP baseline profile QCIF15 AMR WB+
+extern DLNAProfile DLNA_PROFILE_AVC_3GPP_BL_QCIF15_AMR; ///< AVC 3GPP baseline profile QCIF15 AMR
+
+extern DLNAProfile DLNA_PROFILE_AVC_TS_HD_EU; ///< DLNA Profile for HD DVB Television broadcasts
+extern DLNAProfile DLNA_PROFILE_AVC_TS_HD_EU_T;
+extern DLNAProfile DLNA_PROFILE_AVC_TS_HD_EU_ISO; ///< DLNA Profile for HD DVB Television broadcasts without timestamp
+
+extern DLNAVideoMapping MPEG4_P10_VIDEO_MAP[];
+
+#endif /* _PROFILES_MPEG4_P10_H */
+
diff --git a/inc/profiles/mpeg4_p2.h b/inc/profiles/mpeg4_p2.h
new file mode 100644
index 0000000..7437afd
--- /dev/null
+++ b/inc/profiles/mpeg4_p2.h
@@ -0,0 +1,80 @@
+/*
+ * File: profiles_mpeg4_p2.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:36
+ */
+
+#ifndef _PROFILES_MPEG4_P2_H
+#define _PROFILES_MPEG4_P2_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_AAC; ///< MPEG 4 Part 2 Simple Profile AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_HEAAC; ///< MPEG 4 Part 2 Simple Profile HEAAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_ATRAC3plus; ///< MPEG 4 Part 2 Simple Profile ATRAC3+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_AAC_LTP; ///< MPEG 4 Part 2 Simple Profile AAC LTP
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_L2_AAC; ///< MPEG 4 Part 2 Simple Profile L2 AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_L2_AMR; ///< MPEG 4 Part 2 Simple Profile L2 AMR
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_VGA_AAC; ///< MPEG 4 Part 2 Simple Profile MP4 VGA AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_SP_VGA_HEAAC; ///< MPEG 4 Part 2 Simple Profile MP4 VGA HEAAC
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_AAC; ///< MPEG 4 Part 2 Advanced Simple Profile AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_HEAAC; ///< MPEG 4 Part 2 Advanded Simple Profile HEAAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_HEAAC_MULT5; ///< MPEG 4 Part 2 Advanced Simple Profile HEAAC 5.1
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_ATRAC3plus; ///< MPEG 4 Part 2 Advanced Simple Profile Atrac3+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L5_SO_AAC; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L5_SO_HEAAC; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 HEAAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L5_SO_HEAAC_MULT5; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 HEAAC 5.1
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L5_SO_G726; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 G726
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L4_SO_AAC; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L4_SO_HEAAC; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 HEAAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L4_SO_HEAAC_MULT5; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 HEAAC 5.1
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_MP4_ASP_L4_SO_G726; ///< MPEG 4 Part 2 Advanced Simple Profile Simple Object < Level 5 G726
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AAC; ///< MPEG 4 Part 2 Simple Profile AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AAC_T; ///< MPEG 4 Part 2 Simple Profile AAC with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AAC_ISO; ///< MPEG 4 Part 2 Simple Profile AAC without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG1_L3; ///< MPEG 4 Part 2 Simple Profile MP3
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG1_L3_T; ///< MPEG 4 Part 2 Simple Profile MP3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG1_L3_ISO; ///< MPEG 4 Part 2 Simple Profile MP3 without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AC3; ///< MPEG 4 Part 2 Simple Profile AC3
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AC3_T; ///< MPEG 4 Part 2 Simple Profile AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_AC3_ISO; ///< MPEG 4 Part 2 Simple Profile AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG2_L2; ///< MPEG 4 Part 2 Simple Profile MP2 1/2
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG2_L2_T; ///< MPEG 4 Part 2 Simple Profile MP2 1/2 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_SP_MPEG2_L2_IS0; ///< MPEG 4 Part 2 Simple Profile MP2 1/2 without time stamp
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_AC3; ///< MPEG 4 Part 2 Core AC3
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_AC3_T; ///< MPEG 4 Part 2 Core AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_AC3_ISO; ///< MPEG 4 Part 2 Core AC3 without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_MPEG2_L2; ///< MPEG 4 Part 2 Core MPEG 2 1/2
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_MPEG2_L2_T; ///< MPEG 4 Part 2 Core MPEG 2 1/2 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_CO_MPEG2_L2_ISO; ///< MPEG 4 Part 2 Core MPEG 2 1/2 without time stamp
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AAC; ///< MPEG 4 Part 2 Advanced Simple Profile AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AAC_T; ///< MPEG 4 Part 2 Advanced Simple Profile AAC with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AAC_ISO; ///< MPEG 4 Part 2 Advanced Simple Profile AAC without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_MPEG1_L3; ///< MPEG 4 Part 2 Advanced Simple Profile MP3
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_MPEG1_L3_T; ///< MPEG 4 Part 2 Advanced Simple Profile MP3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_MPEG1_L3_ISO; ///< MPEG 4 Part 2 Advanced Simple Profile MP3 without time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AC3; ///< MPEG 4 Part 2 Advanced Simple Profile AC3
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AC3_T; ///< MPEG 4 Part 2 Advanced Simple Profile AC3 with time stamp
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_TS_ASP_AC3_ISO; ///< MPEG 4 Part 2 Advanced Simple Profile AC3 without time stamp
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_ASF_SP_G726; ///< ASF Simple Profile G726
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_ASF_ASP_L5_SO_G726; ///< ASF Advanced Simple Prpfile G726 < Level 5
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_ASF_ASP_L4_SO_G726; ///< ASF Advanced Simple Prpfile G726 < Level 4
+
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_H263_MP4_P0_L10_AAC; ///< H263 Profile 0 Level 10 AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_H263_MP4_P0_L10_AAC_LTP; ///< H263 Profile 0 Level 10 AAC LTP
+extern DLNAProfile DLNA_PROFILE_MPEG4_H263_3GPP_P0_L10_AMR_WBplus; ///< H263 3GPP Profile 0 Level 10 AMR-WB+
+extern DLNAProfile DLNA_PROFILE_MPEG4_H263_3GPP_P3_L10_AMR; ///< H263 Profile 3 Level 10 AMR
+
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_3GPP_SP_L0B_AAC; ///< MPEG 4 Part 2 3GPP Simple Profile Level 0b AAC
+extern DLNAProfile DLNA_PROFILE_MPEG4_P2_3GPP_SP_L0B_AMR; ///< MPEG 4 Part 2 3GPP Simple Profile Level 0b AMR
+
+extern DLNAVideoMapping MPEG4_P2_VIDEO_MAP[];
+#endif /* _PROFILES_MPEG4_P2_H */
+
diff --git a/inc/profiles/png.h b/inc/profiles/png.h
new file mode 100644
index 0000000..69d4bcd
--- /dev/null
+++ b/inc/profiles/png.h
@@ -0,0 +1,22 @@
+/*
+ * File: profiles_png.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:01
+ */
+
+#ifndef _PROFILES_PNG_H
+#define _PROFILES_PNG_H
+
+#include "profile_data.h"
+
+/* Images */
+extern DLNAProfile DLNA_PROFILE_PNG_LRG; ///< PNG high resolution
+
+/* Icons */
+extern DLNAIconProfile DLNA_ICON_PNG_SM_24A; ///< DLNA icon profile of small png images
+extern DLNAIconProfile DLNA_ICON_PNG_LRG_24A; ///< DLNA icon profile of large png images
+extern DLNAIconProfile DLNA_ICON_PNG_TN; ///< DLNA png thumbnail profile of images
+
+#endif /* _PROFILES_PNG_H */
+
diff --git a/inc/profiles/profile_data.h b/inc/profiles/profile_data.h
new file mode 100644
index 0000000..7ae01d2
--- /dev/null
+++ b/inc/profiles/profile_data.h
@@ -0,0 +1,213 @@
+/*
+ * File: profile_data.h
+ * Author: savop
+ *
+ * Created on 5. Januar 2010, 12:27
+ */
+
+#ifndef _PROFILE_DATA_H
+#define _PROFILE_DATA_H
+
+#ifdef __cplusplus
+#include <vdr/tools.h>
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+}
+#endif
+
+#define MAX_BITRATES 32 ///< maximum amount of different CBR bitrates
+#define MAX_CHANNEL_LAYOUTS 20 ///< maximum amount of different channel layout modes
+#define MAX_SAMPLE_RATES 16 ///< maximum amount of different sampling rates
+
+#define Kbps(x) x*1000 ///< Kbit per second
+#define Mbps(x) x*1000*1000 ///< Mbit per second
+#define KHz(x) x*1000
+#define MHz(x) x*1000*1000
+
+#define CHANNEL_LAYOUT_10 CH_LAYOUT_MONO ///< 1/0 1
+#define CHANNEL_LAYOUT_10_1 (CHANNEL_LAYOUT_10|CH_LOW_FREQUENCY)///< 1/0 1.1 (incl. LFE)
+#define CHANNEL_LAYOUT_20 CH_LAYOUT_STEREO ///< 2/0 2
+#define CHANNEL_LAYOUT_20_1 (CHANNEL_LAYOUT_20|CH_LOW_FREQUENCY)///< 2/0 2.1 (incl. LFE)
+#define CHANNEL_LAYOUT_21 (CH_LAYOUT_STEREO|CH_BACK_CENTER) ///< 2/1 3
+#define CHANNEL_LAYOUT_21_1 (CHANNEL_LAYOUT_21|CH_LOW_FREQUENCY)///< 2/1 3.1 (incl. LFE)
+#define CHANNEL_LAYOUT_22 CH_LAYOUT_QUAD ///< 2/2 4
+#define CHANNEL_LAYOUT_22_1 (CHANNEL_LAYOUT_22|CH_LOW_FREQUENCY)///< 2/2 4.1 (incl. LFE)
+#define CHANNEL_LAYOUT_30 CH_LAYOUT_SURROUND ///< 3/0 3
+#define CHANNEL_LAYOUT_30_1 (CHANNEL_LAYOUT_30|CH_LOW_FREQUENCY)///< 3/0 3.1 (incl. LFE)
+#define CHANNEL_LAYOUT_31 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) ///< 3/1 4
+#define CHANNEL_LAYOUT_31_1 (CHANNEL_LAYOUT_31|CH_LOW_FREQUENCY)///< 3/1 4.1 (incl. LFE)
+#define CHANNEL_LAYOUT_32 CH_LAYOUT_5POINT0 ///< 3/2 5
+#define CHANNEL_LAYOUT_5_1 CH_LAYOUT_5POINT1 ///< 5.1 5.1 (incl. LFE)
+#define CHANNEL_LAYOUT_7_1 CH_LAYOUT_7POINT1 ///< 7.1 7.1 (incl. LFE)
+
+/**
+ * The combination of DLNA profile ID and the corresponding mime type
+ *
+ * This complies with the DLNA media format guidelines. Though this is very
+ * similar to the profile structure of libdlna, it comes without the additional
+ * label field as it seams to be not needed.
+ */
+struct DLNAProfile {
+ const char* ID; ///< the DLNA profile ID
+ const char* mime; ///< the mime type of the resource
+};
+
+/**
+ * The DLNA profile for a icon image
+ *
+ * This complies with the DLNA media format guidelines. It contains a valid
+ * mime type, the resolution of the image and the corresponding bit depth
+ */
+struct DLNAIconProfile {
+ const char* mime; ///< the mime type of the image
+ unsigned short width; ///< image width in pixel
+ unsigned short height; ///< image height in pixel
+ unsigned char bitDepth; ///< bit depth in bits per pixel
+};
+
+enum VideoContainerProfile {
+ DLNA_VCP_UNKNOWN=-1,
+ DLNA_VCP_MPEG1=0,
+ DLNA_VCP_MPEG2_PS,
+ DLNA_VCP_MPEG2_TS,
+ DLNA_VCP_MPEG2_TS_T,
+ DLNA_VCP_MPEG2_TS_ISO,
+ DLNA_VCP_MP4,
+ DLNA_VCP_3GPP,
+ DLNA_VCP_ASF,
+};
+
+enum VideoPortionProfile {
+ DLNA_VPP_UNKNOWN=-1,
+ DLNA_VPP_MPEG1=0,
+ DLNA_VPP_MPEG2_PAL_SD,
+ DLNA_VPP_MPEG2_PAL_HD,
+ DLNA_VPP_MPEG2_NTSC_SD,
+ DLNA_VPP_MPEG2_NTSC_HD,
+ DLNA_VPP_MPEG2_SP,
+ DLNA_VPP_MPEG2_MP_LL,
+ DLNA_VPP_MPEG4_P2_SP_L0B,
+ DLNA_VPP_MPEG4_P2_SP_L2,
+ DLNA_VPP_MPEG4_P2_SP_L3,
+ DLNA_VPP_MPEG4_P2_SP_L3_VGA,
+ DLNA_VPP_MPEG4_P2_ASP_L5,
+ DLNA_VPP_MPEG4_P2_ASP_L5_SO,
+ DLNA_VPP_MPEG4_P2_ASP_L4_SO,
+ DLNA_VPP_MPEG4_P2_H263_P0_L10,
+ DLNA_VPP_MPEG4_P2_H263_P3_L10,
+ DLNA_VPP_MPEG4_P2_CO,
+ DLNA_VPP_MPEG4_P10_MP_SD,
+ DLNA_VPP_MPEG4_P10_MP_HD,
+ DLNA_VPP_MPEG4_P10_BL_L3_SD,
+ DLNA_VPP_MPEG4_P10_BL_L3L_SD,
+ DLNA_VPP_MPEG4_P10_BL_CIF30,
+ DLNA_VPP_MPEG4_P10_BL_L2_CIF30,
+ DLNA_VPP_MPEG4_P10_BL_CIF15,
+ DLNA_VPP_MPEG4_P10_BL_L12_CIF15,
+ DLNA_VPP_MPEG4_P10_BL_L1B_QCIF
+};
+
+enum AudioPortionProfile {
+ DLNA_APP_UNKNOWN=-1,
+ DLNA_APP_LPCM=0,
+ DLNA_APP_MPEG1_L1,
+ DLNA_APP_MPEG1_L2,
+ DLNA_APP_MPEG1_L3,
+ DLNA_APP_MPEG1_L3X,
+ DLNA_APP_MPEG2_L2, //TODO: Distinguish MPEG1 oder MPEG2 audio with FFMPEG
+ DLNA_APP_AAC,
+ DLNA_APP_AAC_MULT5,
+ DLNA_APP_AAC_LTP,
+ DLNA_APP_AAC_LTP_MULT5,
+ DLNA_APP_AAC_LTP_MULT7,
+ DLNA_APP_HEAAC,
+ DLNA_APP_HEAAC_L2,
+ DLNA_APP_HEAAC_MULT5,
+ DLNA_APP_ATRAC3plus,
+ DLNA_APP_AC3,
+ DLNA_APP_XAC3,
+ DLNA_APP_G726,
+ DLNA_APP_AMR,
+ DLNA_APP_AMR_WBplus,
+ DLNA_APP_BL_QCIF15,
+ DLNA_APP_BSAC,
+ DLNA_APP_BSAC_MULT5
+};
+
+struct DLNAVideoMapping {
+ DLNAProfile* Profile;
+ VideoContainerProfile VideoContainer;
+ VideoPortionProfile VideoProfile;
+ AudioPortionProfile AudioProfile;
+};
+
+struct AcceptedBitrates {
+ /**
+ * <b>true</b> if VBR, <b>false</b> otherwise
+ */
+ bool VBR;
+ /**
+ * list of valid bitrates.
+ *
+ * if VBR is true, the array must contain exactly two items.
+ * The first item is the minimum and the second item is the maximum bitrate
+ *
+ * The bitrate unit is bps. So, if you have 15bps, it is 15000000bps
+ */
+ int bitrates[MAX_BITRATES];
+};
+
+struct AcceptedResolution {
+ /**
+ * Screen width
+ */
+ int width;
+ /**
+ * Screen height
+ */
+ int height;
+ /**
+ * Frames per second
+ *
+ * this value may contain a higher value which is divided by the multiplier
+ * given in <b>multiplier</b>
+ */
+ int fps;
+ /**
+ * Multiplier for calculating FPS
+ *
+ * The multiplier typically contains values like 1 or 1001 to calculate
+ * the exact frame rate of 29,97 FPS in most NTSC systems
+ */
+ int multiplier;
+};
+
+struct AcceptedAudioChannels {
+ int max_channels;
+ int64_t layouts[MAX_CHANNEL_LAYOUTS];
+ bool supportsLFE;
+};
+
+struct AcceptedSamplingRates {
+ int rates[MAX_SAMPLE_RATES];
+};
+
+class cDLNAProfiler {
+public:
+ virtual DLNAProfile* probeDLNAProfile(AVFormatContext* FormatCtx) = 0;
+};
+
+class cAudioProfiler {
+public:
+ virtual AudioPortionProfile probeAudioProfile(AVFormatContext* FormatCtx) = 0;
+};
+
+class cVideoProfiler {
+public:
+ virtual VideoPortionProfile probeVideoProfile(AVFormatContext* FormatCtx) = 0;
+ virtual VideoContainerProfile probeContainerProfile(AVFormatContext* FormatCtx) = 0;
+};
+
+#endif /* _PROFILE_DATA_H */
+
diff --git a/inc/profiles/wma.h b/inc/profiles/wma.h
new file mode 100644
index 0000000..80e25ec
--- /dev/null
+++ b/inc/profiles/wma.h
@@ -0,0 +1,18 @@
+/*
+ * File: profiles_wma.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 13:32
+ */
+
+#ifndef _PROFILES_WMA_H
+#define _PROFILES_WMA_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_WMABASE; ///< WMA with less than 193Kbit/s
+extern DLNAProfile DLNA_PROFILE_WMAFULL; ///< WMA
+extern DLNAProfile DLNA_PROFILE_WMAPRO; ///< WMA Professional
+
+#endif /* _PROFILES_WMA_H */
+
diff --git a/inc/profiles/wmv9.h b/inc/profiles/wmv9.h
new file mode 100644
index 0000000..fd69499
--- /dev/null
+++ b/inc/profiles/wmv9.h
@@ -0,0 +1,24 @@
+/*
+ * File: profiles_wmv9.h
+ * Author: savop
+ *
+ * Created on 7. Dezember 2009, 14:53
+ */
+
+#ifndef _PROFILES_WMV9_H
+#define _PROFILES_WMV9_H
+
+#include "profile_data.h"
+
+extern DLNAProfile DLNA_PROFILE_WMVMED_BASE; ///< WMV medium resolution baseline audio
+extern DLNAProfile DLNA_PROFILE_WMVMED_FULL; ///< WMV medium resolution full audio
+extern DLNAProfile DLNA_PROFILE_WMVMED_PRO; ///< WMV medium resolution professional audio
+extern DLNAProfile DLNA_PROFILE_WMVHIGH_FULL; ///< WMV high resolution full audio
+extern DLNAProfile DLNA_PROFILE_WMVHIGH_PRO; ///< WMV high resolution professional audio
+extern DLNAProfile DLNA_PROFILE_WMVHM_BASE; ///< WMV HighMAT profile
+extern DLNAProfile DLNA_PROFILE_WMVSPLL_BASE; ///< WMV Low resolution simple profile low level
+extern DLNAProfile DLNA_PROFILE_WMVSPML_BASE; ///< WMV Low resolution simple profile medium level
+extern DLNAProfile DLNA_PROFILE_WMVSPML_MP3; ///< WMV Low resolution simple profile medium level MP3 audio
+
+#endif /* _PROFILES_WMV9_H */
+
diff --git a/inc/recplayer.h b/inc/recplayer.h
new file mode 100644
index 0000000..376ca3c
--- /dev/null
+++ b/inc/recplayer.h
@@ -0,0 +1,53 @@
+/*
+ * File: recplayer.h
+ * Author: savop
+ *
+ * Created on 8. Juni 2009, 11:57
+ */
+
+#ifndef _RECPLAYER_H
+#define _RECPLAYER_H
+
+#include "../common.h"
+#include "filehandle.h"
+#include <vdr/recording.h>
+
+/**
+ * The recording player
+ *
+ * This class provides the ability to play VDR records. The difference between
+ * usual files and VDR recording files is, that recordings are possibly splitted
+ * into multiple files. The class will scan those files and tries to dynamically
+ * navigate in them like it would do, if it is a single file.
+ *
+ */
+class cRecordingPlayer : public cFileHandle {
+public:
+ /**
+ * Get a new instance of a recording player
+ *
+ * This returns a new instance of a recording player which plays the
+ * specified VDR recording.
+ *
+ * @param Recording the recording to play
+ * @return the new instance of the recording player
+ */
+ static cRecordingPlayer *newInstance(cRecording *Recording);
+ virtual ~cRecordingPlayer();
+ virtual void open(UpnpOpenFileMode mode);
+ virtual int read(char* buf, size_t buflen);
+ virtual int write(char* buf, size_t buflen);
+ virtual int seek(off_t offset, int origin);
+ virtual void close();
+private:
+ void scanLastOffsets();
+ cRecordingPlayer(cRecording *Recording);
+ off_t* mLastOffsets;
+ int mLastFileNumber;
+ cRecording *mRecording;
+ cFileName *mRecordingFile;
+ cUnbufferedFile *mCurrentFile;
+};
+
+#endif /* _RECPLAYER_H */
+
diff --git a/inc/resources.h b/inc/resources.h
new file mode 100644
index 0000000..a655de8
--- /dev/null
+++ b/inc/resources.h
@@ -0,0 +1,318 @@
+/*
+ * File: resources.h
+ * Author: savop
+ *
+ * Created on 30. September 2009, 15:17
+ */
+
+#ifndef _RESOURCES_H
+#define _RESOURCES_H
+
+#include "database.h"
+#include "object.h"
+#include <vdr/channels.h>
+#include <vdr/recording.h>
+
+class cUPnPResourceMediator;
+class cMediaDatabase;
+
+/**
+ * UPnP Resource
+ *
+ * This contains all details about a resource
+ */
+class cUPnPResource : public cListObject {
+ friend class cUPnPResourceMediator;
+ friend class cUPnPResources;
+private:
+ unsigned int mResourceID;
+ int mResourceType;
+ cString mResource;
+ cString mDuration;
+ cString mResolution;
+ cString mProtocolInfo;
+ cString mContentType;
+ cString mImportURI;
+ off64_t mSize;
+ unsigned int mBitrate;
+ unsigned int mSampleFrequency;
+ unsigned int mBitsPerSample;
+ unsigned int mNrAudioChannels;
+ unsigned int mColorDepth;
+ cUPnPResource();
+public:
+ /**
+ * Get resource ID
+ *
+ * Gets the resource ID
+ *
+ * @return the resource ID
+ */
+ unsigned int getID() const { return this->mResourceID; }
+ /**
+ * Get the resources
+ *
+ * Returns the resource. This is in most cases the file name or resource locator
+ * where to find the resource
+ *
+ * @return the resource string
+ */
+ const char* getResource() const { return this->mResource; }
+ /**
+ * Get the duration
+ *
+ * Returns a date time string with the duration of the resource
+ *
+ * @return the duration of the resource
+ */
+ const char* getDuration() const { return this->mDuration; }
+ /**
+ * Get the resolution
+ *
+ * Returns the resolution string with the pattern width x height in pixels
+ *
+ * @return the resolution of the resource
+ */
+ const char* getResolution() const { return this->mResolution; }
+ /**
+ * Get the protocol info
+ *
+ * This returns the protocol info field of a resource
+ *
+ * @return the protocol info string
+ */
+ const char* getProtocolInfo() const { return this->mProtocolInfo; }
+ /**
+ * Get the content type
+ *
+ * Returns the mime type of the content of the resource
+ *
+ * @return the content type of the resource
+ */
+ const char* getContentType() const { return this->mContentType; }
+ /**
+ * Get the import URI
+ *
+ * This returns the import URI where the resource was located before importing
+ * it
+ *
+ * @return the import URI
+ */
+ const char* getImportURI() const { return this->mImportURI; }
+ /**
+ * Get the resource type
+ *
+ * This returns the resource type of the resource.
+ *
+ * @return the resource type
+ */
+ int getResourceType() const { return this->mResourceType; }
+ /**
+ * Get the file size
+ *
+ * Returns the file size in bytes of the resource or 0 if its unknown or a
+ * stream
+ *
+ * @return the file size
+ */
+ off64_t getFileSize() const { return this->mSize; };
+ /**
+ * Get the last modification
+ *
+ * This returns the timestamp of the last modification to the file. If it
+ * is a stream, then its the current time.
+ *
+ * @return the timestamp with the last modification of the resource
+ */
+ time_t getLastModification() const;
+ /**
+ * Get the bitrate
+ *
+ * This returns the bitrate of the resource in bits per second.
+ *
+ * @return the bitrate of the resource
+ */
+ unsigned int getBitrate() const { return this->mBitrate; }
+ /**
+ * Get the sample frequency
+ *
+ * Returns the sample frequency in samples per second.
+ *
+ * @return the sample frequency of the resource
+ */
+ unsigned int getSampleFrequency() const { return this->mSampleFrequency; }
+ /**
+ * Get the bits per sample
+ *
+ * Returns the number of bits per sample.
+ *
+ * @return the bits per sample of the resource
+ */
+ unsigned int getBitsPerSample() const { return this->mBitsPerSample; }
+ /**
+ * Get number of audio channels
+ *
+ * Returns the number of audio channels of the audio stream in a video
+ *
+ * @return the number of audio channels
+ */
+ unsigned int getNrAudioChannels() const { return this->mNrAudioChannels; }
+ /**
+ * Get the color depth
+ *
+ * Returns the color depth of the resource in pits per pixel
+ *
+ * @return the color depth of the resource
+ */
+ unsigned int getColorDepth() const { return this->mColorDepth; }
+};
+
+class cUPnPClassObject;
+class cUPnPClassItem;
+class cUPnPClassVideoItem;
+class cUPnPClassVideoBroadcast;
+
+/**
+ * The resource manager
+ *
+ * This manages the resources in an internal cache. It may create a new resource
+ * from a channel, a recording or a custom file.
+ */
+class cUPnPResources {
+private:
+ cHash<cUPnPResource>* mResources;
+ static cUPnPResources* mInstance;
+ cUPnPResourceMediator* mMediator;
+ cSQLiteDatabase* mDatabase;
+ cUPnPResources();
+public:
+ /**
+ * Fill object with its resources
+ *
+ * This will load all the resources from the database, which are associated
+ * to the given object
+ *
+ * @param Object the object, which shall be filled
+ * @return returns
+ * - \bc 0, if loading was successful
+ * - \bc <0, otherwise
+ */
+ int getResourcesOfObject(cUPnPClassObject* Object);
+ /**
+ * Loads all resources from database
+ *
+ * This loads all resources from the database into the internal cache.
+ *
+ * @return returns
+ * - \bc 0, if loading was successful
+ * - \bc <0, otherwise
+ */
+ int loadResources();
+ /*! @copydoc cUPnPResourceMediator::getResource */
+ cUPnPResource* getResource(unsigned int ResourceID);
+ virtual ~cUPnPResources();
+ /**
+ * Get the instance of the resource manager
+ *
+ * This returns the instance of the resource manager.
+ *
+ * @return the instance of the manager
+ */
+ static cUPnPResources* getInstance();
+ /**
+ * Create resource from channel
+ *
+ * This creates a new resource from the given channel. It determines what
+ * kind of video stream it is and further details if available. It stores
+ * the resource in the database after creating it.
+ *
+ * @param Object the videoBroadcast item which holds the resource
+ * @param Channel the VDR TV channel
+ * @return returns
+ * - \bc 0, if loading was successful
+ * - \bc <0, otherwise
+ */
+ int createFromChannel(cUPnPClassVideoBroadcast* Object, cChannel* Channel);
+ /**
+ * Create resource from recording
+ *
+ * This creates a new resource from the given recording. It determines what
+ * kind of video stream it is and further details if available. It stores
+ * the resource in the database after creating it.
+ *
+ * @param Object the videoItem item which holds the resource
+ * @param Recording the VDR TV recording
+ * @return returns
+ * - \bc 0, if loading was successful
+ * - \bc <0, otherwise
+ */
+ int createFromRecording(cUPnPClassVideoItem* Object, cRecording* Recording);
+ /**
+ * Create resource from file
+ *
+ * This creates a new resource from the given file. It determines all available
+ * information about the resource by analizing the content. It stores
+ * the resource in the database after creating it.
+ *
+ * @param Object the item which holds the resource
+ * @param File the file name
+ * @return returns
+ * - \bc 0, if loading was successful
+ * - \bc <0, otherwise
+ */
+ int createFromFile(cUPnPClassItem* Object, cString File);
+};
+
+/**
+ * The resource mediator
+ *
+ * This is another mediator which communicates with the database. It manages the
+ * resources in the database
+ */
+class cUPnPResourceMediator {
+ friend class cUPnPResources;
+private:
+ cSQLiteDatabase* mDatabase;
+ cUPnPResourceMediator();
+ unsigned int getNextResourceID();
+public:
+ virtual ~cUPnPResourceMediator();
+ /**
+ * Get a resource by ID
+ *
+ * This returns a resource by its resource ID
+ *
+ * @param ResourceID the resource ID of the demanded resource
+ * @return the requested resource
+ */
+ cUPnPResource* getResource(unsigned int ResourceID);
+ /**
+ * Saves the resource
+ *
+ * This updates the information in the database with those in the resource
+ * object
+ *
+ * @param Resource the resource which shall be saved
+ * @return returns
+ * - \bc 0, if saving was successful
+ * - \bc <0, if an error occured
+ */
+ int saveResource(cUPnPClassObject* Object, cUPnPResource* Resource);
+ /**
+ * Create new resource
+ *
+ * This creates a new resource and stores the skeleton in the database. The
+ * newly created resource will only contain all required information.
+ *
+ * @param Object the Object which will hold the resource
+ * @param ResourceType the type of the resource
+ * @param ResourceFile the file or URL, where the resource can be located
+ * @param ContentType the mime type of the content
+ * @param ProtocolInfo the protocol information of the resource
+ * @return the newly created resource
+ */
+ cUPnPResource* newResource(cUPnPClassObject* Object, int ResourceType, cString ResourceFile, cString ContentType, cString ProtocolInfo);
+};
+
+#endif /* _RESOURCES_H */
+
diff --git a/inc/search.h b/inc/search.h
new file mode 100644
index 0000000..ef162b1
--- /dev/null
+++ b/inc/search.h
@@ -0,0 +1,156 @@
+/*
+ * File: search.h
+ * Author: savop
+ *
+ * Created on 27. August 2009, 21:21
+ */
+
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+#include <map>
+#include <vdr/tools.h>
+#include "util.h"
+
+/**
+ * Sort criteria
+ *
+ * This is a structure for sorting objects. It has a certain property and
+ * a direction flag.
+ */
+struct cSortCrit : public cListObject {
+ const char* Property; ///< the Property, which shall be sorted
+ bool SortDescending; ///< sort the objects in descending order
+};
+
+typedef std::map<const char*, const char*, strCmp> propertyMap;
+
+/**
+ * Web path parser
+ *
+ * Parses paths which came from the webserver. It splits the path into
+ * a section, a certain method and its properties.
+ *
+ * This can be used to easily determine which file was requested by a client
+ */
+class cPathParser {
+private:
+ cString mKey;
+ propertyMap mProperties;
+ int mSection;
+ int mMethod;
+ bool parsePath(const char* Path, int* Section, int* Method, propertyMap* Properties);
+ void pushPropertyKey(const char* Start, const char* End);
+ void pushPropertyValue(const char* Start, const char* End);
+ void pushMethod(int Method);
+ void pushSection(int Section);
+ cPathParser();
+public:
+ virtual ~cPathParser();
+ /**
+ * Parses the path
+ *
+ * This will parse the path and stores the result in the pointers given.
+ *
+ * @return returns
+ * - \bc true, if the parsing was successful
+ * - \bc false, otherwise
+ */
+ static bool parse(
+ const char* Path, ///< the path which is parsed
+ int* Section, ///< the number of the registered section
+ int* Method, ///< the number of the registered method
+ propertyMap* Properties ///< the properties found in the path
+ );
+};
+
+/**
+ * Creates a list with sort criteria
+ *
+ * This parser creates a list of sort criteria. It parses the sort criteria string
+ * from a \em Browse or \em Search request and stores the information in a \c cSortCrit
+ * structure.
+ */
+class cSortCriteria {
+private:
+ cSortCrit* mCurrentCrit;
+ cList<cSortCrit>* mCriteriaList;
+ bool parseSort(const char* Sort);
+ void pushProperty(const char* Property);
+ void pushDirection(const char Direction);
+ cList<cSortCrit>* getSortList() const { return this->mCriteriaList; }
+ cSortCriteria();
+public:
+ virtual ~cSortCriteria();
+ /**
+ * Parses the sort criteria
+ *
+ * This parses the sort criteria and returns a list with valid criterias
+ *
+ * @return returns
+ * - a list with valid sort criterias
+ * - \bc null, otherwise
+ */
+ static cList<cSortCrit>* parse(
+ const char* Sort ///< the string container the sort criteria
+ );
+};
+
+/**
+ * Parses the filter criteria
+ *
+ * This parses the filter criteria which comes from a \em Browse or \em Search
+ * request.
+ */
+class cFilterCriteria {
+private:
+ cStringList* mFilterList;
+ cFilterCriteria();
+ bool parseFilter(const char* Filter);
+ void pushProperty(const char* Property);
+ void pushAsterisk(const char Asterisk);
+ cStringList* getFilterList() const { return this->mFilterList; }
+public:
+ virtual ~cFilterCriteria();
+ /**
+ * Parses the filter criteria
+ *
+ * This parses the filter criteria. It may be a empty string list, a \bc NULL
+ * pointer or a list with properties which shall be shown in the \em DIDL-Lite fragment.
+ *
+ * @return the stringlist containing the filter
+ */
+ static cStringList* parse(
+ const char* Filter ///< the filter string
+ );
+};
+
+/**
+ * @private
+ * @todo This is implemented very soon
+ */
+class cSearch {
+private:
+ char* SQLWhereStmt;
+ const char* CurrentProperty;
+ const char* CurrentOperator;
+ const char* CurrentValue;
+ static cSearch* mInstance;
+ cSearch();
+ bool parseCriteria(const char* Search);
+ void pushExistance (const char* Exists);
+ void pushProperty (const char* Property);
+ void pushOperator (const char* Operator);
+ void pushConcatOp (const char* Operator);
+ void pushStartBrackedExp(const char);
+ void pushEndBrackedExp(const char);
+ void pushValue (const char* Start, const char* End);
+ void pushExpression(const char* Start, const char* End);
+public:
+ virtual ~cSearch();
+ static const char* parse(const char* Search);
+};
+
+
+#endif /* _SEARCH_H */
+
diff --git a/inc/server.h b/inc/server.h
new file mode 100644
index 0000000..260ac57
--- /dev/null
+++ b/inc/server.h
@@ -0,0 +1,221 @@
+/*
+ * File: server.h
+ * Author: savop
+ *
+ * Created on 19. April 2009, 17:42
+ */
+
+#ifndef _SERVER_H
+#define _SERVER_H
+
+#include <netinet/in.h>
+#include <vdr/recording.h>
+#include <vdr/thread.h>
+#include <upnp/upnp.h>
+#include "util.h"
+#include "../common.h"
+#include "webserver.h"
+#include "metadata.h"
+#include "upnp/connectionmanager.h"
+#include "upnp/contentdirectory.h"
+#include "../upnp.h"
+
+/**
+ * The UPnP Server
+ *
+ * This is the core of the UPnP server. This handles all the components which
+ * are needed for a UPnP media server. Incoming messages are passed through it
+ * and it determines what to do.
+ */
+class cUPnPServer {
+ friend class cPluginUpnp;
+public:
+ /**
+ * Constructor
+ *
+ * This will create a new server and initializes the main functionalities
+ * The server has to be started manually by invoking cUPnPServer::start().
+ */
+ cUPnPServer();
+ /**
+ * Destructor
+ *
+ * This will destroy the server object. Open ports and connections will be
+ * closed.
+ */
+ virtual ~cUPnPServer();
+ /**
+ * Enable the server
+ *
+ * This switch indicates if the server is startable or not
+ *
+ * If it is set to false, any invocation of start() will do nothing.
+ *
+ * @param enabled if \bc true, the server will be enabled. If \bc false it is
+ * disabled.
+ */
+ void enable(bool enabled);
+ /**
+ * Start the UPnP server
+ *
+ * This will start the UPnP server activities as a background task.
+ *
+ * @return returns
+ * - \bc true, when the server started successfully
+ * - \bc false, otherwise
+ */
+ bool start(void);
+ /**
+ * Restart the server
+ *
+ * When the server is not operating properly it can be restarted.
+ * It will stop the server functionalities, clear everything and
+ * start it again.
+ *
+ * @return returns
+ * - \bc true, when the server restarted successfully
+ * - \bc false, otherwise
+ */
+ bool restart(void);
+ /**
+ * Stop the server
+ *
+ * This will stop the server. This means that open connections to
+ * any clients and open ports will be closed.
+ */
+ void stop(void);
+ /**
+ * Automatically detect settings
+ *
+ * This will automatically detect the network settings if the autodetection
+ * is turned on.
+ *
+ * @return returns
+ * - \bc true, if autoDetection was successful
+ * - \bc false, otherwise
+ */
+ bool autoDetectSettings(void);
+ /**
+ * Get the server address
+ *
+ * Returns a server address structure including IP address and port
+ *
+ * @return The server socket address
+ */
+ sockaddr_in* getServerAddress(void);
+ /**
+ * Get the interface the server listens to
+ *
+ * @return the network interface
+ */
+ const char* getInterface(void) const { return this->mInterface; }
+ /**
+ * Set the server port
+ *
+ * The port must be in the scope of user definied ports (49152 - 65535). If
+ * the port is 0, it is autoassigned. You can retrieve the actual port by
+ * calling getServerAddress(), which will give you a structure with the port
+ * in it.
+ *
+ * The server must be restarted if the IP or port changes.
+ *
+ * Returns 1 when the port is valid, 0 otherwise
+ *
+ * @param port The port of the server
+ * @return returns
+ * - \bc true, if the new server port is set
+ * - \bc false, otherwise
+ */
+ bool setServerPort(unsigned short port);
+ /**
+ * The Interface to listen on
+ *
+ * Sets the listener interface, for instance 'eth1' or 'wlan0'
+ *
+ * @param Interface The interface of the server
+ * @return returns
+ * - \bc true, if the new server address is set
+ * - \bc false, otherwise
+ */
+ bool setInterface(const char* Interface);
+ /**
+ * Set the server address
+ *
+ * Specifies the servers IP address. The server needs to restart
+ * when the IP is changed. However, it's not possible to detect
+ * changes through the system.
+ *
+ * This method should only be used in cases of fixed IP addresses
+ * for example when no DHCP server is available.
+ *
+ * @param Address The address of the server
+ * @return returns
+ * - \bc true, if the new server address is set
+ * - \bc false, otherwise
+ */
+ bool setAddress(const char* Address);
+ /**
+ * Enables oder Disables auto detection mode
+ *
+ * If this is set to true, the setup will get it's information via
+ * auto detection
+ *
+ * @param enable \bc true enables and \bc false disables the auto detection
+ * @return returns
+ * - \bc true, if the new server address is set
+ * - \bc false, otherwise
+ */
+ bool setAutoDetection(bool enable);
+ /**
+ * Checks if the server is enabled
+ *
+ * This indicates if the server is currently enabled.
+ *
+ * @return returns
+ * - \bc true, if the server is enabled
+ * - \bc false, otherwise
+ */
+ bool isEnabled(void) const { return this->mIsEnabled; }
+ /**
+ * Checks if the server is running
+ *
+ * If the server is enabled, this indicates if it is running.
+ *
+ * @return returns
+ * - \bc true if the server is running
+ * - \bc false, otherwise
+ */
+ bool isRunning(void) const { return this->mIsRunning; }
+ /**
+ * Is auto detection enabled or not
+ *
+ * Returns true or false if auto detection is enabled or not
+ *
+ * @return returns
+ * - \bc true, if autodetection is enabled
+ * - \bc false, otherwise
+ */
+ bool isAutoDetectionEnabled() { return this->mIsAutoDetectionEnabled; }
+protected:
+private:
+ /**
+ * Inits the server
+ *
+ * This method initializes all member variables with default values
+ */
+ bool init(void);
+ bool uninit(void);
+ static int upnpActionCallback(Upnp_EventType eventtype, void *event, void *cookie);
+ bool mIsRunning;
+ bool mIsEnabled;
+ sockaddr_in* mServerAddr;
+ cString mInterface;
+ bool mIsAutoDetectionEnabled;
+ cString mDeviceDescription;
+ cUPnPWebServer* mWebServer;
+ cMediaDatabase* mMediaDatabase;
+ UpnpDevice_Handle mDeviceHandle;
+ static cConnectionManager* mConnectionManager;
+ static cContentDirectory* mContentDirectory;
+};
+#endif /* _SERVER_H */ \ No newline at end of file
diff --git a/inc/upnp/connectionmanager.h b/inc/upnp/connectionmanager.h
new file mode 100644
index 0000000..6ed2987
--- /dev/null
+++ b/inc/upnp/connectionmanager.h
@@ -0,0 +1,99 @@
+/*
+ * File: connectionmanager.h
+ * Author: savop
+ *
+ * Created on 21. August 2009, 18:35
+ */
+
+#ifndef _CONNECTIONMANAGER_H
+#define _CONNECTIONMANAGER_H
+
+#include "service.h"
+
+/**
+ * Connection status
+ *
+ * The connection status of a certain virtual connection
+ */
+enum eConnectionStatus {
+ OK,
+ CONTENT_FORMAT_MISMATCH,
+ INSUFFICIENT_BANDWIDTH,
+ UNRELIABLE_CHANNEL,
+ UNKNOWN
+};
+
+/**
+ * Direction
+ *
+ * The direction of a virtual connection. Input means client to server, Output
+ * server to client
+ */
+enum eDirection {
+ OUTPUT,
+ INPUT
+};
+
+/**
+ * Virtual connection
+ *
+ * A virtual connection managed by the connection manager service
+ */
+class cVirtualConnection : public cListObject {
+ friend class cConnectionManager;
+private:
+ cString mRemoteProtocolInfo;
+ cString mRemoteConnectionManager;
+ eDirection mDirection;
+ int mRemoteConnectionID;
+ int mConnectionID;
+ int mAVTransportID;
+ const int mRcsID;
+ eConnectionStatus mStatus;
+ cVirtualConnection();
+ static const char* getStatusString(eConnectionStatus Status);
+ static const char* getDirectionString(eDirection Direction);
+ static int getDirection(const char* Direction);
+ static int getConnectionStatus(const char* ConnectionStatus);
+};
+
+/**
+ * The connection manager service
+ *
+ * This is the connection manager service which handles all incoming connection,
+ * creates and destroys connections to clients.
+ */
+class cConnectionManager : public cUpnpService {
+public:
+ /**
+ * Constructor of a Connection manager
+ *
+ * This creates an instance of a <em>Connection Manager Service</em> and provides
+ * interfaces for executing actions and subscribing on events.
+ */
+ cConnectionManager(
+ UpnpDevice_Handle DeviceHandle ///< the UPnP device handle of this root device
+ );
+ virtual ~cConnectionManager();
+ /*! @copydoc cUpnpService::subscribe(Upnp_Subscription_Request* Request) */
+ virtual int subscribe(Upnp_Subscription_Request* Request);
+ /*! @copydoc cUpnpService::execute(Upnp_Action_Request* Request) */
+ virtual int execute(Upnp_Action_Request* Request);
+ /*! @copydoc cUpnpService::setError(Upnp_Action_Request* Request, int Error) */
+ virtual void setError(Upnp_Action_Request* Request, int Error);
+private:
+ int getProtocolInfo(Upnp_Action_Request* Request);
+ int getCurrentConnectionIDs(Upnp_Action_Request* Request);
+ int getCurrentConnectionInfo(Upnp_Action_Request* Request);
+ int prepareForConnection(Upnp_Action_Request* Request);
+ int connectionComplete(Upnp_Action_Request* Request);
+ cVirtualConnection* createVirtualConnection(const char* RemoteProtocolInfo = NULL, const char* RemoteConnectionManager = NULL, int RemoteConnectionID = -1, eDirection Direction = OUTPUT);
+ bool destroyVirtualConnection(int ConnectionID);
+ const char* getConnectionIDsCVS();
+ cVirtualConnection* mDefaultConnection;
+ cList<cVirtualConnection>* mVirtualConnections;
+ cString mSupportedProtocols;
+};
+
+#endif /* _CONNECTIONMANAGER_H */
+
diff --git a/inc/upnp/contentdirectory.h b/inc/upnp/contentdirectory.h
new file mode 100644
index 0000000..ec32dfa
--- /dev/null
+++ b/inc/upnp/contentdirectory.h
@@ -0,0 +1,56 @@
+/*
+ * File: contentdirectory.h
+ * Author: savop
+ *
+ * Created on 21. August 2009, 16:12
+ */
+
+#ifndef _CONTENTDIRECTORY_H
+#define _CONTENTDIRECTORY_H
+
+#include <upnp/upnp.h>
+#include "service.h"
+#include "metadata.h"
+
+/**
+ * The content directory service
+ *
+ * This is the content directory service which handles all incoming requests
+ * for contents managed by the media server.
+ */
+class cContentDirectory : public cUpnpService, public cThread {
+public:
+ /**
+ * Constructor of a Content Directory
+ *
+ * This creates an instance of a <em>Content Directory Service</em> and provides
+ * interfaces for executing actions and subscribing on events.
+ */
+ cContentDirectory(
+ UpnpDevice_Handle DeviceHandle, ///< The UPnP device handle of the root device
+ cMediaDatabase* MediaDatabase ///< the media database where requests are processed
+ );
+ virtual ~cContentDirectory();
+ /*! @copydoc cUpnpService::subscribe(Upnp_Subscription_Request* Request) */
+ virtual int subscribe(Upnp_Subscription_Request* Request);
+ /*! @copydoc cUpnpService::execute(Upnp_Action_Request* Request) */
+ virtual int execute(Upnp_Action_Request* Request);
+ /*! @copydoc cUpnpService::setError(Upnp_Action_Request* Request, int Error) */
+ virtual void setError(Upnp_Action_Request* Request, int Error);
+private:
+ cMediaDatabase* mMediaDatabase;
+ void Action();
+ int getSearchCapabilities(Upnp_Action_Request* Request);
+ int getSortCapabilities(Upnp_Action_Request* Request);
+ int getSystemUpdateID(Upnp_Action_Request* Request);
+ int browse(Upnp_Action_Request* Request);
+// int search(Upnp_Action_Request* Request);
+// int createObject(Upnp_Action_Request* Request);
+// int destroyObject(Upnp_Action_Request* Request);
+// int updateObject(Upnp_Action_Request* Request);
+// int deleteResource(Upnp_Action_Request* Request);
+// int createReference(Upnp_Action_Request* Request);
+};
+
+#endif /* _CONTENTDIRECTORY_H */
+
diff --git a/inc/upnp/dlna.h b/inc/upnp/dlna.h
new file mode 100644
index 0000000..c61c39f
--- /dev/null
+++ b/inc/upnp/dlna.h
@@ -0,0 +1,97 @@
+/*
+ * File: dlna.h
+ * Author: savop
+ *
+ * Created on 18. April 2009, 23:27
+ */
+
+#ifndef _DLNA_H
+#define _DLNA_H
+
+#include "../common.h"
+#include "profiles.h"
+#include <list>
+
+using namespace std;
+
+/**
+ * Enable DLNA compliant media transfer
+ *
+ * This class enables media transmission with DLNA conformity. Its compliant with
+ * version 1.5 of the DLNA guidelines.
+ *
+ */
+class cDlna {
+ friend class cUPnPServer;
+public:
+ /**
+ * Returns the instance of DLNA object
+ *
+ * This will create a DLNA object instance. It will return the same instance
+ * on subsequent calls.
+ *
+ * @return the DLNA object instance
+ */
+ static cDlna* getInstance(void);
+ virtual ~cDlna();
+ //const char* getProtocolInfo(UPnPObjectID OID);
+ /**
+ * Device description document
+ *
+ * This will return the device description document with service type
+ * definitions as well as some DLNA specific information
+ *
+ * @return The description document
+ */
+ const char* getDeviceDescription(
+ const char* URLBase ///< the URLBase to be set in the document
+ );
+ /**
+ * Registeres a DLNA profile
+ *
+ * Registeres a DLNA profile with specific optional options
+ *
+ * @see common.h
+ */
+ void registerProfile(
+ DLNAProfile* Profile ///< the DLNA profile
+ );
+ /**
+ * Registeres all known DLNA profiles
+ *
+ * Registeres all well known DLNA profiles with its known options
+ */
+ void registerProfiles();
+ /**
+ * CSV list of supported protocols
+ *
+ * Returns a comma separated list with all supported protocols. This
+ * means, it returns the list of protocols of the registered profiles.
+ *
+ * @return CSV list of registered protocols
+ */
+ const char* getSupportedProtocols();
+ /**
+ * Protocol info of a specific DLNA profile
+ *
+ * Returns the protocol info string of a specific DLNA profile with its
+ * options and flags.
+ *
+ * @return the protocol info string of the profile
+ */
+ const char* getProtocolInfo(
+ DLNAProfile *Prof, ///< the Profile of which the protocol info shall be returned
+ int Op = -1, ///< operation mode
+ const char* Ps = NULL, ///< play speed (CSV list)
+ int Ci = -1, ///< conversion indication flag
+ unsigned int Flags = 0 ///< DLNA flags
+ );
+private:
+ cDlna();
+ void init(void);
+ static cDlna* mInstance;
+ list<DLNAProfile*> mRegisteredProfiles;
+};
+
+#endif /* _DLNA_H */
+
diff --git a/inc/upnp/service.h b/inc/upnp/service.h
new file mode 100644
index 0000000..df74d9b
--- /dev/null
+++ b/inc/upnp/service.h
@@ -0,0 +1,119 @@
+/*
+ * File: upnpservice.h
+ * Author: savop
+ *
+ * Created on 21. August 2009, 18:38
+ */
+
+#ifndef _UPNPSERVICE_H
+#define _UPNPSERVICE_H
+
+#include <upnp/upnp.h>
+
+/**
+ * UPnP Service interface
+ *
+ * This is a service interface implemented by a UPnP service like CDS oder CMS
+ *
+ * It comes with some tool functions which are commonly useful for processing
+ * an event or action.
+ */
+class cUpnpService {
+public:
+ /**
+ * Constructor of a service
+ *
+ * @private
+ * @param DeviceHandle the UPnP device handle of this root device
+ */
+ cUpnpService(
+ UpnpDevice_Handle DeviceHandle ///< the UPnP device handle of this root device
+ );
+ virtual ~cUpnpService(){};
+ /**
+ * Subscribes to an event
+ *
+ * This is a callback function to register a new subscriber for an event.
+ *
+ * @return An integer representing one of the following:
+ * - \bc UPNP_E_SUCCESS, if subscription was okay
+ * - or any other non null value in case of an error
+ *
+ * @param Request Information about the subscription
+ */
+ virtual int subscribe(
+ Upnp_Subscription_Request* Request ///< Information about the subscription
+ ) = 0;
+ /**
+ * Executes an action
+ *
+ * This executes an action initialized by a control point. The result is
+ * stored in the first parameter.
+ *
+ * @return An integer representing one of the following:
+ * - \bc UPNP_E_SUCCESS, if subscription was okay
+ * - or any other non null value in case of an error
+ *
+ * @param Request Input and output parameters of an action
+ */
+ virtual int execute(
+ Upnp_Action_Request* Request ///< Input and output parameters of an action
+ ) = 0;
+protected:
+ /**
+ * Sets an error on an action request
+ *
+ * This function puts a error message into the action request structure
+ * according to its error code
+ *
+ * @param Request the action request, to set the error for
+ * @param Error the error code of which the message should be obtained
+ */
+ virtual void setError(
+ Upnp_Action_Request* Request, ///< the action request, to set the error for
+ int Error ///< the error code of which the message should be obtained
+ );
+ /**
+ * Parses an integer value
+ *
+ * This tool function parses an integer value from a given \em IXML document. It is searching
+ * for the very first occurance of the demanded item.
+ *
+ * @return Returns
+ * - \bc 0, if parsing was successful
+ * - \bc <0, if an error occured
+ *
+ * @param Document the document, which is parsed
+ * @param Item the demanded item
+ * @param Value the value of the item
+ */
+ int parseIntegerValue(
+ IN IXML_Document* Document, ///< the document, which is parsed
+ IN const char* Item, ///< the demanded item
+ OUT int* Value ///< the value of the item
+ );
+ /**
+ * Parses a string value
+ *
+ * This tool function parses a string value from a given \em IXML document. It is searching
+ * for the very first occurance of the demanded item.
+ *
+ * @return Returns
+ * - \bc 0, if parsing was successful
+ * - \bc <0, if an error occured
+ *
+ * @param Document the document, which is parsed
+ * @param Item the demanded item
+ * @param Value the value of the item
+ */
+ int parseStringValue(
+ IN IXML_Document* Document, ///< the document, which is parsed
+ IN const char* Item, ///< the demanded item
+ OUT char** Value ///< the value of the item
+ );
+
+ UpnpDevice_Handle mDeviceHandle; ///< the UPnP device handle of the root device
+};
+
+#endif /* _UPNPSERVICE_H */
+
diff --git a/inc/util.h b/inc/util.h
new file mode 100644
index 0000000..5f6f4a3
--- /dev/null
+++ b/inc/util.h
@@ -0,0 +1,148 @@
+/*
+ * File: util.h
+ * Author: savop
+ *
+ * Created on 21. Mai 2009, 21:25
+ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include <vdr/tools.h>
+#include <vdr/plugin.h>
+#include <upnp/ixml.h>
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+}
+#endif
+
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+/**
+ * Compares two strings
+ *
+ * This struct compares two strings and returns true on equality or false otherwise
+ * It is used in conjuction with hashmaps
+ */
+struct strCmp {
+ /**
+ * Compares two strings
+ * @return returns
+ * - \bc true, in case of equality
+ * - \bc false, otherwise
+ * @param s1 the first string
+ * @param s2 the second string
+ */
+ bool operator()(const char* s1, const char* s2) const { return (strcmp(s1,s2) < 0); }
+};
+/**
+ * Gets the IP address
+ *
+ * Returns the IP address of a given interface. The interface must be a valid interface
+ * identifier like eth0 or wlan1.
+ *
+ * @return a structure containing the IP address
+ * @param Interface to obtain the IP from
+ */
+const sockaddr_in* getIPFromInterface(const char* Interface);
+/**
+ * Gets the MAC address
+ *
+ * Returns a string representation of the MAC address of a given interface. The interface
+ * must be a valid interface identifier like eth0 or wlan1.
+ *
+ * The pattern of the address is sixth byte hex number separated with ":"
+ *
+ * @return a string containing the MAC
+ * @param Interface to obtain the MAC from
+ */
+const char* getMACFromInterface(const char* Interface);
+/**
+ * List with interfaces
+ *
+ * Returns an array with interfaces found on the system. The number of items
+ * in the array is stored in the parameter \c count.
+ *
+ * @return array list of interfaces
+ * @param count number of interfaces in the array
+ */
+char** getNetworkInterfaces(int *count);
+/**
+ * First occurance of item
+ *
+ * Finds the first occurance of a specified item in a given \bc IXML document and returns its value.
+ * If an error occures, its code is stored in the last parameter \c 'error'.
+ *
+ * @return the value of the item
+ * @param doc the \c IXML document to be parsed
+ * @param item the item which shall be found
+ * @param error the error code in case of an error
+ */
+char* ixmlGetFirstDocumentItem( IN IXML_Document * doc, IN const char *item, int* error );
+/**
+ * Adds a property
+ *
+ * This adds a UPnP property to an \bc IXML document.
+ * The property must have the pattern "namespace:property@attribute".
+ *
+ * @return returns
+ * - \bc <0, in case of an error
+ * - \bc 0, otherwise
+ * @param document the \c IXML document to put the parameter in
+ * @param node the specific node where to put the parameter
+ * @param upnpproperty the upnp property
+ * @param value the value of the upnp property
+ */
+int ixmlAddProperty(IN IXML_Document* document, IN IXML_Element* node, const char* upnpproperty, const char* value );
+/**
+ * creates a part of a string
+ *
+ * This creates a substring of a string which begins at the given offset and has the
+ * specified lenght.
+ *
+ * @return the new string
+ * @param str the full string
+ * @param offset the starting index
+ * @param length the length of the new string
+ */
+char* substr(const char* str, unsigned int offset, unsigned int length);
+
+char* duration(off64_t duration, unsigned int timeBase = 1);
+
+#if 0
+{
+#endif
+}
+#endif
+
+/**
+ * Escapes XML special characters
+ *
+ * This function escapes XML special characters, which must be transformed before
+ * inserting it into another XML document.
+ *
+ * @return the escaped document
+ * @param Data the data to escape
+ * @param Buf the pointer where the escaped document shall be stored
+ */
+const char* escapeXMLCharacters(const char* Data, char** Buf);
+
+/** @private */
+class cMenuEditIpItem: public cMenuEditItem {
+private:
+ char *value;
+ int curNum;
+ int pos;
+ bool step;
+protected:
+ virtual void Set(void);
+public:
+ cMenuEditIpItem(const char *Name, char *Value); // Value must be 16 bytes
+ ~cMenuEditIpItem();
+ virtual eOSState ProcessKey(eKeys Key);
+};
+
+#endif /* _UTIL_H */
+
diff --git a/inc/webserver.h b/inc/webserver.h
new file mode 100644
index 0000000..0a49cf9
--- /dev/null
+++ b/inc/webserver.h
@@ -0,0 +1,160 @@
+/*
+ * File: upnpwebserver.h
+ * Author: savop
+ *
+ * Created on 30. Mai 2009, 18:13
+ */
+
+#ifndef _UPNPWEBSERVER_H
+#define _UPNPWEBSERVER_H
+
+#include "../common.h"
+#include <upnp/upnp.h>
+
+/**
+ * The internal webserver
+ *
+ * This is the internal webserver. It distributes all the contents of the
+ * UPnP-Server.
+ *
+ */
+class cUPnPWebServer {
+ friend class cUPnPServer;
+private:
+ static cUPnPWebServer *mInstance;
+ static UpnpVirtualDirCallbacks mVirtualDirCallbacks;
+ const char* mRootdir;
+ cUPnPWebServer(const char* root = "/");
+protected:
+public:
+ /**
+ * Initializes the webserver
+ *
+ * It enables the webserver which comes with the <em>Intel SDK</em> and creates
+ * virtual directories for shares media.
+ *
+ * @return returns
+ * - \bc true, if initializing was successful
+ * - \bc false, otherwise
+ */
+ bool init();
+ /**
+ * Uninitializes the webserver
+ *
+ * This stops the webserver.
+ *
+ * @return returns
+ * - \bc true, if initializing was successful
+ * - \bc false, otherwise
+ */
+ bool uninit();
+ /**
+ * Returns the instance of the webserver
+ *
+ * Returns the instance of the webserver. This will create a single
+ * instance of none is existing on the very first call. A subsequent call
+ * will return the same instance.
+ *
+ * @return the instance of webserver
+ */
+ static cUPnPWebServer* getInstance(
+ const char* rootdir = "/" /**< the root directory of the webserver */
+ );
+ virtual ~cUPnPWebServer();
+//};
+
+ /****************************************************
+ *
+ * The callback functions for the webserver
+ *
+ ****************************************************/
+
+ /**
+ * Retrieve file information
+ *
+ * Returns file related information for an virtual directory file
+ *
+ * @return 0 on success, -1 otherwise
+ * @param filename The filename of which the information is gathered
+ * @param info The File_Info structure with the data
+ */
+ static int getInfo(const char* filename, struct File_Info* info);
+ /**
+ * Opens a virtual directory file
+ *
+ * Opens a file in a virtual directory with the specified mode.
+ *
+ * Possible modes are:
+ * - \b UPNP_READ, Opens the file for reading
+ * - \b UPNP_WRITE, Opens the file for writing
+ *
+ * It returns a file handle to the opened file, NULL otherwise
+ *
+ * @return FileHandle to the opened file, NULL otherwise
+ * @param filename The file to open
+ * @param mode UPNP_WRITE for writing, UPNP_READ for reading.
+ */
+ static UpnpWebFileHandle open(const char* filename, UpnpOpenFileMode mode);
+ /**
+ * Reads from the opened file
+ *
+ * Reads <code>buflen</code> bytes from the file and stores the content
+ * to the buffer
+ *
+ * Returns 0 no more bytes read (EOF)
+ * >0 bytes read from file
+ *
+ * @return number of bytes read, 0 on EOF
+ * @param fh the file handle of the opened file
+ * @param buf the buffer to write the bytes to
+ * @param buflen the maximum count of bytes to read
+ *
+ */
+ static int read(UpnpWebFileHandle fh, char* buf, size_t buflen);
+ /**
+ * Writes to the opened file
+ *
+ * Writes <code>buflen</code> bytes from the buffer and stores the content
+ * in the file
+ *
+ * Returns >0 bytes wrote to file, maybe less the buflen in case of write
+ * errors
+ *
+ * @return number of bytes read, 0 on EOF
+ * @param fh the file handle of the opened file
+ * @param buf the buffer to read the bytes from
+ * @param buflen the maximum count of bytes to write
+ *
+ */
+ static int write(UpnpWebFileHandle fh, char* buf, size_t buflen);
+ /**
+ * Seek in the file
+ *
+ * Seeks in the opened file and sets the file pointer to the specified offset
+ *
+ * Returns 0 on success, non-zero value otherwise
+ *
+ * @return 0 on success, non-zero value otherwise
+ * @param fh the file handle of the opened file
+ * @param offset a negative oder positive value which moves the pointer
+ * forward or backward
+ * @param origin SEEK_CUR, SEEK_END or SEEK_SET
+ *
+ */
+ static int seek(UpnpWebFileHandle fh, off_t offset, int origin);
+ /**
+ * Closes the file
+ *
+ * closes the opened file
+ *
+ * Returns 0 on success, non-zero value otherwise
+ *
+ * @return 0 on success, non-zero value otherwise
+ * @param fh the file handle of the opened file
+ *
+ */
+ static int close(UpnpWebFileHandle fh);
+};
+
+#endif /* _UPNPWEBSERVER_H */
+