Ticket #9632: xbo360upnp

File xbo360upnp, 13.4 KB (added by Joe Bryant <tenminjoe@…>, 13 years ago)

Patch to make UPnP compatible with Xbox 360

Line 
1
2
3Index: /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.h
4===================================================================
5--- /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.h    (revision 27420)
6+++ /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.h    (working copy)
7@@ -164,6 +164,8 @@
8 
9     protected:
10 
11+        virtual bool IsOurContainerPrefix(QString sContainerID) { return false; };
12+        virtual QString RemoveContainerPrefix(QString sContainerID) { return sContainerID; };
13         QString RemoveToken ( const QString &sToken, const QString &sStr, int num );
14 
15         virtual UPnpCDSExtensionResults *ProcessRoot     ( UPnpCDSRequest          *pRequest,
16@@ -199,7 +201,7 @@
17 
18         // ------------------------------------------------------------------
19 
20-        virtual UPnpCDSRootInfo *GetRootInfo   ( int nIdx) = 0;
21+        virtual UPnpCDSRootInfo *GetRootInfo   ( int nIdx, QString sContainerId = "" ) = 0;
22         virtual int              GetRootCount  ( )         = 0;
23         virtual QString          GetTableName  ( QString sColumn      ) = 0;
24         virtual QString          GetItemListSQL( QString sColumn = "" ) = 0;
25
26
27Index: /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.cpp
28===================================================================
29--- /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.cpp  (revision 27420)
30+++ /home/joe/mythtv-trunk/mythtv/libs/libmythupnp/upnpcds.cpp  (working copy)
31@@ -481,13 +481,17 @@
32     // ----------------------------------------------------------------------
33     // -=>TODO: Need to process all expressions in searchCriteria... for now,
34     //          Just focus on the "upnp:class derivedfrom" expression
35+    //          and the "upnp:class =" expression
36     // ----------------------------------------------------------------------
37 
38     for ( QStringList::Iterator it  = request.m_sSearchList.begin();
39                                 it != request.m_sSearchList.end();
40                               ++it )
41     {
42-        if ((*it).contains("upnp:class derivedfrom", Qt::CaseInsensitive))
43+        if ((*it).contains("upnp:class derivedfrom", Qt::CaseInsensitive)
44+            ||
45+            (*it).contains("upnp:class =", Qt::CaseInsensitive)
46+        )
47         {
48             QStringList sParts = (*it).split(' ', QString::SkipEmptyParts);
49 
50@@ -495,6 +499,7 @@
51             {
52                 request.m_sSearchClass = sParts[2].trimmed();
53                 request.m_sSearchClass.remove( '"' );
54+                request.m_sSearchClass.remove( ')' );
55 
56                 break;
57             }
58@@ -758,7 +763,12 @@
59 
60     UPnpCDSExtensionResults *pResults = new UPnpCDSExtensionResults();
61 
62-    CreateItems( pRequest, pResults, 0, "", false );
63+    QString sKey = "";
64+    if (IsOurContainerPrefix(pRequest->m_sContainerID))
65+    {
66+        sKey = RemoveContainerPrefix(pRequest->m_sContainerID);
67+    }
68+    CreateItems( pRequest, pResults, 0, sKey, false );
69 
70     return pResults;
71 }
72@@ -1258,7 +1268,7 @@
73     pResults->m_nTotalMatches = 0;
74     pResults->m_nUpdateID     = 1;
75 
76-    UPnpCDSRootInfo *pInfo = GetRootInfo( nNodeIdx );
77+    UPnpCDSRootInfo *pInfo = GetRootInfo( nNodeIdx, pRequest->m_sContainerID );
78 
79     if (pInfo == NULL)
80         return;
81
82
83Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mediaserver.cpp
84===================================================================
85--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mediaserver.cpp  (revision 27420)
86+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mediaserver.cpp  (working copy)
87@@ -16,6 +16,7 @@
88 #include "upnpcdsmusic.h"
89 #include "upnpcdsvideo.h"
90 #include "upnpmedia.h"
91+#include "upnpcdsmusicalbum.h"
92 
93 //////////////////////////////////////////////////////////////////////////////
94 //////////////////////////////////////////////////////////////////////////////
95@@ -178,6 +179,10 @@
96 
97             RegisterExtension(new UPnpCDSVideo());
98 
99+            VERBOSE(VB_UPNP, "MediaServer::Registering UPnpCDSMusicAlbum Extension");
100+
101+            RegisterExtension(new UPnpCDSMusicAlbum());
102+
103             upnpMedia = new UPnpMedia(true,true);
104             //upnpMedia->BuildMediaMap();
105         }
106
107
108Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.h
109===================================================================
110--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.h   (revision 27420)
111+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.h   (working copy)
112@@ -46,7 +46,7 @@
113 
114         virtual int              GetDistinctCount( UPnpCDSRootInfo *pInfo );
115 
116-        virtual UPnpCDSRootInfo *GetRootInfo   (int nIdx);
117+        virtual UPnpCDSRootInfo *GetRootInfo   ( int nIdx, QString sContainerId = "" );
118         virtual int              GetRootCount  ( );
119         virtual QString          GetTableName  ( QString sColumn );
120         virtual QString          GetItemListSQL( QString sColumn = "");
121
122
123Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.h
124===================================================================
125--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.h   (revision 27420)
126+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.h   (working copy)
127@@ -24,14 +24,18 @@
128     private:
129 
130         static UPnpCDSRootInfo g_RootNodes[];
131+        static UPnpCDSRootInfo g_Containers[];
132         static int             g_nRootCount;
133+        static int             g_nContainersCount;
134 
135     protected:
136 
137+        virtual bool             IsOurContainerPrefix ( QString sContainerId );
138+        virtual QString          RemoveContainerPrefix ( QString sContainerId );
139         virtual bool             IsBrowseRequestForUs( UPnpCDSRequest *pRequest );
140         virtual bool             IsSearchRequestForUs( UPnpCDSRequest *pRequest );
141 
142-        virtual UPnpCDSRootInfo *GetRootInfo   (int nIdx);
143+        virtual UPnpCDSRootInfo *GetRootInfo   ( int nIdx, QString sContainerId = "" );
144         virtual int              GetRootCount  ( );
145         virtual QString          GetTableName  ( QString sColumn );
146         virtual QString          GetItemListSQL( QString sColumn = "" );
147
148
149Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.cpp
150===================================================================
151--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.cpp    (revision 27420)
152+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.cpp    (working copy)
153@@ -112,7 +112,7 @@
154 //
155 /////////////////////////////////////////////////////////////////////////////
156 
157-UPnpCDSRootInfo *UPnpCDSTv::GetRootInfo( int nIdx )
158+UPnpCDSRootInfo *UPnpCDSTv::GetRootInfo( int nIdx, QString sContainerId )
159 {
160     if ((nIdx >=0 ) && ( nIdx < g_nRootCount ))
161         return &(g_RootNodes[ nIdx ]);
162
163
164Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.cpp
165===================================================================
166--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.cpp (revision 27420)
167+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsvideo.cpp (working copy)
168@@ -44,7 +44,7 @@
169 //
170 /////////////////////////////////////////////////////////////////////////////
171 
172-UPnpCDSRootInfo *UPnpCDSVideo::GetRootInfo( int nIdx )
173+UPnpCDSRootInfo *UPnpCDSVideo::GetRootInfo( int nIdx, QString sContainerId )
174 {
175     if ((nIdx >=0 ) && ( nIdx < g_nRootCount ))
176         return &(g_RootNodes[ nIdx ]);
177
178
179Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mythbackend.pro
180===================================================================
181--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mythbackend.pro  (revision 27420)
182+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/mythbackend.pro  (working copy)
183@@ -22,12 +22,14 @@
184 HEADERS += playbacksock.h scheduler.h server.h housekeeper.h backendutil.h
185 HEADERS += upnpcdstv.h upnpcdsmusic.h upnpcdsvideo.h mediaserver.h
186 HEADERS += mythxml.h upnpmedia.h main_helpers.h backendcontext.h
187+HEADERS += upnpcdsmusicalbum.h
188 
189 SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp
190 SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp
191 SOURCES += housekeeper.cpp backendutil.cpp
192 SOURCES += upnpcdstv.cpp upnpcdsmusic.cpp upnpcdsvideo.cpp mediaserver.cpp
193 SOURCES += mythxml.cpp upnpmedia.cpp main_helpers.cpp backendcontext.cpp
194+SOURCES += upnpcdsmusicalbum.cpp
195 
196 using_oss:DEFINES += USING_OSS
197 
198
199
200Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.cpp
201===================================================================
202--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.cpp (revision 27420)
203+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdsmusic.cpp (working copy)
204@@ -108,12 +108,37 @@
205 
206 int UPnpCDSMusic::g_nRootCount = sizeof( g_RootNodes ) / sizeof( UPnpCDSRootInfo );
207 
208+UPnpCDSRootInfo UPnpCDSMusic::g_Containers[] =
209+{
210+     {
211+        "musicalbum",
212+        "song.album_id",
213+        "SELECT song_id as id, "
214+        "name, "
215+        "1 as children "
216+        "FROM music_songs song "
217+        "%1 "
218+        "ORDER BY name",
219+        "WHERE album_id = :KEY"
220+     }
221+};
222+
223+int UPnpCDSMusic::g_nContainersCount = sizeof( g_Containers ) / sizeof( UPnpCDSRootInfo );
224+
225 /////////////////////////////////////////////////////////////////////////////
226 //
227 /////////////////////////////////////////////////////////////////////////////
228 
229-UPnpCDSRootInfo *UPnpCDSMusic::GetRootInfo( int nIdx )
230+UPnpCDSRootInfo *UPnpCDSMusic::GetRootInfo( int nIdx, QString sContainerId )
231 {
232+    for(int i=0; i<g_nContainersCount; i++)
233+    {
234+        if (sContainerId.startsWith(g_Containers[ i ].title))
235+        {
236+            return &(g_Containers[ i ]);
237+        }
238+    }
239+       
240     if ((nIdx >=0 ) && ( nIdx < g_nRootCount ))
241         return &(g_RootNodes[ nIdx ]);
242 
243@@ -174,6 +199,38 @@
244 //
245 /////////////////////////////////////////////////////////////////////////////
246 
247+bool UPnpCDSMusic::IsOurContainerPrefix(QString sContainerId)
248+{
249+    for(int i=0; i<g_nContainersCount; i++)
250+    {
251+        if (sContainerId.startsWith(g_Containers[ i ].title))
252+        {
253+            return true;
254+        }
255+    }
256+    return false;
257+}
258+
259+/////////////////////////////////////////////////////////////////////////////
260+//
261+/////////////////////////////////////////////////////////////////////////////
262+
263+QString UPnpCDSMusic::RemoveContainerPrefix(QString sContainerId)
264+{
265+    for(int i=0; i<g_nContainersCount; i++)
266+    {
267+        if (sContainerId.startsWith(g_Containers[ i ].title))
268+        {
269+            return sContainerId.right(sContainerId.length() - strlen(g_Containers[ i ].title));
270+        }
271+    }
272+    return sContainerId;
273+}
274+
275+/////////////////////////////////////////////////////////////////////////////
276+//
277+/////////////////////////////////////////////////////////////////////////////
278+
279 bool UPnpCDSMusic::IsBrowseRequestForUs( UPnpCDSRequest *pRequest )
280 {
281     // ----------------------------------------------------------------------
282@@ -181,7 +238,7 @@
283     // ----------------------------------------------------------------------
284 
285     // Xbox360 compatibility code.
286-
287+    /*
288     if (pRequest->m_eClient == CDS_ClientXBox &&
289         pRequest->m_sContainerID == "7")
290     {
291@@ -191,7 +248,7 @@
292 
293         return true;
294     }
295-
296+    */
297     if ((pRequest->m_sObjectId.isEmpty()) &&
298         (!pRequest->m_sContainerID.isEmpty()))
299         pRequest->m_sObjectId = pRequest->m_sContainerID;
300@@ -212,7 +269,7 @@
301     // ----------------------------------------------------------------------
302 
303     // XBox 360 compatibility code
304-
305+    /*
306     if (pRequest->m_eClient == CDS_ClientXBox &&
307         pRequest->m_sContainerID == "7")
308     {
309@@ -224,7 +281,7 @@
310 
311         return true;
312     }
313-
314+    */
315     if (pRequest->m_sContainerID == "4")
316     {
317         pRequest->m_sObjectId       = "Music";
318@@ -304,7 +361,7 @@
319                             .arg( sServerIp )
320                             .arg( sPort     );
321 
322-    QString sURIParams = QString( "?Id=%1" )
323+    QString sURIParams = QString( "\%3FId\%3D%1" )
324                             .arg( nId );
325 
326 
327@@ -365,15 +422,14 @@
328                                                 .arg( sURIParams );
329 
330     Resource *pRes = pItem->AddResource( sProtocol, sURI );
331-
332-    nLength /= 1000;
333-
334     QString sDur;
335 
336-    sDur.sprintf("%02d:%02d:%02d",
337-                  (nLength / 3600) % 24,
338-                  (nLength / 60) % 60,
339-                  nLength % 60);
340+    sDur.sprintf("%02d:%02d:%02d.%03d",
341+                  (nLength / 3600000) % 24,
342+                  (nLength / 60000) % 60,
343+                  (nLength / 1000) % 60,
344+                  nLength % 1000
345+                );
346 
347     pRes->AddAttribute( "duration"  , sDur      );
348 }
349
350
351Index: /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.h
352===================================================================
353--- /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.h      (revision 27420)
354+++ /home/joe/mythtv-trunk/mythtv/programs/mythbackend/upnpcdstv.h      (working copy)
355@@ -32,7 +32,7 @@
356         virtual bool             IsBrowseRequestForUs( UPnpCDSRequest *pRequest );
357         virtual bool             IsSearchRequestForUs( UPnpCDSRequest *pRequest );
358 
359-        virtual UPnpCDSRootInfo *GetRootInfo   (int nIdx);
360+        virtual UPnpCDSRootInfo *GetRootInfo   ( int nIdx, QString sContainerId = "" );
361         virtual int              GetRootCount  ( );
362         virtual QString          GetTableName  ( QString sColumn );
363         virtual QString          GetItemListSQL( QString sColumn = "" );