diff options
Diffstat (limited to 'inc')
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 */ + |