Ticket #9632: xbo360upnp

File xbo360upnp, 13.4 KB (added by Joe Bryant <tenminjoe@…>, 14 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 = "" );