void CKaraokeWindowBackground::StartImage( const CStdString& path ) { // Showing controls m_ImgControl->SetVisible( true ); m_VisControl->SetVisible( false ); m_ImgControl->SetFileName( path ); m_currentMode = BACKGROUND_IMAGE; CLog::Log( LOGDEBUG, "Karaoke background started using BACKGROUND_IMAGE mode using image %s", path.c_str() ); }
IFile* CFileFactory::CreateLoader(const CURL& url) { CStdString strProtocol = url.GetProtocol(); strProtocol.MakeLower(); if (strProtocol == "zip") return new CFileZip(); else if (strProtocol == "pfc") return new CFilePFC(); // Laureon: Filesystem: Added #ifdef HAS_FILESYSTEM_RAR else if (strProtocol == "rar") return new CFileRar(); #endif else if (strProtocol == "musicdb") return new CFileMusicDatabase(); else if (strProtocol == "videodb") return NULL; else if (strProtocol == "special") return new CFileSpecialProtocol(); else if (strProtocol == "multipath") return new CMultiPathFile(); else if (strProtocol == "file" || strProtocol.IsEmpty()) return new CFileHD(); else if (strProtocol == "filereader") return new CFileFileReader(); #if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE) else if (strProtocol == "cdda") return new CFileCDDA(); #endif #ifdef HAS_FILESYSTEM else if (strProtocol == "iso9660") return new CFileISO(); #endif else if(strProtocol == "udf") return new CFileUDF(); if( g_application.getNetwork().IsAvailable() ) { if (strProtocol == "http" || strProtocol == "https" || strProtocol == "dav" || strProtocol == "davs" || strProtocol == "ftp" || strProtocol == "ftpx" || strProtocol == "ftps" || strProtocol == "rss") return new CFileCurl(); #ifdef HAS_FILESYSTEM_SFTP else if (strProtocol == "sftp" || strProtocol == "ssh") return new CFileSFTP(); #endif else if (strProtocol == "shout") return new CFileShoutcast(); else if (strProtocol == "lastfm") return new CFileLastFM(); else if (strProtocol == "tuxbox") return new CFileTuxBox(); else if (strProtocol == "hdhomerun") return new CFileHomeRun(); else if (strProtocol == "sling") return new CSlingboxFile(); else if (strProtocol == "myth") return new CMythFile(); else if (strProtocol == "cmyth") return new CMythFile(); #ifdef HAS_FILESYSTEM_SMB #ifdef _WIN32 else if (strProtocol == "smb") return new CWINFileSMB(); #else else if (strProtocol == "smb") return new CFileSMB(); #endif #endif #ifdef HAS_FILESYSTEM #ifdef HAS_FILESYSTEM_RTV else if (strProtocol == "rtv") return new CFileRTV(); #endif #ifdef HAS_FILESYSTEM_DAAP else if (strProtocol == "daap") return new CFileDAAP(); #endif #endif #ifdef HAS_FILESYSTEM_SAP else if (strProtocol == "sap") return new CSAPFile(); #endif #ifdef HAS_FILESYSTEM_VTP else if (strProtocol == "vtp") return new CVTPFile(); #endif #ifdef HAS_FILESYSTEM_NFS else if (strProtocol == "nfs") return new CFileNFS(); #endif #ifdef HAS_FILESYSTEM_AFP else if (strProtocol == "afp") return new CFileAFP(); #endif else if (strProtocol == "pipe") return new CFilePipe(); else if (strProtocol == "upnp") return new CFileUPnP(); } CLog::Log(LOGWARNING, "%s - Unsupported protocol(%s) in %s", __FUNCTION__, strProtocol.c_str(), url.Get().c_str() ); return NULL; }
int CDVDPlayerVideo::OutputPicture(DVDVideoPicture* pPicture, double pts) { #ifdef HAS_VIDEO_PLAYBACK /* check so that our format or aspect has changed. if it has, reconfigure renderer */ if (!g_renderManager.IsConfigured() || m_output.width != pPicture->iWidth || m_output.height != pPicture->iHeight || m_output.dwidth != pPicture->iDisplayWidth || m_output.dheight != pPicture->iDisplayHeight || m_output.framerate != m_fFrameRate || m_output.color_format != (unsigned int)pPicture->format || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified || m_output.color_range != pPicture->color_range) { CLog::Log(LOGNOTICE, " fps: %f, pwidth: %i, pheight: %i, dwidth: %i, dheight: %i", m_fFrameRate, pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight); unsigned flags = 0; if(pPicture->color_range == 1) flags |= CONF_FLAGS_YUV_FULLRANGE; switch(pPicture->color_matrix) { case 7: // SMPTE 240M (1987) flags |= CONF_FLAGS_YUVCOEF_240M; break; case 6: // SMPTE 170M case 5: // ITU-R BT.470-2 case 4: // FCC flags |= CONF_FLAGS_YUVCOEF_BT601; break; case 1: // ITU-R Rec.709 (1990) -- BT.709 flags |= CONF_FLAGS_YUVCOEF_BT709; break; case 3: // RESERVED case 2: // UNSPECIFIED default: if(pPicture->iWidth > 1024 || pPicture->iHeight >= 600) flags |= CONF_FLAGS_YUVCOEF_BT709; else flags |= CONF_FLAGS_YUVCOEF_BT601; break; } CStdString formatstr; switch(pPicture->format) { case DVDVideoPicture::FMT_YUV420P: flags |= CONF_FLAGS_FORMAT_YV12; formatstr = "YV12"; break; case DVDVideoPicture::FMT_NV12: flags |= CONF_FLAGS_FORMAT_NV12; formatstr = "NV12"; break; case DVDVideoPicture::FMT_UYVY: flags |= CONF_FLAGS_FORMAT_UYVY; formatstr = "UYVY"; break; case DVDVideoPicture::FMT_YUY2: flags |= CONF_FLAGS_FORMAT_YUY2; formatstr = "YUY2"; break; case DVDVideoPicture::FMT_VDPAU: flags |= CONF_FLAGS_FORMAT_VDPAU; formatstr = "VDPAU"; break; case DVDVideoPicture::FMT_DXVA: flags |= CONF_FLAGS_FORMAT_DXVA; formatstr = "DXVA"; break; case DVDVideoPicture::FMT_VAAPI: flags |= CONF_FLAGS_FORMAT_VAAPI; formatstr = "VAAPI"; break; case DVDVideoPicture::FMT_OMXEGL: flags |= CONF_FLAGS_FORMAT_OMXEGL; break; case DVDVideoPicture::FMT_CVBREF: flags |= CONF_FLAGS_FORMAT_CVBREF; formatstr = "BGRA"; break; } if(m_bAllowFullscreen) { flags |= CONF_FLAGS_FULLSCREEN; m_bAllowFullscreen = false; // only allow on first configure } CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight,m_fFrameRate, formatstr.c_str()); if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, m_fFrameRate, flags)) { CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); return EOS_ABORT; } m_output.width = pPicture->iWidth; m_output.height = pPicture->iHeight; m_output.dwidth = pPicture->iDisplayWidth; m_output.dheight = pPicture->iDisplayHeight; m_output.framerate = m_fFrameRate; m_output.color_format = pPicture->format; m_output.color_matrix = pPicture->color_matrix; m_output.color_range = pPicture->color_range; } double maxfps = 60.0; bool limited = false; int result = 0; if (!g_renderManager.IsStarted()) { CLog::Log(LOGERROR, "%s - renderer not started", __FUNCTION__); return EOS_ABORT; } maxfps = g_renderManager.GetMaximumFPS(); // check if our output will limit speed if(m_fFrameRate * abs(m_speed) / DVD_PLAYSPEED_NORMAL > maxfps*0.9) limited = true; //correct any pattern in the timestamps m_pullupCorrection.Add(pts); pts += m_pullupCorrection.GetCorrection(); //try to calculate the framerate CalcFrameRate(); // signal to clock what our framerate is, it may want to adjust it's // speed to better match with our video renderer's output speed double interval; int refreshrate = m_pClock->UpdateFramerate(m_fFrameRate, &interval); if (refreshrate > 0) //refreshrate of -1 means the videoreferenceclock is not running {//when using the videoreferenceclock, a frame is always presented half a vblank interval too late pts -= DVD_TIME_BASE * interval; } //User set delay pts += m_iVideoDelay; // calculate the time we need to delay this picture before displaying double iSleepTime, iClockSleep, iFrameSleep, iPlayingClock, iCurrentClock, iFrameDuration; iPlayingClock = m_pClock->GetClock(iCurrentClock, false); // snapshot current clock iClockSleep = pts - iPlayingClock; //sleep calculated by pts to clock comparison iFrameSleep = m_FlipTimeStamp - iCurrentClock; // sleep calculated by duration of frame iFrameDuration = pPicture->iDuration; // correct sleep times based on speed if(m_speed) { iClockSleep = iClockSleep * DVD_PLAYSPEED_NORMAL / m_speed; iFrameSleep = iFrameSleep * DVD_PLAYSPEED_NORMAL / abs(m_speed); iFrameDuration = iFrameDuration * DVD_PLAYSPEED_NORMAL / abs(m_speed); } else { iClockSleep = 0; iFrameSleep = 0; } // dropping to a very low framerate is not correct (it should not happen at all) iClockSleep = min(iClockSleep, DVD_MSEC_TO_TIME(500)); iFrameSleep = min(iFrameSleep, DVD_MSEC_TO_TIME(500)); if( m_stalled ) iSleepTime = iFrameSleep; else iSleepTime = iFrameSleep + (iClockSleep - iFrameSleep) / m_autosync; #ifdef PROFILE /* during profiling, try to play as fast as possible */ iSleepTime = 0; #endif // present the current pts of this frame to user, and include the actual // presentation delay, to allow him to adjust for it if( m_stalled ) m_iCurrentPts = DVD_NOPTS_VALUE; else m_iCurrentPts = pts - max(0.0, iSleepTime); // timestamp when we think next picture should be displayed based on current duration m_FlipTimeStamp = iCurrentClock; m_FlipTimeStamp += max(0.0, iSleepTime); m_FlipTimeStamp += iFrameDuration; if (iSleepTime <= 0 && m_speed) m_iLateFrames++; else m_iLateFrames = 0; // ask decoder to drop frames next round, as we are very late if(m_iLateFrames > 10) { if (!(pPicture->iFlags & DVP_FLAG_NOSKIP)) { //if we're calculating the framerate, //don't drop frames until we've calculated a stable framerate if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL) { result |= EOS_VERYLATE; m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it } //if we requested 5 drops in a row and we're still late, drop on output //this keeps a/v sync if the decoder can't drop, or we're still calculating the framerate if (m_iDroppedRequest > 5) { m_iDroppedRequest--; //decrease so we only drop half the frames return result | EOS_DROPPED; } m_iDroppedRequest++; } } else { m_iDroppedRequest = 0; } if( m_speed < 0 ) { if( iClockSleep < -DVD_MSEC_TO_TIME(200) && !(pPicture->iFlags & DVP_FLAG_NOSKIP) ) return result | EOS_DROPPED; } if( (pPicture->iFlags & DVP_FLAG_DROPPED) ) return result | EOS_DROPPED; if( m_speed != DVD_PLAYSPEED_NORMAL && limited ) { // calculate frame dropping pattern to render at this speed // we do that by deciding if this or next frame is closest // to the flip timestamp double current = fabs(m_dropbase - m_droptime); double next = fabs(m_dropbase - (m_droptime + iFrameDuration)); double frametime = (double)DVD_TIME_BASE / maxfps; m_droptime += iFrameDuration; #ifndef PROFILE if( next < current && !(pPicture->iFlags & DVP_FLAG_NOSKIP) ) return result | EOS_DROPPED; #endif while(!m_bStop && m_dropbase < m_droptime) m_dropbase += frametime; while(!m_bStop && m_dropbase - frametime > m_droptime) m_dropbase -= frametime; m_pullupCorrection.Flush(); } else { m_droptime = 0.0f; m_dropbase = 0.0f; } // set fieldsync if picture is interlaced EFIELDSYNC mDisplayField = FS_NONE; if( pPicture->iFlags & DVP_FLAG_INTERLACED ) { if( pPicture->iFlags & DVP_FLAG_TOP_FIELD_FIRST ) mDisplayField = FS_TOP; else mDisplayField = FS_BOT; } ProcessOverlays(pPicture, pts); AutoCrop(pPicture); int index = g_renderManager.AddVideoPicture(*pPicture); // video device might not be done yet while (index < 0 && !CThread::m_bStop && CDVDClock::GetAbsoluteClock(false) < iCurrentClock + iSleepTime + DVD_MSEC_TO_TIME(500) ) { Sleep(1); index = g_renderManager.AddVideoPicture(*pPicture); } if (index < 0) return EOS_DROPPED; g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); return result; #else // no video renderer, let's mark it as dropped return EOS_DROPPED; #endif }
bool CGUIWindowVideoFiles::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_INIT: { // check for a passed destination path CStdString strDestination = message.GetStringParam(); if (!strDestination.IsEmpty()) { message.SetStringParam(""); g_stSettings.m_iVideoStartWindow = GetID(); CLog::Log(LOGINFO, "Attempting to quickpath to: %s", strDestination.c_str()); // reset directory path, as we have effectively cleared it here m_history.ClearPathHistory(); } // is this the first time accessing this window? // a quickpath overrides the a default parameter if ((m_vecItems->m_strPath == "?" || m_vecItems->m_strPath == "") && strDestination.IsEmpty()) { m_vecItems->m_strPath = strDestination = g_settings.m_defaultVideoSource; CLog::Log(LOGINFO, "Attempting to default to: %s", strDestination.c_str()); } // try to open the destination path if (!strDestination.IsEmpty()) { // open root if (strDestination.Equals("$ROOT")) { m_vecItems->m_strPath = ""; CLog::Log(LOGINFO, " Success! Opening root listing."); } // open playlists location else if (strDestination.Equals("$PLAYLISTS")) { m_vecItems->m_strPath = "special://videoplaylists/"; CLog::Log(LOGINFO, " Success! Opening destination path: %s", m_vecItems->m_strPath.c_str()); } else { // default parameters if the jump fails m_vecItems->m_strPath = ""; bool bIsSourceName = false; SetupShares(); VECSOURCES shares; m_rootDir.GetSources(shares); int iIndex = CUtil::GetMatchingSource(strDestination, shares, bIsSourceName); if (iIndex > -1) { bool bDoStuff = true; if (iIndex < shares.size() && shares[iIndex].m_iHasLock == 2) { CFileItem item(shares[iIndex]); if (!g_passwordManager.IsItemUnlocked(&item,"video")) { m_vecItems->m_strPath = ""; // no u don't bDoStuff = false; CLog::Log(LOGINFO, " Failure! Failed to unlock destination path: %s", strDestination.c_str()); } } // set current directory to matching share if (bDoStuff) { if (bIsSourceName) m_vecItems->m_strPath=shares[iIndex].strPath; else m_vecItems->m_strPath=strDestination; CLog::Log(LOGINFO, " Success! Opened destination path: %s", strDestination.c_str()); } } else { CLog::Log(LOGERROR, " Failed! Destination parameter (%s) does not match a valid source!", strDestination.c_str()); } } // check for network up if (CUtil::IsRemote(m_vecItems->m_strPath) && !WaitForNetwork()) m_vecItems->m_strPath.Empty(); SetHistoryForPath(m_vecItems->m_strPath); } return CGUIWindowVideoBase::OnMessage(message); } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); //if (iControl == CONTROL_BTNSCAN) //{ // OnScan(); // } /*else*/ if (iControl == CONTROL_STACK) { // toggle between the following states: // 0 : no stacking // 1 : stacking g_stSettings.m_iMyVideoStack++; if (g_stSettings.m_iMyVideoStack > STACK_SIMPLE) g_stSettings.m_iMyVideoStack = STACK_NONE; g_settings.Save(); UpdateButtons(); Update( m_vecItems->m_strPath ); } else if (iControl == CONTROL_BTNPLAYLISTS) { if (!m_vecItems->m_strPath.Equals("special://videoplaylists/")) { CStdString strParent = m_vecItems->m_strPath; UpdateButtons(); Update("special://videoplaylists/"); } } // list/thumb panel else if (m_viewControl.HasControl(iControl)) { int iItem = m_viewControl.GetSelectedItem(); int iAction = message.GetParam1(); const CFileItemPtr pItem = m_vecItems->Get(iItem); // use play button to add folders of items to temp playlist if (iAction == ACTION_PLAYER_PLAY && pItem->m_bIsFolder && !pItem->IsParentFolder()) { if (pItem->IsDVD()) return CAutorun::PlayDisc(); if (pItem->m_bIsShareOrDrive) return false; // if playback is paused or playback speed != 1, return if (g_application.IsPlayingVideo()) { if (g_application.m_pPlayer->IsPaused()) return false; if (g_application.GetPlaySpeed() != 1) return false; } // not playing, or playback speed == 1 // queue folder or playlist into temp playlist and play if ((pItem->m_bIsFolder && !pItem->IsParentFolder()) || pItem->IsPlayList()) PlayItem(iItem); return true; } } } } return CGUIWindowVideoBase::OnMessage(message); }
bool CZeroconfDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { assert(strPath.substr(0, 11) == "zeroconf://"); CStdString path = strPath.substr(11, strPath.length()); CUtil::RemoveSlashAtEnd(path); if(path.empty()) { std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices(); for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it) { //only use discovered services we can connect to through directory CStdString tmp; if(GetXBMCProtocol(it->GetType(), tmp)) { CFileItemPtr item(new CFileItem("", true)); CURL url; url.SetProtocol("zeroconf"); CStdString service_path = CZeroconfBrowser::ZeroconfService::toPath(*it); CUtil::URLEncode(service_path); url.SetFileName(service_path); item->m_strPath = url.Get(); //now do the formatting CStdString protocol = GetHumanReadableProtocol(it->GetType()); item->SetLabel(it->GetName() + " (" + protocol + ")"); item->SetLabelPreformated(true); //just set the default folder icon item->FillInDefaultIcon(); items.Add(item); } } return true; } else { //decode the path first CStdString decoded = path; CUtil::URLDecode(decoded); try { CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded); if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service)) { CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str()); return false; } else { assert(!zeroconf_service.GetIP().empty()); CURL service; service.SetPort(zeroconf_service.GetPort()); service.SetHostName(zeroconf_service.GetIP()); //do protocol conversion (_smb._tcp -> smb) //ToDo: try automatic conversion -> remove leading '_' and '._tcp'? CStdString protocol; if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol)) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str()); return false; } service.SetProtocol(protocol); return CDirectory::GetDirectory(service.Get(), items, "", true, true); } } catch (std::runtime_error& e) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what()); return false; } } }
bool StringUtils::ValidateUUID(const CStdString &uuid) { CRegExp guidRE; guidRE.RegComp(ADDON_GUID_RE); return (guidRE.RegFind(uuid.c_str()) == 0); }
bool CVideoReferenceClock::ParseNvSettings(int& RefreshRate) { double fRefreshRate; char Buff[255]; int ReturnV; struct lconv *Locale = localeconv(); FILE* NvSettings; const char* VendorPtr = (const char*)glGetString(GL_VENDOR); if (!VendorPtr) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: glGetString(GL_VENDOR) returned NULL, not using nvidia-settings"); return false; } CStdString Vendor = VendorPtr; Vendor.ToLower(); if (Vendor.find("nvidia") == std::string::npos) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: GL_VENDOR:%s, not using nvidia-settings", Vendor.c_str()); return false; } NvSettings = popen(NVSETTINGSCMD, "r"); if (!NvSettings) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: %s: %s", NVSETTINGSCMD, strerror(errno)); return false; } ReturnV = fscanf(NvSettings, "%254[^\n]", Buff); pclose(NvSettings); if (ReturnV != 1) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: %s produced no output", NVSETTINGSCMD); return false; } CLog::Log(LOGDEBUG, "CVideoReferenceClock: output of %s: %s", NVSETTINGSCMD, Buff); for (int i = 0; i < 255 && Buff[i]; i++) { //workaround for locale mismatch if (Buff[i] == '.' || Buff[i] == ',') Buff[i] = *Locale->decimal_point; } ReturnV = sscanf(Buff, "%lf", &fRefreshRate); if (ReturnV != 1 || fRefreshRate <= 0.0) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: can't make sense of that"); return false; } RefreshRate = MathUtils::round_int(fRefreshRate); CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate by nvidia-settings: %f hertz, rounding to %i hertz", fRefreshRate, RefreshRate); return true; }
void XBPyThread::Process() { CLog::Log(LOGDEBUG,"Python thread: start processing"); int m_Py_file_input = Py_file_input; // get the global lock PyEval_AcquireLock(); PyThreadState* state = Py_NewInterpreter(); if (!state) { PyEval_ReleaseLock(); CLog::Log(LOGERROR,"Python thread: FAILED to get thread state!"); return; } // swap in my thread state PyThreadState_Swap(state); XBMCAddon::AddonClass::Ref<XBMCAddon::Python::LanguageHook> languageHook(new XBMCAddon::Python::LanguageHook(state->interp)); languageHook->RegisterMe(); m_pExecuter->InitializeInterpreter(addon); CLog::Log(LOGDEBUG, "%s - The source file to load is %s", __FUNCTION__, m_source); // get path from script file name and add python path's // this is used for python so it will search modules from script path first CStdString scriptDir; URIUtils::GetDirectory(CSpecialProtocol::TranslatePath(m_source), scriptDir); URIUtils::RemoveSlashAtEnd(scriptDir); CStdString path = scriptDir; // add on any addon modules the user has installed ADDON::VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON::ADDON_SCRIPT_MODULE, addons); for (unsigned int i = 0; i < addons.size(); ++i) #ifdef TARGET_WINDOWS { CStdString strTmp(CSpecialProtocol::TranslatePath(addons[i]->LibPath())); g_charsetConverter.utf8ToSystem(strTmp); path += PY_PATH_SEP + strTmp; } #else path += PY_PATH_SEP + CSpecialProtocol::TranslatePath(addons[i]->LibPath()); #endif // and add on whatever our default path is path += PY_PATH_SEP; // we want to use sys.path so it includes site-packages // if this fails, default to using Py_GetPath PyObject *sysMod(PyImport_ImportModule((char*)"sys")); // must call Py_DECREF when finished PyObject *sysModDict(PyModule_GetDict(sysMod)); // borrowed ref, no need to delete PyObject *pathObj(PyDict_GetItemString(sysModDict, "path")); // borrowed ref, no need to delete if( pathObj && PyList_Check(pathObj) ) { for( int i = 0; i < PyList_Size(pathObj); i++ ) { PyObject *e = PyList_GetItem(pathObj, i); // borrowed ref, no need to delete if( e && PyString_Check(e) ) { path += PyString_AsString(e); // returns internal data, don't delete or modify path += PY_PATH_SEP; } } } else { path += Py_GetPath(); } Py_DECREF(sysMod); // release ref to sysMod // set current directory and python's path. if (m_argv != NULL) PySys_SetArgv(m_argc, m_argv); CLog::Log(LOGDEBUG, "%s - Setting the Python path to %s", __FUNCTION__, path.c_str()); PySys_SetPath((char *)path.c_str()); CLog::Log(LOGDEBUG, "%s - Entering source directory %s", __FUNCTION__, scriptDir.c_str()); PyObject* module = PyImport_AddModule((char*)"__main__"); PyObject* moduleDict = PyModule_GetDict(module); // when we are done initing we store thread state so we can be aborted PyThreadState_Swap(NULL); PyEval_ReleaseLock(); // we need to check if we was asked to abort before we had inited bool stopping = false; { CSingleLock lock(m_critSec); m_threadState = state; stopping = m_stopping; } PyEval_AcquireLock(); PyThreadState_Swap(state); if (!stopping) { try { if (m_type == 'F') { // run script from file // We need to have python open the file because on Windows the DLL that python // is linked against may not be the DLL that xbmc is linked against so // passing a FILE* to python from an fopen has the potential to crash. PyObject* file = PyFile_FromString((char *) CSpecialProtocol::TranslatePath(m_source).c_str(), (char*)"r"); FILE *fp = PyFile_AsFile(file); if (fp) { PyObject *f = PyString_FromString(CSpecialProtocol::TranslatePath(m_source).c_str()); PyDict_SetItemString(moduleDict, "__file__", f); if (addon.get() != NULL) { PyObject *pyaddonid = PyString_FromString(addon->ID().c_str()); PyDict_SetItemString(moduleDict, "__xbmcaddonid__", pyaddonid); CStdString version = ADDON::GetXbmcApiVersionDependency(addon); PyObject *pyxbmcapiversion = PyString_FromString(version.c_str()); PyDict_SetItemString(moduleDict, "__xbmcapiversion__", pyxbmcapiversion); CLog::Log(LOGDEBUG,"Instantiating addon using automatically obtained id of \"%s\" dependent on version %s of the xbmc.python api",addon->ID().c_str(),version.c_str()); } Py_DECREF(f); XBMCAddon::Python::PyContext pycontext; // this is a guard class that marks this callstack as being in a python context PyRun_FileExFlags(fp, CSpecialProtocol::TranslatePath(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict,1,NULL); } else CLog::Log(LOGERROR, "%s not found!", m_source); } else { //run script PyRun_String(m_source, m_Py_file_input, moduleDict, moduleDict); } } catch (const XbmcCommons::Exception& e) { e.LogThrowMessage(); } catch (...) { CLog::Log(LOGERROR, "failure in %s", m_source); } } bool systemExitThrown = false; if (!PyErr_Occurred()) CLog::Log(LOGINFO, "Scriptresult: Success"); else if (PyErr_ExceptionMatches(PyExc_SystemExit)) { systemExitThrown = true; CLog::Log(LOGINFO, "Scriptresult: Aborted"); } else { PythonBindings::PythonToCppException e; e.LogThrowMessage(); { CPyThreadState releaseGil; CSingleLock gc(g_graphicsContext); CGUIDialogKaiToast *pDlgToast = (CGUIDialogKaiToast*)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST); if (pDlgToast) { CStdString desc; CStdString path; CStdString script; URIUtils::Split(m_source, path, script); if (script.Equals("default.py")) { CStdString path2; URIUtils::RemoveSlashAtEnd(path); URIUtils::Split(path, path2, script); } desc.Format(g_localizeStrings.Get(2100), script); pDlgToast->QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(257), desc); } } } PyObject *m = PyImport_AddModule((char*)"xbmc"); if(!m || PyObject_SetAttrString(m, (char*)"abortRequested", PyBool_FromLong(1))) CLog::Log(LOGERROR, "Scriptresult: failed to set abortRequested"); // make sure all sub threads have finished for(PyThreadState* s = state->interp->tstate_head, *old = NULL; s;) { if(s == state) { s = s->next; continue; } if(old != s) { CLog::Log(LOGINFO, "Scriptresult: Waiting on thread %"PRIu64, (uint64_t)s->thread_id); old = s; } CPyThreadState pyState; Sleep(100); pyState.Restore(); s = state->interp->tstate_head; } // pending calls must be cleared out XBMCAddon::RetardedAsynchCallbackHandler::clearPendingCalls(state); PyThreadState_Swap(NULL); PyEval_ReleaseLock(); //set stopped event - this allows ::stop to run and kill remaining threads //this event has to be fired without holding m_critSec // //Also the GIL (PyEval_AcquireLock) must not be held //if not obeyed there is still no deadlock because ::stop waits with timeout (smart one!) stoppedEvent.Set(); { CSingleLock lock(m_critSec); m_threadState = NULL; } PyEval_AcquireLock(); PyThreadState_Swap(state); m_pExecuter->DeInitializeInterpreter(); // run the gc before finishing // // if the script exited by throwing a SystemExit excepton then going back // into the interpreter causes this python bug to get hit: // http://bugs.python.org/issue10582 // and that causes major failures. So we are not going to go back in // to run the GC if that's the case. if (!m_stopping && languageHook->HasRegisteredAddonClasses() && !systemExitThrown && PyRun_SimpleString(GC_SCRIPT) == -1) CLog::Log(LOGERROR,"Failed to run the gc to clean up after running prior to shutting down the Interpreter %s",m_source); Py_EndInterpreter(state); // If we still have objects left around, produce an error message detailing what's been left behind if (languageHook->HasRegisteredAddonClasses()) CLog::Log(LOGWARNING, "The python script \"%s\" has left several " "classes in memory that we couldn't clean up. The classes include: %s", m_source, getListOfAddonClassesAsString(languageHook).c_str()); // unregister the language hook languageHook->UnregisterMe(); PyEval_ReleaseLock(); }
bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate) { #ifdef TARGET_RASPBERRY_PI if (URIUtils::GetExtension(texturePath).Equals(".jpg") || URIUtils::GetExtension(texturePath).Equals(".tbn") /*|| URIUtils::GetExtension(texturePath).Equals(".png")*/) { COMXImage omx_image; if(omx_image.ReadFile(texturePath)) { // TODO: we only decode as half width and height. this is a workaround for the PI memory limitation if(omx_image.Decode(omx_image.GetWidth() / 2, omx_image.GetHeight() / 2)) { Allocate(omx_image.GetDecodedWidth(), omx_image.GetDecodedHeight(), XB_FMT_A8R8G8B8); if(!m_pixels) { CLog::Log(LOGERROR, "Texture manager (OMX) out of memory"); omx_image.Close(); return false; } m_hasAlpha = omx_image.IsAlpha(); if (autoRotate && omx_image.GetOrientation()) m_orientation = omx_image.GetOrientation() - 1; if(omx_image.GetDecodedData()) { int size = ( ( GetPitch() * GetRows() ) > omx_image.GetDecodedSize() ) ? omx_image.GetDecodedSize() : ( GetPitch() * GetRows() ); memcpy(m_pixels, (unsigned char *)omx_image.GetDecodedData(), size); } omx_image.Close(); return true; } else { omx_image.Close(); } } } #endif if (URIUtils::GetExtension(texturePath).Equals(".dds")) { // special case for DDS images CDDSImage image; if (image.ReadFile(texturePath)) { Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false); return true; } return false; } //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib. if (URIUtils::GetExtension(texturePath).Equals(".jpg") || URIUtils::GetExtension(texturePath).Equals(".tbn")) { CJpegIO jpegfile; if (jpegfile.Open(texturePath, maxWidth, maxHeight)) { if (jpegfile.Width() > 0 && jpegfile.Height() > 0) { Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8); if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8)) { if (autoRotate && jpegfile.Orientation()) m_orientation = jpegfile.Orientation() - 1; m_hasAlpha=false; ClampToEdge(); return true; } } } CLog::Log(LOGDEBUG, "%s - Load of %s failed. Falling back to ImageLib", __FUNCTION__, texturePath.c_str()); } DllImageLib dll; if (!dll.Load()) return false; ImageInfo image; memset(&image, 0, sizeof(image)); unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); if(!dll.LoadImage(texturePath.c_str(), width, height, &image)) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str()); return false; } LoadFromImage(image, autoRotate); dll.ReleaseImage(&image); return true; }
void CRssReader::Process() { while (m_vecQueue.size()) { int iFeed = m_vecQueue.front(); m_vecQueue.erase(m_vecQueue.begin()); m_strFeed[iFeed] = ""; m_strColors[iFeed] = ""; CHTTP http; http.SetUserAgent("XBMC/pre-2.1 (http://www.xboxmediacenter.com)"); CStdString strXML; CStdString strUrl = m_vecUrls[iFeed]; int nRetries = 3; CURL url(strUrl); if ((url.GetProtocol() == "http" || url.GetProtocol() == "https") && (!g_guiSettings.GetBool("network.enableinternet") || !g_application.getNetwork().IsAvailable())) strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>"; else { while ( (!m_bStop) && (nRetries > 0) ) { nRetries--; if (url.GetProtocol() != "http" && url.GetProtocol() != "https") { CFile file; if (file.Open(strUrl)) { char *yo = new char[(int)file.GetLength()+1]; file.Read(yo,file.GetLength()); yo[file.GetLength()] = '\0'; strXML = yo; delete[] yo; break; } } else if (http.Get(strUrl, strXML)) { CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str()); break; } } } if ((!strXML.IsEmpty()) && m_pObserver) { // erase any <content:encoded> tags (also unsupported by tinyxml) int iStart = strXML.Find("<content:encoded>"); int iEnd = 0; while (iStart > 0) { // get <content:encoded> end position iEnd = strXML.Find("</content:encoded>", iStart) + 18; // erase the section strXML = strXML.erase(iStart, iEnd - iStart); iStart = strXML.Find("<content:encoded>"); } if (Parse((LPSTR)strXML.c_str(),iFeed)) { CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str()); } } } UpdateObserver(); }
bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, const CStdString &strTarget, CStreamDetails *pStreamDetails) { unsigned int nTime = XbmcThreads::SystemClockMillis(); CDVDInputStream *pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, strPath, ""); if (!pInputStream) { CLog::Log(LOGERROR, "InputStream: Error creating stream for %s", strPath.c_str()); return false; } if (pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { CLog::Log(LOGERROR, "InputStream: dvd streams not supported for thumb extraction, file: %s", strPath.c_str()); delete pInputStream; return false; } if (!pInputStream->Open(strPath.c_str(), "")) { CLog::Log(LOGERROR, "InputStream: Error opening, %s", strPath.c_str()); if (pInputStream) delete pInputStream; return false; } CDVDDemux *pDemuxer = NULL; try { pDemuxer = CDVDFactoryDemuxer::CreateDemuxer(pInputStream); if(!pDemuxer) { delete pInputStream; CLog::Log(LOGERROR, "%s - Error creating demuxer", __FUNCTION__); return false; } } catch(...) { CLog::Log(LOGERROR, "%s - Exception thrown when opening demuxer", __FUNCTION__); if (pDemuxer) delete pDemuxer; delete pInputStream; return false; } if (pStreamDetails) DemuxerToStreamDetails(pInputStream, pDemuxer, *pStreamDetails, strPath); CDemuxStream* pStream = NULL; int nVideoStream = -1; for (int i = 0; i < pDemuxer->GetNrOfStreams(); i++) { pStream = pDemuxer->GetStream(i); if (pStream) { if(pStream->type == STREAM_VIDEO) nVideoStream = i; else pStream->SetDiscard(AVDISCARD_ALL); } } bool bOk = false; if (nVideoStream != -1) { CDVDVideoCodec *pVideoCodec; CDVDStreamInfo hint(*pDemuxer->GetStream(nVideoStream), true); hint.software = true; if (hint.codec == CODEC_ID_MPEG2VIDEO || hint.codec == CODEC_ID_MPEG1VIDEO) { // libmpeg2 is not thread safe so use ffmepg for mpeg2/mpeg1 thumb extraction CDVDCodecOptions dvdOptions; pVideoCodec = CDVDFactoryCodec::OpenCodec(new CDVDVideoCodecFFmpeg(), hint, dvdOptions); } else { pVideoCodec = CDVDFactoryCodec::CreateVideoCodec( hint ); } if (pVideoCodec) { int nTotalLen = pDemuxer->GetStreamLength(); int nSeekTo = nTotalLen / 3; CLog::Log(LOGDEBUG,"%s - seeking to pos %dms (total: %dms) in %s", __FUNCTION__, nSeekTo, nTotalLen, strPath.c_str()); if (pDemuxer->SeekTime(nSeekTo, true)) { DemuxPacket* pPacket = NULL; int iDecoderState = VC_ERROR; DVDVideoPicture picture; // num streams * 40 frames, should get a valid frame, if not abort. int abort_index = pDemuxer->GetNrOfStreams() * 40; do { pPacket = pDemuxer->Read(); if (!pPacket) break; if (pPacket->iStreamId != nVideoStream) { CDVDDemuxUtils::FreeDemuxPacket(pPacket); continue; } iDecoderState = pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts); CDVDDemuxUtils::FreeDemuxPacket(pPacket); if (iDecoderState & VC_ERROR) break; if (iDecoderState & VC_PICTURE) { memset(&picture, 0, sizeof(DVDVideoPicture)); if (pVideoCodec->GetPicture(&picture)) { if(!(picture.iFlags & DVP_FLAG_DROPPED)) break; } } } while (abort_index--); if (iDecoderState & VC_PICTURE && !(picture.iFlags & DVP_FLAG_DROPPED)) { { int nWidth = g_advancedSettings.m_thumbSize; double aspect = (double)picture.iDisplayWidth / (double)picture.iDisplayHeight; if(hint.forced_aspect && hint.aspect != 0) aspect = hint.aspect; int nHeight = (int)((double)g_advancedSettings.m_thumbSize / aspect); DllSwScale dllSwScale; dllSwScale.Load(); BYTE *pOutBuf = new BYTE[nWidth * nHeight * 4]; struct SwsContext *context = dllSwScale.sws_getContext(picture.iWidth, picture.iHeight, PIX_FMT_YUV420P, nWidth, nHeight, PIX_FMT_BGRA, SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); uint8_t *src[] = { picture.data[0], picture.data[1], picture.data[2], 0 }; int srcStride[] = { picture.iLineSize[0], picture.iLineSize[1], picture.iLineSize[2], 0 }; uint8_t *dst[] = { pOutBuf, 0, 0, 0 }; int dstStride[] = { nWidth*4, 0, 0, 0 }; if (context) { dllSwScale.sws_scale(context, src, srcStride, 0, picture.iHeight, dst, dstStride); dllSwScale.sws_freeContext(context); CPicture::CreateThumbnailFromSurface(pOutBuf, nWidth, nHeight, nWidth * 4, strTarget); bOk = true; } dllSwScale.Unload(); delete [] pOutBuf; } } else { CLog::Log(LOGDEBUG,"%s - decode failed in %s", __FUNCTION__, strPath.c_str()); } } delete pVideoCodec; } } if (pDemuxer) delete pDemuxer; delete pInputStream; if(!bOk) { XFILE::CFile file; if(file.OpenForWrite(strTarget)) file.Close(); } unsigned int nTotalTime = XbmcThreads::SystemClockMillis() - nTime; CLog::Log(LOGDEBUG,"%s - measured %u ms to extract thumb from file <%s> ", __FUNCTION__, nTotalTime, strPath.c_str()); return bOk; }
bool CISO9660Directory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString strRoot = strPath; URIUtils::AddSlashAtEnd(strRoot); // Scan active disc if not done before if (!m_isoReader.IsScanned()) m_isoReader.Scan(); CURL url(strPath); WIN32_FIND_DATA wfd; HANDLE hFind; memset(&wfd, 0, sizeof(wfd)); CStdString strSearchMask; CStdString strDirectory = url.GetFileName(); if (strDirectory != "") { strSearchMask.Format("\\%s", strDirectory.c_str()); } else { strSearchMask = "\\"; } for (int i = 0; i < (int)strSearchMask.size(); ++i ) { if (strSearchMask[i] == '/') strSearchMask[i] = '\\'; } hFind = m_isoReader.FindFirstFile((char*)strSearchMask.c_str(), &wfd); if (hFind == NULL) return false; do { if (wfd.cFileName[0] != 0) { if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { CStdString strDir = wfd.cFileName; if (strDir != "." && strDir != "..") { CFileItemPtr pItem(new CFileItem(wfd.cFileName)); pItem->m_strPath = strRoot; pItem->m_strPath += wfd.cFileName; pItem->m_bIsFolder = true; URIUtils::AddSlashAtEnd(pItem->m_strPath); FILETIME localTime; FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime); pItem->m_dateTime=localTime; items.Add(pItem); } } else { CFileItemPtr pItem(new CFileItem(wfd.cFileName)); pItem->m_strPath = strRoot; pItem->m_strPath += wfd.cFileName; pItem->m_bIsFolder = false; pItem->m_dwSize = CUtil::ToInt64(wfd.nFileSizeHigh, wfd.nFileSizeLow); FILETIME localTime; FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime); pItem->m_dateTime=localTime; items.Add(pItem); } } } while (m_isoReader.FindNextFile(hFind, &wfd)); m_isoReader.FindClose(hFind); return true; }
RENDER_STEREO_MODE CStereoscopicsManager::GetStereoModeOfPlayingVideo(void) { RENDER_STEREO_MODE mode = RENDER_STEREO_MODE_OFF; CStdString playerMode = g_infoManager.GetLabel(VIDEOPLAYER_STEREOSCOPIC_MODE); if (!playerMode.IsEmpty()) { int convertedMode = ConvertVideoToGuiStereoMode(playerMode); if (convertedMode > -1) mode = (RENDER_STEREO_MODE) convertedMode; } CLog::Log(LOGDEBUG, "StereoscopicsManager: autodetected GUI stereo mode for movie mode %s is: %s", playerMode.c_str(), GetLabelForStereoMode(mode).c_str()); return mode; }
void CKaraokeWindowBackground::StartVideo( const CStdString& path, __int64 offset) { CFileItem item( path, false); m_videoEnded = false; // Video options CPlayerOptions options; options.video_only = true; if ( offset > 0 ) options.starttime = (double) (offset / 1000.0); if ( !item.IsVideo() ) { CLog::Log(LOGERROR, "KaraokeVideoBackground: file %s is not a video file, ignoring", path.c_str() ); return; } if ( item.IsDVD() ) { CLog::Log(LOGERROR, "KaraokeVideoBackground: DVD video playback is not supported"); return; } if ( !m_videoPlayer ) m_videoPlayer = new CDVDPlayer(*this); if ( !m_videoPlayer ) return; if ( !m_videoPlayer->OpenFile( item, options ) ) { CLog::Log(LOGERROR, "KaraokeVideoBackground: error opening video file %s", item.m_strPath.c_str()); return; } CLog::Log(LOGDEBUG, "KaraokeVideoBackground: video file %s opened successfully", item.m_strPath.c_str()); m_ImgControl->SetVisible( false ); m_VisControl->SetVisible( false ); m_currentMode = BACKGROUND_VIDEO; }
void CURL::Parse(const CStdString& strURL1) { Reset(); // start by validating the path CStdString strURL = CUtil::ValidatePath(strURL1); // strURL can be one of the following: // format 1: protocol://[username:password]@hostname[:port]/directoryandfile // format 2: protocol://file // format 3: drive:directoryandfile // // first need 2 check if this is a protocol or just a normal drive & path if (!strURL.size()) return ; if (strURL.Equals("?", true)) return; // form is format 1 or 2 // format 1: protocol://[domain;][username:password]@hostname[:port]/directoryandfile // format 2: protocol://file // decode protocol int iPos = strURL.Find("://"); if (iPos < 0) { // This is an ugly hack that needs some work. // example: filename /foo/bar.zip/alice.rar/bob.avi // This should turn into zip://rar:///foo/bar.zip/alice.rar/bob.avi iPos = 0; bool is_apk = (strURL.Find(".apk/", iPos) > 0); while (1) { if (is_apk) iPos = strURL.Find(".apk/", iPos); else iPos = strURL.Find(".zip/", iPos); int extLen = 3; if (iPos < 0) { /* set filename and update extension*/ SetFileName(strURL); return ; } iPos += extLen + 1; CStdString archiveName = strURL.Left(iPos); struct __stat64 s; if (XFILE::CFile::Stat(archiveName, &s) == 0) { #ifdef _LINUX if (!S_ISDIR(s.st_mode)) #else if (!(s.st_mode & S_IFDIR)) #endif { Encode(archiveName); if (is_apk) { CURL c((CStdString)"apk" + "://" + archiveName + '/' + strURL.Right(strURL.size() - iPos - 1)); *this = c; } else { CURL c((CStdString)"zip" + "://" + archiveName + '/' + strURL.Right(strURL.size() - iPos - 1)); *this = c; } return; } } } } else { SetProtocol(strURL.Left(iPos)); iPos += 3; } // virtual protocols // why not handle all format 2 (protocol://file) style urls here? // ones that come to mind are iso9660, cdda, musicdb, etc. // they are all local protocols and have no server part, port number, special options, etc. // this removes the need for special handling below. if ( m_strProtocol.Equals("stack") || m_strProtocol.Equals("virtualpath") || m_strProtocol.Equals("multipath") || m_strProtocol.Equals("filereader") || m_strProtocol.Equals("special") ) { SetFileName(strURL.Mid(iPos)); return; } // check for username/password - should occur before first / if (iPos == -1) iPos = 0; // for protocols supporting options, chop that part off here // maybe we should invert this list instead? int iEnd = strURL.length(); const char* sep = NULL; //TODO fix all Addon paths CStdString strProtocol2 = GetTranslatedProtocol(); if(m_strProtocol.Equals("rss") || m_strProtocol.Equals("rar") || m_strProtocol.Equals("addons") || m_strProtocol.Equals("image") || m_strProtocol.Equals("videodb") || m_strProtocol.Equals("musicdb") || m_strProtocol.Equals("androidapp")) sep = "?"; else if(strProtocol2.Equals("http") || strProtocol2.Equals("https") || strProtocol2.Equals("plugin") || strProtocol2.Equals("addons") || strProtocol2.Equals("hdhomerun") || strProtocol2.Equals("rtsp") || strProtocol2.Equals("apk") || strProtocol2.Equals("zip")) sep = "?;#|"; else if(strProtocol2.Equals("ftp") || strProtocol2.Equals("ftps")) sep = "?;"; if(sep) { int iOptions = strURL.find_first_of(sep, iPos); if (iOptions >= 0 ) { // we keep the initial char as it can be any of the above int iProto = strURL.find_first_of("|",iOptions); if (iProto >= 0) { m_strProtocolOptions = strURL.substr(iProto+1); m_strOptions = strURL.substr(iOptions,iProto-iOptions); } else m_strOptions = strURL.substr(iOptions); iEnd = iOptions; } } int iSlash = strURL.Find("/", iPos); if(iSlash >= iEnd) iSlash = -1; // was an invalid slash as it was contained in options if( !m_strProtocol.Equals("iso9660") ) { int iAlphaSign = strURL.Find("@", iPos); if (iAlphaSign >= 0 && iAlphaSign < iEnd && (iAlphaSign < iSlash || iSlash < 0)) { // username/password found CStdString strUserNamePassword = strURL.Mid(iPos, iAlphaSign - iPos); // first extract domain, if protocol is smb if (m_strProtocol.Equals("smb")) { int iSemiColon = strUserNamePassword.Find(";"); if (iSemiColon >= 0) { m_strDomain = strUserNamePassword.Left(iSemiColon); strUserNamePassword.Delete(0, iSemiColon + 1); } } // username:password int iColon = strUserNamePassword.Find(":"); if (iColon >= 0) { m_strUserName = strUserNamePassword.Left(iColon); iColon++; m_strPassword = strUserNamePassword.Right(strUserNamePassword.size() - iColon); } // username else { m_strUserName = strUserNamePassword; } iPos = iAlphaSign + 1; iSlash = strURL.Find("/", iAlphaSign); if(iSlash >= iEnd) iSlash = -1; } } // detect hostname:port/ if (iSlash < 0) { CStdString strHostNameAndPort = strURL.Mid(iPos, iEnd - iPos); int iColon = strHostNameAndPort.Find(":"); if (iColon >= 0) { m_strHostName = strHostNameAndPort.Left(iColon); iColon++; CStdString strPort = strHostNameAndPort.Right(strHostNameAndPort.size() - iColon); m_iPort = atoi(strPort.c_str()); } else { m_strHostName = strHostNameAndPort; } } else { CStdString strHostNameAndPort = strURL.Mid(iPos, iSlash - iPos); int iColon = strHostNameAndPort.Find(":"); if (iColon >= 0) { m_strHostName = strHostNameAndPort.Left(iColon); iColon++; CStdString strPort = strHostNameAndPort.Right(strHostNameAndPort.size() - iColon); m_iPort = atoi(strPort.c_str()); } else { m_strHostName = strHostNameAndPort; } iPos = iSlash + 1; if (iEnd > iPos) { m_strFileName = strURL.Mid(iPos, iEnd - iPos); iSlash = m_strFileName.Find("/"); if(iSlash < 0) m_strShareName = m_strFileName; else m_strShareName = m_strFileName.Left(iSlash); } } // iso9960 doesnt have an hostname;-) if (m_strProtocol.CompareNoCase("iso9660") == 0 || m_strProtocol.CompareNoCase("musicdb") == 0 || m_strProtocol.CompareNoCase("videodb") == 0 || m_strProtocol.CompareNoCase("sources") == 0 || m_strProtocol.CompareNoCase("lastfm") == 0 || m_strProtocol.CompareNoCase("pvr") == 0 || m_strProtocol.Left(3).CompareNoCase("mem") == 0) { if (m_strHostName != "" && m_strFileName != "") { CStdString strFileName = m_strFileName; m_strFileName.Format("%s/%s", m_strHostName.c_str(), strFileName.c_str()); m_strHostName = ""; } else { if (!m_strHostName.IsEmpty() && strURL[iEnd-1]=='/') m_strFileName = m_strHostName + "/"; else m_strFileName = m_strHostName; m_strHostName = ""; } } m_strFileName.Replace("\\", "/"); /* update extension */ SetFileName(m_strFileName); /* decode urlencoding on this stuff */ if(URIUtils::ProtocolHasEncodedHostname(m_strProtocol)) { Decode(m_strHostName); // Validate it as it is likely to contain a filename SetHostName(CUtil::ValidatePath(m_strHostName)); } Decode(m_strUserName); Decode(m_strPassword); }
bool CGUIWindowMusicSongs::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: if (m_thumbLoader.IsLoading()) m_thumbLoader.StopThread(); break; case GUI_MSG_WINDOW_INIT: { // removed the start window check from files view // the window translator does it by using a virtual window id (5) // check for a passed destination path CStdString strDestination = message.GetStringParam(); if (!strDestination.IsEmpty()) { message.SetStringParam(""); CLog::Log(LOGINFO, "Attempting to quickpath to: %s", strDestination.c_str()); m_history.ClearPathHistory(); } // is this the first time the window is opened? printf("%s\n", m_vecItems->m_strPath.c_str()); if ((m_vecItems->m_strPath == "?" || m_vecItems->m_strPath == "") && strDestination.IsEmpty()) { strDestination = g_settings.m_defaultMusicSource; m_vecItems->m_strPath=strDestination; CLog::Log(LOGINFO, "Attempting to default to: %s", strDestination.c_str()); } // try to open the destination path if (!strDestination.IsEmpty()) { // open root if (strDestination.Equals("$ROOT")) { m_vecItems->m_strPath = ""; CLog::Log(LOGINFO, " Success! Opening root listing."); } // open playlists location else if (strDestination.Equals("$PLAYLISTS")) { m_vecItems->m_strPath = "special://musicplaylists/"; CLog::Log(LOGINFO, " Success! Opening destination path: %s", m_vecItems->m_strPath.c_str()); } else { // default parameters if the jump fails m_vecItems->m_strPath.Empty(); bool bIsSourceName = false; SetupShares(); VECSOURCES shares; m_rootDir.GetSources(shares); int iIndex = CUtil::GetMatchingSource(strDestination, shares, bIsSourceName); if (iIndex > -1) { bool unlocked = true; if (iIndex < (int)shares.size() && shares[iIndex].m_iHasLock == 2) { CFileItem item(shares[iIndex]); if (!g_passwordManager.IsItemUnlocked(&item,"music")) { m_vecItems->m_strPath = ""; // no u don't unlocked = false; CLog::Log(LOGINFO, " Failure! Failed to unlock destination path: %s", strDestination.c_str()); } } // set current directory to matching share if (unlocked) { if (bIsSourceName) m_vecItems->m_strPath=shares[iIndex].strPath; else m_vecItems->m_strPath=strDestination; CLog::Log(LOGINFO, " Success! Opened destination path: %s (%s)", strDestination.c_str(), m_vecItems->m_strPath.c_str()); } } else { CLog::Log(LOGERROR, " Failed! Destination parameter (%s) does not match a valid source!", strDestination.c_str()); } } // check for network up if (CUtil::IsRemote(m_vecItems->m_strPath) && !WaitForNetwork()) m_vecItems->m_strPath.Empty(); // need file filters or GetDirectory in SetHistoryPath fails SetHistoryForPath(m_vecItems->m_strPath); } return CGUIWindowMusicBase::OnMessage(message); } break; case GUI_MSG_DIRECTORY_SCANNED: { CFileItem directory(message.GetStringParam(), true); // Only update thumb on a local drive if (directory.IsHD()) { CStdString strParent; CUtil::GetParentPath(directory.m_strPath, strParent); if (directory.m_strPath == m_vecItems->m_strPath || strParent == m_vecItems->m_strPath) { Update(m_vecItems->m_strPath); } } } break; case GUI_MSG_NOTIFY_ALL: { if (message.GetParam1()==GUI_MSG_REMOVED_MEDIA) DeleteRemoveableMediaDirectoryCache(); } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTNPLAYLISTS) { if (!m_vecItems->m_strPath.Equals("special://musicplaylists/")) Update("special://musicplaylists/"); } else if (iControl == CONTROL_BTNSCAN) { OnScan(-1); } else if (iControl == CONTROL_BTNREC) { if (g_application.IsPlayingAudio() ) { if (g_application.m_pPlayer->CanRecord() ) { bool bIsRecording = g_application.m_pPlayer->IsRecording(); g_application.m_pPlayer->Record(!bIsRecording); UpdateButtons(); } } } else if (iControl == CONTROL_BTNRIP) { OnRipCD(); } } break; } return CGUIWindowMusicBase::OnMessage(message); }
bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext) { CURL url(scrURL.m_url); http.SetReferer(scrURL.m_spoof); CStdString strCachePath; if (scrURL.m_isgz) http.SetContentEncoding("gzip"); if (!scrURL.m_cache.IsEmpty()) { URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "scrapers/"+cacheContext+"/"+scrURL.m_cache, strCachePath); if (XFILE::CFile::Exists(strCachePath)) { XFILE::CFile file; if (file.Open(strCachePath)) { char* temp = new char[(int)file.GetLength()]; file.Read(temp,file.GetLength()); strHTML.clear(); strHTML.append(temp,temp+file.GetLength()); file.Close(); delete[] temp; return true; } } } CStdString strHTML1(strHTML); if (scrURL.m_post) { CStdString strOptions = url.GetOptions(); strOptions = strOptions.substr(1); url.SetOptions(""); if (!http.Post(url.Get(), strOptions, strHTML1)) return false; } else if (!http.Get(url.Get(), strHTML1)) return false; strHTML = strHTML1; if (scrURL.m_url.Find(".zip") > -1 ) { XFILE::CZipFile file; CStdString strBuffer; int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz); if (iSize) { strHTML.clear(); strHTML.append(strBuffer.c_str(),strBuffer.data()+iSize); } } if (!scrURL.m_cache.IsEmpty()) { CStdString strCachePath; URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "scrapers/"+cacheContext+"/"+scrURL.m_cache, strCachePath); XFILE::CFile file; if (file.OpenForWrite(strCachePath,true)) file.Write(strHTML.data(),strHTML.size()); file.Close(); } return true; }
bool CDatabase::Update(const DatabaseSettings &settings) { DatabaseSettings dbSettings = settings; InitSettings(dbSettings); int version = GetMinVersion(); CStdString latestDb = dbSettings.name; latestDb.AppendFormat("%d", version); while (version >= 0) { CStdString dbName = dbSettings.name; if (version) dbName.AppendFormat("%d", version); if (Connect(dbName, dbSettings, false)) { // Database exists, take a copy for our current version (if needed) and reopen that one if (version < GetMinVersion()) { CLog::Log(LOGNOTICE, "Old database found - updating from version %i to %i", version, GetMinVersion()); bool copy_fail = false; try { m_pDB->copy(latestDb); } catch(...) { CLog::Log(LOGERROR, "Unable to copy old database %s to new version %s", dbName.c_str(), latestDb.c_str()); copy_fail = true; } Close(); if ( copy_fail ) return false; if (!Connect(latestDb, dbSettings, false)) { CLog::Log(LOGERROR, "Unable to open freshly copied database %s", latestDb.c_str()); return false; } } // yay - we have a copy of our db, now do our worst with it if (UpdateVersion(latestDb)) return true; // update failed - loop around and see if we have another one available Close(); } // drop back to the previous version and try that version--; } // try creating a new one if (Connect(latestDb, dbSettings, true)) return true; // failed to update or open the database Close(); CLog::Log(LOGERROR, "Unable to create new database"); return false; }
double StringUtils::CompareFuzzy(const CStdString &left, const CStdString &right) { return (0.5 + fstrcmp(left.c_str(), right.c_str(), 0.0) * (left.length() + right.length())) / 2.0; }
bool CDatabase::Connect(const CStdString &dbName, const DatabaseSettings &dbSettings, bool create) { // create the appropriate database structure if (dbSettings.type.Equals("sqlite3")) { m_pDB.reset( new SqliteDatabase() ) ; } #ifdef HAS_MYSQL else if (dbSettings.type.Equals("mysql")) { m_pDB.reset( new MysqlDatabase() ) ; } #endif else { CLog::Log(LOGERROR, "Unable to determine database type: %s", dbSettings.type.c_str()); return false; } // host name is always required m_pDB->setHostName(dbSettings.host.c_str()); if (!dbSettings.port.IsEmpty()) m_pDB->setPort(dbSettings.port.c_str()); if (!dbSettings.user.IsEmpty()) m_pDB->setLogin(dbSettings.user.c_str()); if (!dbSettings.pass.IsEmpty()) m_pDB->setPasswd(dbSettings.pass.c_str()); // database name is always required m_pDB->setDatabase(dbName.c_str()); // create the datasets m_pDS.reset(m_pDB->CreateDataset()); m_pDS2.reset(m_pDB->CreateDataset()); if (m_pDB->connect(create) != DB_CONNECTION_OK) return false; try { // test if db already exists, if not we need to create the tables if (!m_pDB->exists() && create) { if (dbSettings.type.Equals("sqlite3")) { // Modern file systems have a cluster/block size of 4k. // To gain better performance when performing write // operations to the database, set the page size of the // database file to 4k. // This needs to be done before any table is created. m_pDS->exec("PRAGMA page_size=4096\n"); // Also set the memory cache size to 16k m_pDS->exec("PRAGMA default_cache_size=4096\n"); } CreateTables(); } // sqlite3 post connection operations if (dbSettings.type.Equals("sqlite3")) { m_pDS->exec("PRAGMA cache_size=4096\n"); m_pDS->exec("PRAGMA synchronous='NORMAL'\n"); m_pDS->exec("PRAGMA count_changes='OFF'\n"); } } catch (DbErrors &error) { CLog::Log(LOGERROR, "%s failed with '%s'", __FUNCTION__, error.getMsg()); m_openCount = 1; // set to open so we can execute Close() Close(); return false; } m_openCount = 1; // our database is open return true; }
bool CVideoReferenceClock::SetupD3D() { int ReturnV; CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up Direct3d"); m_D3dCallback.Aquire(); //get d3d device m_D3dDev = g_Windowing.Get3DDevice(); //we need a high priority thread to get accurate timing if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) CLog::Log(LOGDEBUG, "CVideoReferenceClock: SetThreadPriority failed"); D3DCAPS9 DevCaps; ReturnV = m_D3dDev->GetDeviceCaps(&DevCaps); if (ReturnV != D3D_OK) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDeviceCaps returned %s: %s", DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); return false; } if ((DevCaps.Caps & D3DCAPS_READ_SCANLINE) != D3DCAPS_READ_SCANLINE) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: Hardware does not support GetRasterStatus"); return false; } D3DRASTER_STATUS RasterStatus; ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); if (ReturnV != D3D_OK) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); return false; } D3DDISPLAYMODE DisplayMode; ReturnV = m_D3dDev->GetDisplayMode(0, &DisplayMode); if (ReturnV != D3D_OK) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDisplayMode returned returned %s: %s", DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); return false; } //forced update of windows refreshrate UpdateRefreshrate(true); if (g_advancedSettings.m_measureRefreshrate) { //measure the refreshrate a couple times list<double> Measures; for (int i = 0; i < NRMEASURES; i++) Measures.push_back(MeasureRefreshrate(MEASURETIME)); //build up a string of measured rates CStdString StrRates; for (list<double>::iterator it = Measures.begin(); it != Measures.end(); it++) StrRates.AppendFormat("%.2f ", *it); //get the top half of the measured rates Measures.sort(); double RefreshRate = 0.0; int NrMeasurements = 0; while (NrMeasurements < NRMEASURES / 2 && !Measures.empty()) { if (Measures.back() > 0.0) { RefreshRate += Measures.back(); NrMeasurements++; } Measures.pop_back(); } if (NrMeasurements < NRMEASURES / 2) { CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, unable to get a good measurement", StrRates.c_str(), m_RefreshRate); return false; } RefreshRate /= NrMeasurements; m_RefreshRate = MathUtils::round_int(RefreshRate); CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, assuming %i hertz", StrRates.c_str(), m_RefreshRate); } else { m_RefreshRate = m_PrevRefreshRate; if (m_RefreshRate == 23 || m_RefreshRate == 29 || m_RefreshRate == 59) m_RefreshRate++; if (m_Interlaced) { m_RefreshRate *= 2; CLog::Log(LOGDEBUG, "CVideoReferenceClock: display is interlaced"); } CLog::Log(LOGDEBUG, "CVideoReferenceClock: detected refreshrate: %i hertz, assuming %i hertz", m_PrevRefreshRate, (int)m_RefreshRate); } m_MissedVblanks = 0; return true; }
CStdString CHttpApi::WebMethodCall(CStdString &command, CStdString ¶meter) { CStdString response = MethodCall(command, parameter); response.Format("%s%s%s", m_pXbmcHttp->incWebHeader ? "<html>\n" : "", response.c_str(), m_pXbmcHttp->incWebFooter ? "\n</html>\n" : ""); return response; }
/*! \brief Create a IDirectory object of the share type specified in \e strPath . \param strPath Specifies the share type to access, can be a share or share with path. \return IDirectory object to access the directories on the share. \sa IDirectory */ IDirectory* CDirectoryFactory::Create(const CStdString& strPath) { CURL url(strPath); CWakeOnAccess::Get().WakeUpHost(url); CFileItem item(strPath, false); IFileDirectory* pDir=CFileDirectoryFactory::Create(strPath, &item); if (pDir) return pDir; CStdString strProtocol = url.GetProtocol(); if (strProtocol.size() == 0 || strProtocol == "file") return new CHDDirectory(); if (strProtocol == "special") return new CSpecialProtocolDirectory(); if (strProtocol == "sources") return new CSourcesDirectory(); if (strProtocol == "addons") return new CAddonsDirectory(); #if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE) if (strProtocol == "cdda") return new CCDDADirectory(); #endif #ifdef HAS_FILESYSTEM if (strProtocol == "iso9660") return new CISO9660Directory(); #endif if (strProtocol == "udf") return new CUDFDirectory(); if (strProtocol == "plugin") return new CPluginDirectory(); #if defined(TARGET_ANDROID) if (strProtocol == "apk") return new CAPKDirectory(); #endif if (strProtocol == "zip") return new CZipDirectory(); if (strProtocol == "rar") { #ifdef HAS_FILESYSTEM_RAR return new CRarDirectory(); #else CLog::Log(LOGWARNING, "%s - Compiled without non-free, rar support is disabled", __FUNCTION__); #endif } if (strProtocol == "multipath") return new CMultiPathDirectory(); if (strProtocol == "stack") return new CStackDirectory(); if (strProtocol == "playlistmusic") return new CPlaylistDirectory(); if (strProtocol == "playlistvideo") return new CPlaylistDirectory(); if (strProtocol == "musicdb") return new CMusicDatabaseDirectory(); if (strProtocol == "musicsearch") return new CMusicSearchDirectory(); if (strProtocol == "videodb") return new CVideoDatabaseDirectory(); if (strProtocol == "library") return new CLibraryDirectory(); if (strProtocol == "favourites") return new CFavouritesDirectory(); if (strProtocol == "filereader") return CDirectoryFactory::Create(url.GetFileName()); if( g_application.getNetwork().IsAvailable(true) ) // true to wait for the network (if possible) { if (strProtocol == "tuxbox") return new CTuxBoxDirectory(); if (strProtocol == "ftp" || strProtocol == "ftps") return new CFTPDirectory(); if (strProtocol == "http" || strProtocol == "https") return new CHTTPDirectory(); if (strProtocol == "dav" || strProtocol == "davs") return new CDAVDirectory(); #ifdef HAS_FILESYSTEM_SFTP if (strProtocol == "sftp" || strProtocol == "ssh") return new CSFTPDirectory(); #endif #ifdef HAS_FILESYSTEM_SMB #ifdef TARGET_WINDOWS if (strProtocol == "smb") return new CWINSMBDirectory(); #else if (strProtocol == "smb") return new CSMBDirectory(); #endif #endif #ifdef HAS_FILESYSTEM #ifdef HAS_FILESYSTEM_DAAP if (strProtocol == "daap") return new CDAAPDirectory(); #endif #ifdef HAS_FILESYSTEM_RTV if (strProtocol == "rtv") return new CRTVDirectory(); #endif #endif #ifdef HAS_UPNP if (strProtocol == "upnp") return new CUPnPDirectory(); #endif if (strProtocol == "hdhomerun") return new CHomeRunDirectory(); if (strProtocol == "sling") return new CSlingboxDirectory(); if (strProtocol == "myth") return new CMythDirectory(); if (strProtocol == "cmyth") return new CMythDirectory(); if (strProtocol == "rss") return new CRSSDirectory(); #ifdef HAS_FILESYSTEM_SAP if (strProtocol == "sap") return new CSAPDirectory(); #endif #ifdef HAS_FILESYSTEM_VTP if (strProtocol == "vtp") return new CVTPDirectory(); #endif #ifdef HAS_FILESYSTEM_HTSP if (strProtocol == "htsp") return new CHTSPDirectory(); #endif #ifdef HAS_PVRCLIENTS if (strProtocol == "pvr") return new CPVRDirectory(); #endif #ifdef HAS_ZEROCONF if (strProtocol == "zeroconf") return new CZeroconfDirectory(); #endif #ifdef HAS_FILESYSTEM_NFS if (strProtocol == "nfs") return new CNFSDirectory(); #endif #ifdef HAS_FILESYSTEM_AFP if (strProtocol == "afp") return new CAFPDirectory(); #endif #ifdef HAVE_LIBBLURAY if (strProtocol == "bluray") return new CBlurayDirectory(); #endif #if defined(TARGET_ANDROID) if (strProtocol == "androidapp") return new CAndroidAppDirectory(); #endif } CLog::Log(LOGWARNING, "%s - Unsupported protocol(%s) in %s", __FUNCTION__, strProtocol.c_str(), url.Get().c_str() ); return NULL; }
bool CLangInfo::Load(const CStdString& strFileName) { SetDefaults(); CXBMCTinyXML xmlDoc; if (!xmlDoc.LoadFile(strFileName)) { CLog::Log(LOGERROR, "unable to load %s: %s at line %d", strFileName.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow()); return false; } TiXmlElement* pRootElement = xmlDoc.RootElement(); CStdString strValue = pRootElement->Value(); if (strValue != CStdString("language")) { CLog::Log(LOGERROR, "%s Doesn't contain <language>", strFileName.c_str()); return false; } if (pRootElement->Attribute("locale")) m_defaultRegion.m_strLangLocaleName = pRootElement->Attribute("locale"); #ifdef _WIN32 // Windows need 3 chars isolang code if (m_defaultRegion.m_strLangLocaleName.length() == 2) { if (! g_LangCodeExpander.ConvertTwoToThreeCharCode(m_defaultRegion.m_strLangLocaleName, m_defaultRegion.m_strLangLocaleName, true)) m_defaultRegion.m_strLangLocaleName = ""; } if (!g_LangCodeExpander.ConvertWindowsToGeneralCharCode(m_defaultRegion.m_strLangLocaleName, m_languageCodeGeneral)) m_languageCodeGeneral = ""; #else if (m_defaultRegion.m_strLangLocaleName.length() != 3) { if (!g_LangCodeExpander.ConvertToThreeCharCode(m_languageCodeGeneral, m_defaultRegion.m_strLangLocaleName)) m_languageCodeGeneral = ""; } else m_languageCodeGeneral = m_defaultRegion.m_strLangLocaleName; #endif const TiXmlNode *pCharSets = pRootElement->FirstChild("charsets"); if (pCharSets && !pCharSets->NoChildren()) { const TiXmlNode *pGui = pCharSets->FirstChild("gui"); if (pGui && !pGui->NoChildren()) { CStdString strForceUnicodeFont = ((TiXmlElement*) pGui)->Attribute("unicodefont"); if (strForceUnicodeFont.Equals("true")) m_defaultRegion.m_forceUnicodeFont=true; m_defaultRegion.m_strGuiCharSet=pGui->FirstChild()->Value(); } const TiXmlNode *pSubtitle = pCharSets->FirstChild("subtitle"); if (pSubtitle && !pSubtitle->NoChildren()) m_defaultRegion.m_strSubtitleCharSet=pSubtitle->FirstChild()->Value(); } const TiXmlNode *pDVD = pRootElement->FirstChild("dvd"); if (pDVD && !pDVD->NoChildren()) { const TiXmlNode *pMenu = pDVD->FirstChild("menu"); if (pMenu && !pMenu->NoChildren()) m_defaultRegion.m_strDVDMenuLanguage=pMenu->FirstChild()->Value(); const TiXmlNode *pAudio = pDVD->FirstChild("audio"); if (pAudio && !pAudio->NoChildren()) m_defaultRegion.m_strDVDAudioLanguage=pAudio->FirstChild()->Value(); const TiXmlNode *pSubtitle = pDVD->FirstChild("subtitle"); if (pSubtitle && !pSubtitle->NoChildren()) m_defaultRegion.m_strDVDSubtitleLanguage=pSubtitle->FirstChild()->Value(); } const TiXmlNode *pRegions = pRootElement->FirstChild("regions"); if (pRegions && !pRegions->NoChildren()) { const TiXmlElement *pRegion=pRegions->FirstChildElement("region"); while (pRegion) { CRegion region(m_defaultRegion); region.m_strName=pRegion->Attribute("name"); if (region.m_strName.IsEmpty()) region.m_strName="N/A"; if (pRegion->Attribute("locale")) region.m_strRegionLocaleName = pRegion->Attribute("locale"); #ifdef _WIN32 // Windows need 3 chars regions code if (region.m_strRegionLocaleName.length() == 2) { if (! g_LangCodeExpander.ConvertLinuxToWindowsRegionCodes(region.m_strRegionLocaleName, region.m_strRegionLocaleName)) region.m_strRegionLocaleName = ""; } #endif const TiXmlNode *pDateLong=pRegion->FirstChild("datelong"); if (pDateLong && !pDateLong->NoChildren()) region.m_strDateFormatLong=pDateLong->FirstChild()->Value(); const TiXmlNode *pDateShort=pRegion->FirstChild("dateshort"); if (pDateShort && !pDateShort->NoChildren()) region.m_strDateFormatShort=pDateShort->FirstChild()->Value(); const TiXmlElement *pTime=pRegion->FirstChildElement("time"); if (pTime && !pTime->NoChildren()) { region.m_strTimeFormat=pTime->FirstChild()->Value(); region.m_strMeridiemSymbols[MERIDIEM_SYMBOL_AM]=pTime->Attribute("symbolAM"); region.m_strMeridiemSymbols[MERIDIEM_SYMBOL_PM]=pTime->Attribute("symbolPM"); } const TiXmlNode *pTempUnit=pRegion->FirstChild("tempunit"); if (pTempUnit && !pTempUnit->NoChildren()) region.SetTempUnit(pTempUnit->FirstChild()->Value()); const TiXmlNode *pSpeedUnit=pRegion->FirstChild("speedunit"); if (pSpeedUnit && !pSpeedUnit->NoChildren()) region.SetSpeedUnit(pSpeedUnit->FirstChild()->Value()); const TiXmlNode *pTimeZone=pRegion->FirstChild("timezone"); if (pTimeZone && !pTimeZone->NoChildren()) region.SetTimeZone(pTimeZone->FirstChild()->Value()); m_regions.insert(PAIR_REGIONS(region.m_strName, region)); pRegion=pRegion->NextSiblingElement("region"); } const CStdString& strName=CSettings::Get().GetString("locale.country"); SetCurrentRegion(strName); } LoadTokens(pRootElement->FirstChild("sorttokens"),g_advancedSettings.m_vecTokens); return true; }
void CGUIWindowDebugInfo::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetResInfo(), false); g_cpuInfo.getUsedPercentage(); // must call it to recalculate pct values static int yShift = 20; static int xShift = 40; static unsigned int lastShift = time(NULL); time_t now = time(NULL); if (now - lastShift > 10) { yShift *= -1; if (now % 5 == 0) xShift *= -1; lastShift = now; MarkDirtyRegion(); } if (!m_layout) { CGUIFont *font13 = g_fontManager.GetDefaultFont(); CGUIFont *font13border = g_fontManager.GetDefaultFont(true); if (font13) m_layout = new CGUITextLayout(font13, true, 0, font13border); } if (!m_layout) return; CStdString info; if (LOG_LEVEL_DEBUG_FREEMEM <= g_advancedSettings.m_logLevel) { MEMORYSTATUSEX stat; stat.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&stat); CStdString profiling = CGUIControlProfiler::IsRunning() ? " (profiling)" : ""; CStdString strCores = g_cpuInfo.GetCoresUsageString(); #if !defined(_LINUX) info.Format("LOG: %sraven.log\nMEM: %"PRIu64"/%"PRIu64" KB - FPS: %2.1f fps\nCPU: %s%s", g_settings.m_logFolder.c_str(), stat.ullAvailPhys/1024, stat.ullTotalPhys/1024, g_infoManager.GetFPS(), strCores.c_str(), profiling.c_str()); #else double dCPU = m_resourceCounter.GetCPUUsage(); info.Format("LOG: %sraven.log\nMEM: %"PRIu64"/%"PRIu64" KB - FPS: %2.1f fps\nCPU: %s (CPU-XBMC %4.2f%%%s)", g_settings.m_logFolder.c_str(), stat.ullAvailPhys/1024, stat.ullTotalPhys/1024, g_infoManager.GetFPS(), strCores.c_str(), dCPU, profiling.c_str()); #endif } // render the skin debug info if (g_SkinInfo->IsDebugging()) { if (!info.IsEmpty()) info += "\n"; CGUIWindow *window = g_windowManager.GetWindow(g_windowManager.GetFocusedWindow()); CGUIWindow *pointer = g_windowManager.GetWindow(WINDOW_DIALOG_POINTER); CPoint point; if (pointer) point = CPoint(pointer->GetXPosition(), pointer->GetYPosition()); if (window) { CStdString windowName = CButtonTranslator::TranslateWindow(window->GetID()); if (!windowName.IsEmpty()) windowName += " (" + CStdString(window->GetProperty("xmlfile").asString()) + ")"; else windowName = window->GetProperty("xmlfile").asString(); info += "Window: " + windowName + " "; // transform the mouse coordinates to this window's coordinates g_graphicsContext.SetScalingResolution(window->GetCoordsRes(), true); point.x *= g_graphicsContext.GetGUIScaleX(); point.y *= g_graphicsContext.GetGUIScaleY(); g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetResInfo(), false); } info.AppendFormat("Mouse: (%d,%d) ", (int)point.x, (int)point.y); if (window) { CGUIControl *control = window->GetFocusedControl(); if (control) info.AppendFormat("Focused: %i (%s)", control->GetID(), CGUIControlFactory::TranslateControlType(control->GetControlType()).c_str()); } } float w, h; if (m_layout->Update(info)) MarkDirtyRegion(); m_layout->GetTextExtent(w, h); float x = xShift + 0.04f * g_graphicsContext.GetWidth(); float y = yShift + 0.04f * g_graphicsContext.GetHeight(); m_renderRegion.SetRect(x, y, x+w, y+h); }
CStdString CTextureCache::CheckAndCacheImage(const CStdString &url, bool returnDDS) { CStdString path(GetCachedImage(url)); if (!path.IsEmpty()) { if (returnDDS && 0 != strncmp(url.c_str(), "special://skin/", 15)) // TODO: should skin images be .dds'd (currently they're not necessarily writeable) { // check for dds version CStdString ddsPath = CUtil::ReplaceExtension(path, ".dds"); if (CFile::Exists(ddsPath)) return ddsPath; if (g_advancedSettings.m_useDDSFanart) AddJob(new CDDSJob(path)); } return path; } // Uncached image - best we can do for now is cache it so that the texture manager // can load it. // TODO: In the future we need a cache job to callback when the image is loaded // thus automatically updating the images. We'd also need fallback code inside // the CGUITexture class to display something from this point on. // Have this caching stuff be a lifo stack, and bump things up the stack when we should (check whether // CJobQueue does this...) That way we can have a bunch of "cache thumb kthxpls" run from a background // thread, and all we do here is cache from the size we've already been given. If we haven't been // given a size, we must assume that the user wants fullsize. We could, in fact, add the sizing of it // into the URL scheme using options... i.e. http://my.thumb/file|width=blah|height=foo // that gives us sizing goodness, plus pre-caching goodness where we know shit should be cached // all with the fandangled jobmanager.... // We almost need a better interface on the loading side of things - i.e. we need the textures to // request a particular image and to get some (immediate?) recognition as to whether it's cached // so that a fallback image can be specified. Perhaps the texture updating routines (i.e. // UpdateInfo and/or SetFileName) might handle this? The procedure would be to hit the db // to see if this image is available or not. If it isn't, then we simply load the fallback or // "loading..." image, but keep testing to see if the image has been cached or not. Hmm, // that's inefficient as well - at the very least a string compare or 12 per frame as it tests // a list of caching jobs, or (more inefficiently) a db query every frame. // The "best" method is the callback technique - this can be done quite easily though if the texture // is the one that makes the request I think? At least when one texture is involved - we pass in our // pointer to the callback list. In fact, we could generalize this somewhat with the texture // manager handling those pointers - after all, it already handles reference counting, so why not // count using the callback pointers instead? We then wouldn't have to call AllocResources() all // the time. When the texture is loaded it's moved from the queued to the allocated list, and at // that point we could have an interim list (loaded) that we then run the callbacks on once a frame. // There'd be a "LOADING" enum for allocation of the image and the texture could then show a fallback? // Main problem with this is CGUITexture doesn't have any concept of a fallback: CGUIImage does instead. // The main fallback mechanism we use is LISTITEM_ICON vs LISTITEM_THUMB - with the former we actually // use the thumb if it's available, and drop back to the icon if it's not. In either case, having // a "loading" fallback would be useful even if it wasn't the icon. I guess this could be a property // of CGUITexture similar to how background="true" is? The loading texture would be displayed if // and only if there is an image being loaded. Need to talk to Jezz_X about this - eg if you have // a current image and a new one is loading we currently hold on to the current one and render // the current one faded out - we'd need to change this so that the fading only happened once it // was ready to render. CStdString originalFile = GetCacheFile(url); CStdString hash = CCacheJob::CacheImage(url, originalFile); if (!hash.IsEmpty()) { AddCachedTexture(url, originalFile, hash); if (g_advancedSettings.m_useDDSFanart) AddJob(new CDDSJob(GetCachedPath(originalFile))); return GetCachedPath(originalFile); } return ""; }
//------------------------------------------------------------------------------------------------------------------- bool Xcddb::queryCDinfo(CCdInfo* pInfo) { if ( pInfo == NULL ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo pInfo == NULL"); m_lastError = E_PARAMETER_WRONG; return false; } int lead_out = pInfo->GetTrackCount(); int real_track_count = pInfo->GetTrackCount(); unsigned long discid = pInfo->GetCddbDiscId(); unsigned long frames[100]; //########################################################## // if ( queryCache(discid) ) { CLog::Log(LOGDEBUG, "Xcddb::queryCDinfo discid [%08lx] already cached", discid); return true; } //########################################################## // for (int i = 0;i < lead_out;i++) { frames[i] = pInfo->GetTrackInformation( i + 1 ).nFrames; if (i > 0 && frames[i] < frames[i - 1]) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo E_TOC_INCORRECT"); m_lastError = E_TOC_INCORRECT; return false; } } unsigned long complete_length = pInfo->GetDiscLength(); //########################################################## // Open socket to cddb database if ( !openSocket() ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error opening socket"); m_lastError = E_NETWORK_ERROR_OPEN_SOCKET; return false; } CStdString recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //OK, read/write allowed case 201: //OK, read only break; case 432: //No connections allowed: permission denied case 433: //No connections allowed: X users allowed, Y currently active case 434: //No connections allowed: system load too high default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Send the Hello message CStdString strGreeting = "cddb hello xbmc xbmc XBMC/"+g_infoManager.GetLabel(SYSTEM_BUILD_VERSION); if ( ! Send(strGreeting.c_str()) ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", strGreeting.c_str()); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //Handshake successful case 402: //Already shook hands break; case 431: //Handshake not successful, closing connection default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Set CDDB protocol-level to 5 if ( ! Send("proto 5")) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", "proto 5"); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //CDDB protocol level: current cur_level, supported supp_level case 201: //OK, protocol version now: cur_level case 502: //Protocol level already cur_level break; case 501: //Illegal protocol level. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Compose the cddb query string char query_buffer[1024]; strcpy(query_buffer, ""); strcat(query_buffer, "cddb query"); { char tmp_buffer[256]; sprintf(tmp_buffer, " %08lx", discid); strcat(query_buffer, tmp_buffer); } { char tmp_buffer[256]; sprintf(tmp_buffer, " %i", real_track_count); strcat(query_buffer, tmp_buffer); } for (int i = 0;i < lead_out;i++) { char tmp_buffer[256]; sprintf(tmp_buffer, " %lu", frames[i]); strcat(query_buffer, tmp_buffer); } { char tmp_buffer[256]; sprintf(tmp_buffer, " %lu", complete_length); strcat(query_buffer, tmp_buffer); } //########################################################## // Query for matches if ( ! Send(query_buffer)) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", query_buffer); m_lastError = E_NETWORK_ERROR_SEND; return false; } // 200 rock d012180e Soundtrack / Hackers CStdString read_buffer; recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //Found exact match strtok((char *)recv_buffer.c_str(), " "); read_buffer.Format("cddb read %s %08x", strtok(NULL, " "), discid); break; case 210: //Found exact matches, list follows (until terminating marker) case 211: //Found inexact matches, list follows (until terminating marker) /* soundtrack bf0cf90f Modern Talking / Victory - The 11th Album rock c90cf90f Modern Talking / Album: Victory (The 11th Album) misc de0d020f Modern Talking / Ready for the victory rock e00d080f Modern Talking / Album: Victory (The 11th Album) rock c10d150f Modern Talking / Victory (The 11th Album) . */ recv_buffer += Recv(true); addInexactList(recv_buffer.c_str()); m_lastError=E_WAIT_FOR_INPUT; return false; //This is actually good. The calling method will handle this case 202: //No match found CLog::Log(LOGNOTICE, "Xcddb::queryCDinfo No match found in CDDB database when doing the query shown below:\n%s",query_buffer); case 403: //Database entry is corrupt case 409: //No handshake default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Read the data from cddb if ( !Send(read_buffer) ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", read_buffer.c_str()); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(true); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 210: //OK, CDDB database entry follows (until terminating marker) // Cool, I got it ;-) writeCacheFile( recv_buffer.c_str(), discid ); parseData(recv_buffer.c_str()); break; case 401: //Specified CDDB entry not found. case 402: //Server error. case 403: //Database entry is corrupt. case 409: //No handshake. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Quit if ( ! Send("quit") ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", "quit"); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 0: //By some reason, also 0 is a valid value. This is not documented, and might depend on that no string was found and atoi then returns 0 case 230: //Closing connection. Goodbye. break; case 530: //error, closing connection. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Close connection if ( !closeSocket() ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error closing socket"); m_lastError = E_NETWORK_ERROR_SEND; return false; } return true; }
void CURL::SetOptions(const CStdString& strOptions) { m_strOptions.Empty(); if( strOptions.length() > 0) { if( strOptions[0] == '?' || strOptions[0] == '#' || strOptions[0] == ';' || strOptions.Find("xml") >=0 ) { m_strOptions = strOptions; } else CLog::Log(LOGWARNING, "%s - Invalid options specified for url %s", __FUNCTION__, strOptions.c_str()); } }
bool CSmbFile::Open(const CURL& url) { Close(); // we can't open files like smb://file.f or smb://server/file.f // if a file matches the if below return false, it can't exist on a samba share. if (!IsValidFile(url.GetFileName())) { CLog::Log(LOGNOTICE,"FileSmb->Open: Bad URL : '%s'",url.GetFileName().c_str()); return false; } m_url = url; // opening a file to another computer share will create a new session // when opening smb://server xbms will try to find folder.jpg in all shares // listed, which will create lot's of open sessions. CStdString strFileName; m_fd = OpenFile(url, strFileName); CLog::Log(LOGDEBUG,"CSmbFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd); if (m_fd == -1) { // write error to logfile #ifdef TARGET_WINDOWS int nt_error = smb.ConvertUnixToNT(errno); CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error)); #else CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno)); #endif return false; } CSingleLock lock(smb); #ifdef TARGET_WINDOWS struct __stat64 tmpBuffer = {0}; #else struct stat tmpBuffer; #endif if (smbc_stat(strFileName, &tmpBuffer) < 0) { smbc_close(m_fd); m_fd = -1; return false; } m_fileSize = tmpBuffer.st_size; int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET); if ( ret < 0 ) { smbc_close(m_fd); m_fd = -1; return false; } // We've successfully opened the file! return true; }
bool CTagLoaderTagLib::Load(const CStdString& strFileName, CMusicInfoTag& tag, const CStdString& fallbackFileExtension, MUSIC_INFO::EmbeddedArt *art /* = NULL */) { CStdString strExtension = URIUtils::GetExtension(strFileName); strExtension.ToLower(); strExtension.TrimLeft('.'); if (strExtension.IsEmpty()) { strExtension = fallbackFileExtension; if (strExtension.IsEmpty()) return false; strExtension.ToLower(); } TagLibVFSStream* stream = new TagLibVFSStream(strFileName, true); if (!stream) { CLog::Log(LOGERROR, "could not create TagLib VFS stream for: %s", strFileName.c_str()); return false; } ID3v2::Tag::setLatin1StringHandler(&StringHandler); TagLib::File* file = NULL; TagLib::APE::File* apeFile = NULL; TagLib::ASF::File* asfFile = NULL; TagLib::FLAC::File* flacFile = NULL; TagLib::IT::File* itFile = NULL; TagLib::Mod::File* modFile = NULL; TagLib::MP4::File* mp4File = NULL; TagLib::MPC::File* mpcFile = NULL; TagLib::MPEG::File* mpegFile = NULL; TagLib::Ogg::Vorbis::File* oggVorbisFile = NULL; TagLib::Ogg::FLAC::File* oggFlacFile = NULL; TagLib::S3M::File* s3mFile = NULL; TagLib::TrueAudio::File* ttaFile = NULL; TagLib::WavPack::File* wvFile = NULL; TagLib::XM::File* xmFile = NULL; if (strExtension == "ape") file = apeFile = new APE::File(stream); else if (strExtension == "asf" || strExtension == "wmv" || strExtension == "wma") file = asfFile = new ASF::File(stream); else if (strExtension == "flac") file = flacFile = new FLAC::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "it") file = itFile = new IT::File(stream); else if (strExtension == "mod" || strExtension == "module" || strExtension == "nst" || strExtension == "wow") file = modFile = new Mod::File(stream); else if (strExtension == "mp4" || strExtension == "m4a" || strExtension == "m4r" || strExtension == "m4b" || strExtension == "m4p" || strExtension == "3g2") file = mp4File = new MP4::File(stream); else if (strExtension == "mpc") file = mpcFile = new MPC::File(stream); else if (strExtension == "mp3" || strExtension == "aac") file = mpegFile = new MPEG::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "s3m") file = s3mFile = new S3M::File(stream); else if (strExtension == "tta") file = ttaFile = new TrueAudio::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "wv") file = wvFile = new WavPack::File(stream); else if (strExtension == "xm") file = xmFile = new XM::File(stream); else if (strExtension == "ogg") file = oggVorbisFile = new Ogg::Vorbis::File(stream); else if (strExtension == "oga") // Leave this madness until last - oga container can have Vorbis or FLAC { file = oggFlacFile = new Ogg::FLAC::File(stream); if (!file || !file->isValid()) { delete file; oggFlacFile = NULL; file = oggVorbisFile = new Ogg::Vorbis::File(stream); } } if (!file || !file->isOpen()) { delete file; delete stream; CLog::Log(LOGDEBUG, "file could not be opened for tag reading"); return false; } APE::Tag *ape = NULL; ASF::Tag *asf = NULL; MP4::Tag *mp4 = NULL; ID3v1::Tag *id3v1 = NULL; ID3v2::Tag *id3v2 = NULL; Ogg::XiphComment *xiph = NULL; Tag *generic = NULL; if (apeFile) ape = apeFile->APETag(false); else if (asfFile) asf = asfFile->tag(); else if (flacFile) { xiph = flacFile->xiphComment(false); id3v2 = flacFile->ID3v2Tag(false); } else if (mp4File) mp4 = mp4File->tag(); else if (mpegFile) { id3v1 = mpegFile->ID3v1Tag(false); id3v2 = mpegFile->ID3v2Tag(false); ape = mpegFile->APETag(false); } else if (oggFlacFile) xiph = dynamic_cast<Ogg::XiphComment *>(oggFlacFile->tag()); else if (oggVorbisFile) xiph = dynamic_cast<Ogg::XiphComment *>(oggVorbisFile->tag()); else if (ttaFile) id3v2 = ttaFile->ID3v2Tag(false); else if (wvFile) ape = wvFile->APETag(false); else if (mpcFile) ape = mpcFile->APETag(false); else // This is a catch all to get generic information for other files types (s3m, xm, it, mod, etc) generic = file->tag(); if (file->audioProperties()) tag.SetDuration(file->audioProperties()->length()); if (asf) ParseASF(asf, art, tag); if (id3v1) ParseID3v1Tag(id3v1, art, tag); if (id3v2) ParseID3v2Tag(id3v2, art, tag); if (generic) ParseGenericTag(generic, art, tag); if (mp4) ParseMP4Tag(mp4, art, tag); if (xiph) // xiph tags override id3v2 tags in badly tagged FLACs ParseXiphComment(xiph, art, tag); if (ape && (!id3v2 || g_advancedSettings.m_prioritiseAPEv2tags)) // ape tags override id3v2 if we're prioritising them ParseAPETag(ape, art, tag); // art for flac files is outside the tag if (flacFile) SetFlacArt(flacFile, art, tag); if (!tag.GetTitle().IsEmpty() || !tag.GetArtist().empty() || !tag.GetAlbum().IsEmpty()) tag.SetLoaded(); tag.SetURL(strFileName); delete file; delete stream; return true; }