Esempio n. 1
0
CodecVector CHTSPData::GetTranscodingCodecs(void)
{
  htsmsg_t *msg;
  htsmsg_field_t *f;
  CodecVector v;
  CHTSResult result;

  msg = htsmsg_create_map();
  htsmsg_add_str(msg, "method", "getCodecs");

  ReadResult(msg, result);
  if (result.status != PVR_ERROR_NO_ERROR)
  {
    XBMC->Log(LOG_DEBUG, "%s - failed to getCodecs", __FUNCTION__);
    return v;
  }

  msg = htsmsg_get_list(result.message, "encoders");
  if(!msg)
  {
    XBMC->Log(LOG_DEBUG, "%s - failed to get encoders", __FUNCTION__);
    return v;
  }

  HTSMSG_FOREACH(f, msg) {
    if (f->hmf_type != HMF_STR)
      continue;

    CodecDescriptor codec = CodecDescriptor::GetCodecByName(f->hmf_str);
    if (codec.Codec().codec_type != XBMC_CODEC_TYPE_UNKNOWN)
      v.push_back(codec);
  }

  return v;
}
Esempio n. 2
0
void CHTSPDemuxer::ParseSubscriptionStart ( htsmsg_t *m )
{
  vector<XbmcPvrStream>  streams;
  htsmsg_t               *l;
  htsmsg_field_t         *f;
  DemuxPacket            *pkt;

  /* Validate */
  if ((l = htsmsg_get_list(m, "streams")) == NULL)
  {
    Logger::Log(LogLevel::LEVEL_ERROR, "malformed subscriptionStart: 'streams' missing");
    return;
  }
  m_streamStat.clear();

  /* Process each */
  HTSMSG_FOREACH(f, l)
  {
    uint32_t      idx, u32;
    const char    *type;
    XbmcPvrStream stream;

    if (f->hmf_type != HMF_MAP)
      continue;
    if ((type = htsmsg_get_str(&f->hmf_msg, "type")) == NULL)
      continue;
    if (htsmsg_get_u32(&f->hmf_msg, "index", &idx))
      continue;

    /* Find stream */
    m_streamStat[idx] = 0;
    m_streams.GetStreamData(idx, &stream);
    Logger::Log(LogLevel::LEVEL_DEBUG, "demux subscription start");
    
    CodecDescriptor codecDescriptor = CodecDescriptor::GetCodecByName(type);
    xbmc_codec_t codec = codecDescriptor.Codec();
    
    if (codec.codec_type != XBMC_CODEC_TYPE_UNKNOWN)
    {
      stream.iCodecType  = codec.codec_type;
      stream.iCodecId    = codec.codec_id;
      stream.iPhysicalId = idx;

      /* Subtitle ID */
      if ((stream.iCodecType == XBMC_CODEC_TYPE_SUBTITLE) &&
          !strcmp("DVBSUB", type))
      {
        uint32_t composition_id = 0, ancillary_id = 0;
        htsmsg_get_u32(&f->hmf_msg, "composition_id", &composition_id);
        htsmsg_get_u32(&f->hmf_msg, "ancillary_id"  , &ancillary_id);
        stream.iIdentifier = (composition_id & 0xffff)
                           | ((ancillary_id & 0xffff) << 16);
      }

      /* Language */
      if (stream.iCodecType == XBMC_CODEC_TYPE_SUBTITLE ||
          stream.iCodecType == XBMC_CODEC_TYPE_AUDIO)
      {
        const char *language;
        
        if ((language = htsmsg_get_str(&f->hmf_msg, "language")) != NULL)
          strncpy(stream.strLanguage, language, sizeof(stream.strLanguage) - 1);
      }

      /* Audio data */
      if (stream.iCodecType == XBMC_CODEC_TYPE_AUDIO)
      {
        stream.iChannels
          = htsmsg_get_u32_or_default(&f->hmf_msg, "channels", 2);
        stream.iSampleRate
          = htsmsg_get_u32_or_default(&f->hmf_msg, "rate", 48000);
      }

      /* Video */
      if (stream.iCodecType == XBMC_CODEC_TYPE_VIDEO)
      {
        stream.iWidth   = htsmsg_get_u32_or_default(&f->hmf_msg, "width", 0);
        stream.iHeight  = htsmsg_get_u32_or_default(&f->hmf_msg, "height", 0);
        
        /* Ignore this message if the stream details haven't been determined 
           yet, a new message will be sent once they have. This is fixed in 
           some versions of tvheadend and is here for backward compatibility. */
        if (stream.iWidth == 0 || stream.iHeight == 0)
        {
          Logger::Log(LogLevel::LEVEL_DEBUG, "Ignoring subscriptionStart, stream details missing");
          return;
        }
        
        /* Setting aspect ratio to zero will cause XBMC to handle changes in it */
        stream.fAspect = 0.0f;
        
        if ((u32 = htsmsg_get_u32_or_default(&f->hmf_msg, "duration", 0)) > 0)
        {
          stream.iFPSScale = u32;
          stream.iFPSRate  = DVD_TIME_BASE;
        }
      }
        
      streams.push_back(stream);
      Logger::Log(LogLevel::LEVEL_DEBUG, "  id: %d, type %s, codec: %u", idx, type, stream.iCodecId);
    }
  }
Esempio n. 3
0
void CHTSPDemux::ParseSubscriptionStart(htsmsg_t *m)
{
  vector<PVR_STREAM_PROPERTIES::PVR_STREAM> newStreams;

  htsmsg_t       *streams;
  htsmsg_field_t *f;
  uint32_t        subs;

  if(htsmsg_get_u32(m, "subscriptionId", &subs))
  {
    XBMC->Log(LOG_ERROR, "%s - invalid subscription id", __FUNCTION__);
    return;
  }
  m_subs = subs;

  if((streams = htsmsg_get_list(m, "streams")) == NULL)
  {
    XBMC->Log(LOG_ERROR, "%s - malformed message", __FUNCTION__);
    return;
  }

  HTSMSG_FOREACH(f, streams)
  {
    uint32_t    index;
    const char* type;
    htsmsg_t*   sub;

    if (newStreams.size() >= PVR_STREAM_MAX_STREAMS)
    {
      XBMC->Log(LOG_ERROR, "%s - max amount of streams reached", __FUNCTION__);
      break;
    }

    if (f->hmf_type != HMF_MAP)
      continue;

    sub = &f->hmf_msg;

    if ((type = htsmsg_get_str(sub, "type")) == NULL)
      continue;

    if (htsmsg_get_u32(sub, "index", &index))
      continue;

    bool bValidStream(true);
    PVR_STREAM_PROPERTIES::PVR_STREAM newStream;
    m_streams.GetStreamData(index, &newStream);

    CodecDescriptor codecId = CodecDescriptor::GetCodecByName(type);
    if (codecId.Codec().codec_type != XBMC_CODEC_TYPE_UNKNOWN)
    {
      newStream.iCodecType = codecId.Codec().codec_type;
      newStream.iCodecId   = codecId.Codec().codec_id;

      if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_SUBTITLE)
      {
        uint32_t composition_id = 0, ancillary_id = 0;
        htsmsg_get_u32(sub, "composition_id", &composition_id);
        htsmsg_get_u32(sub, "ancillary_id"  , &ancillary_id);
        newStream.iIdentifier = (composition_id & 0xffff) | ((ancillary_id & 0xffff) << 16);
        HTSPSetDemuxStreamInfoLanguage(newStream, sub);
      }
    }
    else
    {
      bValidStream = false;
    }

    if (bValidStream)
    {
      XBMC->Log(LOG_DEBUG, "%s - id: %d, type: %s, codec: %u", __FUNCTION__, index, codecId.Name().c_str(), codecId.Codec().codec_id);

      newStream.iPhysicalId  = index;
      if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_AUDIO)
      {
        HTSPSetDemuxStreamInfoAudio(newStream, sub);
        HTSPSetDemuxStreamInfoLanguage(newStream, sub);
      }
      else if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_VIDEO)
        HTSPSetDemuxStreamInfoVideo(newStream, sub);

      newStreams.push_back(newStream);
    }
    else
    {
      XBMC->Log(LOG_DEBUG, "%s - id: %d, type: %s, ignored", __FUNCTION__, index, type);
    }
  }
Esempio n. 4
0
void cVNSIDemux::StreamChange(cResponsePacket *resp)
{
  std::vector<XbmcPvrStream> newStreams;

  while (!resp->end())
  {
    uint32_t    pid = resp->extract_U32();
    const char* type  = resp->extract_String();

    XbmcPvrStream newStream;
    m_streams.GetStreamData(pid, &newStream);

    CodecDescriptor codecId = CodecDescriptor::GetCodecByName(type);
    if (codecId.Codec().codec_type != XBMC_CODEC_TYPE_UNKNOWN)
    {
      newStream.iPhysicalId     = pid;
      newStream.iCodecType      = codecId.Codec().codec_type;
      newStream.iCodecId        = codecId.Codec().codec_id;
    }
    else
    {
      return;
    }

    if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_AUDIO)
    {
      const char *language = resp->extract_String();

      newStream.iChannels       = resp->extract_U32();
      newStream.iSampleRate     = resp->extract_U32();
      newStream.iBlockAlign     = resp->extract_U32();
      newStream.iBitRate        = resp->extract_U32();
      newStream.iBitsPerSample  = resp->extract_U32();
      newStream.strLanguage[0]  = language[0];
      newStream.strLanguage[1]  = language[1];
      newStream.strLanguage[2]  = language[2];
      newStream.strLanguage[3]  = 0;
      newStream.iIdentifier     = -1;

      newStreams.push_back(newStream);
    }
    else if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_VIDEO)
    {
      newStream.iFPSScale       = resp->extract_U32();
      newStream.iFPSRate        = resp->extract_U32();
      newStream.iHeight         = resp->extract_U32();
      newStream.iWidth          = resp->extract_U32();
      newStream.fAspect         = (float)resp->extract_Double();
      newStream.strLanguage[0]  = 0;
      newStream.strLanguage[1]  = 0;
      newStream.strLanguage[2]  = 0;
      newStream.strLanguage[3]  = 0;
      newStream.iIdentifier     = -1;

      newStreams.push_back(newStream);
    }
    else if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_SUBTITLE)
    {
      const char *language    = resp->extract_String();
      uint32_t composition_id = resp->extract_U32();
      uint32_t ancillary_id   = resp->extract_U32();
      newStream.strLanguage[0]  = language[0];
      newStream.strLanguage[1]  = language[1];
      newStream.strLanguage[2]  = language[2];
      newStream.strLanguage[3]  = 0;
      newStream.iIdentifier     = (composition_id & 0xffff) | ((ancillary_id & 0xffff) << 16);

      newStreams.push_back(newStream);

      delete[] language;
    }
    else if (codecId.Codec().codec_type == XBMC_CODEC_TYPE_RDS)
    {
      const char *language     = resp->extract_String();
      uint32_t rel_channel_pid = resp->extract_U32();
      newStream.strLanguage[0]  = language[0];
      newStream.strLanguage[1]  = language[1];
      newStream.strLanguage[2]  = language[2];
      newStream.strLanguage[3]  = 0;
      newStream.iIdentifier     = -1;

      newStreams.push_back(newStream);

      delete[] language;
    }
    else
    {
      m_streams.Clear();
      delete[] type;
      return;
    }

    delete[] type;
  }

  m_streams.UpdateStreams(newStreams);
}