aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Plate <elupus@ecce.se>2012-09-22 08:01:16 -0700
committerJoakim Plate <elupus@ecce.se>2012-09-22 08:01:16 -0700
commit8b2d36ee732b161811490636d4039ed27dd754b0 (patch)
tree07046bf54826128383162793a581df1465bf95d5
parentce6c3caf6fb1ae336154af3e52ed099f78ca2cb5 (diff)
parent41ca644e807d4897a316fd63d89be05c22589bdd (diff)
Merge pull request #1460 from elupus/pvrfix
pvr: fixed the constant re-open of video/audio codecs while probing stream
-rw-r--r--xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h3
-rw-r--r--xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp262
-rw-r--r--xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h44
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.cpp12
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.h2
5 files changed, 154 insertions, 169 deletions
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h
index 70f37caaf0..74c26ce8f8 100644
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h
@@ -99,6 +99,7 @@ public:
ExtraSize = 0;
memset(language, 0, sizeof(language));
disabled = false;
+ changes = 0;
flags = FLAG_NONE;
}
@@ -130,6 +131,8 @@ public:
char language[4]; // ISO 639 3-letter language code (empty string if undefined)
bool disabled; // set when stream is disabled. (when no decoder exists)
+ int changes; // increment on change which player may need to know about
+
enum EFlags
{ FLAG_NONE = 0x0000
, FLAG_DEFAULT = 0x0001
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
index 980ca76b71..bb0a1082ce 100644
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
@@ -29,12 +29,29 @@
using namespace PVR;
-CDemuxStreamVideoPVRClient::~CDemuxStreamVideoPVRClient()
+CDemuxStreamPVRInternal::CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent)
+ : m_parent(parent)
+ , m_parser(NULL)
+ , m_context(NULL)
{
- if (m_pParser)
+}
+
+CDemuxStreamPVRInternal::~CDemuxStreamPVRInternal()
+{
+ DisposeParser();
+}
+
+void CDemuxStreamPVRInternal::DisposeParser()
+{
+ if (m_parser)
+ {
+ m_parent->m_dllAvCodec.av_parser_close(m_parser);
+ m_parser = NULL;
+ }
+ if (m_context)
{
- m_parent->m_dllAvCodec.av_parser_close(m_pParser);
- m_pParser = NULL;
+ m_parent->m_dllAvCodec.avcodec_close(m_context);
+ m_context = NULL;
}
}
@@ -53,15 +70,6 @@ void CDemuxStreamVideoPVRClient::GetStreamInfo(std::string& strInfo)
}
}
-CDemuxStreamAudioPVRClient::~CDemuxStreamAudioPVRClient()
-{
- if (m_pParser)
- {
- m_parent->m_dllAvCodec.av_parser_close(m_pParser);
- m_pParser = NULL;
- }
-}
-
void CDemuxStreamAudioPVRClient::GetStreamInfo(std::string& strInfo)
{
switch (codec)
@@ -94,7 +102,6 @@ CDVDDemuxPVRClient::CDVDDemuxPVRClient() : CDVDDemux()
{
m_pInput = NULL;
for (int i = 0; i < MAX_STREAMS; i++) m_streams[i] = NULL;
- for (int i = 0; i < MAX_STREAMS; i++) m_streamsToParse[i] = NULL;
}
CDVDDemuxPVRClient::~CDVDDemuxPVRClient()
@@ -104,21 +111,22 @@ CDVDDemuxPVRClient::~CDVDDemuxPVRClient()
bool CDVDDemuxPVRClient::Open(CDVDInputStream* pInput)
{
- Abort();
- m_pInput = pInput;
- if (!g_PVRClients->GetPlayingClient(m_pvrClient))
- return false;
-
- RequestStreams();
-
if (!m_dllAvCodec.Load())
{
CLog::Log(LOGWARNING, "%s could not load ffmpeg", __FUNCTION__);
return false;
}
+ Abort();
+
// register codecs
m_dllAvCodec.avcodec_register_all();
+
+ m_pInput = pInput;
+ if (!g_PVRClients->GetPlayingClient(m_pvrClient))
+ return false;
+
+ RequestStreams();
return true;
}
@@ -133,14 +141,6 @@ void CDVDDemuxPVRClient::Dispose()
delete m_streams[i];
}
m_streams[i] = NULL;
-
- if (m_streamsToParse[i])
- {
- if (m_streamsToParse[i]->ExtraData)
- delete[] (BYTE*)(m_streamsToParse[i]->ExtraData);
- delete m_streamsToParse[i];
- }
- m_streamsToParse[i] = NULL;
}
m_pInput = NULL;
@@ -170,61 +170,65 @@ void CDVDDemuxPVRClient::Flush()
m_pvrClient->DemuxFlush();
}
-bool CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pPacket)
+void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt)
{
- bool bReturn(false);
+ CDemuxStream* st = m_streams[pkt->iStreamId];
+ if (st == NULL)
+ return;
+
+ if (st->ExtraSize)
+ return;
+
+ CDemuxStreamPVRInternal* pvr = dynamic_cast<CDemuxStreamPVRInternal*>(st);
+
+ if(pvr == NULL
+ || pvr->m_parser == NULL)
+ return;
- if (pPacket && pPacket->iSize)
+ if(pvr->m_parser->parser->split == NULL)
{
- CDemuxStream* st = m_streamsToParse[pPacket->iStreamId];
- AVCodecParserContext* pParser = NULL;
- if (st && st->type == STREAM_VIDEO)
- pParser = ((CDemuxStreamVideoPVRClient*)st)->m_pParser;
- else if (st && st->type == STREAM_AUDIO)
- pParser = ((CDemuxStreamAudioPVRClient*)st)->m_pParser;
-
- if (st && pParser)
+ CLog::Log(LOGDEBUG, "%s - parser have not split function", __FUNCTION__);
+ pvr->DisposeParser();
+ return;
+ }
+
+ if(pvr->m_context == NULL)
+ {
+ AVCodec *codec = m_dllAvCodec.avcodec_find_decoder(st->codec);
+ if (codec == NULL)
{
- // use split function of parser to get SPS
- if (pParser->parser->split)
- {
- AVCodec *codec;
- AVCodecContext *pCodecContext = NULL;
- codec = m_dllAvCodec.avcodec_find_decoder(st->codec);
- if (!codec)
- {
- CLog::Log(LOGERROR, "%s - Error, can't find decoder", __FUNCTION__);
- }
- else
- {
- pCodecContext = m_dllAvCodec.avcodec_alloc_context3(codec);
- int i = pParser->parser->split(pCodecContext, pPacket->pData, pPacket->iSize);
- if (i > 0 && i < FF_MAX_EXTRADATA_SIZE)
- {
- if (st->ExtraData)
- delete[] (uint8_t*)(st->ExtraData);
- st->ExtraSize = i;
- st->ExtraData = new uint8_t[st->ExtraSize+FF_INPUT_BUFFER_PADDING_SIZE];
- memcpy(st->ExtraData, pPacket->pData, st->ExtraSize);
- memset((uint8_t*)st->ExtraData + st->ExtraSize, 0 , FF_INPUT_BUFFER_PADDING_SIZE);
- bReturn = true;
- }
- else
- {
- CLog::Log(LOGERROR, "%s - Error, could not split extra data", __FUNCTION__);
- }
- }
- m_dllAvCodec.avcodec_close(pCodecContext);
- }
- else
- {
- // steam has no extradata to split
- bReturn = true;
- }
+ CLog::Log(LOGERROR, "%s - can't find decoder", __FUNCTION__);
+ pvr->DisposeParser();
+ return;
+ }
+
+ pvr->m_context = m_dllAvCodec.avcodec_alloc_context3(codec);
+ if(pvr->m_context == NULL)
+ {
+ CLog::Log(LOGERROR, "%s - can't allocate context", __FUNCTION__);
+ pvr->DisposeParser();
+ return;
}
}
- return bReturn;
+ int len = pvr->m_parser->parser->split(pvr->m_context, pkt->pData, pkt->iSize);
+ if (len > 0 && len < FF_MAX_EXTRADATA_SIZE)
+ {
+ delete[] (uint8_t*)(st->ExtraData);
+ st->ExtraSize = len;
+ st->ExtraData = new uint8_t[len+FF_INPUT_BUFFER_PADDING_SIZE];
+ memcpy(st->ExtraData, pkt->pData, len);
+ memset((uint8_t*)st->ExtraData + len, 0 , FF_INPUT_BUFFER_PADDING_SIZE);
+ }
+
+ if(st->ExtraData)
+ {
+ CLog::Log(LOGDEBUG, "%s - extradata found for %d:%d - closing parser", __FUNCTION__, st->iId, st->iPhysicalId);
+ pvr->DisposeParser();
+ st->changes++;
+ }
+
+ return;
}
DemuxPacket* CDVDDemuxPVRClient::Read()
@@ -250,24 +254,11 @@ DemuxPacket* CDVDDemuxPVRClient::Read()
{
Reset();
}
-
- // check if streams needs parsing
- int streamId = pPacket->iStreamId;
- CDemuxStream *stream = NULL;
- if (streamId >= 0 && streamId < MAX_STREAMS)
- stream = m_streamsToParse[streamId];
- if (stream)
+ else if (pPacket->iStreamId >= 0
+ && pPacket->iStreamId < MAX_STREAMS
+ && m_streams[pPacket->iStreamId])
{
- if (!ParsePacket(pPacket))
- {
- CDVDDemuxUtils::FreeDemuxPacket(pPacket);
- return CDVDDemuxUtils::AllocateDemuxPacket(0);
- }
- else
- {
- m_streams[streamId] = m_streamsToParse[streamId];
- m_streamsToParse[streamId] = NULL;
- }
+ ParsePacket(pPacket);
}
return pPacket;
@@ -289,8 +280,6 @@ void CDVDDemuxPVRClient::RequestStreams()
for (unsigned int i = 0; i < props.iStreamCount; ++i)
{
- CDemuxStream* (*streams)[MAX_STREAMS] = &m_streams;
-
if (props.stream[i].iCodecType == AVMEDIA_TYPE_AUDIO)
{
CDemuxStreamAudioPVRClient* st = new CDemuxStreamAudioPVRClient(this);
@@ -299,14 +288,8 @@ void CDVDDemuxPVRClient::RequestStreams()
st->iBlockAlign = props.stream[i].iBlockAlign;
st->iBitRate = props.stream[i].iBitRate;
st->iBitsPerSample = props.stream[i].iBitsPerSample;
- st->m_pParser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
- if (st->m_pParser)
- {
- m_streamsToParse[props.stream[i].iStreamIndex] = st;
- streams = &m_streamsToParse;
- }
- else
- m_streams[props.stream[i].iStreamIndex] = st;
+ st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
+ m_streams[props.stream[i].iStreamIndex] = st;
}
else if (props.stream[i].iCodecType == AVMEDIA_TYPE_VIDEO)
{
@@ -316,14 +299,8 @@ void CDVDDemuxPVRClient::RequestStreams()
st->iHeight = props.stream[i].iHeight;
st->iWidth = props.stream[i].iWidth;
st->fAspect = props.stream[i].fAspect;
- st->m_pParser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
- if (st->m_pParser)
- {
- m_streamsToParse[props.stream[i].iStreamIndex] = st;
- streams = &m_streamsToParse;
- }
- else
- m_streams[props.stream[i].iStreamIndex] = st;
+ st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
+ m_streams[props.stream[i].iStreamIndex] = st;
}
else if (props.stream[i].iCodecId == CODEC_ID_DVB_TELETEXT)
{
@@ -338,18 +315,18 @@ void CDVDDemuxPVRClient::RequestStreams()
else
m_streams[props.stream[i].iStreamIndex] = new CDemuxStream();
- (*streams)[props.stream[i].iStreamIndex]->codec = (CodecID)props.stream[i].iCodecId;
- (*streams)[props.stream[i].iStreamIndex]->iId = props.stream[i].iStreamIndex;
- (*streams)[props.stream[i].iStreamIndex]->iPhysicalId = props.stream[i].iPhysicalId;
- (*streams)[props.stream[i].iStreamIndex]->language[0] = props.stream[i].strLanguage[0];
- (*streams)[props.stream[i].iStreamIndex]->language[1] = props.stream[i].strLanguage[1];
- (*streams)[props.stream[i].iStreamIndex]->language[2] = props.stream[i].strLanguage[2];
- (*streams)[props.stream[i].iStreamIndex]->language[3] = props.stream[i].strLanguage[3];
+ m_streams[props.stream[i].iStreamIndex]->codec = (CodecID)props.stream[i].iCodecId;
+ m_streams[props.stream[i].iStreamIndex]->iId = props.stream[i].iStreamIndex;
+ m_streams[props.stream[i].iStreamIndex]->iPhysicalId = props.stream[i].iPhysicalId;
+ m_streams[props.stream[i].iStreamIndex]->language[0] = props.stream[i].strLanguage[0];
+ m_streams[props.stream[i].iStreamIndex]->language[1] = props.stream[i].strLanguage[1];
+ m_streams[props.stream[i].iStreamIndex]->language[2] = props.stream[i].strLanguage[2];
+ m_streams[props.stream[i].iStreamIndex]->language[3] = props.stream[i].strLanguage[3];
CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): added stream %d:%d with codec_id %d",
- (*streams)[props.stream[i].iStreamIndex]->iId,
- (*streams)[props.stream[i].iStreamIndex]->iPhysicalId,
- (*streams)[props.stream[i].iStreamIndex]->codec);
+ m_streams[props.stream[i].iStreamIndex]->iId,
+ m_streams[props.stream[i].iStreamIndex]->iPhysicalId,
+ m_streams[props.stream[i].iStreamIndex]->codec);
}
}
@@ -359,34 +336,23 @@ void CDVDDemuxPVRClient::UpdateStreams(PVR_STREAM_PROPERTIES *props)
for (unsigned int i = 0; i < props->iStreamCount; ++i)
{
- CDemuxStream* (*streams)[MAX_STREAMS] = &m_streams;
-
- if (m_streams[props->stream[i].iStreamIndex] != NULL &&
- m_streams[props->stream[i].iStreamIndex]->codec == (CodecID)props->stream[i].iCodecId)
- {
- streams = &m_streams;
- }
- else if (m_streamsToParse[props->stream[i].iStreamIndex] != NULL &&
- m_streamsToParse[props->stream[i].iStreamIndex]->codec == (CodecID)props->stream[i].iCodecId)
- {
- streams = &m_streamsToParse;
- }
- else
+ if (m_streams[props->stream[i].iStreamIndex] == NULL &&
+ m_streams[props->stream[i].iStreamIndex]->codec != (CodecID)props->stream[i].iCodecId)
{
CLog::Log(LOGERROR,"Invalid stream inside UpdateStreams");
continue;
}
- if ((*streams)[props->stream[i].iStreamIndex]->type == STREAM_AUDIO)
+ if (m_streams[props->stream[i].iStreamIndex]->type == STREAM_AUDIO)
{
- CDemuxStreamAudioPVRClient* st = (CDemuxStreamAudioPVRClient*) (*streams)[props->stream[i].iStreamIndex];
+ CDemuxStreamAudioPVRClient* st = (CDemuxStreamAudioPVRClient*) m_streams[props->stream[i].iStreamIndex];
st->iChannels = props->stream[i].iChannels;
st->iSampleRate = props->stream[i].iSampleRate;
st->iBlockAlign = props->stream[i].iBlockAlign;
st->iBitRate = props->stream[i].iBitRate;
st->iBitsPerSample = props->stream[i].iBitsPerSample;
}
- else if ((*streams)[props->stream[i].iStreamIndex]->type == STREAM_VIDEO)
+ else if (m_streams[props->stream[i].iStreamIndex]->type == STREAM_VIDEO)
{
if (bGotVideoStream)
{
@@ -394,7 +360,7 @@ void CDVDDemuxPVRClient::UpdateStreams(PVR_STREAM_PROPERTIES *props)
continue;
}
- CDemuxStreamVideoPVRClient* st = (CDemuxStreamVideoPVRClient*) (*streams)[props->stream[i].iStreamIndex];
+ CDemuxStreamVideoPVRClient* st = (CDemuxStreamVideoPVRClient*) m_streams[props->stream[i].iStreamIndex];
if (st->iWidth <= 0 || st->iHeight <= 0)
{
CLog::Log(LOGWARNING, "CDVDDemuxPVRClient - %s - invalid stream data", __FUNCTION__);
@@ -408,21 +374,21 @@ void CDVDDemuxPVRClient::UpdateStreams(PVR_STREAM_PROPERTIES *props)
st->fAspect = props->stream[i].fAspect;
bGotVideoStream = true;
}
- else if ((*streams)[props->stream[i].iStreamIndex]->type == STREAM_SUBTITLE)
+ else if (m_streams[props->stream[i].iStreamIndex]->type == STREAM_SUBTITLE)
{
- CDemuxStreamSubtitlePVRClient* st = (CDemuxStreamSubtitlePVRClient*) (*streams)[props->stream[i].iStreamIndex];
+ CDemuxStreamSubtitlePVRClient* st = (CDemuxStreamSubtitlePVRClient*) m_streams[props->stream[i].iStreamIndex];
st->identifier = props->stream[i].iIdentifier;
}
- (*streams)[props->stream[i].iStreamIndex]->language[0] = props->stream[i].strLanguage[0];
- (*streams)[props->stream[i].iStreamIndex]->language[1] = props->stream[i].strLanguage[1];
- (*streams)[props->stream[i].iStreamIndex]->language[2] = props->stream[i].strLanguage[2];
- (*streams)[props->stream[i].iStreamIndex]->language[3] = props->stream[i].strLanguage[3];
+ m_streams[props->stream[i].iStreamIndex]->language[0] = props->stream[i].strLanguage[0];
+ m_streams[props->stream[i].iStreamIndex]->language[1] = props->stream[i].strLanguage[1];
+ m_streams[props->stream[i].iStreamIndex]->language[2] = props->stream[i].strLanguage[2];
+ m_streams[props->stream[i].iStreamIndex]->language[3] = props->stream[i].strLanguage[3];
CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::UpdateStreams(): update stream %d:%d with codec_id %d",
- (*streams)[props->stream[i].iStreamIndex]->iId,
- (*streams)[props->stream[i].iStreamIndex]->iPhysicalId,
- (*streams)[props->stream[i].iStreamIndex]->codec);
+ m_streams[props->stream[i].iStreamIndex]->iId,
+ m_streams[props->stream[i].iStreamIndex]->iPhysicalId,
+ m_streams[props->stream[i].iStreamIndex]->codec);
}
}
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h
index e7ed91049b..340a861df4 100644
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h
@@ -45,36 +45,48 @@ extern "C" {
class CDVDDemuxPVRClient;
struct PVR_STREAM_PROPERTIES;
-class CDemuxStreamVideoPVRClient : public CDemuxStreamVideo
+class CDemuxStreamPVRInternal
+{
+public:
+ CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent);
+ ~CDemuxStreamPVRInternal();
+
+ void DisposeParser();
+
+ CDVDDemuxPVRClient * m_parent;
+ AVCodecParserContext* m_parser;
+ AVCodecContext * m_context;
+};
+
+class CDemuxStreamVideoPVRClient
+ : public CDemuxStreamVideo
+ , public CDemuxStreamPVRInternal
{
- CDVDDemuxPVRClient *m_parent;
public:
CDemuxStreamVideoPVRClient(CDVDDemuxPVRClient *parent)
- : m_parent(parent), m_pParser(NULL)
+ : CDemuxStreamPVRInternal(parent)
{}
- virtual ~CDemuxStreamVideoPVRClient();
virtual void GetStreamInfo(std::string& strInfo);
- AVCodecParserContext* m_pParser;
};
-class CDemuxStreamAudioPVRClient : public CDemuxStreamAudio
+class CDemuxStreamAudioPVRClient
+ : public CDemuxStreamAudio
+ , public CDemuxStreamPVRInternal
{
- CDVDDemuxPVRClient *m_parent;
public:
CDemuxStreamAudioPVRClient(CDVDDemuxPVRClient *parent)
- : m_parent(parent)
+ : CDemuxStreamPVRInternal(parent)
{}
- virtual ~CDemuxStreamAudioPVRClient();
virtual void GetStreamInfo(std::string& strInfo);
- AVCodecParserContext* m_pParser;
};
-class CDemuxStreamSubtitlePVRClient : public CDemuxStreamSubtitle
+class CDemuxStreamSubtitlePVRClient
+ : public CDemuxStreamSubtitle
+ , public CDemuxStreamPVRInternal
{
- CDVDDemuxPVRClient *m_parent;
public:
CDemuxStreamSubtitlePVRClient(CDVDDemuxPVRClient *parent)
- : m_parent(parent)
+ : CDemuxStreamPVRInternal(parent)
{}
virtual void GetStreamInfo(std::string& strInfo);
};
@@ -82,8 +94,7 @@ public:
class CDVDDemuxPVRClient : public CDVDDemux
{
- friend class CDemuxStreamVideoPVRClient;
- friend class CDemuxStreamAudioPVRClient;
+ friend class CDemuxStreamPVRInternal;
public:
@@ -110,7 +121,6 @@ protected:
#define MAX_STREAMS 100
#endif
CDemuxStream* m_streams[MAX_STREAMS]; // maximum number of streams that ffmpeg can handle
- CDemuxStream* m_streamsToParse[MAX_STREAMS];
boost::shared_ptr<PVR::CPVRClient> m_pvrClient;
DllAvCodec m_dllAvCodec;
@@ -118,6 +128,6 @@ protected:
private:
void RequestStreams();
void UpdateStreams(PVR_STREAM_PROPERTIES *props);
- bool ParsePacket(DemuxPacket* pPacket);
+ void ParsePacket(DemuxPacket* pPacket);
};
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
index bc26e41317..3ebf5aed93 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -1278,7 +1278,8 @@ void CDVDPlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket)
void CDVDPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
{
- if (m_CurrentAudio.stream != (void*)pStream)
+ if (m_CurrentAudio.stream != (void*)pStream
+ || m_CurrentAudio.changes != pStream->changes)
{
/* check so that dmuxer hints or extra data hasn't changed */
/* if they have, reopen stream */
@@ -1326,7 +1327,8 @@ void CDVDPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
{
- if (m_CurrentVideo.stream != (void*)pStream)
+ if (m_CurrentVideo.stream != (void*)pStream
+ || m_CurrentVideo.changes != pStream->changes)
{
/* check so that dmuxer hints or extra data hasn't changed */
/* if they have reopen stream */
@@ -1358,7 +1360,8 @@ void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
void CDVDPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket)
{
- if (m_CurrentSubtitle.stream != (void*)pStream)
+ if (m_CurrentSubtitle.stream != (void*)pStream
+ || m_CurrentSubtitle.changes != pStream->changes)
{
/* check so that dmuxer hints or extra data hasn't changed */
/* if they have reopen stream */
@@ -1386,7 +1389,8 @@ void CDVDPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket)
void CDVDPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket)
{
- if (m_CurrentTeletext.stream != (void*)pStream)
+ if (m_CurrentTeletext.stream != (void*)pStream
+ || m_CurrentTeletext.changes != pStream->changes)
{
/* check so that dmuxer hints or extra data hasn't changed */
/* if they have, reopen stream */
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h
index 7dd85c0180..cbb49d53ea 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.h
+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
@@ -67,6 +67,7 @@ public:
double dur; // last frame expected duration
CDVDStreamInfo hint; // stream hints, used to notice stream changes
void* stream; // pointer or integer, identifying stream playing. if it changes stream changed
+ int changes; // remembered counter from stream to track codec changes
bool inited;
bool started; // has the player started
const StreamType type;
@@ -89,6 +90,7 @@ public:
dur = DVD_NOPTS_VALUE;
hint.Clear();
stream = NULL;
+ changes = 0;
inited = false;
started = false;
startpts = DVD_NOPTS_VALUE;