3 * Copyright (C) 2005-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
22 #include "xbmc_pvr_types.h"
29 * Represents a single stream. It extends the PODS to provide some operators
32 class XbmcPvrStream : public PVR_STREAM_PROPERTIES::PVR_STREAM
40 XbmcPvrStream(const XbmcPvrStream &other)
42 memcpy(this, &other, sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM));
45 XbmcPvrStream& operator=(const XbmcPvrStream &other)
47 memcpy(this, &other, sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM));
52 * Compares this stream based on another stream
56 inline bool operator==(const XbmcPvrStream &other) const
58 return iPhysicalId == other.iPhysicalId && iCodecId == other.iCodecId;
62 * Compares this stream with another one so that video streams are sorted
63 * before any other streams and the others are sorted by the physical ID
67 bool operator<(const XbmcPvrStream &other) const
69 if (iCodecType == XBMC_CODEC_TYPE_VIDEO)
71 else if (other.iCodecType != XBMC_CODEC_TYPE_VIDEO)
72 return iPhysicalId < other.iPhysicalId;
82 memset(this, 0, sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM));
83 iCodecId = XBMC_INVALID_CODEC_ID;
84 iCodecType = XBMC_CODEC_TYPE_UNKNOWN;
88 * Checks whether the stream has been cleared
91 inline bool IsCleared() const
93 return iCodecId == XBMC_INVALID_CODEC_ID &&
94 iCodecType == XBMC_CODEC_TYPE_UNKNOWN;
98 class XbmcStreamProperties
101 typedef std::vector<XbmcPvrStream> stream_vector;
103 XbmcStreamProperties(void)
105 // make sure the vector won't have to resize itself later
106 m_streamVector = new stream_vector();
107 m_streamVector->reserve(PVR_STREAM_MAX_STREAMS);
110 virtual ~XbmcStreamProperties(void)
112 delete m_streamVector;
120 m_streamVector->clear();
121 m_streamIndex.clear();
125 * Returns the index of the stream with the specified physical ID, or -1 if
126 * there no stream is found. This method is called very often which is why
127 * we keep a separate map for this.
131 int GetStreamId(unsigned int iPhysicalId) const
133 std::map<unsigned int, int>::const_iterator it = m_streamIndex.find(iPhysicalId);
134 if (it != m_streamIndex.end())
141 * Returns the stream with the specified physical ID, or null if no such
146 XbmcPvrStream* GetStreamById(unsigned int iPhysicalId) const
148 int position = GetStreamId(iPhysicalId);
149 return position != -1 ? &m_streamVector->at(position) : NULL;
153 * Populates the specified stream with the stream having the specified
154 * physical ID. If the stream is not found only target stream's physical ID
159 void GetStreamData(unsigned int iPhysicalId, XbmcPvrStream* stream)
161 XbmcPvrStream *foundStream = GetStreamById(iPhysicalId);
163 stream = foundStream;
166 stream->iIdentifier = -1;
167 stream->iPhysicalId = iPhysicalId;
172 * Populates props with the current streams and returns whether there are
173 * any streams at the moment or not.
177 bool GetProperties(PVR_STREAM_PROPERTIES* props)
180 for (stream_vector::const_iterator it = m_streamVector->begin();
181 it != m_streamVector->end(); ++it, ++i)
183 memcpy(&props->stream[i], &(*it), sizeof(PVR_STREAM_PROPERTIES::PVR_STREAM));
186 props->iStreamCount = m_streamVector->size();
187 return (props->iStreamCount > 0);
191 * Merges new streams into the current list of streams. Identical streams
192 * will retain their respective indexes and new streams will replace unused
193 * indexes or be appended.
196 void UpdateStreams(stream_vector &newStreams)
198 // sort the new streams
199 std::sort(newStreams.begin(), newStreams.end());
201 // ensure we never have more than PVR_STREAMS_MAX_STREAMS streams
202 if (newStreams.size() > PVR_STREAM_MAX_STREAMS)
204 while (newStreams.size() > PVR_STREAM_MAX_STREAMS)
205 newStreams.pop_back();
207 XBMC->Log(LOG_ERROR, "%s - max amount of streams reached", __FUNCTION__);
210 stream_vector::iterator newStreamPosition;
211 for (stream_vector::iterator it = m_streamVector->begin(); it != m_streamVector->end(); ++it)
213 newStreamPosition = std::find(newStreams.begin(), newStreams.end(), *it);
215 // if the current stream no longer exists we clear it, otherwise we
216 // copy it and remove it from newStreams
217 if (newStreamPosition == newStreams.end())
221 *it = *newStreamPosition;
222 newStreams.erase(newStreamPosition);
226 // replace cleared streams with new streams
227 for (stream_vector::iterator it = m_streamVector->begin();
228 it != m_streamVector->end() && !newStreams.empty(); ++it)
232 *it = newStreams.front();
233 newStreams.erase(newStreams.begin());
237 // append any remaining new streams
238 m_streamVector->insert(m_streamVector->end(), newStreams.begin(), newStreams.end());
240 // remove trailing cleared streams
241 while (m_streamVector->back().IsCleared())
242 m_streamVector->pop_back();
249 stream_vector *m_streamVector;
250 std::map<unsigned int, int> m_streamIndex;
253 * Updates the stream index
257 m_streamIndex.clear();
260 for (stream_vector::const_iterator it = m_streamVector->begin(); it != m_streamVector->end(); ++it, ++i)
261 m_streamIndex[it->iPhysicalId] = i;