Пример #1
0
CStdString CKeyboardStat::GetKeyName(int KeyID)
{ int keyid;
  CStdString keyname;
  XBMCKEYTABLE keytable;

  keyname.clear();

// Get modifiers

  if (KeyID & CKey::MODIFIER_CTRL)
    keyname.append("ctrl-");
  if (KeyID & CKey::MODIFIER_SHIFT)
    keyname.append("shift-");
  if (KeyID & CKey::MODIFIER_ALT)
    keyname.append("alt-");
  if (KeyID & CKey::MODIFIER_SUPER)
    keyname.append("win-");
  if (KeyID & CKey::MODIFIER_META)
    keyname.append("meta-");

// Now get the key name

  keyid = KeyID & 0xFF;
  if (KeyTableLookupVKeyName(keyid, &keytable))
    keyname.append(keytable.keyname);
  else
    keyname.AppendFormat("%i", keyid);
  keyname.AppendFormat(" (0x%02x)", KeyID);

  return keyname;
}
Пример #2
0
bool XMLUtils::GetAdditiveString(const TiXmlNode* pRootNode, const char* strTag,
                                 const CStdString& strSeparator, CStdString& strStringValue,
                                 bool clear)
{
  CStdString strTemp;
  const TiXmlElement* node = pRootNode->FirstChildElement(strTag);
  bool bResult=false;
  if (node && node->FirstChild() && clear)
    strStringValue.clear();
  while (node)
  {
    if (node->FirstChild())
    {
      bResult = true;
      strTemp = node->FirstChild()->Value();
      const char* clear=node->Attribute("clear");
      if (strStringValue.IsEmpty() || (clear && strcasecmp(clear,"true")==0))
        strStringValue = strTemp;
      else
        strStringValue += strSeparator+strTemp;
    }
    node = node->NextSiblingElement(strTag);
  }

  return bResult;
}
void CAirPlayServer::CTCPClient::ComposeAuthRequestAnswer(CStdString& responseHeader, CStdString& responseBody)
{
  int16_t random=rand();
  CStdString randomStr = StringUtils::Format("%i", random);
  m_authNonce=XBMC::XBMC_MD5::GetMD5(randomStr);
  responseHeader = StringUtils::Format(AUTH_REQUIRED, m_authNonce.c_str());
  responseBody.clear();
}
Пример #4
0
bool CPictureThumbLoader::LoadItem(CFileItem* pItem)
{
  if (pItem->m_bIsShareOrDrive) return true;
  if (pItem->IsParentFolder()) return true;

  if (pItem->HasThumbnail() && m_regenerateThumbs)
  {
    CTextureCache::Get().ClearCachedImage(pItem->GetThumbnailImage());
    CTextureDatabase db;
    if (db.Open())
      db.ClearTextureForPath(pItem->GetPath(), "thumb");
    pItem->SetThumbnailImage("");
  }

  CStdString thumb;
  if (pItem->IsPicture() && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() && !pItem->IsCBR() && !pItem->IsPlayList())
  { // load the thumb from the image file
    thumb = pItem->HasThumbnail() ? pItem->GetThumbnailImage() : CTextureCache::GetWrappedThumbURL(pItem->GetPath());
  }
  else if (pItem->IsVideo() && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() && !pItem->IsCBR() && !pItem->IsPlayList())
  { // video
    thumb = pItem->GetCachedVideoThumb();
    if (!CFile::Exists(thumb))
    {
      CStdString strPath, strFileName;
      URIUtils::Split(thumb, strPath, strFileName);

      CStdString autoThumb = strPath + "auto-" + strFileName;

      // this is abit of a hack to avoid loading zero sized images
      // which we know will fail. They will just display empty image
      // we should really have some way for the texture loader to
      // do fallbacks to default images for a failed image instead
      if (CFile::Exists(autoThumb))
      {
        thumb = autoThumb;
      }
      else if (g_guiSettings.GetBool("myvideos.extractthumb") && g_guiSettings.GetBool("myvideos.extractflags"))
      {
        CFileItem item(*pItem);
        CThumbExtractor* extract = new CThumbExtractor(item, pItem->GetPath(), true, autoThumb);
        AddJob(extract);
        thumb.clear();
      }
    }
  }
  else if (!pItem->HasThumbnail())
  { // folder, zip, cbz, rar, cbr, playlist may have a previously cached image
    thumb = GetCachedImage(*pItem, "thumb");
  }
  if (!thumb.IsEmpty())
  {
    CTextureCache::Get().BackgroundCacheImage(thumb);
    pItem->SetThumbnailImage(thumb);
  }
  pItem->FillInDefaultIcon();
  return true;
}
Пример #5
0
bool CAirTunesServer::StartServer(int port, bool nonlocal, bool usePassword, const CStdString &password/*=""*/)
{
  bool success = false;
  CStdString pw = password;
  CNetworkInterface *net = g_application.getNetwork().GetFirstConnectedInterface();
  StopServer(true);

  if (net)
  {
    m_macAddress = net->GetMacAddress();
    StringUtils::Replace(m_macAddress, ":","");
    while (m_macAddress.size() < 12)
    {
      m_macAddress = CStdString("0") + m_macAddress;
    }
  }
  else
  {
    m_macAddress = "000102030405";
  }

  if (!usePassword)
  {
    pw.clear();
  }

  ServerInstance = new CAirTunesServer(port, nonlocal);
  if (ServerInstance->Initialize(pw))
  {
    success = true;
    CStdString appName = StringUtils::Format("%s@%s",
                                             m_macAddress.c_str(),
                                             g_infoManager.GetLabel(SYSTEM_FRIENDLY_NAME).c_str());

    std::vector<std::pair<std::string, std::string> > txt;
    txt.push_back(std::make_pair("txtvers",  "1"));
    txt.push_back(std::make_pair("cn", "0,1"));
    txt.push_back(std::make_pair("ch", "2"));
    txt.push_back(std::make_pair("ek", "1"));
    txt.push_back(std::make_pair("et", "0,1"));
    txt.push_back(std::make_pair("sv", "false"));
    txt.push_back(std::make_pair("tp",  "UDP"));
    txt.push_back(std::make_pair("sm",  "false"));
    txt.push_back(std::make_pair("ss",  "16"));
    txt.push_back(std::make_pair("sr",  "44100"));
    txt.push_back(std::make_pair("pw",  usePassword?"true":"false"));
    txt.push_back(std::make_pair("vn",  "3"));
    txt.push_back(std::make_pair("da",  "true"));
    txt.push_back(std::make_pair("vs",  "130.14"));
    txt.push_back(std::make_pair("md",  "0,1,2"));
    txt.push_back(std::make_pair("am",  "Xbmc,1"));

    CZeroconf::GetInstance()->PublishService("servers.airtunes", "_raop._tcp", appName, port, txt);
  }

  return success;
}
Пример #6
0
TEST_F(TestCharsetConverter, getCharsetNameByLabel)
{
  CStdString varstr =
    g_charsetConverter.getCharsetNameByLabel("Western Europe (ISO)");
  EXPECT_STREQ("ISO-8859-1", varstr.c_str());
  varstr.clear();
  varstr = g_charsetConverter.getCharsetNameByLabel("Bogus");
  EXPECT_STREQ("", varstr.c_str());
}
Пример #7
0
bool CPictureThumbLoader::LoadItemCached(CFileItem* pItem)
{
  if (pItem->m_bIsShareOrDrive
  ||  pItem->IsParentFolder())
    return false;

  if (pItem->HasArt("thumb") && m_regenerateThumbs)
  {
    CTextureCache::Get().ClearCachedImage(pItem->GetArt("thumb"));
    if (m_textureDatabase->Open())
    {
      m_textureDatabase->ClearTextureForPath(pItem->GetPath(), "thumb");
      m_textureDatabase->Close();
    }
    pItem->SetArt("thumb", "");
  }

  CStdString thumb;
  if (pItem->IsPicture() && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() && !pItem->IsCBR() && !pItem->IsPlayList())
  { // load the thumb from the image file
    thumb = pItem->HasArt("thumb") ? pItem->GetArt("thumb") : CTextureCache::GetWrappedThumbURL(pItem->GetPath());
  }
  else if (pItem->IsVideo() && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() && !pItem->IsCBR() && !pItem->IsPlayList())
  { // video
    CVideoThumbLoader loader;
    if (!loader.FillThumb(*pItem))
    {
      CStdString thumbURL = CVideoThumbLoader::GetEmbeddedThumbURL(*pItem);
      if (CTextureCache::Get().HasCachedImage(thumbURL))
      {
        thumb = thumbURL;
      }
      else if (CSettings::Get().GetBool("myvideos.extractthumb") && CSettings::Get().GetBool("myvideos.extractflags"))
      {
        CFileItem item(*pItem);
        CThumbExtractor* extract = new CThumbExtractor(item, pItem->GetPath(), true, thumbURL);
        AddJob(extract);
        thumb.clear();
      }
    }
  }
  else if (!pItem->HasArt("thumb"))
  { // folder, zip, cbz, rar, cbr, playlist may have a previously cached image
    thumb = GetCachedImage(*pItem, "thumb");
  }
  if (!thumb.IsEmpty())
  {
    CTextureCache::Get().BackgroundCacheImage(thumb);
    pItem->SetArt("thumb", thumb);
  }
  pItem->FillInDefaultIcon();
  return true;
}
Пример #8
0
void CWeatherJob::LocalizeOverview(CStdString &str)
{
  CStdStringArray words;
  StringUtils::SplitString(str, " ", words);
  str.clear();
  for (unsigned int i = 0; i < words.size(); i++)
  {
    LocalizeOverviewToken(words[i]);
    str += words[i] + " ";
  }
  str.TrimRight(" ");
}
Пример #9
0
void CHttpHeader::GetHeader(CStdString& strHeader)
{
  strHeader.clear();

  HeaderParamsIter iter = m_params.begin();
  while (iter != m_params.end())
  {
    strHeader += ((*iter).first + ": " + (*iter).second + "\n");
  }

  strHeader += "\n";
}
Пример #10
0
void CHttpHeader::GetHeader(CStdString& strHeader) const
{
    strHeader.clear();

    std::map<CStdString,CStdString>::const_iterator iter = m_params.begin();
    while (iter != m_params.end())
    {
        strHeader += ((*iter).first + ": " + (*iter).second + "\n");
        iter++;
    }

    strHeader += "\n";
}
Пример #11
0
bool GUIFontManager::GetFirstFontSetUnicode(CStdString& strFontSet)
{
  strFontSet.clear();

  // Load our font file
  CXBMCTinyXML xmlDoc;
  if (!OpenFontFile(xmlDoc))
    return false;

  TiXmlElement* pRootElement = xmlDoc.RootElement();
  const TiXmlNode *pChild = pRootElement->FirstChild();

  CStdString strValue = pChild->Value();
  if (strValue == "fontset")
  {
    while (pChild)
    {
      strValue = pChild->Value();
      if (strValue == "fontset")
      {
        const char* idAttr = ((TiXmlElement*) pChild)->Attribute("id");

        const char* unicodeAttr = ((TiXmlElement*) pChild)->Attribute("unicode");

        // Check if this is a fontset with a ttf attribute set to true
        if (unicodeAttr != NULL && stricmp(unicodeAttr, "true") == 0)
        {
          //  This is the first ttf fontset
          strFontSet=idAttr;
          break;
        }

      }

      pChild = pChild->NextSibling();
    }

    // If no fontset was loaded
    if (pChild == NULL)
      CLog::Log(LOGWARNING, "file doesnt have <fontset> with attribute unicode=\"true\"");
  }
  else
  {
    CLog::Log(LOGERROR, "file doesnt have <fontset> in <fonts>, but rather %s", strValue.c_str());
  }

  return !strFontSet.empty();
}
Пример #12
0
bool XMLUtils::GetPath(const TiXmlNode* pRootNode, const char* strTag, CStdString& strStringValue)
{
  const TiXmlElement* pElement = pRootNode->FirstChildElement(strTag);
  if (!pElement) return false;

  const char* encoded = pElement->Attribute("urlencoded");
  const TiXmlNode* pNode = pElement->FirstChild();
  if (pNode != NULL)
  {
    strStringValue = pNode->Value();
    if (encoded && strcasecmp(encoded,"yes") == 0)
      strStringValue = CURL::Decode(strStringValue);
    return true;
  }
  strStringValue.clear();
  return false;
}
Пример #13
0
CStdString CTextureCache::GetCachedImage(const CStdString &image, CStdString &cachedHash, bool trackUsage)
{
  cachedHash.clear();
  CStdString url = UnwrapImageURL(image);

  if (IsCachedImage(url))
    return url;

  // lookup the item in the database
  CTextureDetails details;
  if (GetCachedTexture(url, details))
  {
    if (trackUsage)
      IncrementUseCount(details);
    return GetCachedPath(details.file);
  }
  return "";
}
Пример #14
0
void CTextSearch::GetAndCutNextTerm(CStdString &strSearchTerm, CStdString &strNextTerm)
{
  CStdString strFindNext(" ");

  if (StringUtils::EndsWith(strSearchTerm, "\""))
  {
    strSearchTerm.erase(0, 1);
    strFindNext = "\"";
  }

  int iNextPos = strSearchTerm.Find(strFindNext);
  if (iNextPos != -1)
  {
    strNextTerm = strSearchTerm.Left(iNextPos);
    strSearchTerm.erase(0, iNextPos + 1);
  }
  else
  {
    strNextTerm = strSearchTerm;
    strSearchTerm.clear();
  }
}
Пример #15
0
bool CFanart::ParseColors(const CStdString &colorsIn, CStdString &colorsOut)
{
  // Formats:
  // 0: XBMC ARGB Hexadecimal string comma seperated "FFFFFFFF,DDDDDDDD,AAAAAAAA"
  // 1: The TVDB RGB Int Triplets, pipe seperate with leading/trailing pipes "|68,69,59|69,70,58|78,78,68|"

  // Essentially we read the colors in using the proper format, and store them in our own fixed temporary format (3 DWORDS), and then
  // write them back in in the specified format.

  if (colorsIn.empty())
    return false;

  // check for the TVDB RGB triplets "|68,69,59|69,70,58|78,78,68|"
  if (colorsIn[0] == '|')
  { // need conversion
    colorsOut.clear();
    CStdStringArray strColors;
    StringUtils::SplitString(colorsIn, "|", strColors);
    for (int i = 0; i < std::min((int)strColors.size()-1, (int)max_fanart_colors); i++)
    { // split up each color
      CStdStringArray strTriplets;
      StringUtils::SplitString(strColors[i+1], ",", strTriplets);
      if (strTriplets.size() == 3)
      { // convert
        if (colorsOut.size())
          colorsOut += ",";
        colorsOut += StringUtils::Format("FF%2x%2x%2x", atol(strTriplets[0].c_str()), atol(strTriplets[1].c_str()), atol(strTriplets[2].c_str()));
      }
    }
  }
  else
  { // assume is our format
    colorsOut = colorsIn;
  }
  return true;
}
Пример #16
0
// Allow user to select a Fanart
void CGUIDialogMusicInfo::OnGetFanart()
{
  CFileItemList items;

  if (m_albumItem->HasProperty("fanart_image"))
  {
    CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
    itemCurrent->SetThumbnailImage(m_albumItem->GetProperty("fanart_image").asString());
    itemCurrent->SetLabel(g_localizeStrings.Get(20440));
    items.Add(itemCurrent);
  }

  // Grab the thumbnails from the web
  for (unsigned int i = 0; i < m_artist.fanart.GetNumFanarts(); i++)
  {
    CStdString strItemPath;
    strItemPath.Format("fanart://Remote%i",i);
    CFileItemPtr item(new CFileItem(strItemPath, false));
    CStdString thumb = m_artist.fanart.GetPreviewURL(i);
    item->SetThumbnailImage(CTextureCache::GetWrappedThumbURL(thumb));
    item->SetIconImage("DefaultPicture.png");
    item->SetLabel(g_localizeStrings.Get(20441));

    // TODO: Do we need to clear the cached image?
    //    CTextureCache::Get().ClearCachedImage(thumb);
    items.Add(item);
  }

  // Grab a local thumb
  CMusicDatabase database;
  database.Open();
  CStdString strArtistPath;
  database.GetArtistPath(m_artist.idArtist,strArtistPath);
  CFileItem item(strArtistPath,true);
  CStdString strLocal = item.GetLocalFanart();
  if (!strLocal.IsEmpty())
  {
    CFileItemPtr itemLocal(new CFileItem("fanart://Local",false));
    itemLocal->SetThumbnailImage(strLocal);
    itemLocal->SetLabel(g_localizeStrings.Get(20438));

    // TODO: Do we need to clear the cached image?
    CTextureCache::Get().ClearCachedImage(strLocal);
    items.Add(itemLocal);
  }
  else
  {
    CFileItemPtr itemNone(new CFileItem("fanart://None", false));
    itemNone->SetIconImage("DefaultArtist.png");
    itemNone->SetLabel(g_localizeStrings.Get(20439));
    items.Add(itemNone);
  }

  CStdString result;
  VECSOURCES sources(g_settings.m_musicSources);
  g_mediaManager.GetLocalDrives(sources);
  bool flip=false;
  if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445))
    return;   // user cancelled

  // delete the thumbnail if that's what the user wants, else overwrite with the
  // new thumbnail
  if (result.Equals("fanart://Current"))
   return;

  if (result.Equals("fanart://Local"))
    result = strLocal;

  if (result.Left(15)  == "fanart://Remote")
  {
    int iFanart = atoi(result.Mid(15).c_str());
    m_artist.fanart.SetPrimaryFanart(iFanart);
    result = m_artist.fanart.GetImageURL();
  }
  else if (result.Equals("fanart://None") || !CFile::Exists(result))
    result.clear();

  if (flip && !result.empty())
    result = CTextureCache::GetWrappedImageURL(result, "", "flipped");

  // update thumb in the database
  CMusicDatabase db;
  if (db.Open())
  {
    db.SetArtForItem(m_albumItem->GetMusicInfoTag()->GetDatabaseId(), m_albumItem->GetMusicInfoTag()->GetType(), "fanart", result);
    db.Close();
  }

  if (!result.empty())
    m_albumItem->SetProperty("fanart_image",result);
  else
    m_albumItem->ClearProperty("fanart_image");
  m_hasUpdatedThumb = true;
  // tell our GUI to completely reload all controls (as some of them
  // are likely to have had this image in use so will need refreshing)
  CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
  g_windowManager.SendMessage(msg);
  // Update our screen
  Update();
}
Пример #17
0
bool URIUtils::GetParentPath(const CStdString& strPath, CStdString& strParent)
{
  strParent = "";

  CURL url(strPath);
  CStdString strFile = url.GetFileName();
  if ( URIUtils::ProtocolHasParentInHostname(url.GetProtocol()) && strFile.IsEmpty())
  {
    strFile = url.GetHostName();
    return GetParentPath(strFile, strParent);
  }
  else if ((url.GetProtocol() == "videodb" || url.GetProtocol() == "musicdb") && !url.GetOptions().empty())
  {
    CStdString options = url.GetOptions();
    size_t filterStart = options.find("filter=");
    if (filterStart != string::npos)
    {
      size_t filterEnd = options.find("&", filterStart);
      options.erase(filterStart, filterEnd - filterStart);
      if (options.Equals("?"))
        options.clear();

      url.SetOptions(options);
      strParent = url.Get();
      return true;
    }
  }
  else if (url.GetProtocol() == "stack")
  {
    CStackDirectory dir;
    CFileItemList items;
    dir.GetDirectory(strPath,items);
    GetDirectory(items[0]->GetPath(),items[0]->m_strDVDLabel);
    if (items[0]->m_strDVDLabel.Mid(0,6).Equals("rar://") || items[0]->m_strDVDLabel.Mid(0,6).Equals("zip://"))
      GetParentPath(items[0]->m_strDVDLabel, strParent);
    else
      strParent = items[0]->m_strDVDLabel;
    for( int i=1;i<items.Size();++i)
    {
      GetDirectory(items[i]->GetPath(),items[i]->m_strDVDLabel);
      if (items[0]->m_strDVDLabel.Mid(0,6).Equals("rar://") || items[0]->m_strDVDLabel.Mid(0,6).Equals("zip://"))
        items[i]->SetPath(GetParentPath(items[i]->m_strDVDLabel));
      else
        items[i]->SetPath(items[i]->m_strDVDLabel);

      GetCommonPath(strParent,items[i]->GetPath());
    }
    return true;
  }
  else if (url.GetProtocol() == "multipath")
  {
    // get the parent path of the first item
    return GetParentPath(CMultiPathDirectory::GetFirstPath(strPath), strParent);
  }
  else if (url.GetProtocol() == "plugin")
  {
    if (!url.GetOptions().IsEmpty())
    {
      url.SetOptions("");
      strParent = url.Get();
      return true;
    }
    if (!url.GetFileName().IsEmpty())
    {
      url.SetFileName("");
      strParent = url.Get();
      return true;
    }
    if (!url.GetHostName().IsEmpty())
    {
      url.SetHostName("");
      strParent = url.Get();
      return true;
    }
    return true;  // already at root
  }
  else if (url.GetProtocol() == "special")
  {
    if (HasSlashAtEnd(strFile) )
      strFile = strFile.Left(strFile.size() - 1);
    if(strFile.ReverseFind('/') < 0)
      return false;
  }
  else if (strFile.size() == 0)
  {
    if (url.GetHostName().size() > 0)
    {
      // we have an share with only server or workgroup name
      // set hostname to "" and return true to get back to root
      url.SetHostName("");
      strParent = url.Get();
      return true;
    }
    return false;
  }

  if (HasSlashAtEnd(strFile) )
  {
    strFile = strFile.Left(strFile.size() - 1);
  }

  int iPos = strFile.ReverseFind('/');
#ifndef _LINUX
  if (iPos < 0)
  {
    iPos = strFile.ReverseFind('\\');
  }
#endif
  if (iPos < 0)
  {
    url.SetFileName("");
    strParent = url.Get();
    return true;
  }

  strFile = strFile.Left(iPos);

  AddSlashAtEnd(strFile);

  url.SetFileName(strFile);
  strParent = url.Get();
  return true;
}
Пример #18
0
void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const std::string &language)
{
  if (items->IsEmpty())
  {
    CFileItemPtr service = GetService();
    if (service)
      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, service->GetLabel(), g_localizeStrings.Get(24113));
    UpdateStatus(SEARCH_COMPLETE);
    return;
  }

  CStdString strFileName;
  CStdString strDestPath;
#if 0
  // TODO: Code to download all subtitles for all stack items in one run
  if (g_application.CurrentFileItem().IsStack())
  {
    for (int i = 0; i < items->Size(); i++)
    {
//    check for all stack items and match to given subs, item [0] == CD1, item [1] == CD2
//    CLog::Log(LOGDEBUG, "Stack Subs [%s} Found", vecItems[i]->GetLabel().c_str());
    }
  }
#endif

  // Get (unstacked) path
  const CStdString &strCurrentFile = g_application.CurrentUnstackedItem().GetPath();

  if (StringUtils::StartsWith(strCurrentFile, "http://"))
  {
    strFileName = "TemporarySubs";
    strDestPath = "special://temp/";
  }
  else
  {
    strFileName = URIUtils::GetFileName(strCurrentFile);
    if (CSettings::Get().GetBool("subtitles.savetomoviefolder"))
    {
      strDestPath = URIUtils::GetDirectory(strCurrentFile);
      if (!CUtil::SupportsWriteFileOperations(strDestPath))
        strDestPath.clear();
    }
    if (strDestPath.empty())
    {
      if (CSpecialProtocol::TranslatePath("special://subtitles").empty())
        strDestPath = "special://temp";
      else
        strDestPath = "special://subtitles";
    }
  }
  // Extract the language and appropriate extension
  CStdString strSubLang;
  g_LangCodeExpander.ConvertToTwoCharCode(strSubLang, language);
  CStdString strUrl = items->Get(0)->GetPath();
  CStdString strSubExt = URIUtils::GetExtension(strUrl);

  // construct subtitle path
  URIUtils::RemoveExtension(strFileName);
  CStdString strSubName = StringUtils::Format("%s.%s%s", strFileName.c_str(), strSubLang.c_str(), strSubExt.c_str());
  CStdString strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubName);

  // and copy the file across
  CFile::Cache(strUrl, strSubPath);

  // for ".sub" subtitles we check if ".idx" counterpart exists and copy that as well
  if (strSubExt.Equals(".sub"))
  {
    strUrl = URIUtils::ReplaceExtension(strUrl, ".idx");
    if(CFile::Exists(strUrl))
    {
      CStdString strSubNameIdx = StringUtils::Format("%s.%s.idx", strFileName.c_str(), strSubLang.c_str());
      strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubNameIdx);
      CFile::Cache(strUrl, strSubPath);
    }
  }

  SetSubtitles(strSubPath);
  // Close the window
  Close();
}
Пример #19
0
CStdString CSpecialProtocol::TranslatePath(const CURL &url)
{
  // check for special-protocol, if not, return
  if (!url.GetProtocol().Equals("special"))
  {
#if defined(TARGET_POSIX) && defined(_DEBUG)
    CStdString path(url.Get());
    if (path.length() >= 2 && path[1] == ':')
    {
      CLog::Log(LOGWARNING, "Trying to access old style dir: %s\n", path.c_str());
     // printf("Trying to access old style dir: %s\n", path.c_str());
    }
#endif

    return url.Get();
  }

  CStdString FullFileName = url.GetFileName();

  CStdString translatedPath;
  CStdString FileName;
  CStdString RootDir;

  // Split up into the special://root and the rest of the filename
  int pos = FullFileName.Find('/');
  if (pos != -1 && pos > 1)
  {
    RootDir = FullFileName.Left(pos);

    if (pos < FullFileName.GetLength())
      FileName = FullFileName.Mid(pos + 1);
  }
  else
    RootDir = FullFileName;

  if (RootDir.Equals("subtitles"))
    translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("subtitles.custompath"), FileName);
  else if (RootDir.Equals("userdata"))
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetUserDataFolder(), FileName);
  else if (RootDir.Equals("database"))
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetDatabaseFolder(), FileName);
  else if (RootDir.Equals("thumbnails"))
    translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetThumbnailsFolder(), FileName);
  else if (RootDir.Equals("recordings") || RootDir.Equals("cdrips"))
    translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("audiocds.recordingpath"), FileName);
  else if (RootDir.Equals("screenshots"))
    translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("debug.screenshotpath"), FileName);
  else if (RootDir.Equals("musicplaylists"))
    translatedPath = URIUtils::AddFileToFolder(CUtil::MusicPlaylistsLocation(), FileName);
  else if (RootDir.Equals("videoplaylists"))
    translatedPath = URIUtils::AddFileToFolder(CUtil::VideoPlaylistsLocation(), FileName);
  else if (RootDir.Equals("skin"))
    translatedPath = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), FileName);
  else if (RootDir.Equals("logpath"))
    translatedPath = URIUtils::AddFileToFolder(g_advancedSettings.m_logFolder, FileName);


  // from here on, we have our "real" special paths
  else if (RootDir.Equals("xbmc") ||
           RootDir.Equals("xbmcbin") ||
           RootDir.Equals("home") ||
           RootDir.Equals("userhome") ||
           RootDir.Equals("temp") ||
           RootDir.Equals("profile") ||
           RootDir.Equals("masterprofile") ||
           RootDir.Equals("frameworks"))
  {
    CStdString basePath = GetPath(RootDir);
    if (!basePath.IsEmpty())
      translatedPath = URIUtils::AddFileToFolder(basePath, FileName);
    else
      translatedPath.clear();
  }

  // check if we need to recurse in
  if (URIUtils::IsSpecial(translatedPath))
  { // we need to recurse in, as there may be multiple translations required
    return TranslatePath(translatedPath);
  }

  // Validate the final path, just in case
  return CUtil::ValidatePath(translatedPath);
}
Пример #20
0
void CGUIDialogPVRGuideSearch::OnSearch()
{
  CStdString              strTmp;
  CGUISpinControlEx      *pSpin;
  CGUIEditControl        *pEdit;
  CGUIRadioButtonControl *pRadioButton;

  if (!m_searchFilter)
    return;

  pEdit = (CGUIEditControl *)GetControl(CONTROL_EDIT_SEARCH);
  if (pEdit) m_searchFilter->m_strSearchTerm = pEdit->GetLabel2();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_INC_DESC);
  if (pRadioButton) m_searchFilter->m_bSearchInDescription = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_CASE_SENS);
  if (pRadioButton) m_searchFilter->m_bIsCaseSensitive = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_FTA_ONLY);
  if (pRadioButton) m_searchFilter->m_bFTAOnly = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_UNK_GENRE);
  if (pRadioButton) m_searchFilter->m_bIncludeUnknownGenres = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_IGNORE_REC);
  if (pRadioButton) m_searchFilter->m_bIgnorePresentRecordings = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_BTN_IGNORE_TMR);
  if (pRadioButton) m_searchFilter->m_bIgnorePresentTimers = pRadioButton->IsSelected();

  pRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_SPIN_NO_REPEATS);
  if (pRadioButton) m_searchFilter->m_bPreventRepeats = pRadioButton->IsSelected();

  pSpin = (CGUISpinControlEx *)GetControl(CONTROL_SPIN_GENRE);
  if (pSpin) m_searchFilter->m_iGenreType = pSpin->GetValue();

  pSpin = (CGUISpinControlEx *)GetControl(CONTROL_SPIN_MIN_DURATION);
  if (pSpin) m_searchFilter->m_iMinimumDuration = pSpin->GetValue();

  pSpin = (CGUISpinControlEx *)GetControl(CONTROL_SPIN_MAX_DURATION);
  if (pSpin) m_searchFilter->m_iMaximumDuration = pSpin->GetValue();

  pSpin = (CGUISpinControlEx *)GetControl(CONTROL_SPIN_CHANNELS);
  if (pSpin) m_searchFilter->m_iChannelNumber = pSpin->GetValue();

  pSpin = (CGUISpinControlEx *)GetControl(CONTROL_SPIN_GROUPS);
  if (pSpin) m_searchFilter->m_iChannelGroup = pSpin->GetValue();

  pEdit = (CGUIEditControl *)GetControl(CONTROL_EDIT_START_TIME);
  if (pEdit) strTmp = pEdit->GetLabel2();

  pEdit = (CGUIEditControl *)GetControl(CONTROL_EDIT_START_DATE);
  if (pEdit) ReadDateTime(pEdit->GetLabel2(), strTmp, m_searchFilter->m_startDateTime);
  strTmp.clear();

  pEdit = (CGUIEditControl *)GetControl(CONTROL_EDIT_STOP_TIME);
  if (pEdit) strTmp = pEdit->GetLabel2();

  pEdit = (CGUIEditControl *)GetControl(CONTROL_EDIT_STOP_DATE);
  if (pEdit) ReadDateTime(pEdit->GetLabel2(), strTmp, m_searchFilter->m_endDateTime);
}
Пример #21
0
void COptions::SetOption(int nOptionID, LPCTSTR value, bool save /*=true*/)
{
	CStdString str = value;
	Init();

	switch (nOptionID)
	{
	case OPTION_SERVERPORT:
	case OPTION_TLSPORTS:
		{
			std::set<int> portSet;

			str.TrimLeft(_T(" ,"));

			int pos = str.FindOneOf(_T(" ,"));
			while (pos != -1)
			{
				int port = _ttoi(str.Left(pos));
				if (port >= 1 && port <= 65535)
					portSet.insert(port);
				str = str.Mid(pos + 1);
				str.TrimLeft(_T(" ,"));
				pos = str.FindOneOf(_T(" ,"));
			}
			if (str != _T(""))
			{
				int port = _ttoi(str);
				if (port >= 1 && port <= 65535)
					portSet.insert(port);
			}

			str = _T("");
			for (std::set<int>::const_iterator iter = portSet.begin(); iter != portSet.end(); iter++)
			{
				CStdString tmp;
				tmp.Format(_T("%d "), *iter);
				str += tmp;
			}
			str.TrimRight(' ');
		}
		break;
	case OPTION_WELCOMEMESSAGE:
		{
			std::vector<CStdString> msgLines;
			int oldpos = 0;
			str.Replace(_T("\r\n"), _T("\n"));
			int pos = str.Find(_T("\n"));
			CStdString line;
			while (pos != -1)
			{
				if (pos)
				{
					line = str.Mid(oldpos, pos - oldpos);
					line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
					line.TrimRight(_T(" "));
					if (msgLines.size() || line != _T(""))
						msgLines.push_back(line);
				}
				oldpos = pos + 1;
				pos = str.Find(_T("\n"), oldpos);
			}
			line = str.Mid(oldpos);
			if (line != _T(""))
			{
				line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
				msgLines.push_back(line);
			}
			str = _T("");
			for (unsigned int i = 0; i < msgLines.size(); i++)
				str += msgLines[i] + _T("\r\n");
			str.TrimRight(_T("\r\n"));
			if (str == _T(""))
			{
				str = _T("%v");
				str += _T("\r\nwritten by Tim Kosse ([email protected])");
				str += _T("\r\nPlease visit https://filezilla-project.org/");
			}
		}
		break;
	case OPTION_ADMINIPBINDINGS:
		{
			CStdString sub;
			std::list<CStdString> ipBindList;
			for (unsigned int i = 0; i<_tcslen(value); i++)
			{
				TCHAR cur = value[i];
				if ((cur < '0' || cur > '9') && cur != '.' && cur != ':')
				{
					if (sub == _T("") && cur == '*')
					{
						ipBindList.clear();
						ipBindList.push_back(_T("*"));
						break;
					}

					if (sub != _T(""))
					{
						if (IsIpAddress(sub))
							ipBindList.push_back(sub);
						sub = _T("");
					}
				}
				else
					sub += cur;
			}
			if (sub != _T(""))
			{
				if (IsIpAddress(sub))
					ipBindList.push_back(sub);
			}
			str = _T("");
			for (std::list<CStdString>::iterator iter = ipBindList.begin(); iter!=ipBindList.end(); iter++)
				if (!IsLocalhost(*iter))
					str += *iter + _T(" ");

			str.TrimRight(_T(" "));
		}
		break;
	case OPTION_ADMINPASS:
		if (str != _T("") && str.GetLength() < 6)
			return;
		break;
	case OPTION_MODEZ_DISALLOWED_IPS:
	case OPTION_IPFILTER_ALLOWED:
	case OPTION_IPFILTER_DISALLOWED:
	case OPTION_ADMINIPADDRESSES:
		{
			str.Replace('\r', ' ');
			str.Replace('\n', ' ');
			str.Replace('\r', ' ');
			while (str.Replace(_T("  "), _T(" ")));
			str += _T(" ");

			CStdString ips;

			int pos = str.Find(' ');
			while (pos != -1)
			{
				CStdString sub = str.Left(pos);
				str = str.Mid(pos + 1);
				str.TrimLeft(' ');

				if (sub == _T("*"))
					ips += _T(" ") + sub;
				else
				{
					if (IsValidAddressFilter(sub))
						ips += " " + sub;
					pos = str.Find(' ');
				}
			}
			ips.TrimLeft(' ');

			str = ips;
		}
		break;
	case OPTION_IPBINDINGS:
		{
			std::list<CStdString> ipBindList;

			str += _T(" ");
			while (!str.empty()) {
				int pos  = str.Find(' ');
				if (pos < 0) {
					break;
				}
				CStdString sub = str.Left(pos);
				str = str.Mid(pos + 1);

				if (sub == _T("*")) {
					ipBindList.clear();
					ipBindList.push_back(_T("*"));
					break;
				}
				else if (IsIpAddress(sub, true)) {
					ipBindList.push_back(sub);
				}
			}

			if (ipBindList.empty())
				ipBindList.push_back(_T("*"));

			str.clear();
			for (auto const& ip : ipBindList) {
				str += ip + _T(" ");
			}

			str.TrimRight(_T(" "));
		}
		break;
	case OPTION_CUSTOMPASVIPSERVER:
		if (str.Find(_T("filezilla.sourceforge.net")) != -1)
			str = _T("http://ip.filezilla-project.org/ip.php");
		break;
	}

	{
		simple_lock lock(m_mutex);
		m_sOptionsCache[nOptionID-1].bCached = TRUE;
		m_sOptionsCache[nOptionID-1].nType = 0;
		m_sOptionsCache[nOptionID-1].str = str;
		m_OptionsCache[nOptionID-1]=m_sOptionsCache[nOptionID-1];
	}

	if (!save)
		return;

	USES_CONVERSION;
	CStdString xmlFileName = GetExecutableDirectory() + _T("FileZilla Server.xml");
	char* bufferA = T2A(xmlFileName);
	if (!bufferA)
		return;

	TiXmlDocument document;
	if (!document.LoadFile(bufferA))
		return;

	TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
	if (!pRoot)
		return;

	TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
	if (!pSettings)
		pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

	TiXmlElement* pItem;
	for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
	{
		const char* pName = pItem->Attribute("name");
		if (!pName)
			continue;
		CStdString name(pName);
		if (name != m_Options[nOptionID-1].name)
			continue;

		break;
	}

	if (!pItem)
		pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement();
	pItem->Clear();
	pItem->SetAttribute("name", ConvToNetwork(m_Options[nOptionID - 1].name).c_str());
	pItem->SetAttribute("type", "string");
	pItem->LinkEndChild(new TiXmlText(ConvToNetwork(value).c_str()));

	document.SaveFile(bufferA);
}
Пример #22
0
// Allow user to select a Fanart
void CGUIDialogVideoInfo::OnGetFanart()
{
  CFileItemList items;

  CFileItem item(*m_movieItem->GetVideoInfoTag());
  if (item.HasArt("fanart"))
  {
    CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
    itemCurrent->SetArt("thumb", item.GetArt("fanart"));
    itemCurrent->SetLabel(g_localizeStrings.Get(20440));
    items.Add(itemCurrent);
  }

  // ensure the fanart is unpacked
  m_movieItem->GetVideoInfoTag()->m_fanart.Unpack();

  // Grab the thumbnails from the web
  for (unsigned int i = 0; i < m_movieItem->GetVideoInfoTag()->m_fanart.GetNumFanarts(); i++)
  {
    CStdString strItemPath;
    strItemPath.Format("fanart://Remote%i",i);
    CFileItemPtr item(new CFileItem(strItemPath, false));
    CStdString thumb = m_movieItem->GetVideoInfoTag()->m_fanart.GetPreviewURL(i);
    item->SetArt("thumb", CTextureCache::GetWrappedThumbURL(thumb));
    item->SetIconImage("DefaultPicture.png");
    item->SetLabel(g_localizeStrings.Get(20441));

    // TODO: Do we need to clear the cached image?
//    CTextureCache::Get().ClearCachedImage(thumb);
    items.Add(item);
  }

  CStdString strLocal = item.GetLocalFanart();
  if (!strLocal.IsEmpty())
  {
    CFileItemPtr itemLocal(new CFileItem("fanart://Local",false));
    itemLocal->SetArt("thumb", strLocal);
    itemLocal->SetLabel(g_localizeStrings.Get(20438));

    // TODO: Do we need to clear the cached image?
    CTextureCache::Get().ClearCachedImage(strLocal);
    items.Add(itemLocal);
  }
  else
  {
    CFileItemPtr itemNone(new CFileItem("fanart://None", false));
    itemNone->SetIconImage("DefaultVideo.png");
    itemNone->SetLabel(g_localizeStrings.Get(20439));
    items.Add(itemNone);
  }

  CStdString result;
  VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("video"));
  AddItemPathToFileBrowserSources(sources, item);
  g_mediaManager.GetLocalDrives(sources);
  bool flip=false;
  if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) || result.Equals("fanart://Current"))
    return;   // user cancelled

  if (result.Equals("fanart://Local"))
    result = strLocal;

  if (result.Left(15) == "fanart://Remote")
  {
    int iFanart = atoi(result.Mid(15).c_str());
    // set new primary fanart, and update our database accordingly
    m_movieItem->GetVideoInfoTag()->m_fanart.SetPrimaryFanart(iFanart);
    CVideoDatabase db;
    if (db.Open())
    {
      db.UpdateFanart(*m_movieItem, (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType());
      db.Close();
    }
    result = m_movieItem->GetVideoInfoTag()->m_fanart.GetImageURL();
  }
  else if (result.Equals("fanart://None") || !CFile::Exists(result))
    result.clear();

  // set the fanart image
  if (flip && !result.IsEmpty())
    result = CTextureCache::GetWrappedImageURL(result, "", "flipped");
  CVideoDatabase db;
  if (db.Open())
  {
    db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "fanart", result);
    db.Close();
  }

  CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
  m_movieItem->SetArt("fanart", result);
  m_hasUpdatedThumb = true;

  // Update our screen
  Update();
}
Пример #23
0
TEST_F(CLuaTest, LoadConfig)
{
    CStdString  config;
    config = "name      = \"hill\"\r\n"
             "age       = 23\r\n"
             "married   = true\r\n"
             "salary    = 50432.34\r\n"
             "company   = {'adobe', 'flukenetworks', 'cisco'}\r\n"
             "skill     = {cplus='good', python='excellent', c=100, algorithm='excellent', pass=true}\r\n";
    ASSERT_EQ(m_lua.doString(config), 0);

    CStdString  value;
    bool        bValue;
    double      dValue;

    //
    // test the string value
    //
    ASSERT_TRUE(m_lua.loadString("name", value));
    ASSERT_TRUE(value == "hill");

    value.clear();
    ASSERT_FALSE(m_lua.loadString("novalue", value));

    value.clear();
    ASSERT_TRUE(m_lua.loadString("age", value));
    ASSERT_TRUE(value == "23");

    //
    // test the bool value
    // 
    value.clear();
    ASSERT_FALSE(m_lua.loadString("married", value));

    value.clear();
    ASSERT_TRUE(m_lua.loadBoolean("married", bValue));
    ASSERT_TRUE(bValue);

    //
    // test the number value
    //
    value.clear();
    ASSERT_TRUE(m_lua.loadString("salary", value));
    ASSERT_TRUE(value == "50432.34");

    value.clear();
    ASSERT_TRUE(m_lua.loadDouble("salary", dValue));
    ASSERT_TRUE(dValue == 50432.34);

    //
    // test the array value
    //
    vector<CStdString>  arrValue;
    ASSERT_TRUE(m_lua.loadArray_s("company", arrValue));
    ASSERT_TRUE(arrValue[0] == "adobe");
    ASSERT_TRUE(arrValue[1] == "flukenetworks");
    ASSERT_TRUE(arrValue[2] == "cisco");
    ASSERT_FALSE(m_lua.loadArray_s("NOcompany", arrValue));

    //
    // test the table value
    //
    LuaObject   objValue;
    ASSERT_FALSE(m_lua.loadObject("NObject", objValue));
    ASSERT_TRUE(m_lua.loadObject("skill", objValue));
    ASSERT_TRUE(objValue["cplus"] == "good");
    ASSERT_TRUE(objValue["python"] == "excellent");
    ASSERT_TRUE(objValue["pass"] == "true");
    ASSERT_TRUE(objValue["c"] == "100");
    ASSERT_TRUE(objValue["algorithm"] == "excellent");
    ASSERT_FALSE(m_lua.loadObject("NObject", objValue));
}
Пример #24
0
void InfoExpression::Parse(const CStdString &expression)
{
  stack<char> operators;
  CStdString operand;
  for (unsigned int i = 0; i < expression.size(); i++)
  {
    if (GetOperator(expression[i]))
    {
      // cleanup any operand, translate and put into our expression list
      if (!operand.empty())
      {
        unsigned int info = g_infoManager.Register(operand, m_context);
        if (info)
        {
          m_postfix.push_back(m_operands.size());
          m_operands.push_back(info);
        }
        operand.clear();
      }
      // handle closing parenthesis
      if (expression[i] == ']')
      {
        while (!operators.empty())
        {
          char oper = operators.top();
          operators.pop();

          if (oper == '[')
            break;

          m_postfix.push_back(-GetOperator(oper)); // negative denotes operator
        }
      }
      else
      {
        // all other operators we pop off the stack any operator
        // that has a higher priority than the one we have.
        while (!operators.empty() && GetOperator(operators.top()) > GetOperator(expression[i]))
        {
          // only handle parenthesis once they're closed.
          if (operators.top() == '[' && expression[i] != ']')
            break;

          m_postfix.push_back(-GetOperator(operators.top()));  // negative denotes operator
          operators.pop();
        }
        operators.push(expression[i]);
      }
    }
    else
    {
      operand += expression[i];
    }
  }

  if (!operand.empty())
  {
    unsigned int info = g_infoManager.Register(operand, m_context);
    if (info)
    {
      m_postfix.push_back(m_operands.size());
      m_operands.push_back(info);
    }
  }

  // finish up by adding any operators
  while (!operators.empty())
  {
    m_postfix.push_back(-GetOperator(operators.top()));  // negative denotes operator
    operators.pop();
  }

  // test evaluate
  bool test;
  if (!Evaluate(NULL, test))
    CLog::Log(LOGERROR, "Error evaluating boolean expression %s", expression.c_str());
}
Пример #25
0
bool CRecentlyAddedJob::UpdateMusic()
{
  CGUIWindow* home = g_windowManager.GetWindow(WINDOW_HOME);
  
  if ( home == NULL )
    return false;
  
  CLog::Log(LOGDEBUG, "CRecentlyAddedJob::UpdateMusic() - Running RecentlyAdded home screen update");
  
  int            i = 0;
  CFileItemList  musicItems;
  CMusicDatabase musicdatabase;
  CMusicThumbLoader loader;
  loader.Initialize();
  
  musicdatabase.Open();
  
  if (musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://4/", musicItems, NUM_ITEMS))
  {
    long idAlbum = -1;
    CStdString strAlbumThumb;
    CStdString strAlbumFanart;
    for (; i < musicItems.Size(); ++i)
    {
      CFileItemPtr item = musicItems.Get(i);
      CStdString   value;
      value.Format("%i", i + 1);
      
      CStdString   strRating;
      CStdString   strAlbum  = item->GetMusicInfoTag()->GetAlbum();
      CStdString   strArtist = StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator);

      if (idAlbum != item->GetMusicInfoTag()->GetAlbumId())
      {
        strAlbumThumb.clear();
        strAlbumFanart.clear();
        idAlbum = item->GetMusicInfoTag()->GetAlbumId();

        if (loader.LoadItem(item.get()))
        {
          strAlbumThumb = item->GetArt("thumb");
          strAlbumFanart = item->GetArt("fanart");
        }
      }

      strRating.Format("%c", item->GetMusicInfoTag()->GetRating());
      
      home->SetProperty("LatestSong." + value + ".Title"   , item->GetMusicInfoTag()->GetTitle());
      home->SetProperty("LatestSong." + value + ".Year"    , item->GetMusicInfoTag()->GetYear());
      home->SetProperty("LatestSong." + value + ".Artist"  , strArtist);      
      home->SetProperty("LatestSong." + value + ".Album"   , strAlbum);
      home->SetProperty("LatestSong." + value + ".Rating"  , strRating);
      home->SetProperty("LatestSong." + value + ".Path"    , item->GetMusicInfoTag()->GetURL());
      home->SetProperty("LatestSong." + value + ".Thumb"   , strAlbumThumb);
      home->SetProperty("LatestSong." + value + ".Fanart"  , strAlbumFanart);
    }
  }
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestSong." + value + ".Title"   , "");
    home->SetProperty("LatestSong." + value + ".Year"    , "");
    home->SetProperty("LatestSong." + value + ".Artist"  , "");      
    home->SetProperty("LatestSong." + value + ".Album"   , "");
    home->SetProperty("LatestSong." + value + ".Rating"  , "");
    home->SetProperty("LatestSong." + value + ".Path"    , "");
    home->SetProperty("LatestSong." + value + ".Thumb"   , "");
    home->SetProperty("LatestSong." + value + ".Fanart"  , "");
  }
  
  i = 0;
  VECALBUMS albums;
  
  if (musicdatabase.GetRecentlyAddedAlbums(albums, NUM_ITEMS))
  { 
    for (; i < (int)albums.size(); ++i)
    {
      CStdString value;
      CStdString strPath;
      CStdString strThumb;
      CStdString strFanart;
      CStdString strDBpath;
      CStdString strSQLAlbum;
      CAlbum&    album=albums[i];     

      value.Format("%i", i + 1);
      strThumb = musicdatabase.GetArtForItem(album.idAlbum, "album", "thumb");
      strFanart = musicdatabase.GetArtistArtForItem(album.idAlbum, "album", "fanart");
      strDBpath.Format("musicdb://3/%i/", album.idAlbum);
      strSQLAlbum.Format("idAlbum=%i", album.idAlbum);
      
      CStdString strArtist = musicdatabase.GetSingleValue("albumview", "strArtists", strSQLAlbum);
      
      home->SetProperty("LatestAlbum." + value + ".Title"   , album.strAlbum);
      home->SetProperty("LatestAlbum." + value + ".Year"    , album.iYear);
      home->SetProperty("LatestAlbum." + value + ".Artist"  , strArtist);      
      home->SetProperty("LatestAlbum." + value + ".Rating"  , album.iRating);
      home->SetProperty("LatestAlbum." + value + ".Path"    , strDBpath);
      home->SetProperty("LatestAlbum." + value + ".Thumb"   , strThumb);
      home->SetProperty("LatestAlbum." + value + ".Fanart"  , strFanart);
    }
  }
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestAlbum." + value + ".Title"   , "");
    home->SetProperty("LatestAlbum." + value + ".Year"    , "");
    home->SetProperty("LatestAlbum." + value + ".Artist"  , "");      
    home->SetProperty("LatestAlbum." + value + ".Rating"  , "");
    home->SetProperty("LatestAlbum." + value + ".Path"    , "");
    home->SetProperty("LatestAlbum." + value + ".Thumb"   , "");
    home->SetProperty("LatestAlbum." + value + ".Fanart"  , "");            
  }
  
  musicdatabase.Close();
  return true;
}
Пример #26
0
void CGUIDialogMediaFilter::OnSettingChanged(SettingInfo &setting)
{
  map<uint32_t, Filter>::iterator it = m_filters.find(setting.id);
  if (it == m_filters.end())
    return;

  bool changed = true;
  bool remove = false;
  Filter& filter = it->second;

  switch (filter.type)
  {
    case SettingInfo::STRING:
    case SettingInfo::EDIT:
    {
      CStdString *str = static_cast<CStdString*>(filter.data);
      if (!str->empty())
      {
        if (filter.rule == NULL)
          filter.rule = AddRule(filter.field, filter.ruleOperator);
        filter.rule->m_parameter.clear();
        filter.rule->m_parameter.push_back(*str);
      }
      else
        remove = true;
        
      break;
    }
    
    case SettingInfo::CHECK:
    {
      int choice = *(int *)setting.data;
      if (choice > CHECK_ALL)
      {
        CSmartPlaylistRule::SEARCH_OPERATOR ruleOperator = choice == CHECK_YES ? CSmartPlaylistRule::OPERATOR_TRUE : CSmartPlaylistRule::OPERATOR_FALSE;
        if (filter.rule == NULL)
          filter.rule = AddRule(filter.field, ruleOperator);
        else
          filter.rule->m_operator = ruleOperator;
      }
      else
        remove = true;

      break;
    }

    case SettingInfo::BUTTON:
    {
      CFileItemList items;
      OnBrowse(filter, items);
      
      if (items.Size() > 0)
      {
        if (filter.rule == NULL)
          filter.rule = AddRule(filter.field, filter.ruleOperator);

        filter.rule->m_parameter.clear();
        for (int index = 0; index < items.Size(); index++)
          filter.rule->m_parameter.push_back(items[index]->GetLabel());

        *(CStdString *)filter.data = filter.rule->GetLocalizedParameter(m_mediaType);
      }
      else
      {
        remove = true;
        *(CStdString *)filter.data = "";
      }

      SET_CONTROL_LABEL2(filter.controlIndex, *(CStdString *)filter.data);
      break;
    }

    case SettingInfo::RANGE:
    {
      SettingInfo &setting = m_settings[filter.controlIndex - CONTROL_START];
      float *valueLower = ((float **)filter.data)[0];
      float *valueUpper = ((float **)filter.data)[1];

      if (*valueLower > setting.min || *valueUpper < setting.max)
      {
        if (filter.rule == NULL)
          filter.rule = AddRule(filter.field, filter.ruleOperator);

        filter.rule->m_parameter.clear();
        if (filter.field == FieldAirDate)
        {
          CDateTime lower = (time_t)*valueLower;
          CDateTime upper = (time_t)*valueUpper;
          filter.rule->m_parameter.push_back(lower.GetAsDBDate());
          filter.rule->m_parameter.push_back(upper.GetAsDBDate());
        }
        else
        {
          CStdString tmp;
          tmp.Format("%.1f", *valueLower);
          filter.rule->m_parameter.push_back(tmp);
          tmp.clear();
          tmp.Format("%.1f", *valueUpper);
          filter.rule->m_parameter.push_back(tmp);
        }
      }
      else
      {
        remove = true;
        *((float **)filter.data)[0] = setting.min;
        *((float **)filter.data)[1] = setting.max;
      }
      break;
    }

    default:
      changed = false;
      break;
  }

  // we need to remove the existing rule for the title
  if (remove && filter.rule != NULL)
  {
    DeleteRule(filter.field);
    filter.rule = NULL;
  }

  if (changed)
  {
    CGUIMessage message(GUI_MSG_NOTIFY_ALL, GetID(), 0, GUI_MSG_FILTER_ITEMS, 10); // 10 for advanced
    g_windowManager.SendMessage(message);

    UpdateControls();
  }
}
Пример #27
0
void CGUIDialogMediaSource::OnPathBrowse(int item)
{
  if (item < 0 || item > m_paths->Size()) return;
  // Browse is called.  Open the filebrowser dialog.
  // Ignore current path is best at this stage??
  CStdString path;
  bool allowNetworkShares(m_type != "programs");
  VECSOURCES extraShares;

  if (m_name != CUtil::GetTitleFromPath(m_paths->Get(item)->GetPath()))
    m_bNameChanged=true;

  if (m_type == "music")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android music directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "music") && !path.empty() && CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20240);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    // add the music playlist location
    share1.strPath = "special://musicplaylists/";
    share1.strName = g_localizeStrings.Get(20011);
    share1.m_ignore = true;
    extraShares.push_back(share1);

    share1.strPath = "sap://";
    share1.strName = "SAP Streams";
    extraShares.push_back(share1);

    if (CSettings::Get().GetString("audiocds.recordingpath") != "")
    {
      share1.strPath = "special://recordings/";
      share1.strName = g_localizeStrings.Get(21883);
      extraShares.push_back(share1);
    }
 }
  else if (m_type == "video")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android video directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "videos") && !path.empty() && CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20241);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    // add the video playlist location
    share1.m_ignore = true;
    share1.strPath = "special://videoplaylists/";
    share1.strName = g_localizeStrings.Get(20012);
    extraShares.push_back(share1);

    share1.strPath = "rtv://*/";
    share1.strName = "ReplayTV Devices";
    extraShares.push_back(share1);

    share1.strPath = "hdhomerun://";
    share1.strName = "HDHomerun Devices";
    extraShares.push_back(share1);

    share1.strPath = "sap://";
    share1.strName = "SAP Streams";
    extraShares.push_back(share1);

    // add the recordings dir as needed
    if (CPVRDirectory::HasRecordings())
    {
      share1.strPath = "pvr://recordings/";
      share1.strName = g_localizeStrings.Get(19017); // TV Recordings
      extraShares.push_back(share1);
    }
  }
  else if (m_type == "pictures")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android music directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "pictures") && !path.empty() &&  CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20242);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }

    path.clear();
    if (CXBMCApp::GetExternalStorage(path, "photos") && !path.empty() &&  CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20243);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    share1.m_ignore = true;
    if (CSettings::Get().GetString("debug.screenshotpath") != "")
    {
      share1.strPath = "special://screenshots/";
      share1.strName = g_localizeStrings.Get(20008);
      extraShares.push_back(share1);
    }
  }
  else if (m_type == "programs")
  {
    // nothing to add
  }
  if (CGUIDialogFileBrowser::ShowAndGetSource(path, allowNetworkShares, extraShares.size()==0?NULL:&extraShares))
  {
    if (item < m_paths->Size()) // if the skin does funky things, m_paths may have been cleared
      m_paths->Get(item)->SetPath(path);
    if (!m_bNameChanged || m_name.empty())
    {
      CURL url(path);
      m_name = url.GetWithoutUserDetails();
      URIUtils::RemoveSlashAtEnd(m_name);
      m_name = CUtil::GetTitleFromPath(m_name);
    }
    UpdateButtons();
  }
}
Пример #28
0
CStdString CID3Tag::ParseMP3Genre(const CStdString& str) const
{
  m_dll.Load();

  CStdString strTemp = str;
  set<CStdString> setGenres;

  while (!strTemp.IsEmpty())
  {
    // remove any leading spaces
    strTemp.TrimLeft();

    if (strTemp.IsEmpty())
      break;

    // start off looking for (something)
    if (strTemp[0] == '(')
    {
      strTemp.erase(0, 1);
      if (strTemp.empty())
        break;

      // now look for ((something))
      if (strTemp[0] == '(')
      {
        // remove ((something))
        int i = strTemp.find_first_of(')');
        strTemp.erase(0, i + 2);
      }
    }

    // no parens, so we have a start of a string
    // push chars into temp string until valid terminator found
    // valid terminators are ) or , or ;
    else
    {
      CStdString t;
      size_t i = strTemp.find_first_of("),;");
      if (i != std::string::npos)
      {
        t = strTemp.Left(i);
        strTemp.erase(0, i + 1);
      } else {
        t = strTemp;
        strTemp.clear();
      }
      
      // remove any leading or trailing white space
      // from temp string
      t.Trim();
      if (!t.length()) continue;

      // if the temp string is natural number try to convert it to a genre string
      if (StringUtils::IsNaturalNumber(t))
      {
        id3_ucs4_t* ucs4=m_dll.id3_latin1_ucs4duplicate((id3_latin1_t*)t.c_str());
        const id3_ucs4_t* genre=m_dll.id3_genre_name(ucs4);
        m_dll.id3_ucs4_free(ucs4);
        t=ToStringCharset(genre, ID3_FIELD_TEXTENCODING_ISO_8859_1);
      }

      // convert RX to Remix as per ID3 V2.3 spec
      else if ((t == "RX") || (t == "Rx") || (t == "rX") || (t == "rx"))
      {
        t = "Remix";
      }

      // convert CR to Cover as per ID3 V2.3 spec
      else if ((t == "CR") || (t == "Cr") || (t == "cR") || (t == "cr"))
      {
        t = "Cover";
      }

      // insert genre name in set
      setGenres.insert(t);
    }

  }

  // return a " / " seperated string
  CStdString strGenre;
  set<CStdString>::iterator it;
  for (it = setGenres.begin(); it != setGenres.end(); it++)
  {
    CStdString strTemp = *it;
    if (!strGenre.IsEmpty())
      strGenre += g_advancedSettings.m_musicItemSeparator;
    strGenre += strTemp;
  }
  return strGenre;
}
Пример #29
0
void CDVDPlayerVideo::Process()
{
  CLog::Log(LOGNOTICE, "running thread: video_thread");

  DVDVideoPicture picture;
  CPulldownCorrection pulldown;
  CDVDVideoPPFFmpeg mPostProcess("");
  CStdString sPostProcessType;
  bool bPostProcessDeint = false;

  memset(&picture, 0, sizeof(DVDVideoPicture));

  double pts = 0;
  double frametime = (double)DVD_TIME_BASE / m_fFrameRate;

  int iDropped = 0; //frames dropped in a row
  bool bRequestDrop = false;

  m_videoStats.Start();

  while (!m_bStop)
  {
    int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000;
    int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0;

    CDVDMsg* pMsg;
    MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, iQueueTimeOut, iPriority);

    if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT)
    {
      CLog::Log(LOGERROR, "Got MSGQ_ABORT or MSGO_IS_ERROR return true");
      break;
    }
    else if (ret == MSGQ_TIMEOUT)
    {
      // if we only wanted priority messages, this isn't a stall
      if( iPriority )
        continue;

      //Okey, start rendering at stream fps now instead, we are likely in a stillframe
      if( !m_stalled )
      {
        if(m_started)
          CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate);
        m_stalled = true;
        pts+= frametime*4;
      }

      //Waiting timed out, output last picture
      if( picture.iFlags & DVP_FLAG_ALLOCATED )
      {
        //Remove interlaced flag before outputting
        //no need to output this as if it was interlaced
        picture.iFlags &= ~DVP_FLAG_INTERLACED;
        picture.iFlags |= DVP_FLAG_NOSKIP;
        OutputPicture(&picture, pts);
        pts+= frametime;
      }

      continue;
    }

    if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE))
    {
      ((CDVDMsgGeneralSynchronize*)pMsg)->Wait( &m_bStop, SYNCSOURCE_VIDEO );
      CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_SYNCHRONIZE");
      pMsg->Release();

      /* we may be very much off correct pts here, but next picture may be a still*/
      /* make sure it isn't dropped */
      m_iNrOfPicturesNotToSkip = 5;
      continue;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
    {
      CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;

      if(pMsgGeneralResync->m_timestamp != DVD_NOPTS_VALUE)
        pts = pMsgGeneralResync->m_timestamp;

      double delay = m_FlipTimeStamp - m_pClock->GetAbsoluteClock();
      if( delay > frametime ) delay = frametime;
      else if( delay < 0 )    delay = 0;

      if(pMsgGeneralResync->m_clock)
      {
        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 1)", pts);
        m_pClock->Discontinuity(pts - delay);
      }
      else
        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 0)", pts);

      pMsgGeneralResync->Release();
      continue;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY))
    {
      if (m_speed != DVD_PLAYSPEED_PAUSE)
      {
        double timeout = static_cast<CDVDMsgDouble*>(pMsg)->m_value;

        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_DELAY(%f)", timeout);

        timeout *= (double)DVD_PLAYSPEED_NORMAL / abs(m_speed);
        timeout += CDVDClock::GetAbsoluteClock();

        while(!m_bStop && CDVDClock::GetAbsoluteClock() < timeout)
          Sleep(1);
      }
    }
    else if (pMsg->IsType(CDVDMsg::VIDEO_SET_ASPECT))
    {
      CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::VIDEO_SET_ASPECT");
      m_fForcedAspectRatio = *((CDVDMsgDouble*)pMsg);
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))
    {
      if(m_pVideoCodec)
        m_pVideoCodec->Reset();
      picture.iFlags &= ~DVP_FLAG_ALLOCATED;
      m_packets.clear();
      m_started = false;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush())
    {
      if(m_pVideoCodec)
        m_pVideoCodec->Reset();
      picture.iFlags &= ~DVP_FLAG_ALLOCATED;
      m_packets.clear();

      m_pullupCorrection.Flush();
      //we need to recalculate the framerate
      //TODO: this needs to be set on a streamchange instead
      ResetFrameRateCalc();

      m_stalled = true;
      m_started = false;
    }
    else if (pMsg->IsType(CDVDMsg::VIDEO_NOSKIP))
    {
      // libmpeg2 is also returning incomplete frames after a dvd cell change
      // so the first few pictures are not the correct ones to display in some cases
      // just display those together with the correct one.
      // (setting it to 2 will skip some menu stills, 5 is working ok for me).
      m_iNrOfPicturesNotToSkip = 5;
    }
    else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
    {
      m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;
      if(m_speed == DVD_PLAYSPEED_PAUSE)
        m_iNrOfPicturesNotToSkip = 0;
    }
    else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
    {
      if(m_started)
        m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
    {
      CDVDMsgVideoCodecChange* msg(static_cast<CDVDMsgVideoCodecChange*>(pMsg));
      OpenStream(msg->m_hints, msg->m_codec);
      msg->m_codec = NULL;
      picture.iFlags &= ~DVP_FLAG_ALLOCATED;
    }

    if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
    {
      DemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket();
      bool bPacketDrop     = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop();

      if (m_stalled)
      {
        CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe left, switching to normal playback");
        m_stalled = false;

        //don't allow the first frames after a still to be dropped
        //sometimes we get multiple stills (long duration frames) after each other
        //in normal mpegs
        m_iNrOfPicturesNotToSkip = 5;
      }
      else if( iDropped*frametime > DVD_MSEC_TO_TIME(100) && m_iNrOfPicturesNotToSkip == 0 )
      { // if we dropped too many pictures in a row, insert a forced picture
        m_iNrOfPicturesNotToSkip = 1;
      }

#ifdef PROFILE
      bRequestDrop = false;
#else
      if (m_messageQueue.GetDataSize() == 0
      ||  m_speed < 0)
      {
        bRequestDrop = false;
        m_iDroppedRequest = 0;
        m_iLateFrames     = 0;
      }
#endif

      // if player want's us to drop this packet, do so nomatter what
      if(bPacketDrop)
        bRequestDrop = true;

      // tell codec if next frame should be dropped
      // problem here, if one packet contains more than one frame
      // both frames will be dropped in that case instead of just the first
      // decoder still needs to provide an empty image structure, with correct flags
      m_pVideoCodec->SetDropState(bRequestDrop);

      // ask codec to do deinterlacing if possible
      EDEINTERLACEMODE mDeintMode = g_settings.m_currentVideoSettings.m_DeinterlaceMode;
      EINTERLACEMETHOD mInt       = g_renderManager.AutoInterlaceMethod(g_settings.m_currentVideoSettings.m_InterlaceMethod);

      unsigned int     mFilters = 0;

      if (mDeintMode != VS_DEINTERLACEMODE_OFF)
      {
        if (mInt == VS_INTERLACEMETHOD_DEINTERLACE)
          mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY;
        else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
          mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED;

        if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters)
          mFilters |=  CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;
      }

      mFilters = m_pVideoCodec->SetFilters(mFilters);

      int iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts);

      // buffer packets so we can recover should decoder flush for some reason
      if(m_pVideoCodec->GetConvergeCount() > 0)
      {
        m_packets.push_back(DVDMessageListItem(pMsg, 0));
        if(m_packets.size() > m_pVideoCodec->GetConvergeCount() 
        || m_packets.size() * frametime > DVD_SEC_TO_TIME(10))
          m_packets.pop_front();
      }

      m_videoStats.AddSampleBytes(pPacket->iSize);
      // assume decoder dropped a picture if it didn't give us any
      // picture from a demux packet, this should be reasonable
      // for libavformat as a demuxer as it normally packetizes
      // pictures when they come from demuxer
      if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE))
      {
        m_iDroppedFrames++;
        iDropped++;
      }

      // loop while no error
      while (!m_bStop)
      {

        // if decoder was flushed, we need to seek back again to resume rendering
        if (iDecoderState & VC_FLUSHED)
        {
          CLog::Log(LOGDEBUG, "CDVDPlayerVideo - video decoder was flushed");
          while(!m_packets.empty())
          {
            CDVDMsgDemuxerPacket* msg = (CDVDMsgDemuxerPacket*)m_packets.front().message->Acquire();
            m_packets.pop_front();

            // all packets except the last one should be dropped
            // if prio packets and current packet should be dropped, this is likely a new reset
            msg->m_drop = !m_packets.empty() || (iPriority > 0 && bPacketDrop);
            m_messageQueue.Put(msg, iPriority + 10);
          }

          m_pVideoCodec->Reset();
          m_packets.clear();
          break;
        }

        // if decoder had an error, tell it to reset to avoid more problems
        if (iDecoderState & VC_ERROR)
        {
          CLog::Log(LOGDEBUG, "CDVDPlayerVideo - video decoder returned error");
          break;
        }

        // check for a new picture
        if (iDecoderState & VC_PICTURE)
        {
          do {
            // note: decoder may have multiple buffers to return to us, so
            // keep popping out buffers until there are no more:
            m_pVideoCodec->ClearPicture(&picture);
            if (! m_pVideoCodec->GetPicture(&picture))
              break;

            sPostProcessType.clear();

            picture.iGroupId = pPacket->iGroupId;

            if(picture.iDuration == 0.0)
              picture.iDuration = frametime;

            if(bPacketDrop)
              picture.iFlags |= DVP_FLAG_DROPPED;

            if (m_iNrOfPicturesNotToSkip > 0)
            {
              picture.iFlags |= DVP_FLAG_NOSKIP;
              m_iNrOfPicturesNotToSkip--;
            }

            // validate picture timing, 
            // if both dts/pts invalid, use pts calulated from picture.iDuration
            // if pts invalid use dts, else use picture.pts as passed
            if (picture.dts == DVD_NOPTS_VALUE && picture.pts == DVD_NOPTS_VALUE)
              picture.pts = pts;
            else if (picture.pts == DVD_NOPTS_VALUE)
              picture.pts = picture.dts;

            /* use forced aspect if any */
            if( m_fForcedAspectRatio != 0.0f )
              picture.iDisplayWidth = (int) (picture.iDisplayHeight * m_fForcedAspectRatio);

            //Deinterlace if codec said format was interlaced or if we have selected we want to deinterlace
            //this video
            if ((mDeintMode == VS_DEINTERLACEMODE_AUTO && (picture.iFlags & DVP_FLAG_INTERLACED)) || mDeintMode == VS_DEINTERLACEMODE_FORCE)
            {
              if(mInt == VS_INTERLACEMETHOD_SW_BLEND)
              {
                if (!sPostProcessType.empty())
                  sPostProcessType += ",";
                sPostProcessType += g_advancedSettings.m_videoPPFFmpegDeint;
                bPostProcessDeint = true;
              }
            }

            if (g_settings.m_currentVideoSettings.m_PostProcess)
            {
              if (!sPostProcessType.empty())
                sPostProcessType += ",";
              // This is what mplayer uses for its "high-quality filter combination"
              sPostProcessType += g_advancedSettings.m_videoPPFFmpegPostProc;
            }

            if (!sPostProcessType.empty())
            {
              mPostProcess.SetType(sPostProcessType, bPostProcessDeint);
              if (mPostProcess.Process(&picture))
                mPostProcess.GetPicture(&picture);
            }

            /* if frame has a pts (usually originiating from demux packet), use that */
            if(picture.pts != DVD_NOPTS_VALUE)
            {
              if(pulldown.enabled())
                picture.pts += pulldown.pts();

              pts = picture.pts;
            }

            if(pulldown.enabled())
            {
              picture.iDuration = pulldown.dur();
              pulldown.next();
            }

            if (picture.iRepeatPicture)
              picture.iDuration *= picture.iRepeatPicture + 1;

#if 1
            int iResult = OutputPicture(&picture, pts);
#elif 0
            // testing NV12 rendering functions
            DVDVideoPicture* pTempNV12Picture = CDVDCodecUtils::ConvertToNV12Picture(&picture);
            int iResult = OutputPicture(pTempNV12Picture, pts);
            CDVDCodecUtils::FreePicture(pTempNV12Picture);
#elif 0
            // testing YUY2 or UYVY rendering functions
            // WARNING: since this scales a full YV12 frame, weaving artifacts will show on interlaced content
            // even with the deinterlacer on
            DVDVideoPicture* pTempYUVPackedPicture = CDVDCodecUtils::ConvertToYUV422PackedPicture(&picture, DVDVideoPicture::FMT_UYVY);
            //DVDVideoPicture* pTempYUVPackedPicture = CDVDCodecUtils::ConvertToYUV422PackedPicture(&picture, DVDVideoPicture::FMT_YUY2);
            int iResult = OutputPicture(pTempYUVPackedPicture, pts);
            CDVDCodecUtils::FreePicture(pTempYUVPackedPicture);
#endif

            if(m_started == false)
            {
              m_codecname = m_pVideoCodec->GetName();
              m_started = true;
              m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
            }

            // guess next frame pts. iDuration is always valid
            if (m_speed != 0)
              pts += picture.iDuration * m_speed / abs(m_speed);

            if( iResult & EOS_ABORT )
            {
              //if we break here and we directly try to decode again wihout
              //flushing the video codec things break for some reason
              //i think the decoder (libmpeg2 atleast) still has a pointer
              //to the data, and when the packet is freed that will fail.
              iDecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
              break;
            }

            if( (iResult & EOS_DROPPED) && !bPacketDrop )
            {
              m_iDroppedFrames++;
              iDropped++;
            }
            else
              iDropped = 0;

            bRequestDrop = (iResult & EOS_VERYLATE) == EOS_VERYLATE;
          } while (true);
        }

        /*
        if (iDecoderState & VC_USERDATA)
        {
          // found some userdata while decoding a frame
          // could be closed captioning
          DVDVideoUserData videoUserData;
          if (m_pVideoCodec->GetUserData(&videoUserData))
          {
            ProcessVideoUserData(&videoUserData, pts);
          }
        }
        */

        // if the decoder needs more data, we just break this loop
        // and try to get more data from the videoQueue
        if (iDecoderState & VC_BUFFER)
          break;

        // the decoder didn't need more data, flush the remaning buffer
        iDecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
      }
    }

    // all data is used by the decoder, we can safely free it now
    pMsg->Release();
  }

  // we need to let decoder release any picture retained resources.
  m_pVideoCodec->ClearPicture(&picture);
}
Пример #30
0
void CGUIDialogVideoInfo::OnGetArt()
{
  map<string, string> currentArt;
  string type = ChooseArtType(*m_movieItem, currentArt);
  if (type.empty())
    return; // cancelled

  // TODO: this can be removed once these are unified.
  if (type == "fanart")
    OnGetFanart();
  else
  {
    CFileItemList items;

    // Current thumb
    if (m_movieItem->HasArt(type))
    {
      CFileItemPtr item(new CFileItem("thumb://Current", false));
      item->SetArt("thumb", m_movieItem->GetArt(type));
      item->SetLabel(g_localizeStrings.Get(13512));
      items.Add(item);
    }
    else if ((type == "poster" || type == "banner") && currentArt.find("thumb") != currentArt.end())
    { // add the 'thumb' type in
      CFileItemPtr item(new CFileItem("thumb://Thumb", false));
      item->SetArt("thumb", currentArt["thumb"]);
      item->SetLabel(g_localizeStrings.Get(13512));
      items.Add(item);
    }

    // Grab the thumbnails from the web
    vector<CStdString> thumbs;
    int season = (m_movieItem->GetVideoInfoTag()->m_type == "season") ? m_movieItem->GetVideoInfoTag()->m_iSeason : -1;
    m_movieItem->GetVideoInfoTag()->m_strPictureURL.GetThumbURLs(thumbs, type, season);

    for (unsigned int i = 0; i < thumbs.size(); ++i)
    {
      CStdString strItemPath;
      strItemPath.Format("thumb://Remote%i", i);
      CFileItemPtr item(new CFileItem(strItemPath, false));
      item->SetArt("thumb", thumbs[i]);
      item->SetIconImage("DefaultPicture.png");
      item->SetLabel(g_localizeStrings.Get(13513));

      // TODO: Do we need to clear the cached image?
      //    CTextureCache::Get().ClearCachedImage(thumb);
      items.Add(item);
    }

    CStdString localThumb = CVideoThumbLoader::GetLocalArt(*m_movieItem, type);
    if (!localThumb.empty())
    {
      CFileItemPtr item(new CFileItem("thumb://Local", false));
      item->SetArt("thumb", localThumb);
      item->SetLabel(g_localizeStrings.Get(13514));
      items.Add(item);
    }
    else
    { // no local thumb exists, so we are just using the IMDb thumb or cached thumb
      // which is probably the IMDb thumb.  These could be wrong, so allow the user
      // to delete the incorrect thumb
      CFileItemPtr item(new CFileItem("thumb://None", false));
      item->SetIconImage("DefaultVideo.png");
      item->SetLabel(g_localizeStrings.Get(13515));
      items.Add(item);
    }

    CStdString result;
    VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("video"));
    AddItemPathToFileBrowserSources(sources, *m_movieItem);
    g_mediaManager.GetLocalDrives(sources);
    if (CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(13511), result) &&
        result != "thumb://Current") // user didn't choose the one they have
    {
      CStdString newThumb;
      if (result.Left(14) == "thumb://Remote")
      {
        int number = atoi(result.Mid(14));
        newThumb = thumbs[number];
      }
      else if (result == "thumb://Thumb")
        newThumb = currentArt["thumb"];
      else if (result == "thumb://Local")
        newThumb = localThumb;
      else if (CFile::Exists(result))
        newThumb = result;
      else // none
        newThumb.clear();

      // update thumb in the database
      CVideoDatabase db;
      if (db.Open())
      {
        db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, type, newThumb);
        db.Close();
      }
      CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
      m_movieItem->SetArt(type, newThumb);
      if (m_movieItem->HasProperty("set_folder_thumb"))
      { // have a folder thumb to set as well
        VIDEO::CVideoInfoScanner::ApplyThumbToFolder(m_movieItem->GetProperty("set_folder_thumb").asString(), newThumb);
      }
      m_hasUpdatedThumb = true;
    }
  }

  // Update our screen
  Update();

  // re-open the art selection dialog as we come back from
  // the image selection dialog
  OnGetArt();
}