Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[UPnP] fix: use Announcement manager to update UPnPRenderer state vars #1578

Merged
merged 1 commit into from

3 participants

Alasdair Campbell Sascha Montellese Joakim Plate
Alasdair Campbell
Collaborator

This fixes sometime incorrect metadata after changing track, and also reduces the number of lookups.

Alasdair Campbell alcoheca was assigned
xbmc/network/upnp/UPnPRenderer.cpp
@@ -175,6 +179,58 @@
}
/*----------------------------------------------------------------------
+| CUPnPRenderer::Announce
++---------------------------------------------------------------------*/
+void
+CUPnPRenderer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
+{
+ if (strcmp(sender, "xbmc"))
+ return;
+
+ NPT_AutoLock lock(m_state);
+ PLT_Service *avt, *rct;
+
+ if (flag == Player) {
+ if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", avt)))
+ return;
+ if (!strcmp(message, "OnPlay")) {
Sascha Montellese Owner

Could we get

if (strcmp(message, "OnPlay") == 0)

here instead. That "!" confused me for a second as it kinda reads like "if not string compare".

EDIT: Same on the ones further down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/network/upnp/UPnPRenderer.cpp
((30 lines not shown))
+ }
+ else if (!strcmp(message, "OnPause")) {
+ avt->SetStateVariable("TransportPlaySpeed", (const char*)NPT_String::FromInteger(data["speed"].asInteger()));
+ avt->SetStateVariable("TransportState", "PAUSED_PLAYBACK");
+ }
+ else if (!strcmp(message, "OnSpeedChanged")) {
+ avt->SetStateVariable("TransportPlaySpeed", (const char*)NPT_String::FromInteger(data["speed"].asInteger()));
+ }
+ }
+ else if (flag == Application && !strcmp(message, "OnVolumeChanged")) {
+ if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:1", rct)))
+ return;
+
+ CStdString buffer;
+
+ buffer.Format("%d", data["volume"].asInteger());
Sascha Montellese Owner

You might wanna cast the return value of asInteger() to (int) because it returns int64_t which doesn't match %d (same further down).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sascha Montellese
Owner

Apart from the two things I mentioned and @jmarshallnz's comment it looks good.

Alasdair Campbell alcoheca [UPnP] fix: use Announcement manager to update metadata and volume st…
…atevariables

rather than every second in Application::ProcessSlow. Also handle play/pause
toggling.
5d2626f
Alasdair Campbell
Collaborator

@elupus happy with this going in?

Joakim Plate
Collaborator
Alasdair Campbell alcoheca merged commit a039355 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 9, 2012
  1. Alasdair Campbell

    [UPnP] fix: use Announcement manager to update metadata and volume st…

    alcoheca authored
    …atevariables
    
    rather than every second in Application::ProcessSlow. Also handle play/pause
    toggling.
This page is out of date. Refresh to see the latest.
115 xbmc/network/upnp/UPnPRenderer.cpp
View
@@ -9,13 +9,35 @@
#include "guilib/GUIWindowManager.h"
#include "pictures/GUIWindowSlideShow.h"
#include "pictures/PictureInfoTag.h"
+#include "interfaces/AnnouncementManager.h"
#include "settings/Settings.h"
#include "utils/URIUtils.h"
+#include "utils/Variant.h"
+
+using namespace ANNOUNCEMENT;
namespace UPNP
{
/*----------------------------------------------------------------------
+| CUPnPRenderer::CUPnPRenderer
++---------------------------------------------------------------------*/
+CUPnPRenderer::CUPnPRenderer(const char* friendly_name, bool show_ip /*= false*/,
+ const char* uuid /*= NULL*/, unsigned int port /*= 0*/)
+ : PLT_MediaRenderer(friendly_name, show_ip, uuid, port)
+{
+ CAnnouncementManager::AddAnnouncer(this);
+}
+
+/*----------------------------------------------------------------------
+| CUPnPRenderer::~CUPnPRenderer
++---------------------------------------------------------------------*/
+CUPnPRenderer::~CUPnPRenderer()
+{
+ CAnnouncementManager::RemoveAnnouncer(this);
+}
+
+/*----------------------------------------------------------------------
| CUPnPRenderer::SetupServices
+---------------------------------------------------------------------*/
NPT_Result
@@ -175,6 +197,58 @@ CUPnPRenderer::ProcessHttpRequest(NPT_HttpRequest& request,
}
/*----------------------------------------------------------------------
+| CUPnPRenderer::Announce
++---------------------------------------------------------------------*/
+void
+CUPnPRenderer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
+{
+ if (strcmp(sender, "xbmc") != 0)
+ return;
+
+ NPT_AutoLock lock(m_state);
+ PLT_Service *avt, *rct;
+
+ if (flag == Player) {
+ if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", avt)))
+ return;
+ if (strcmp(message, "OnPlay") == 0) {
+ avt->SetStateVariable("AVTransportURI", g_application.CurrentFile().c_str());
+ avt->SetStateVariable("CurrentTrackURI", g_application.CurrentFile().c_str());
+
+ NPT_String meta;
+ if (NPT_SUCCEEDED(GetMetadata(meta))) {
+ avt->SetStateVariable("CurrentTrackMetadata", meta);
+ avt->SetStateVariable("AVTransportURIMetaData", meta);
+ }
+
+ avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger()));
+ avt->SetStateVariable("TransportState", "PLAYING");
+ }
+ else if (strcmp(message, "OnPause") == 0) {
+ avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger()));
+ avt->SetStateVariable("TransportState", "PAUSED_PLAYBACK");
+ }
+ else if (strcmp(message, "OnSpeedChanged") == 0) {
+ avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger()));
+ }
+ }
+ else if (flag == Application && strcmp(message, "OnVolumeChanged") == 0) {
+ if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:1", rct)))
+ return;
+
+ CStdString buffer;
+
+ buffer.Format("%ld", data["volume"].asInteger());
+ rct->SetStateVariable("Volume", buffer.c_str());
+
+ buffer.Format("%ld", 256 * (data["volume"].asInteger() * 60 - 60) / 100);
+ rct->SetStateVariable("VolumeDb", buffer.c_str());
+
+ rct->SetStateVariable("Mute", data["muted"].asBoolean() ? "1" : "0");
+ }
+}
+
+/*----------------------------------------------------------------------
| CUPnPRenderer::UpdateState
+---------------------------------------------------------------------*/
void
@@ -182,11 +256,10 @@ CUPnPRenderer::UpdateState()
{
NPT_AutoLock lock(m_state);
- PLT_Service *avt, *rct;
+ PLT_Service *avt;
+
if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", avt)))
return;
- if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:1", rct)))
- return;
/* don't update state while transitioning */
NPT_String state;
@@ -194,34 +267,13 @@ CUPnPRenderer::UpdateState()
if(state == "TRANSITIONING")
return;
- CStdString buffer;
- int volume;
- if (g_settings.m_bMute) {
- rct->SetStateVariable("Mute", "1");
- } else {
- rct->SetStateVariable("Mute", "0");
- }
- volume = g_application.GetVolume();
-
- buffer.Format("%d", volume);
- rct->SetStateVariable("Volume", buffer.c_str());
-
- buffer.Format("%d", 256 * (volume * 60 - 60) / 100);
- rct->SetStateVariable("VolumeDb", buffer.c_str());
+ avt->SetStateVariable("TransportStatus", "OK");
if (g_application.IsPlaying() || g_application.IsPaused()) {
- if (g_application.IsPaused()) {
- avt->SetStateVariable("TransportState", "PAUSED_PLAYBACK");
- } else {
- avt->SetStateVariable("TransportState", "PLAYING");
- }
-
- avt->SetStateVariable("TransportStatus", "OK");
- avt->SetStateVariable("TransportPlaySpeed", (const char*)NPT_String::FromInteger(g_application.GetPlaySpeed()));
avt->SetStateVariable("NumberOfTracks", "1");
avt->SetStateVariable("CurrentTrack", "1");
- buffer = g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS);
+ CStdString buffer = g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS);
avt->SetStateVariable("RelativeTimePosition", buffer.c_str());
avt->SetStateVariable("AbsoluteTimePosition", buffer.c_str());
@@ -234,17 +286,6 @@ CUPnPRenderer::UpdateState()
avt->SetStateVariable("CurrentMediaDuration", "00:00:00");
}
- avt->SetStateVariable("AVTransportURI", g_application.CurrentFile().c_str());
- avt->SetStateVariable("CurrentTrackURI", g_application.CurrentFile().c_str());
-
- NPT_String metadata;
- avt->GetStateVariableValue("AVTransportURIMetaData", metadata);
- // try to recreate the didl dynamically if not set
- if (metadata.IsEmpty()) {
- GetMetadata(metadata);
- }
- avt->SetStateVariable("CurrentTrackMetadata", metadata);
- avt->SetStateVariable("AVTransportURIMetaData", metadata);
} else if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) {
avt->SetStateVariable("TransportState", "PLAYING");
7 xbmc/network/upnp/UPnPRenderer.h
View
@@ -19,6 +19,7 @@
*
*/
#include "PltMediaRenderer.h"
+#include "interfaces/IAnnouncer.h"
namespace UPNP
{
@@ -30,13 +31,17 @@ class CRendererReferenceHolder
};
class CUPnPRenderer : public PLT_MediaRenderer
+ , public ANNOUNCEMENT::IAnnouncer
{
public:
CUPnPRenderer(const char* friendly_name,
bool show_ip = false,
const char* uuid = NULL,
- unsigned int port = 0) : PLT_MediaRenderer(friendly_name, show_ip, uuid, port) {}
+ unsigned int port = 0);
+ virtual ~CUPnPRenderer();
+
+ virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
void UpdateState();
// Http server handler
Something went wrong with that request. Please try again.