Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Pvrfix #1460

Merged
merged 3 commits into from

6 participants

Joakim Plate Lars Op den Kamp Zeljko Ametovic Rainer Hochecker EricV Voyager1
Joakim Plate
Collaborator

This resolves some of the issues that have surfaced with the parsing of demux streams for PVR. This should preferable go in as before next RC since at least one of the fixes is for potential seg faults. The other avoid hammering codec re-open (causing AE faults on macmini).

Note this could quite easily be extended to also parse for interlaced flags and similar from PVR backends.

elupus added some commits
Joakim Plate elupus dvdplayer: allow demuxer signal to player that stream info has changed 3661ddb
Joakim Plate elupus pvr: fixed invalid usage of m_dllAvCodec before open
RequestStreams can call for a parser, this could cause crashes
and undefined behavior.
a1a5742
Joakim Plate elupus pvr: rework parsing of stream to not hammer re-open of codecs
Old code would cause dvdplayer to thrash around closing and re-opening
codecs while a stream was being parse. And if it never found extradata
it would never open any codec.
41ca644
Joakim Plate elupus was assigned
Lars Op den Kamp
Collaborator
Zeljko Ametovic

as I said on IRC, fixes the issue I had with some HD channels

Rainer Hochecker
Collaborator

Unparsed streams go to player now, right?
@elupus don't you think it is a good idea to ignore streams until they are parsed? In the past we had trouble with e.g. incorrect hints coming from backends and made the system crash.

Joakim Plate
Collaborator
Joakim Plate
Collaborator
Rainer Hochecker
Collaborator

Thanks for explaining this. I was not aware of those constraints.

Joakim Plate elupus merged commit 8b2d36e into from
Joakim Plate
Collaborator

No large voiced no's on this yet. So i'm merging.

EricV

I can even add it fixes #13350

Voyager1
Collaborator

@elupus - I don't see where the "changes" member is being incremented, could it be that part of the commit was left out?

Collaborator
Lionel CHAZALLON LongChair referenced this pull request from a commit in plexinc/plex-home-theater-public
Lionel CHAZALLON LongChair Let ratingKey parser be a string parser, fixes #1460
key parser will convert the key to an url, therefore screwing progress report.

We want it to be a string so that Queue watched states can be updated properly, but we dont want it to change it to anything else :)
8c21202
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 21, 2012
  1. Joakim Plate
  2. Joakim Plate

    pvr: fixed invalid usage of m_dllAvCodec before open

    elupus authored
    RequestStreams can call for a parser, this could cause crashes
    and undefined behavior.
  3. Joakim Plate

    pvr: rework parsing of stream to not hammer re-open of codecs

    elupus authored
    Old code would cause dvdplayer to thrash around closing and re-opening
    codecs while a stream was being parse. And if it never found extradata
    it would never open any codec.
This page is out of date. Refresh to see the latest.
3  xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h
View
@@ -99,6 +99,7 @@ class CDemuxStream
ExtraSize = 0;
memset(language, 0, sizeof(language));
disabled = false;
+ changes = 0;
flags = FLAG_NONE;
}
@@ -130,6 +131,8 @@ class CDemuxStream
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
262 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
View
@@ -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);
}
}
44 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h
View
@@ -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 @@ class CDemuxStreamSubtitlePVRClient : public CDemuxStreamSubtitle
class CDVDDemuxPVRClient : public CDVDDemux
{
- friend class CDemuxStreamVideoPVRClient;
- friend class CDemuxStreamAudioPVRClient;
+ friend class CDemuxStreamPVRInternal;
public:
@@ -110,7 +121,6 @@ class CDVDDemuxPVRClient : public CDVDDemux
#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 @@ class CDVDDemuxPVRClient : public CDVDDemux
private:
void RequestStreams();
void UpdateStreams(PVR_STREAM_PROPERTIES *props);
- bool ParsePacket(DemuxPacket* pPacket);
+ void ParsePacket(DemuxPacket* pPacket);
};
12 xbmc/cores/dvdplayer/DVDPlayer.cpp
View
@@ -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 */
2  xbmc/cores/dvdplayer/DVDPlayer.h
View
@@ -67,6 +67,7 @@ class CCurrentStream
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 @@ class CCurrentStream
dur = DVD_NOPTS_VALUE;
hint.Clear();
stream = NULL;
+ changes = 0;
inited = false;
started = false;
startpts = DVD_NOPTS_VALUE;
Something went wrong with that request. Please try again.