PageRenderTime 39ms CodeModel.GetById 18ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp

http://github.com/xbmc/xbmc
C++ | 199 lines | 131 code | 35 blank | 33 comment | 13 complexity | 77ef542235b771be183fb5dad7af9fa7 MD5 | raw file
  1/*
  2 *      Copyright (C) 2005-2013 Team XBMC
  3 *      http://xbmc.org
  4 *
  5 *  This Program is free software; you can redistribute it and/or modify
  6 *  it under the terms of the GNU General Public License as published by
  7 *  the Free Software Foundation; either version 2, or (at your option)
  8 *  any later version.
  9 *
 10 *  This Program is distributed in the hope that it will be useful,
 11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *  GNU General Public License for more details.
 14 *
 15 *  You should have received a copy of the GNU General Public License
 16 *  along with XBMC; see the file COPYING.  If not, see
 17 *  <http://www.gnu.org/licenses/>.
 18 *
 19 */
 20
 21#include "DVDCodecs/DVDCodecs.h"
 22#include "DVDInputStreams/DVDInputStreamHttp.h"
 23#include "DVDDemuxShoutcast.h"
 24#include "DVDDemuxUtils.h"
 25#include "DVDClock.h" // for DVD_TIME_BASE
 26#include "../../../utils/HttpHeader.h"
 27
 28#define ICY_NOTICE1           "icy-notice1" // string
 29#define ICY_NOTICE2           "icy-notice2" // string
 30#define ICY_NAME              "icy-name"    // string
 31#define ICY_GENRE             "icy-genre"   // string
 32#define ICY_URL               "icy-url"     // string
 33#define ICY_PUBLIC            "icy-pub"     // int (1 / 0)
 34#define ICY_BITRATE           "icy-br"      // int (bitrate = val * 1000 ?)
 35#define ICY_METAINTERVAL      "icy-metaint" // int
 36
 37#define CONTENT_TYPE_MP3      "audio/mpeg"
 38#define CONTENT_TYPE_AAC      "audio/aac"
 39#define CONTENT_TYPE_AACPLUS  "audio/aacp"
 40
 41// class CDemuxStreamVideoFFmpeg
 42void CDemuxStreamAudioShoutcast::GetStreamInfo(std::string& strInfo)
 43{
 44  strInfo = "Shoutcast";
 45}
 46
 47CDVDDemuxShoutcast::CDVDDemuxShoutcast() : CDVDDemux()
 48{
 49  m_pInput = NULL;
 50  m_pDemuxStream = NULL;
 51  m_iMetaStreamInterval = 0;
 52}
 53
 54CDVDDemuxShoutcast::~CDVDDemuxShoutcast()
 55{
 56  Dispose();
 57}
 58
 59bool CDVDDemuxShoutcast::Open(CDVDInputStream* pInput)
 60{
 61  Dispose();
 62
 63  m_pInput = pInput;
 64
 65  // the input stream should be a http stream
 66  if (!pInput->IsStreamType(DVDSTREAM_TYPE_HTTP)) return false;
 67  CDVDInputStreamHttp* pInputStreamHttp = (CDVDInputStreamHttp*)pInput;
 68
 69  CHttpHeader* pHeader = pInputStreamHttp->GetHttpHeader();
 70
 71  std::string strMetaInt = pHeader->GetValue(ICY_METAINTERVAL);
 72  std::string strMimeType = pHeader->GetMimeType();
 73
 74  // create new demuxer stream
 75  m_pDemuxStream = new CDemuxStreamAudioShoutcast();
 76  m_pDemuxStream->iId = 0;
 77  m_pDemuxStream->iPhysicalId = 0;
 78  m_pDemuxStream->iDuration = 0;
 79  m_pDemuxStream->iChannels = 2;
 80  m_pDemuxStream->iSampleRate = 0;
 81
 82  // set meta interval
 83  m_iMetaStreamInterval = atoi(strMetaInt.c_str());
 84
 85  if (stricmp(strMimeType.c_str(), CONTENT_TYPE_AAC) == 0 ||
 86      stricmp(strMimeType.c_str(), CONTENT_TYPE_AACPLUS) == 0)
 87  {
 88    // need an aac decoder first
 89    m_pDemuxStream->codec = AV_CODEC_ID_AAC;
 90  }
 91  else // (stricmp(strMimeType, CONTENT_TYPE_MP3) == 0)
 92  {
 93    // default to mp3
 94    m_pDemuxStream->codec = AV_CODEC_ID_MP3;
 95  }
 96
 97  return true;
 98}
 99
100void CDVDDemuxShoutcast::Dispose()
101{
102  if (m_pDemuxStream) delete m_pDemuxStream;
103  m_pDemuxStream = NULL;
104
105  m_pInput = NULL;
106}
107
108void CDVDDemuxShoutcast::Reset()
109{
110  CDVDInputStream* pInputStream = m_pInput;
111  Dispose();
112  Open(pInputStream);
113}
114
115void CDVDDemuxShoutcast::Flush()
116{
117}
118
119DemuxPacket* CDVDDemuxShoutcast::Read()
120{
121  // XXX
122  // if meta interval is greater than FileCurl's max read size (currently 64k)
123  // it will simply fail becuse the meta-interval will get incorrect
124
125  int iDataToRead = SHOUTCAST_BUFFER_SIZE;
126  if (m_iMetaStreamInterval > 0) iDataToRead = m_iMetaStreamInterval;
127
128  DemuxPacket* pPacket;
129  pPacket = CDVDDemuxUtils::AllocateDemuxPacket(iDataToRead);
130  if (pPacket)
131  {
132    pPacket->dts = DVD_NOPTS_VALUE;
133    pPacket->pts = DVD_NOPTS_VALUE;
134    pPacket->iStreamId = 0;
135
136    // read the data
137    int iRead = m_pInput->Read(pPacket->pData, iDataToRead);
138
139    pPacket->iSize = iRead;
140
141    if (iRead <= 0)
142    {
143      CDVDDemuxUtils::FreeDemuxPacket(pPacket);
144      pPacket = NULL;
145    }
146  }
147
148  if (m_iMetaStreamInterval > 0)
149  {
150    // we already have read m_iMetaStreamInterval bytes of streaming data
151    // metadata follows
152    uint8_t l;
153    int iRead = m_pInput->Read(&l, 1);
154    if (iRead > 0)
155    {
156      int iMetaLength = l * 16;
157
158      if (iMetaLength > 0)
159      {
160        // iMetaLength cannot be larger then 16 * 255
161        uint8_t buffer[16 * 255];
162
163        // skip meta data for now
164        m_pInput->Read(buffer, iMetaLength);
165      }
166    }
167  }
168
169  return pPacket;
170}
171
172bool CDVDDemuxShoutcast::SeekTime(int time, bool backwords, double* startpts)
173{
174  return false;
175}
176
177int CDVDDemuxShoutcast::GetStreamLength()
178{
179  return 0;
180}
181
182CDemuxStream* CDVDDemuxShoutcast::GetStream(int iStreamId)
183{
184  return m_pDemuxStream;
185}
186
187int CDVDDemuxShoutcast::GetNrOfStreams()
188{
189  return 1;
190}
191
192std::string CDVDDemuxShoutcast::GetFileName()
193{
194  if(m_pInput)
195    return m_pInput->GetFileName();
196  else
197    return "";
198}
199