Ejemplo n.º 1
0
bool CAudioDecoder::Init(const CFileItem& file, unsigned int filecache)
{
  if (!Initialized())
    return false;

  // for replaygain
  CTagLoaderTagLib tag;
  tag.Load(file.GetPath(), XFILE::CMusicFileDirectory::m_tag, NULL);

  int channels;
  int sampleRate;

  m_context = m_struct.toAddon.Init(file.GetPath().c_str(), filecache,
                              &channels, &sampleRate,
                              &m_bitsPerSample, &m_TotalTime,
                              &m_bitRate, &m_format.m_dataFormat, &m_channel);

  m_format.m_sampleRate = sampleRate;
  if (m_channel)
    m_format.m_channelLayout = CAEChannelInfo(m_channel);
  else
    m_format.m_channelLayout = CAEUtil::GuessChLayout(channels);

  return (m_context != NULL);
}
Ejemplo n.º 2
0
bool CAudioDecoder::Init(const std::string& strFile, unsigned int filecache)
{
  if (!Initialized())
    return false;

  // for replaygain
  CTagLoaderTagLib tag;
  tag.Load(strFile, XFILE::CMusicFileDirectory::m_tag, NULL);

  int channels;
  int sampleRate;

  m_context = m_pStruct->Init(strFile.c_str(), filecache,
                              &channels, &sampleRate,
                              &m_bitsPerSample, &m_TotalTime,
                              &m_bitRate, &m_format.m_dataFormat, &m_channel);

  return (m_context != NULL);
}
Ejemplo n.º 3
0
bool DVDPlayerCodec::Init(const CStdString &strFile, unsigned int filecache)
{
  // take precaution if Init()ialized earlier
  if (m_bInited)
  {
    // keep things as is if Init() was done with known strFile
    if (m_strFileName == strFile)
      return true;

    // got differing filename, so cleanup before starting over
    DeInit();
  }

  m_decoded = NULL;
  m_nDecodedLen = 0;

  CStdString strFileToOpen = strFile;

  CURL urlFile(strFile);
  if (urlFile.GetProtocol() == "shout" )
    strFileToOpen.replace(0, 8, "http://");

  m_pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, strFileToOpen, m_strContentType);
  if (!m_pInputStream)
  {
    CLog::Log(LOGERROR, "%s: Error creating input stream for %s", __FUNCTION__, strFileToOpen.c_str());
    return false;
  }

  if (!m_pInputStream->Open(strFileToOpen.c_str(), m_strContentType))
  {
    CLog::Log(LOGERROR, "%s: Error opening file %s", __FUNCTION__, strFileToOpen.c_str());
    if (m_pInputStream)
      delete m_pInputStream;
    m_pInputStream = NULL;
    return false;
  }

  m_pDemuxer = NULL;

  try
  {
    m_pDemuxer = CDVDFactoryDemuxer::CreateDemuxer(m_pInputStream);
    if (!m_pDemuxer)
    {
      delete m_pInputStream;
      m_pInputStream = NULL;
      CLog::Log(LOGERROR, "%s: Error creating demuxer", __FUNCTION__);
      return false;
    }
  }
  catch(...)
  {
    CLog::Log(LOGERROR, "%s: Exception thrown when opening demuxer", __FUNCTION__);
    if (m_pDemuxer)
    {
      delete m_pDemuxer;
      m_pDemuxer = NULL;
    }
    delete m_pInputStream;
    m_pInputStream = NULL;
    return false;
  }

  CDemuxStream* pStream = NULL;
  m_nAudioStream = -1;
  for (int i = 0; i < m_pDemuxer->GetNrOfStreams(); i++)
  {
    pStream = m_pDemuxer->GetStream(i);
    if (pStream && pStream->type == STREAM_AUDIO)
    {
      m_nAudioStream = i;
      break;
    }
  }

  if (m_nAudioStream == -1)
  {
    CLog::Log(LOGERROR, "%s: Could not find audio stream", __FUNCTION__);
    delete m_pDemuxer;
    m_pDemuxer = NULL;
    delete m_pInputStream;
    m_pInputStream = NULL;
    return false;
  }

  CDVDStreamInfo hint(*pStream, true);

  m_pAudioCodec = CDVDFactoryCodec::CreateAudioCodec(hint);
  if (!m_pAudioCodec)
  {
    CLog::Log(LOGERROR, "%s: Could not create audio codec", __FUNCTION__);
    delete m_pDemuxer;
    m_pDemuxer = NULL;
    delete m_pInputStream;
    m_pInputStream = NULL;
    return false;
  }

  //  Extract ReplayGain info
  // tagLoaderTagLib.Load will try to determine tag type by file extension, so set fallback by contentType
  CStdString strFallbackFileExtension = "";
  if (m_strContentType.Equals("audio/aacp") || m_strContentType.Equals("audio/aacp" "audio/aac"))
    strFallbackFileExtension = "m4a";
  else if (m_strContentType.Equals("audio/x-ms-wma"))
    strFallbackFileExtension = "wma";
  else if (m_strContentType.Equals("audio/x-ape") || m_strContentType.Equals("audio/ape"))
    strFallbackFileExtension = "ape";
  CTagLoaderTagLib tagLoaderTagLib;
  tagLoaderTagLib.Load(strFile, m_tag, strFallbackFileExtension);

  // we have to decode initial data in order to get channels/samplerate
  // for sanity - we read no more than 10 packets
  int nErrors = 0;
  for (int nPacket=0; nPacket < 10 && (m_Channels == 0 || m_SampleRate == 0); nPacket++)
  {
    BYTE dummy[256];
    int nSize = 256;
    if (ReadPCM(dummy, nSize, &nSize) == READ_ERROR)
      ++nErrors;

    m_DataFormat    = m_pAudioCodec->GetDataFormat();
    m_BitsPerSample = CAEUtil::DataFormatToBits(m_DataFormat);
    m_SampleRate = m_pAudioCodec->GetSampleRate();
    m_EncodedSampleRate = m_pAudioCodec->GetEncodedSampleRate();
    m_Channels = m_pAudioCodec->GetChannels();
    m_ChannelInfo = m_pAudioCodec->GetChannelMap();
    m_BitsPerCodedSample = static_cast<CDemuxStreamAudio*>(pStream)->iBitsPerSample;
  }
  if (nErrors >= 10)
  {
    CLog::Log(LOGDEBUG, "%s: Could not decode data", __FUNCTION__);
    return false;
  }

  // test if seeking is supported
  if (Seek(1) != DVD_NOPTS_VALUE)
  {
    // rewind stream to beginning
    Seek(0);
    m_bCanSeek = true;
  }
  else
  {
    m_pInputStream->Seek(0, SEEK_SET);
    m_pDemuxer->Reset();
    m_bCanSeek = false;
  }

  if (m_Channels == 0) // no data - just guess and hope for the best
    m_Channels = 2;

  if (m_SampleRate == 0)
    m_SampleRate = 44100;

  m_TotalTime = m_pDemuxer->GetStreamLength();
  m_Bitrate = m_pAudioCodec->GetBitRate();
  if (!m_Bitrate && m_TotalTime)
  {
    m_Bitrate = (int)(((m_pInputStream->GetLength()*1000) / m_TotalTime) * 8);
  }
  m_pDemuxer->GetStreamCodecName(m_nAudioStream,m_CodecName);

  m_strFileName = strFile;
  m_bInited = true;

  return true;
}
Ejemplo n.º 4
0
bool MP3Codec::Init(const CStdString &strFile, unsigned int filecache)
{
  if (!m_dll.Load())
    return false;

  // set defaults...
  m_InputBufferPos = 0;
  m_OutputBufferPos = 0;
  m_IgnoreFirst = true; // we want to be gapless
  m_IgnoredBytes = 0;
  m_IgnoreLast = true;
  m_lastByteOffset = 0;
  m_eof = false;
  m_CallAgainWithSameBuffer = false;
  m_readRetries = 5;

  int id3v2Size = 0;
  int result = -1;
  int64_t length = 0;
  bool bTags = false;

  if (!m_file.Open(strFile, READ_CACHED))
  {
    CLog::Log(LOGERROR, "MP3Codec: Unable to open file %s", strFile.c_str());
    return false;
  }

  // Guess Bitrate and obtain replayGain information etc.
  length = m_file.GetLength();
  if (length != 0)
  {
    CTagLoaderTagLib tagLoaderTagLib; //opens the file so needs to be after m_file.Open or lastfm radio breaks.
    bTags = tagLoaderTagLib.Load(strFile, m_tag);

    if (bTags)
      ReadDuration();

    if (bTags)
      m_TotalTime = (int64_t)( m_fTotalDuration * 1000.0f);

    // Read in some data so we can determine the sample size and so on
    // This needs to be made more intelligent - possibly use a temp output buffer
    // and cycle around continually reading until we have the necessary data
    // as a first workaround skip the id3v2 tag at the beginning of the file
    if (bTags)
    {
      if (m_iSeekOffsets > 0)
      {
        id3v2Size=(int)m_SeekOffset[0];
        m_file.Seek(id3v2Size);
      }
      else
      {
        CLog::Log(LOGERROR, "MP3Codec: Seek info unavailable for file <%s> (corrupt?)", strFile.c_str());
        goto error;
      }
    }
    
    if ( m_TotalTime && (length - id3v2Size > 0) )
    {
      m_Bitrate = (int)(((length - id3v2Size) / m_fTotalDuration) * 8);  // average bitrate
    }
  }

  m_eof = false;
  while ((result != DECODING_SUCCESS) && !m_eof && (m_OutputBufferPos < OUTPUTFRAMESIZE)) // eof can be set from outside (when stopping playback)
  {
    result = Read(8192, true);
    if (result == DECODING_ERROR)
    {
      CLog::Log(LOGERROR, "MP3Codec: Unable to determine file format of %s (corrupt start of mp3?)", strFile.c_str());
      goto error;
    }
    if (bTags && !m_Bitrate) //use tag bitrate if average bitrate is not available
      m_Bitrate = m_Formatdata[4];
  }

  return true;

error:
  m_file.Close();
  return false;
}
Ejemplo n.º 5
0
TEST(TestTagLoaderTagLib, SplitMBID)
{
  CTagLoaderTagLib lib;

  // SplitMBID should return the vector if it's empty or longer than 1
  std::vector<std::string> values;
  EXPECT_TRUE(lib.SplitMBID(values).empty());

  values.push_back("1");
  values.push_back("2");
  EXPECT_EQ(values, lib.SplitMBID(values));

  // length 1 and invalid should return empty
  values.clear();
  values.push_back("invalid");
  EXPECT_TRUE(lib.SplitMBID(values).empty());

  // length 1 and valid should return the valid id
  values.clear();
  values.push_back("0383dadf-2a4e-4d10-a46a-e9e041da8eb3");
  EXPECT_EQ(lib.SplitMBID(values), values);

  // case shouldn't matter
  values.clear();
  values.push_back("0383DaDf-2A4e-4d10-a46a-e9e041da8eb3");
  EXPECT_EQ(lib.SplitMBID(values).size(), 1u);
  EXPECT_STREQ(lib.SplitMBID(values)[0].c_str(), "0383dadf-2a4e-4d10-a46a-e9e041da8eb3");

  // valid with some stuff off the end or start should return valid
  values.clear();
  values.push_back("foo0383dadf-2a4e-4d10-a46a-e9e041da8eb3 blah");
  EXPECT_EQ(lib.SplitMBID(values).size(), 1u);
  EXPECT_STREQ(lib.SplitMBID(values)[0].c_str(), "0383dadf-2a4e-4d10-a46a-e9e041da8eb3");

  // two valid with various separators
  values.clear();
  values.push_back("0383dadf-2a4e-4d10-a46a-e9e041da8eb3;53b106e7-0cc6-42cc-ac95-ed8d30a3a98e");
  std::vector<std::string> result = lib.SplitMBID(values);
  EXPECT_EQ(result.size(), 2u);
  EXPECT_STREQ(result[0].c_str(), "0383dadf-2a4e-4d10-a46a-e9e041da8eb3");
  EXPECT_STREQ(result[1].c_str(), "53b106e7-0cc6-42cc-ac95-ed8d30a3a98e");

  values.clear();
  values.push_back("0383dadf-2a4e-4d10-a46a-e9e041da8eb3/53b106e7-0cc6-42cc-ac95-ed8d30a3a98e");
  result = lib.SplitMBID(values);
  EXPECT_EQ(result.size(), 2u);
  EXPECT_STREQ(result[0].c_str(), "0383dadf-2a4e-4d10-a46a-e9e041da8eb3");
  EXPECT_STREQ(result[1].c_str(), "53b106e7-0cc6-42cc-ac95-ed8d30a3a98e");

  values.clear();
  values.push_back("0383dadf-2a4e-4d10-a46a-e9e041da8eb3 / 53b106e7-0cc6-42cc-ac95-ed8d30a3a98e; ");
  result = lib.SplitMBID(values);
  EXPECT_EQ(result.size(), 2u);
  EXPECT_STREQ(result[0].c_str(), "0383dadf-2a4e-4d10-a46a-e9e041da8eb3");
  EXPECT_STREQ(result[1].c_str(), "53b106e7-0cc6-42cc-ac95-ed8d30a3a98e");
}
Ejemplo n.º 6
0
bool OGGCodec::Init(const CStdString &strFile1, unsigned int filecache)
{
  if (m_inited)
    return true;
  CStdString strFile=strFile1;
  if (!m_dll.Load())
    return false;

  m_CurrentStream=0;

  CStdString strExtension;
  URIUtils::GetExtension(strFile, strExtension);

  //  A bitstream inside a ogg file?
  if (strExtension==".oggstream")
  {
    //  Extract the bitstream to play
    CStdString strFileName=URIUtils::GetFileName(strFile);
    int iStart=strFileName.ReverseFind('-')+1;
    m_CurrentStream = atoi(strFileName.substr(iStart, strFileName.size()-iStart-10).c_str())-1;
    //  The directory we are in, is the file
    //  that contains the bitstream to play,
    //  so extract it
    CStdString strPath=strFile;
    URIUtils::GetDirectory(strPath, strFile);
    URIUtils::RemoveSlashAtEnd(strFile); // we want the filename
  }

  CFileItem item(strFile, false);

  //  Open the file to play
  if (!m_file.Open(strFile, READ_CACHED))
  {
    CLog::Log(LOGERROR, "OGGCodec: Can't open %s", strFile1.c_str());
    return false;
  }

  //  setup ogg i/o callbacks
  ov_callbacks oggIOCallbacks = m_callback.Get(strFile);

  //  open ogg file with decoder
  if (m_dll.ov_open_callbacks(&m_callback, &m_VorbisFile, NULL, 0, oggIOCallbacks)!=0)
  {
    CLog::Log(LOGERROR, "OGGCodec: Can't open decoder for %s", strFile1.c_str());
    return false;
  }

  long iStreams=m_dll.ov_streams(&m_VorbisFile);
  if (iStreams>1)
  {
    if (m_CurrentStream > iStreams)
      return false;
  }

  //  Calculate the offset in secs where the bitstream starts
  for (int i=0; i<m_CurrentStream; ++i)
    m_TimeOffset += m_dll.ov_time_total(&m_VorbisFile, i);

  //  get file info
  vorbis_info* pInfo=m_dll.ov_info(&m_VorbisFile, m_CurrentStream);
  if (!pInfo)
  {
    CLog::Log(LOGERROR, "OGGCodec: Can't get stream info from %s", strFile1.c_str());
    return false;
  }

  m_SampleRate = pInfo->rate;
  m_Channels = pInfo->channels;
  m_BitsPerSample = 16;
  m_DataFormat = AE_FMT_S16NE;
  if (item.IsInternetStream())
    m_TotalTime = -1;
  else
    m_TotalTime = (int64_t)m_dll.ov_time_total(&m_VorbisFile, m_CurrentStream)*1000;
  m_Bitrate = pInfo->bitrate_nominal;
  if (m_Bitrate == 0 && m_TotalTime > 0 && !item.IsInternetStream())
    m_Bitrate = (int)(m_file.GetLength()*8 / (m_TotalTime / 1000));

  if (m_SampleRate==0 || m_Channels==0 || m_BitsPerSample==0 || m_TotalTime==0)
  {
    CLog::Log(LOGERROR, "OGGCodec: incomplete stream info from %s, SampleRate=%i, Channels=%i, BitsPerSample=%i, TotalTime=%"PRIu64, strFile1.c_str(), m_SampleRate, m_Channels, m_BitsPerSample, m_TotalTime);
    return false;
  }

  //  Get replay gain tags
  vorbis_comment* pComments=m_dll.ov_comment(&m_VorbisFile, m_CurrentStream);
  if (pComments)
  {
    CTagLoaderTagLib tagLoaderTagLib;
    tagLoaderTagLib.Load(strFile, m_tag);
  }

  //  Seek to the logical bitstream to play
  if (m_TimeOffset>0.0)
  {
    if (m_dll.ov_time_seek(&m_VorbisFile, m_TimeOffset)!=0)
    {
      CLog::Log(LOGERROR, "OGGCodec: Can't seek to the bitstream start time (%s)", strFile1.c_str());
      return false;
    }
  }

  return true;
}