Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Merged
merged 1 commit into from

3 participants

@alcoheca
Collaborator

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

@alcoheca 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")) {
@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());
@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
@Montellese
Owner

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

@alcoheca 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
@alcoheca
Collaborator

@elupus happy with this going in?

@elupus
Collaborator
@alcoheca alcoheca merged commit a039355 into xbmc:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 9, 2012
  1. @alcoheca

    [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.
View
115 xbmc/network/upnp/UPnPRenderer.cpp
@@ -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");
View
7 xbmc/network/upnp/UPnPRenderer.h
@@ -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.