m_dllAvCodec.Unload();
}
+void CDVDDemuxPVRClient::DisposeStream(int iStreamId)
+{
+ if (iStreamId < 0 || iStreamId >= MAX_STREAMS)
+ return;
+ if (m_streams[iStreamId]->ExtraData)
+ {
+ delete[] (uint8_t*)m_streams[iStreamId]->ExtraData;
+ m_streams[iStreamId]->ExtraData = NULL;
+ }
+ delete m_streams[iStreamId];
+ m_streams[iStreamId] = NULL;
+}
+
void CDVDDemuxPVRClient::Reset()
{
if(m_pInput && g_PVRManager.IsStarted())
if (pPacket->iStreamId == DMX_SPECIALID_STREAMINFO)
{
- UpdateStreams((PVR_STREAM_PROPERTIES*)pPacket->pData);
+ RequestStreams();
CDVDDemuxUtils::FreeDemuxPacket(pPacket);
return CDVDDemuxUtils::AllocateDemuxPacket(0);
}
else if (pPacket->iStreamId == DMX_SPECIALID_STREAMCHANGE)
{
- Reset();
+ RequestStreams();
}
else if (pPacket->iStreamId >= 0
&& pPacket->iStreamId < MAX_STREAMS
for (unsigned int i = 0; i < props.iStreamCount; ++i)
{
+ CDemuxStream *stm = m_streams[props.stream[i].iStreamIndex];
+
if (props.stream[i].iCodecType == AVMEDIA_TYPE_AUDIO)
{
- CDemuxStreamAudioPVRClient* st = new CDemuxStreamAudioPVRClient(this);
+ CDemuxStreamAudioPVRClient* st = NULL;
+ if (stm)
+ {
+ st = dynamic_cast<CDemuxStreamAudioPVRClient*>(stm);
+ if (!st || (st->codec != (CodecID)props.stream[i].iCodecId))
+ DisposeStream(props.stream[i].iStreamIndex);
+ }
+ if (!m_streams[props.stream[i].iStreamIndex])
+ {
+ st = new CDemuxStreamAudioPVRClient(this);
+ st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
+ if(st->m_parser)
+ st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+ }
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;
- st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
- if(st->m_parser)
- st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
m_streams[props.stream[i].iStreamIndex] = st;
}
else if (props.stream[i].iCodecType == AVMEDIA_TYPE_VIDEO)
{
- CDemuxStreamVideoPVRClient* st = new CDemuxStreamVideoPVRClient(this);
+ CDemuxStreamVideoPVRClient* st = NULL;
+ if (stm)
+ {
+ st = dynamic_cast<CDemuxStreamVideoPVRClient*>(stm);
+ if (!st
+ || (st->codec != (CodecID)props.stream[i].iCodecId)
+ || (st->iWidth != props.stream[i].iWidth)
+ || (st->iHeight != props.stream[i].iHeight))
+ DisposeStream(props.stream[i].iStreamIndex);
+ }
+ if (!m_streams[props.stream[i].iStreamIndex])
+ {
+ st = new CDemuxStreamVideoPVRClient(this);
+ st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
+ if(st->m_parser)
+ st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+ }
st->iFpsScale = props.stream[i].iFPSScale;
st->iFpsRate = props.stream[i].iFPSRate;
st->iHeight = props.stream[i].iHeight;
st->iWidth = props.stream[i].iWidth;
st->fAspect = props.stream[i].fAspect;
- st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId);
- if(st->m_parser)
- st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
m_streams[props.stream[i].iStreamIndex] = st;
}
else if (props.stream[i].iCodecId == CODEC_ID_DVB_TELETEXT)
{
- m_streams[props.stream[i].iStreamIndex] = new CDemuxStreamTeletext();
+ if (stm)
+ {
+ if (stm->codec != (CodecID)props.stream[i].iCodecId)
+ DisposeStream(props.stream[i].iStreamIndex);
+ }
+ if (!m_streams[props.stream[i].iStreamIndex])
+ m_streams[props.stream[i].iStreamIndex] = new CDemuxStreamTeletext();
}
else if (props.stream[i].iCodecType == AVMEDIA_TYPE_SUBTITLE)
{
- CDemuxStreamSubtitlePVRClient* st = new CDemuxStreamSubtitlePVRClient(this);
- st->identifier = props.stream[i].iIdentifier;
+ CDemuxStreamSubtitlePVRClient* st = NULL;
+ if (stm)
+ {
+ st = dynamic_cast<CDemuxStreamSubtitlePVRClient*>(stm);
+ if (!st || (st->codec != (CodecID)props.stream[i].iCodecId))
+ DisposeStream(props.stream[i].iStreamIndex);
+ }
+ if (!m_streams[props.stream[i].iStreamIndex])
+ {
+ st = new CDemuxStreamSubtitlePVRClient(this);
+ }
+ st->identifier = props.stream[i].iIdentifier;
m_streams[props.stream[i].iStreamIndex] = st;
}
else
- m_streams[props.stream[i].iStreamIndex] = new CDemuxStream();
+ {
+ if (!m_streams[props.stream[i].iStreamIndex])
+ m_streams[props.stream[i].iStreamIndex] = new CDemuxStream();
+ }
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]->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",
+ CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): added/updated stream %d:%d with codec_id %d",
m_streams[props.stream[i].iStreamIndex]->iId,
m_streams[props.stream[i].iStreamIndex]->iPhysicalId,
m_streams[props.stream[i].iStreamIndex]->codec);
}
-}
-
-void CDVDDemuxPVRClient::UpdateStreams(PVR_STREAM_PROPERTIES *props)
-{
- bool bGotVideoStream(false);
-
- for (unsigned int i = 0; i < props->iStreamCount; ++i)
+ // check if we need to dispose any streams no longer in props
+ for (unsigned int i = 0; i < MAX_STREAMS; i++)
{
- 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 (m_streams[props->stream[i].iStreamIndex]->type == STREAM_AUDIO)
- {
- 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 (m_streams[props->stream[i].iStreamIndex]->type == STREAM_VIDEO)
+ if (m_streams[i])
{
- if (bGotVideoStream)
+ bool found(false);
+ for (int j = 0; j < props.iStreamCount; j++)
{
- CLog::Log(LOGDEBUG, "CDVDDemuxPVRClient - %s - skip video stream", __FUNCTION__);
- continue;
+ if (props.stream[j].iStreamIndex == i)
+ found = true;
}
-
- CDemuxStreamVideoPVRClient* st = (CDemuxStreamVideoPVRClient*) m_streams[props->stream[i].iStreamIndex];
- if (st->iWidth <= 0 || st->iHeight <= 0)
+ if (!found)
{
- CLog::Log(LOGWARNING, "CDVDDemuxPVRClient - %s - invalid stream data", __FUNCTION__);
- continue;
+ CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): disposed stream %d:%d with codec_id %d",
+ m_streams[i]->iId,
+ m_streams[i]->iPhysicalId,
+ m_streams[i]->codec);
+ DisposeStream(i);
}
-
- st->iFpsScale = props->stream[i].iFPSScale;
- st->iFpsRate = props->stream[i].iFPSRate;
- st->iHeight = props->stream[i].iHeight;
- st->iWidth = props->stream[i].iWidth;
- st->fAspect = props->stream[i].fAspect;
- bGotVideoStream = true;
}
- else if (m_streams[props->stream[i].iStreamIndex]->type == STREAM_SUBTITLE)
- {
- CDemuxStreamSubtitlePVRClient* st = (CDemuxStreamSubtitlePVRClient*) m_streams[props->stream[i].iStreamIndex];
- st->identifier = props->stream[i].iIdentifier;
- }
-
- 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",
- m_streams[props->stream[i].iStreamIndex]->iId,
- m_streams[props->stream[i].iStreamIndex]->iPhysicalId,
- m_streams[props->stream[i].iStreamIndex]->codec);
}
}