/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. #include "DVDCodecs/DVDCodecs.h"
  21. #include "DVDInputStreams/DVDInputStreamHttp.h"
  22. #include "DVDDemuxShoutcast.h"
  23. #include "DVDDemuxUtils.h"
  24. #include "DVDClock.h" // for DVD_TIME_BASE
  25. #include "../../../utils/HttpHeader.h"
  26. #define ICY_NOTICE1 "icy-notice1" // string
  27. #define ICY_NOTICE2 "icy-notice2" // string
  28. #define ICY_NAME "icy-name" // string
  29. #define ICY_GENRE "icy-genre" // string
  30. #define ICY_URL "icy-url" // string
  31. #define ICY_PUBLIC "icy-pub" // int (1 / 0)
  32. #define ICY_BITRATE "icy-br" // int (bitrate = val * 1000 ?)
  33. #define ICY_METAINTERVAL "icy-metaint" // int
  34. #define CONTENT_TYPE_MP3 "audio/mpeg"
  35. #define CONTENT_TYPE_AAC "audio/aac"
  36. #define CONTENT_TYPE_AACPLUS "audio/aacp"
  37. // class CDemuxStreamVideoFFmpeg
  38. void CDemuxStreamAudioShoutcast::GetStreamInfo(std::string& strInfo)
  39. {
  40. strInfo = "Shoutcast";
  41. }
  42. CDVDDemuxShoutcast::CDVDDemuxShoutcast() : CDVDDemux()
  43. {
  44. m_pInput = NULL;
  45. m_pDemuxStream = NULL;
  46. m_iMetaStreamInterval = 0;
  47. }
  48. CDVDDemuxShoutcast::~CDVDDemuxShoutcast()
  49. {
  50. Dispose();
  51. }
  52. bool CDVDDemuxShoutcast::Open(CDVDInputStream* pInput)
  53. {
  54. Dispose();
  55. m_pInput = pInput;
  56. // the input stream should be a http stream
  57. if (!pInput->IsStreamType(DVDSTREAM_TYPE_HTTP)) return false;
  58. CDVDInputStreamHttp* pInputStreamHttp = (CDVDInputStreamHttp*)pInput;
  59. CHttpHeader* pHeader = pInputStreamHttp->GetHttpHeader();
  60. std::string strMetaInt = pHeader->GetValue(ICY_METAINTERVAL);
  61. std::string strMimeType = pHeader->GetMimeType();
  62. // create new demuxer stream
  63. m_pDemuxStream = new CDemuxStreamAudioShoutcast();
  64. m_pDemuxStream->iId = 0;
  65. m_pDemuxStream->iPhysicalId = 0;
  66. m_pDemuxStream->iDuration = 0;
  67. m_pDemuxStream->iChannels = 2;
  68. m_pDemuxStream->iSampleRate = 0;
  69. // set meta interval
  70. m_iMetaStreamInterval = atoi(strMetaInt.c_str());
  71. if (stricmp(strMimeType.c_str(), CONTENT_TYPE_AAC) == 0 ||
  72. stricmp(strMimeType.c_str(), CONTENT_TYPE_AACPLUS) == 0)
  73. {
  74. // need an aac decoder first
  75. m_pDemuxStream->codec = AV_CODEC_ID_AAC;
  76. }
  77. else // (stricmp(strMimeType, CONTENT_TYPE_MP3) == 0)
  78. {
  79. // default to mp3
  80. m_pDemuxStream->codec = AV_CODEC_ID_MP3;
  81. }
  82. return true;
  83. }
  84. void CDVDDemuxShoutcast::Dispose()
  85. {
  86. if (m_pDemuxStream) delete m_pDemuxStream;
  87. m_pDemuxStream = NULL;
  88. m_pInput = NULL;
  89. }
  90. void CDVDDemuxShoutcast::Reset()
  91. {
  92. CDVDInputStream* pInputStream = m_pInput;
  93. Dispose();
  94. Open(pInputStream);
  95. }
  96. void CDVDDemuxShoutcast::Flush()
  97. {
  98. }
  99. DemuxPacket* CDVDDemuxShoutcast::Read()
  100. {
  101. // XXX
  102. // if meta interval is greater than FileCurl's max read size (currently 64k)
  103. // it will simply fail becuse the meta-interval will get incorrect
  104. int iDataToRead = SHOUTCAST_BUFFER_SIZE;
  105. if (m_iMetaStreamInterval > 0) iDataToRead = m_iMetaStreamInterval;
  106. DemuxPacket* pPacket;
  107. pPacket = CDVDDemuxUtils::AllocateDemuxPacket(iDataToRead);
  108. if (pPacket)
  109. {
  110. pPacket->dts = DVD_NOPTS_VALUE;
  111. pPacket->pts = DVD_NOPTS_VALUE;
  112. pPacket->iStreamId = 0;
  113. // read the data
  114. int iRead = m_pInput->Read(pPacket->pData, iDataToRead);
  115. pPacket->iSize = iRead;
  116. if (iRead <= 0)
  117. {
  118. CDVDDemuxUtils::FreeDemuxPacket(pPacket);
  119. pPacket = NULL;
  120. }
  121. }
  122. if (m_iMetaStreamInterval > 0)
  123. {
  124. // we already have read m_iMetaStreamInterval bytes of streaming data
  125. // metadata follows
  126. uint8_t l;
  127. int iRead = m_pInput->Read(&l, 1);
  128. if (iRead > 0)
  129. {
  130. int iMetaLength = l * 16;
  131. if (iMetaLength > 0)
  132. {
  133. // iMetaLength cannot be larger then 16 * 255
  134. uint8_t buffer[16 * 255];
  135. // skip meta data for now
  136. m_pInput->Read(buffer, iMetaLength);
  137. }
  138. }
  139. }
  140. return pPacket;
  141. }
  142. bool CDVDDemuxShoutcast::SeekTime(int time, bool backwords, double* startpts)
  143. {
  144. return false;
  145. }
  146. int CDVDDemuxShoutcast::GetStreamLength()
  147. {
  148. return 0;
  149. }
  150. CDemuxStream* CDVDDemuxShoutcast::GetStream(int iStreamId)
  151. {
  152. return m_pDemuxStream;
  153. }
  154. int CDVDDemuxShoutcast::GetNrOfStreams()
  155. {
  156. return 1;
  157. }
  158. std::string CDVDDemuxShoutcast::GetFileName()
  159. {
  160. if(m_pInput)
  161. return m_pInput->GetFileName();
  162. else
  163. return "";
  164. }