mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
xbmc: update to xbmc-12.1.4
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
6d7638b88b
commit
b164ec443d
@ -19,7 +19,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="xbmc-theme-Confluence"
|
||||
PKG_VERSION="12.1.3"
|
||||
PKG_VERSION="12.1.4"
|
||||
if [ "$XBMC" = "master" ]; then
|
||||
PKG_VERSION="17411f2"
|
||||
fi
|
||||
|
@ -19,7 +19,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="xbmc"
|
||||
PKG_VERSION="12.1.3"
|
||||
PKG_VERSION="12.1.4"
|
||||
if [ "$XBMC" = "master" ]; then
|
||||
PKG_VERSION="17411f2"
|
||||
fi
|
||||
|
@ -1,26 +0,0 @@
|
||||
From b93a152c7c4dcdd2936711b59b5c209bc51d3f13 Mon Sep 17 00:00:00 2001
|
||||
From: Memphiz <memphis@machzwo.de>
|
||||
Date: Wed, 20 Mar 2013 22:22:47 +0100
|
||||
Subject: [PATCH] [airplay] - handle empty session ids from itunes
|
||||
|
||||
---
|
||||
xbmc/network/AirPlayServer.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp
|
||||
index 11daa97..5b64126 100644
|
||||
--- a/xbmc/network/AirPlayServer.cpp
|
||||
+++ b/xbmc/network/AirPlayServer.cpp
|
||||
@@ -645,6 +645,9 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
CStdString authorization = m_httpParser->getValue("authorization");
|
||||
int status = AIRPLAY_STATUS_OK;
|
||||
bool needAuth = false;
|
||||
+
|
||||
+ if (m_sessionId.IsEmpty())
|
||||
+ m_sessionId = "00000000-0000-0000-0000-000000000000";
|
||||
|
||||
if (ServerInstance->m_usePassword && !m_bAuthenticated)
|
||||
{
|
||||
--
|
||||
1.8.1.5
|
||||
|
@ -1,385 +0,0 @@
|
||||
From 7f0b5c61deb28bf7825a3504709be21fa37d95c1 Mon Sep 17 00:00:00 2001
|
||||
From: Memphiz <memphis@machzwo.de>
|
||||
Date: Wed, 20 Mar 2013 22:25:18 +0100
|
||||
Subject: [PATCH] [airplay] - refactor the playstate announcement by using the
|
||||
IAnnouncer interface - also adapt to some new findings on revers engineering
|
||||
itunes airplay traffic (add sessioncounter to reverse event and fix http
|
||||
request formatting) - fixes #14191
|
||||
|
||||
---
|
||||
xbmc/network/AirPlayServer.cpp | 133 ++++++++++++++++++++++++++---------------
|
||||
xbmc/network/AirPlayServer.h | 19 ++++--
|
||||
2 files changed, 97 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp
|
||||
index c4c4984..28e8075 100644
|
||||
--- a/xbmc/network/AirPlayServer.cpp
|
||||
+++ b/xbmc/network/AirPlayServer.cpp
|
||||
@@ -38,6 +38,9 @@
|
||||
#include "utils/Variant.h"
|
||||
#include "guilib/GUIWindowManager.h"
|
||||
#include "URL.h"
|
||||
+#include "interfaces/AnnouncementManager.h"
|
||||
+
|
||||
+using namespace ANNOUNCEMENT;
|
||||
|
||||
#ifdef TARGET_WINDOWS
|
||||
#define close closesocket
|
||||
@@ -134,6 +137,8 @@
|
||||
"<dict>\r\n"\
|
||||
"<key>category</key>\r\n"\
|
||||
"<string>video</string>\r\n"\
|
||||
+"<key>sessionID</key>\r\n"\
|
||||
+"<integer>%d</integer>\r\n"\
|
||||
"<key>state</key>\r\n"\
|
||||
"<string>%s</string>\r\n"\
|
||||
"</dict>\r\n"\
|
||||
@@ -142,6 +147,25 @@
|
||||
#define AUTH_REALM "AirPlay"
|
||||
#define AUTH_REQUIRED "WWW-Authenticate: Digest realm=\"" AUTH_REALM "\", nonce=\"%s\"\r\n"
|
||||
|
||||
+void CAirPlayServer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
|
||||
+{
|
||||
+ if ( (flag & Player) && strcmp(sender, "xbmc") == 0 && ServerInstance)
|
||||
+ {
|
||||
+ if (strcmp(message, "OnStop") == 0)
|
||||
+ {
|
||||
+ ServerInstance->AnnounceToClients(EVENT_STOPPED);
|
||||
+ }
|
||||
+ else if (strcmp(message, "OnPlay") == 0)
|
||||
+ {
|
||||
+ ServerInstance->AnnounceToClients(EVENT_PLAYING);
|
||||
+ }
|
||||
+ else if (strcmp(message, "OnPause") == 0)
|
||||
+ {
|
||||
+ ServerInstance->AnnounceToClients(EVENT_PAUSED);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
bool CAirPlayServer::StartServer(int port, bool nonlocal)
|
||||
{
|
||||
StopServer(true);
|
||||
@@ -187,17 +211,62 @@ void CAirPlayServer::StopServer(bool bWait)
|
||||
}
|
||||
}
|
||||
|
||||
+void CAirPlayServer::AnnounceToClients(int state)
|
||||
+{
|
||||
+ CSingleLock lock (m_connectionLock);
|
||||
+
|
||||
+ std::vector<CTCPClient>::iterator it;
|
||||
+ for (it = m_connections.begin(); it != m_connections.end(); it++)
|
||||
+ {
|
||||
+ CStdString reverseHeader;
|
||||
+ CStdString reverseBody;
|
||||
+ CStdString response;
|
||||
+ int reverseSocket = INVALID_SOCKET;
|
||||
+ it->ComposeReverseEvent(reverseHeader, reverseBody, state);
|
||||
+
|
||||
+ // Send event status per reverse http socket (play, loading, paused)
|
||||
+ // if we have a reverse header and a reverse socket
|
||||
+ if (reverseHeader.size() > 0 && m_reverseSockets.find(it->m_sessionId) != m_reverseSockets.end())
|
||||
+ {
|
||||
+ //search the reverse socket to this sessionid
|
||||
+ response.Format("POST /event HTTP/1.1\r\n");
|
||||
+ reverseSocket = m_reverseSockets[it->m_sessionId]; //that is our reverse socket
|
||||
+ response += reverseHeader;
|
||||
+ }
|
||||
+ response += "\r\n";
|
||||
+
|
||||
+ if (reverseBody.size() > 0)
|
||||
+ {
|
||||
+ response += reverseBody;
|
||||
+ }
|
||||
+
|
||||
+ // don't send it to the connection object
|
||||
+ // the reverse socket itself belongs to
|
||||
+ if (reverseSocket != INVALID_SOCKET && reverseSocket != it->m_socket)
|
||||
+ {
|
||||
+ send(reverseSocket, response.c_str(), response.size(), 0);//send the event status on the eventSocket
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
CAirPlayServer::CAirPlayServer(int port, bool nonlocal) : CThread("AirPlayServer")
|
||||
{
|
||||
m_port = port;
|
||||
m_nonlocal = nonlocal;
|
||||
m_ServerSocket = INVALID_SOCKET;
|
||||
m_usePassword = false;
|
||||
+ CAnnouncementManager::AddAnnouncer(this);
|
||||
+}
|
||||
+
|
||||
+CAirPlayServer::~CAirPlayServer()
|
||||
+{
|
||||
+ CAnnouncementManager::RemoveAnnouncer(this);
|
||||
}
|
||||
|
||||
void CAirPlayServer::Process()
|
||||
{
|
||||
m_bStop = false;
|
||||
+ static int sessionCounter = 0;
|
||||
|
||||
while (!m_bStop)
|
||||
{
|
||||
@@ -240,6 +309,7 @@ void CAirPlayServer::Process()
|
||||
}
|
||||
if (nread <= 0)
|
||||
{
|
||||
+ CSingleLock lock (m_connectionLock);
|
||||
CLog::Log(LOGINFO, "AIRPLAY Server: Disconnection detected");
|
||||
m_connections[i].Disconnect();
|
||||
m_connections.erase(m_connections.begin() + i);
|
||||
@@ -252,6 +322,8 @@ void CAirPlayServer::Process()
|
||||
CLog::Log(LOGDEBUG, "AIRPLAY Server: New connection detected");
|
||||
CTCPClient newconnection;
|
||||
newconnection.m_socket = accept(m_ServerSocket, &newconnection.m_cliaddr, &newconnection.m_addrlen);
|
||||
+ sessionCounter++;
|
||||
+ newconnection.m_sessionCounter = sessionCounter;
|
||||
|
||||
if (newconnection.m_socket == INVALID_SOCKET)
|
||||
{
|
||||
@@ -265,6 +337,7 @@ void CAirPlayServer::Process()
|
||||
}
|
||||
else
|
||||
{
|
||||
+ CSingleLock lock (m_connectionLock);
|
||||
CLog::Log(LOGINFO, "AIRPLAY Server: New connection added");
|
||||
m_connections.push_back(newconnection);
|
||||
}
|
||||
@@ -319,6 +392,7 @@ bool CAirPlayServer::Initialize()
|
||||
|
||||
void CAirPlayServer::Deinitialize()
|
||||
{
|
||||
+ CSingleLock lock (m_connectionLock);
|
||||
for (unsigned int i = 0; i < m_connections.size(); i++)
|
||||
m_connections[i].Disconnect();
|
||||
|
||||
@@ -381,11 +455,9 @@ void CAirPlayServer::CTCPClient::PushBuffer(CAirPlayServer *host, const char *bu
|
||||
// Parse the request
|
||||
CStdString responseHeader;
|
||||
CStdString responseBody;
|
||||
- CStdString reverseHeader;
|
||||
- CStdString reverseBody;
|
||||
- int status = ProcessRequest(responseHeader, responseBody, reverseHeader, reverseBody, sessionId);
|
||||
+ int status = ProcessRequest(responseHeader, responseBody);
|
||||
+ sessionId = m_sessionId;
|
||||
CStdString statusMsg = "OK";
|
||||
- int reverseSocket = INVALID_SOCKET;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
@@ -435,28 +507,6 @@ void CAirPlayServer::CTCPClient::PushBuffer(CAirPlayServer *host, const char *bu
|
||||
{
|
||||
send(m_socket, response.c_str(), response.size(), 0);
|
||||
}
|
||||
-
|
||||
- // Send event status per reverse http socket (play, loading, paused)
|
||||
- // if we have a reverse header and a reverse socket
|
||||
- if (reverseHeader.size() > 0 && reverseSockets.find(sessionId) != reverseSockets.end())
|
||||
- {
|
||||
- //search the reverse socket to this sessionid
|
||||
- response.Format("POST /event HTTP/1.1\r\n");
|
||||
- reverseSocket = reverseSockets[sessionId]; //that is our reverse socket
|
||||
- response += reverseHeader;
|
||||
- }
|
||||
- response += "\r\n";
|
||||
-
|
||||
- if (reverseBody.size() > 0)
|
||||
- {
|
||||
- response += reverseBody;
|
||||
- }
|
||||
-
|
||||
- if (reverseSocket != INVALID_SOCKET)
|
||||
- {
|
||||
- send(reverseSocket, response.c_str(), response.size(), 0);//send the event status on the eventSocket
|
||||
- }
|
||||
-
|
||||
// We need a new parser...
|
||||
delete m_httpParser;
|
||||
m_httpParser = new HttpParser;
|
||||
@@ -484,12 +534,12 @@ void CAirPlayServer::CTCPClient::Copy(const CTCPClient& client)
|
||||
m_httpParser = client.m_httpParser;
|
||||
m_authNonce = client.m_authNonce;
|
||||
m_bAuthenticated = client.m_bAuthenticated;
|
||||
+ m_sessionCounter = client.m_sessionCounter;
|
||||
}
|
||||
|
||||
|
||||
void CAirPlayServer::CTCPClient::ComposeReverseEvent( CStdString& reverseHeader,
|
||||
CStdString& reverseBody,
|
||||
- CStdString sessionId,
|
||||
int state)
|
||||
{
|
||||
|
||||
@@ -501,13 +551,13 @@ void CAirPlayServer::CTCPClient::ComposeReverseEvent( CStdString& reverseHeader,
|
||||
case EVENT_LOADING:
|
||||
case EVENT_PAUSED:
|
||||
case EVENT_STOPPED:
|
||||
- reverseBody.Format(EVENT_INFO, eventStrings[state]);
|
||||
+ reverseBody.Format(EVENT_INFO, m_sessionCounter, eventStrings[state]);
|
||||
CLog::Log(LOGDEBUG, "AIRPLAY: sending event: %s", eventStrings[state]);
|
||||
break;
|
||||
}
|
||||
reverseHeader = "Content-Type: text/x-apple-plist+xml\r\n";
|
||||
- reverseHeader.Format("%sContent-Length: %d",reverseHeader.c_str(),reverseBody.size());
|
||||
- reverseHeader.Format("%sx-apple-session-id: %s\r\n",reverseHeader.c_str(),sessionId.c_str());
|
||||
+ reverseHeader.Format("%sContent-Length: %d\r\n",reverseHeader.c_str(),reverseBody.size());
|
||||
+ reverseHeader.Format("%sx-apple-session-id: %s\r\n",reverseHeader.c_str(),m_sessionId.c_str());
|
||||
m_lastEvent = state;
|
||||
}
|
||||
}
|
||||
@@ -631,17 +681,14 @@ bool CAirPlayServer::CTCPClient::checkAuthorization(const CStdString& authStr,
|
||||
}
|
||||
|
||||
int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
- CStdString& responseBody,
|
||||
- CStdString& reverseHeader,
|
||||
- CStdString& reverseBody,
|
||||
- CStdString& sessionId)
|
||||
+ CStdString& responseBody)
|
||||
{
|
||||
CStdString method = m_httpParser->getMethod();
|
||||
CStdString uri = m_httpParser->getUri();
|
||||
CStdString queryString = m_httpParser->getQueryString();
|
||||
CStdString body = m_httpParser->getBody();
|
||||
CStdString contentType = m_httpParser->getValue("content-type");
|
||||
- sessionId = m_httpParser->getValue("x-apple-session-id");
|
||||
+ m_sessionId = m_httpParser->getValue("x-apple-session-id");
|
||||
CStdString authorization = m_httpParser->getValue("authorization");
|
||||
int status = AIRPLAY_STATUS_OK;
|
||||
bool needAuth = false;
|
||||
@@ -688,7 +735,6 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
if (g_application.m_pPlayer && g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
|
||||
{
|
||||
CApplicationMessenger::Get().MediaPause();
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PAUSED);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -696,7 +742,6 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
if (g_application.m_pPlayer && g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->IsPaused())
|
||||
{
|
||||
CApplicationMessenger::Get().MediaPause();
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PLAYING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -820,8 +865,8 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
|
||||
CFileItem fileToPlay(location, false);
|
||||
fileToPlay.SetProperty("StartPercent", position*100.0f);
|
||||
+ ServerInstance->AnnounceToClients(EVENT_LOADING);
|
||||
CApplicationMessenger::Get().MediaPlay(fileToPlay);
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,7 +924,6 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
{
|
||||
g_windowManager.PreviousWindow();
|
||||
}
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,22 +994,13 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
|
||||
|
||||
if (g_application.m_pPlayer->IsCaching())
|
||||
{
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_LOADING);
|
||||
- }
|
||||
- else if (playing)
|
||||
- {
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PLAYING);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PAUSED);
|
||||
+ CAirPlayServer::ServerInstance->AnnounceToClients(EVENT_LOADING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
responseBody.Format(PLAYBACK_INFO_NOT_READY, duration, cachePosition, position, (playing ? 1 : 0), duration);
|
||||
responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";
|
||||
- ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/xbmc/network/AirPlayServer.h b/xbmc/network/AirPlayServer.h
|
||||
index 168a09f..6dcf741 100644
|
||||
--- a/xbmc/network/AirPlayServer.h
|
||||
+++ b/xbmc/network/AirPlayServer.h
|
||||
@@ -31,14 +31,19 @@
|
||||
#include "threads/CriticalSection.h"
|
||||
#include "utils/HttpParser.h"
|
||||
#include "utils/StdString.h"
|
||||
+#include "interfaces/IAnnouncer.h"
|
||||
|
||||
class DllLibPlist;
|
||||
|
||||
#define AIRPLAY_SERVER_VERSION_STR "101.28"
|
||||
|
||||
-class CAirPlayServer : public CThread
|
||||
+class CAirPlayServer : public CThread, public ANNOUNCEMENT::IAnnouncer
|
||||
{
|
||||
public:
|
||||
+ // IAnnouncer IF
|
||||
+ virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
|
||||
+
|
||||
+ //AirPlayServer impl.
|
||||
static bool StartServer(int port, bool nonlocal);
|
||||
static void StopServer(bool bWait);
|
||||
static bool SetCredentials(bool usePassword, const CStdString& password);
|
||||
@@ -50,9 +55,11 @@ class CAirPlayServer : public CThread
|
||||
|
||||
private:
|
||||
CAirPlayServer(int port, bool nonlocal);
|
||||
+ ~CAirPlayServer();
|
||||
bool SetInternalCredentials(bool usePassword, const CStdString& password);
|
||||
bool Initialize();
|
||||
void Deinitialize();
|
||||
+ void AnnounceToClients(int state);
|
||||
|
||||
class CTCPClient
|
||||
{
|
||||
@@ -66,6 +73,7 @@ class CAirPlayServer : public CThread
|
||||
void PushBuffer(CAirPlayServer *host, const char *buffer,
|
||||
int length, CStdString &sessionId,
|
||||
std::map<CStdString, int> &reverseSockets);
|
||||
+ void ComposeReverseEvent(CStdString& reverseHeader, CStdString& reverseBody, int state);
|
||||
|
||||
void Disconnect();
|
||||
|
||||
@@ -73,15 +81,13 @@ class CAirPlayServer : public CThread
|
||||
struct sockaddr m_cliaddr;
|
||||
socklen_t m_addrlen;
|
||||
CCriticalSection m_critSection;
|
||||
+ int m_sessionCounter;
|
||||
+ CStdString m_sessionId;
|
||||
|
||||
private:
|
||||
int ProcessRequest( CStdString& responseHeader,
|
||||
- CStdString& response,
|
||||
- CStdString& reverseHeader,
|
||||
- CStdString& reverseBody,
|
||||
- CStdString& sessionId);
|
||||
+ CStdString& response);
|
||||
|
||||
- void ComposeReverseEvent(CStdString& reverseHeader, CStdString& reverseBody, CStdString sessionId, int state);
|
||||
void ComposeAuthRequestAnswer(CStdString& responseHeader, CStdString& responseBody);
|
||||
bool checkAuthorization(const CStdString& authStr, const CStdString& method, const CStdString& uri);
|
||||
void Copy(const CTCPClient& client);
|
||||
@@ -93,6 +99,7 @@ class CAirPlayServer : public CThread
|
||||
CStdString m_authNonce;
|
||||
};
|
||||
|
||||
+ CCriticalSection m_connectionLock;
|
||||
std::vector<CTCPClient> m_connections;
|
||||
std::map<CStdString, int> m_reverseSockets;
|
||||
int m_ServerSocket;
|
||||
--
|
||||
1.8.1.5
|
||||
|
@ -1,145 +0,0 @@
|
||||
From efc25def3ff9d875e8f0a79fdf72bbfb33317a1f Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 17 Mar 2013 13:38:56 +0100
|
||||
Subject: [PATCH 1/4] CoreAE: fix invalid logging about mixing matrix
|
||||
|
||||
---
|
||||
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp
|
||||
index b216aef..263044b 100644
|
||||
--- a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp
|
||||
+++ b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp
|
||||
@@ -221,14 +221,14 @@ bool CCoreAudioMixMap::SetMixingMatrix(CAUMatrixMixer *mixerUnit,
|
||||
if(fmt->mChannelsPerFrame > dims[1])
|
||||
{
|
||||
CLog::Log(LOGERROR, "CCoreAudioMixMap::SetMixingMatrix - ouput format doesn't fit mixer size %u > %u"
|
||||
- , fmt->mChannelsPerFrame, dims[0]);
|
||||
+ , fmt->mChannelsPerFrame, dims[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fmt->mChannelsPerFrame < dims[1])
|
||||
{
|
||||
CLog::Log(LOGWARNING, "CCoreAudioMixMap::SetMixingMatrix - ouput format doesn't specify all outputs %u < %u"
|
||||
- , fmt->mChannelsPerFrame, dims[0]);
|
||||
+ , fmt->mChannelsPerFrame, dims[1]);
|
||||
}
|
||||
|
||||
// Configure the mixing matrix
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From 1200cb6ecdcb50eb6b6cddb8cab3be9394bf68d9 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 17 Mar 2013 16:12:35 +0100
|
||||
Subject: [PATCH 2/4] CoreAE: mixing unit must have same output count as mixing
|
||||
map
|
||||
|
||||
---
|
||||
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
index 76030c0..bc1d919 100644
|
||||
--- a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
+++ b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
@@ -152,6 +152,10 @@ bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
|
||||
if (!m_mixerUnit->SetInputBusFormat(MAX_CONNECTION_LIMIT, &fmt))
|
||||
return false;
|
||||
|
||||
+ // Update format structure to reflect the desired format from the mixer
|
||||
+ // The output format of the mixer is identical to the input format, except for the channel count
|
||||
+ fmt.mChannelsPerFrame = m_mixMap->GetOutputChannels();
|
||||
+
|
||||
if (!m_mixerUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus))
|
||||
return false;
|
||||
|
||||
@@ -193,10 +197,6 @@ bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
|
||||
return false;
|
||||
}
|
||||
|
||||
- // Update format structure to reflect the desired format from the mixer
|
||||
- // The output format of the mixer is identical to the input format, except for the channel count
|
||||
- fmt.mChannelsPerFrame = m_mixMap->GetOutputChannels();
|
||||
-
|
||||
UInt32 inputNumber = m_inputUnit->GetBus();
|
||||
int channelOffset = GetMixerChannelOffset(inputNumber);
|
||||
if (!CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &inputFormat, &fmt, channelOffset))
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From 1cee5e135bc2ba8a4b3e3e86437e78da04d437a5 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 17 Mar 2013 16:17:19 +0100
|
||||
Subject: [PATCH 3/4] CoreAE: fix null dereference if no mixer map was created
|
||||
|
||||
---
|
||||
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
index bc1d919..89e97e3 100644
|
||||
--- a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
+++ b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
@@ -104,7 +104,7 @@ bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
|
||||
delete m_mixMap;
|
||||
m_mixMap = CCoreAudioMixMap::CreateMixMap(m_audioUnit, format, layoutTag);
|
||||
|
||||
- if (m_mixMap || m_mixMap->IsValid())
|
||||
+ if (m_mixMap && m_mixMap->IsValid())
|
||||
{
|
||||
// maximum input channel ber input bus
|
||||
//fmt.mChannelsPerFrame = MAXIMUM_MIXER_CHANNELS;
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From c8061dca712b0d3bb30ba93b0478a30bfce40d58 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 17 Mar 2013 20:09:13 +0100
|
||||
Subject: [PATCH 4/4] CoreAE: mixerunits input is the inputunits output
|
||||
|
||||
Not this still doesn't resolve all issues. We are still not
|
||||
setting up a correct channel map for the output
|
||||
---
|
||||
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
index 89e97e3..dc2b175 100644
|
||||
--- a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
+++ b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
|
||||
@@ -154,9 +154,10 @@ bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
|
||||
|
||||
// Update format structure to reflect the desired format from the mixer
|
||||
// The output format of the mixer is identical to the input format, except for the channel count
|
||||
- fmt.mChannelsPerFrame = m_mixMap->GetOutputChannels();
|
||||
+ AudioStreamBasicDescription mixOutput(fmt);
|
||||
+ mixOutput.mChannelsPerFrame = m_mixMap->GetOutputChannels();
|
||||
|
||||
- if (!m_mixerUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus))
|
||||
+ if (!m_mixerUnit->SetFormat(&mixOutput, kAudioUnitScope_Output, kOutputBus))
|
||||
return false;
|
||||
|
||||
ret = AUGraphConnectNodeInput(m_audioGraph, m_mixerUnit->GetNode(), 0, m_audioUnit->GetNode(), 0);
|
||||
@@ -199,11 +200,11 @@ bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
|
||||
|
||||
UInt32 inputNumber = m_inputUnit->GetBus();
|
||||
int channelOffset = GetMixerChannelOffset(inputNumber);
|
||||
- if (!CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &inputFormat, &fmt, channelOffset))
|
||||
+ if (!CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &fmt, &mixOutput, channelOffset))
|
||||
return false;
|
||||
|
||||
// Regenerate audio format and copy format for the Output AU
|
||||
- outputFormat = fmt;
|
||||
+ outputFormat = mixOutput;
|
||||
}
|
||||
else
|
||||
{
|
||||
--
|
||||
1.8.1.5
|
||||
|
@ -1,425 +0,0 @@
|
||||
From 24d3cc22fee2bb90b62278fca18a44624e58279d Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sat, 6 Apr 2013 12:04:50 +0200
|
||||
Subject: [PATCH 1/5] dvdplayer: complete the update of ffmpeg interrupt
|
||||
interface
|
||||
|
||||
The old interface could not handle being called from another thread
|
||||
---
|
||||
.../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 42 +++++++---------------
|
||||
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 2 +-
|
||||
2 files changed, 14 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
index 21cab73..2fa3d93 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
@@ -155,11 +155,9 @@ static void ff_flush_avutil_log_buffers(void)
|
||||
++it;
|
||||
}
|
||||
|
||||
-static XbmcThreads::ThreadLocal<CDVDDemuxFFmpeg> g_demuxer;
|
||||
-
|
||||
-static int interrupt_cb(void* unused)
|
||||
+static int interrupt_cb(void* ctx)
|
||||
{
|
||||
- CDVDDemuxFFmpeg* demuxer = g_demuxer.get();
|
||||
+ CDVDDemuxFFmpeg* demuxer = static_cast<CDVDDemuxFFmpeg*>(ctx);
|
||||
if(demuxer && demuxer->Aborted())
|
||||
return 1;
|
||||
return 0;
|
||||
@@ -176,10 +174,10 @@ static int dvd_file_open(URLContext *h, const char *filename, int flags)
|
||||
|
||||
static int dvd_file_read(void *h, uint8_t* buf, int size)
|
||||
{
|
||||
- if(interrupt_cb(NULL))
|
||||
- return -1;
|
||||
+ if(interrupt_cb(h))
|
||||
+ return AVERROR_EXIT;
|
||||
|
||||
- CDVDInputStream* pInputStream = (CDVDInputStream*)h;
|
||||
+ CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
|
||||
return pInputStream->Read(buf, size);
|
||||
}
|
||||
/*
|
||||
@@ -190,10 +188,10 @@ static int dvd_file_write(URLContext *h, BYTE* buf, int size)
|
||||
*/
|
||||
static offset_t dvd_file_seek(void *h, offset_t pos, int whence)
|
||||
{
|
||||
- if(interrupt_cb(NULL))
|
||||
- return -1;
|
||||
+ if(interrupt_cb(h))
|
||||
+ return AVERROR_EXIT;
|
||||
|
||||
- CDVDInputStream* pInputStream = (CDVDInputStream*)h;
|
||||
+ CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
|
||||
if(whence == AVSEEK_SIZE)
|
||||
return pInputStream->GetLength();
|
||||
else
|
||||
@@ -236,9 +234,8 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
std::string strFile;
|
||||
m_iCurrentPts = DVD_NOPTS_VALUE;
|
||||
m_speed = DVD_PLAYSPEED_NORMAL;
|
||||
- g_demuxer.set(this);
|
||||
m_program = UINT_MAX;
|
||||
- const AVIOInterruptCB int_cb = { interrupt_cb, NULL };
|
||||
+ const AVIOInterruptCB int_cb = { interrupt_cb, this };
|
||||
|
||||
if (!pInput) return false;
|
||||
|
||||
@@ -270,6 +267,10 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
iformat = m_dllAvFormat.av_find_input_format("mjpeg");
|
||||
}
|
||||
|
||||
+ // open the demuxer
|
||||
+ m_pFormatContext = m_dllAvFormat.avformat_alloc_context();
|
||||
+ m_pFormatContext->interrupt_callback = int_cb;
|
||||
+
|
||||
// try to abort after 30 seconds
|
||||
m_timeout.Set(30000);
|
||||
|
||||
@@ -411,8 +412,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
}
|
||||
|
||||
|
||||
- // open the demuxer
|
||||
- m_pFormatContext = m_dllAvFormat.avformat_alloc_context();
|
||||
m_pFormatContext->pb = m_ioContext;
|
||||
|
||||
if (m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0)
|
||||
@@ -422,9 +421,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-
|
||||
- // set the interrupt callback, appeared in libavformat 53.15.0
|
||||
- m_pFormatContext->interrupt_callback = int_cb;
|
||||
|
||||
// Avoid detecting framerate if advancedsettings.xml says so
|
||||
m_pFormatContext->fps_probe_size = (g_advancedSettings.m_videoFpsDetect == 0) ? 0 : -1;
|
||||
@@ -503,8 +499,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
|
||||
void CDVDDemuxFFmpeg::Dispose()
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
if (m_pFormatContext)
|
||||
{
|
||||
if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext)
|
||||
@@ -551,8 +545,6 @@ void CDVDDemuxFFmpeg::Reset()
|
||||
|
||||
void CDVDDemuxFFmpeg::Flush()
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
// naughty usage of an internal ffmpeg function
|
||||
if (m_pFormatContext)
|
||||
m_dllAvFormat.av_read_frame_flush(m_pFormatContext);
|
||||
@@ -567,8 +559,6 @@ void CDVDDemuxFFmpeg::Abort()
|
||||
|
||||
void CDVDDemuxFFmpeg::SetSpeed(int iSpeed)
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
if(!m_pFormatContext)
|
||||
return;
|
||||
|
||||
@@ -629,8 +619,6 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num)
|
||||
|
||||
DemuxPacket* CDVDDemuxFFmpeg::Read()
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
AVPacket pkt;
|
||||
DemuxPacket* pPacket = NULL;
|
||||
// on some cases where the received packet is invalid we will need to return an empty packet (0 length) otherwise the main loop (in CDVDPlayer)
|
||||
@@ -812,8 +800,6 @@ DemuxPacket* CDVDDemuxFFmpeg::Read()
|
||||
|
||||
bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
if(time < 0)
|
||||
time = 0;
|
||||
|
||||
@@ -872,8 +858,6 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
|
||||
|
||||
bool CDVDDemuxFFmpeg::SeekByte(int64_t pos)
|
||||
{
|
||||
- g_demuxer.set(this);
|
||||
-
|
||||
CSingleLock lock(m_critSection);
|
||||
int ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE);
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
||||
index 2b5f2e8..acef490 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
||||
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
||||
@@ -111,6 +111,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux
|
||||
bool Aborted();
|
||||
|
||||
AVFormatContext* m_pFormatContext;
|
||||
+ CDVDInputStream* m_pInput;
|
||||
|
||||
protected:
|
||||
friend class CDemuxStreamAudioFFmpeg;
|
||||
@@ -140,6 +141,5 @@ class CDVDDemuxFFmpeg : public CDVDDemux
|
||||
unsigned m_program;
|
||||
XbmcThreads::EndTime m_timeout;
|
||||
|
||||
- CDVDInputStream* m_pInput;
|
||||
};
|
||||
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From eff39646c73e74124621120bdcdccec4d62db61f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Niedermayer <michaelni@gmx.at>
|
||||
Date: Thu, 23 Feb 2012 23:22:16 +0100
|
||||
Subject: [PATCH 2/5] udp: Fix sign of error codes.
|
||||
|
||||
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
|
||||
---
|
||||
lib/ffmpeg/libavformat/udp.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/ffmpeg/libavformat/udp.c b/lib/ffmpeg/libavformat/udp.c
|
||||
index 9694ad2..309b18c 100644
|
||||
--- a/lib/ffmpeg/libavformat/udp.c
|
||||
+++ b/lib/ffmpeg/libavformat/udp.c
|
||||
@@ -335,7 +335,7 @@ static void *circular_buffer_task( void *_URLContext)
|
||||
int len;
|
||||
|
||||
if (ff_check_interrupt(&h->interrupt_callback)) {
|
||||
- s->circular_buffer_error = EINTR;
|
||||
+ s->circular_buffer_error = AVERROR(EINTR);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ static void *circular_buffer_task( void *_URLContext)
|
||||
if (ret < 0) {
|
||||
if (ff_neterrno() == AVERROR(EINTR))
|
||||
continue;
|
||||
- s->circular_buffer_error = EIO;
|
||||
+ s->circular_buffer_error = AVERROR(EIO);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -361,14 +361,14 @@ static void *circular_buffer_task( void *_URLContext)
|
||||
/* No Space left, error, what do we do now */
|
||||
if(left < UDP_MAX_PKT_SIZE + 4) {
|
||||
av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
|
||||
- s->circular_buffer_error = EIO;
|
||||
+ s->circular_buffer_error = AVERROR(EIO);
|
||||
goto end;
|
||||
}
|
||||
left = FFMIN(left, s->fifo->end - s->fifo->wptr);
|
||||
len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
|
||||
if (len < 0) {
|
||||
if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
|
||||
- s->circular_buffer_error = EIO;
|
||||
+ s->circular_buffer_error = AVERROR(EIO);
|
||||
goto end;
|
||||
}
|
||||
continue;
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From 13abee9310f7dd5982e9a0c5fde9b7f2a0ad9ce0 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas George <nicolas.george@normalesup.org>
|
||||
Date: Thu, 15 Mar 2012 12:19:37 +0100
|
||||
Subject: [PATCH 3/5] udp: fix non-blocking and interrupt handling.
|
||||
|
||||
In non-blocking mode, lowest-level read protocols are
|
||||
supposed block only for a short amount of time to let
|
||||
retry_transfer_wrapper() check for interrupts.
|
||||
|
||||
Also, checking the interrupt_callback in the receiving thread is
|
||||
wrong, as interrupt_callback is not guaranteed to be thread-safe
|
||||
and the job is already done by retry_transfer_wrapper(). The error
|
||||
code was also incorrect.
|
||||
|
||||
Bug reported by Andrey Utkin.
|
||||
---
|
||||
lib/ffmpeg/libavformat/udp.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/lib/ffmpeg/libavformat/udp.c b/lib/ffmpeg/libavformat/udp.c
|
||||
index 309b18c..ed1559d 100644
|
||||
--- a/lib/ffmpeg/libavformat/udp.c
|
||||
+++ b/lib/ffmpeg/libavformat/udp.c
|
||||
@@ -334,11 +334,6 @@ static void *circular_buffer_task( void *_URLContext)
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
- if (ff_check_interrupt(&h->interrupt_callback)) {
|
||||
- s->circular_buffer_error = AVERROR(EINTR);
|
||||
- goto end;
|
||||
- }
|
||||
-
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(s->udp_fd, &rfds);
|
||||
tv.tv_sec = 1;
|
||||
@@ -568,7 +563,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
|
||||
{
|
||||
UDPContext *s = h->priv_data;
|
||||
int ret;
|
||||
- int avail;
|
||||
+ int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
|
||||
|
||||
#if HAVE_PTHREADS
|
||||
if (s->fifo) {
|
||||
@@ -592,12 +587,19 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
|
||||
} else if(s->circular_buffer_error){
|
||||
pthread_mutex_unlock(&s->mutex);
|
||||
return s->circular_buffer_error;
|
||||
- } else if(h->flags & AVIO_FLAG_NONBLOCK) {
|
||||
+ } else if(nonblock) {
|
||||
pthread_mutex_unlock(&s->mutex);
|
||||
return AVERROR(EAGAIN);
|
||||
}
|
||||
else {
|
||||
- pthread_cond_wait(&s->cond, &s->mutex);
|
||||
+ /* FIXME: using the monotonic clock would be better,
|
||||
+ but it does not exist on all supported platforms. */
|
||||
+ int64_t t = av_gettime() + 100000;
|
||||
+ struct timespec tv = { .tv_sec = t / 1000000,
|
||||
+ .tv_nsec = (t % 1000000) * 1000 };
|
||||
+ if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0)
|
||||
+ return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno);
|
||||
+ nonblock = 1;
|
||||
}
|
||||
} while( 1);
|
||||
}
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From 5e4b832f15431cfc15ae26110b3852b7cc6347d0 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 7 Apr 2013 11:46:35 +0200
|
||||
Subject: [PATCH 4/5] dvdplayer: make sure we can also abort the open of a
|
||||
ffmpeg input stream
|
||||
|
||||
---
|
||||
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 5 +++++
|
||||
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp | 7 ++++++-
|
||||
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h | 4 ++++
|
||||
xbmc/cores/dvdplayer/DVDPlayer.cpp | 3 +++
|
||||
4 files changed, 18 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
index 2fa3d93..3a1839c 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "DVDInputStreams/DVDInputStreamBluray.h"
|
||||
#endif
|
||||
#include "DVDInputStreams/DVDInputStreamPVRManager.h"
|
||||
+#include "DVDInputStreams/DVDInputStreamFFmpeg.h"
|
||||
#include "DVDDemuxUtils.h"
|
||||
#include "DVDClock.h" // for DVD_TIME_BASE
|
||||
#include "commons/Exception.h"
|
||||
@@ -225,6 +226,10 @@ bool CDVDDemuxFFmpeg::Aborted()
|
||||
if(m_timeout.IsTimePast())
|
||||
return true;
|
||||
|
||||
+ CDVDInputStreamFFmpeg * input = dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput);
|
||||
+ if(input && input->Aborted())
|
||||
+ return true;
|
||||
+
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
|
||||
index 5949bec..72ea5f8 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
|
||||
+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
CDVDInputStreamFFmpeg::CDVDInputStreamFFmpeg()
|
||||
: CDVDInputStream(DVDSTREAM_TYPE_FFMPEG)
|
||||
+ , m_aborted(false)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -35,7 +36,10 @@
|
||||
|
||||
bool CDVDInputStreamFFmpeg::IsEOF()
|
||||
{
|
||||
- return false;
|
||||
+ if(m_aborted)
|
||||
+ return true;
|
||||
+ else
|
||||
+ return false;
|
||||
}
|
||||
|
||||
bool CDVDInputStreamFFmpeg::Open(const char* strFile, const std::string& content)
|
||||
@@ -43,6 +47,7 @@ bool CDVDInputStreamFFmpeg::Open(const char* strFile, const std::string& content
|
||||
if (!CDVDInputStream::Open(strFile, content))
|
||||
return false;
|
||||
|
||||
+ m_aborted = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h
|
||||
index 8e363b8..6149233 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h
|
||||
+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h
|
||||
@@ -35,5 +35,9 @@ class CDVDInputStreamFFmpeg : public CDVDInputStream
|
||||
virtual bool IsEOF();
|
||||
virtual int64_t GetLength();
|
||||
|
||||
+ virtual void Abort() { m_aborted = true; }
|
||||
+ bool Aborted() { return m_aborted; }
|
||||
+
|
||||
protected:
|
||||
+ bool m_aborted;
|
||||
};
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
||||
index 145301c..a844da1 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
||||
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
||||
@@ -511,6 +511,9 @@ bool CDVDPlayer::CloseFile()
|
||||
if(m_pSubtitleDemuxer)
|
||||
m_pSubtitleDemuxer->Abort();
|
||||
|
||||
+ if(m_pInputStream)
|
||||
+ m_pInputStream->Abort();
|
||||
+
|
||||
CLog::Log(LOGNOTICE, "DVDPlayer: waiting for threads to exit");
|
||||
|
||||
// wait for the main thread to finish up
|
||||
--
|
||||
1.8.1.5
|
||||
|
||||
|
||||
From 1ca77bb84e320639f3cf74591259319a2a5933d6 Mon Sep 17 00:00:00 2001
|
||||
From: Joakim Plate <elupus@ecce.se>
|
||||
Date: Sun, 7 Apr 2013 17:49:40 +0200
|
||||
Subject: [PATCH 5/5] dvdplayer: fixed crash introduced with change in handling
|
||||
of abort
|
||||
|
||||
---
|
||||
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
index 3a1839c..35d0fc5 100644
|
||||
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
||||
@@ -306,7 +306,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
||||
else
|
||||
{
|
||||
unsigned char* buffer = (unsigned char*)m_dllAvUtil.av_malloc(FFMPEG_FILE_BUFFER_SIZE);
|
||||
- m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, m_pInput, dvd_file_read, NULL, dvd_file_seek);
|
||||
+ m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek);
|
||||
m_ioContext->max_packet_size = m_pInput->GetBlockSize();
|
||||
if(m_ioContext->max_packet_size)
|
||||
m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size;
|
||||
--
|
||||
1.8.1.5
|
||||
|
@ -20,7 +20,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="xbmc"
|
||||
PKG_VERSION="12.1.2"
|
||||
PKG_VERSION="12.1.4"
|
||||
GIT_REPO="-b Frodo git://github.com/xbmc/xbmc.git"
|
||||
DEST_DIR="$PKG_NAME-frodo"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user