Esempio n. 1
0
const char *I18nNormalizeLanguageCode(const char *Code)
{
  for (int i = 0; i < 3; i++) {
      if (Code[i]) {
         // ETSI EN 300 468 defines language codes as consisting of three letters
         // according to ISO 639-2. This means that they are supposed to always consist
         // of exactly three letters in the range a-z - no digits, UTF-8 or other
         // funny characters. However, some broadcasters apparently don't have a
         // copy of the DVB standard (or they do, but are perhaps unable to read it),
         // so they put all sorts of non-standard stuff into the language codes,
         // like nonsense as "2ch" or "A 1" (yes, they even go as far as using
         // blanks!). Such things should go into the description of the EPG event's
         // ComponentDescriptor.
         // So, as a workaround for this broadcaster stupidity, let's ignore
         // language codes with unprintable characters...
         if (!isprint(Code[i])) {
            //dsyslog("invalid language code: '%s'", Code);
            return "???";
            }
         // ...and replace blanks with underlines (ok, this breaks the 'const'
         // of the Code parameter - but hey, it's them who started this):
         if (Code[i] == ' ')
            *((char *)&Code[i]) = '_';
         }
      else
         break;
      }
  int n = I18nLanguageIndex(Code);
  return n >= 0 ? I18nLanguageCode(n) : Code;
}
Esempio n. 2
0
bool I18nIsPreferredLanguage(int *PreferredLanguages, const char *LanguageCode, int &OldPreference, int *Position)
{
  int pos = 1;
  bool found = false;
  while (LanguageCode) {
        int LanguageIndex = I18nLanguageIndex(LanguageCode);
        for (int i = 0; i < LanguageCodes.Size(); i++) {
            if (PreferredLanguages[i] < 0)
               break; // the language is not a preferred one
            if (PreferredLanguages[i] == LanguageIndex) {
               if (OldPreference < 0 || i < OldPreference) {
                  OldPreference = i;
                  if (Position)
                     *Position = pos;
                  found = true;
                  break;
                  }
               }
            }
        if ((LanguageCode = strchr(LanguageCode, '+')) != NULL) {
           LanguageCode++;
           pos++;
           }
        else if (pos == 1 && Position)
           *Position = 0;
        }
  if (OldPreference < 0) {
     OldPreference = LanguageCodes.Size(); // higher than the maximum possible value
     return true; // if we don't find a preferred one, we take the first one
     }
  return found;
}
Esempio n. 3
0
bool cSetup::ParseLanguages(const char *Value, int *Values)
{
  int n = 0;
  while (Value && *Value && n < I18nLanguages()->Size()) {
        char buffer[4];
        strn0cpy(buffer, Value, sizeof(buffer));
        int i = I18nLanguageIndex(buffer);
        if (i >= 0)
           Values[n++] = i;
        if ((Value = strchr(Value, ' ')) != NULL)
           Value++;
        }
  Values[n] = -1;
  return true;
}
Esempio n. 4
0
bool cTheme::Load(const char *FileName, bool OnlyDescriptions)
{
  if (!FileNameOk(FileName, true))
     return false;
  bool result = false;
  if (!OnlyDescriptions)
     isyslog("loading %s", FileName);
  FILE *f = fopen(FileName, "r");
  if (f) {
     int line = 0;
     result = true;
     char *s;
     const char *error = NULL;
     cReadLine ReadLine;
     while ((s = ReadLine.Read(f)) != NULL) {
           line++;
           char *p = strchr(s, '#');
           if (p)
              *p = 0;
           s = stripspace(skipspace(s));
           if (!isempty(s)) {
              char *n = s;
              char *v = strchr(s, '=');
              if (v) {
                 *v++ = 0;
                 n = stripspace(skipspace(n));
                 v = stripspace(skipspace(v));
                 if (strstr(n, "Description") == n) {
                    int lang = 0;
                    char *l = strchr(n, '.');
                    if (l)
                       lang = I18nLanguageIndex(++l);
                    if (lang >= 0) {
                       free(descriptions[lang]);
                       descriptions[lang] = strdup(v);
                       }
                    else
                       error = "invalid language code";
                    }
                 else if (!OnlyDescriptions) {
                    for (int i = 0; i < MaxThemeColors; i++) {
                        if (colorNames[i]) {
                           if (strcmp(n, colorNames[i]) == 0) {
                              char *p = NULL;
                              errno = 0;
                              tColor c = strtoul(v, &p, 16);
                              if (!errno && !*p)
                                 colorValues[i] = c;
                              else
                                 error = "invalid color value";
                              break;
                              }
                           }
                        else {
                           error = "unknown color name";
                           break;
                           }
                        }
                    }
                 }
              else
                 error = "missing value";
              }
           if (error) {
              result = false;
              break;
              }
           }
     if (!result)
        esyslog("ERROR: error in %s, line %d%s%s", FileName, line, error ? ": " : "", error ? error : "");
     fclose(f);
     }
  else
     LOG_ERROR_STR(FileName);
  return result;
}
MsgPacket* ChannelController::processGetChannels(MsgPacket* request) {
    ChannelCache& channelCache = ChannelCache::instance();

    isyslog("Fetching channels ...");

    int type = request->get_U32();

    isyslog("Type: %s",
            type == 0 ? "MPEG2/H.264 channels" :
            type == 1 ? "radio channels" :
            type == 2 ? "H.264 channels" :
            "UNDEFINED"
           );

    //
    // PROTOCOL 7 - CLIENT MUST SEND THIS
    //

    const char* language = request->get_String();
    // do we want fta channels ?
    m_wantFta = request->get_U32();
    isyslog("Free To Air channels: %s", m_wantFta ? "Yes" : "No");

    // display only channels with native language audio ?
    m_filterLanguage = request->get_U32();
    isyslog("Only native language: %s", m_filterLanguage ? "Yes" : "No");

    // read caids
    m_caids.clear();
    uint32_t count = request->get_U32();

    isyslog("Enabled CaIDs: ");

    // sanity check (maximum of 20 caids)
    if(count < 20) {
        for(uint32_t i = 0; i < count; i++) {
            int caid = request->get_U32();
            m_caids.push_back(caid);
            isyslog("%04X", caid);
        }
    }

    m_languageIndex = I18nLanguageIndex(language);
    m_channelCount = channelCount();

    MsgPacket* response = createResponse(request);

    std::string groupName;

    LOCK_CHANNELS_READ;
    for(const cChannel* channel = Channels->First(); channel; channel = Channels->Next(channel)) {

        if(channel->GroupSep()) {
            groupName = m_toUtf8.convert(channel->Name());
            continue;
        }

        // skip disabled channels if filtering is enabled
        if(!channelCache.isEnabled(channel)) {
            continue;
        }

        if(!isChannelWanted(channel, type)) {
            continue;
        }

        addChannelToPacket(channel, response, groupName.c_str());
    }

    isyslog("client got %i channels", m_channelCount);
    return response;
}
bool ChannelController::isChannelWanted(const cChannel* channel, int type) {
    // dismiss invalid channels
    if(channel == NULL) {
        return false;
    }

    // radio
    if((type == 1) && !isRadio(channel)) {
        return false;
    }

    // (U)HD channels
    if((type == 2) && (channel->Vtype() != 27 && channel->Vtype() != 36)) {
        return false;
    }

    // skip channels witout SID
    if(channel->Sid() == 0) {
        return false;
    }

    if(strcmp(channel->Name(), ".") == 0) {
        return false;
    }

    // check language
    if(m_filterLanguage && m_languageIndex != -1) {
        bool bLanguageFound = false;
        const char* lang = NULL;

        // check MP2 languages
        for(int i = 0; i < MAXAPIDS; i++) {
            lang = channel->Alang(i);

            if(lang == NULL) {
                break;
            }

            if(m_languageIndex == I18nLanguageIndex(lang)) {
                bLanguageFound = true;
                break;
            }
        }

        // check other digital languages
        for(int i = 0; i < MAXDPIDS; i++) {
            lang = channel->Dlang(i);

            if(lang == NULL) {
                break;
            }

            if(m_languageIndex == I18nLanguageIndex(lang)) {
                bLanguageFound = true;
                break;
            }
        }

        if(!bLanguageFound) {
            return false;
        }
    }

    // user selection for FTA channels
    if(channel->Ca(0) == 0) {
        return m_wantFta;
    }

    // we want all encrypted channels if there isn't any CaID filter
    if(m_caids.size() == 0) {
        return true;
    }

    // check if we have a matching CaID
    for(std::list<int>::iterator i = m_caids.begin(); i != m_caids.end(); i++) {
        for(int j = 0; j < MAXCAIDS; j++) {

            if(channel->Ca(j) == 0) {
                break;
            }

            if(channel->Ca(j) == *i) {
                return true;
            }
        }
    }

    return false;
}
Esempio n. 7
0
void cLiveStreamer::reorderStreams(int lang, cStreamInfo::Type type)
{
  std::map<uint32_t, cTSDemuxer*> weight;

  // compute weights
  int i = 0;
  for (std::list<cTSDemuxer*>::iterator idx = m_Demuxers.begin(); idx != m_Demuxers.end(); idx++, i++)
  {
    cTSDemuxer* stream = (*idx);
    if (stream == NULL)
      continue;

    // 32bit weight:
    // V0000000ASLTXXXXPPPPPPPPPPPPPPPP
    //
    // VIDEO (V):      0x80000000
    // AUDIO (A):      0x00800000
    // SUBTITLE (S):   0x00400000
    // LANGUAGE (L):   0x00200000
    // STREAMTYPE (T): 0x00100000 (only audio)
    // AUDIOTYPE (X):  0x000F0000 (only audio)
    // PID (P):        0x0000FFFF

#define VIDEO_MASK      0x80000000
#define AUDIO_MASK      0x00800000
#define SUBTITLE_MASK   0x00400000
#define LANGUAGE_MASK   0x00200000
#define STREAMTYPE_MASK 0x00100000
#define AUDIOTYPE_MASK  0x000F0000
#define PID_MASK        0x0000FFFF

    // last resort ordering, the PID
    uint32_t w = 0xFFFF - (stream->GetPID() & PID_MASK);

    // stream type weights
    switch(stream->GetContent()) {
      case cStreamInfo::scVIDEO:
        w |= VIDEO_MASK;
        break;

      case cStreamInfo::scAUDIO:
        w |= AUDIO_MASK;

        // weight of audio stream type
        w |= (stream->GetType() == type) ? STREAMTYPE_MASK : 0;

        // weight of audio type
        w |= ((4 - stream->GetAudioType()) << 16) & AUDIOTYPE_MASK;
        break;

      case cStreamInfo::scSUBTITLE:
        w |= SUBTITLE_MASK;
        break;

      default:
        break;
    }

    // weight of language
    int streamLangIndex = I18nLanguageIndex(stream->GetLanguage());
    w |= (streamLangIndex == lang) ? LANGUAGE_MASK : 0;

    // summed weight
    weight[w] = stream;
  }

  // reorder streams on weight
  int idx = 0;
  m_Demuxers.clear();
  for(std::map<uint32_t, cTSDemuxer*>::reverse_iterator i = weight.rbegin(); i != weight.rend(); i++, idx++)
  {
    cTSDemuxer* stream = i->second;
    DEBUGLOG("Stream : Type %s / %s Weight: %08X", stream->TypeName(), stream->GetLanguage(), i->first);
    m_Demuxers.push_back(stream);
  }
}