void PreviewGeneratorQueue::GetPreviewImage( const ProgramInfo &pginfo, const QSize &outputsize, const QString &outputfile, long long time, bool in_seconds, QString token) { if (!s_pgq) return; if (pginfo.GetPathname().isEmpty() || pginfo.GetBasename() == pginfo.GetPathname()) { return; } QStringList extra; pginfo.ToStringList(extra); extra += token; extra += QString::number(outputsize.width()); extra += QString::number(outputsize.height()); extra += outputfile; extra += QString::number(time); extra += (in_seconds ? "1" : "0"); MythEvent *e = new MythEvent("GET_PREVIEW", extra); QCoreApplication::postEvent(s_pgq, e); }
ProgramInfo *LiveTVChain::EntryToProgram(const LiveTVChainEntry &entry) { ProgramInfo *pginfo = new ProgramInfo(entry.chanid, entry.starttime); if (pginfo->GetChanID()) { pginfo->SetPathname(entry.hostprefix + pginfo->GetBasename()); return pginfo; } LOG(VB_GENERAL, LOG_ERR, QString("EntryToProgram(%1@%2) failed to get pginfo") .arg(entry.chanid).arg(entry.starttime.toString())); delete pginfo; return NULL; }
QString PreviewGeneratorQueue::GeneratePreviewImage( ProgramInfo &pginfo, const QSize &size, const QString &outputfile, long long time, bool in_seconds, QString token) { QString key = QString("%1_%2x%3_%4%5") .arg(pginfo.GetBasename()).arg(size.width()).arg(size.height()) .arg(time).arg(in_seconds?"s":"f"); if (pginfo.GetAvailableStatus() == asPendingDelete) { SendEvent(pginfo, "PREVIEW_FAILED", key, token, "Pending Delete", QDateTime()); return QString(); } QString filename = (outputfile.isEmpty()) ? pginfo.GetPathname() + ".png" : outputfile; QString ret_file = filename; QString ret; bool is_special = !outputfile.isEmpty() || time >= 0 || size.width() || size.height(); bool needs_gen = true; if (!is_special) { QDateTime previewLastModified; bool streaming = filename.left(1) != "/"; bool locally_accessible = false; bool bookmark_updated = false; QDateTime bookmark_ts = pginfo.QueryBookmarkTimeStamp(); QDateTime cmp_ts; if (bookmark_ts.isValid()) cmp_ts = bookmark_ts; else if (MythDate::current() >= pginfo.GetRecordingEndTime()) cmp_ts = pginfo.GetLastModifiedTime(); else cmp_ts = pginfo.GetRecordingStartTime(); if (streaming) { ret_file = QString("%1/remotecache/%2") .arg(GetConfDir()).arg(filename.section('/', -1)); QFileInfo finfo(ret_file); if (finfo.isReadable() && finfo.lastModified() >= cmp_ts) { // This is just an optimization to avoid // hitting the backend if our cached copy // is newer than the bookmark, or if we have // a preview and do not update it when the // bookmark changes. previewLastModified = finfo.lastModified(); } else if (!IsGeneratingPreview(key)) { previewLastModified = RemoteGetPreviewIfModified(pginfo, ret_file); } } else { QFileInfo fi(filename); if ((locally_accessible = fi.isReadable())) previewLastModified = fi.lastModified(); } bookmark_updated = (!previewLastModified.isValid() || (previewLastModified <= cmp_ts)); if (bookmark_updated && bookmark_ts.isValid() && previewLastModified.isValid()) { ClearPreviewGeneratorAttempts(key); } bool preview_exists = previewLastModified.isValid(); if (0) { QString alttext = (bookmark_ts.isValid()) ? QString() : QString("\n\t\t\tcmp_ts: %1") .arg(cmp_ts.toString(Qt::ISODate)); LOG(VB_GENERAL, LOG_INFO, QString("previewLastModified: %1\n\t\t\t" "bookmark_ts: %2%3\n\t\t\t" "pginfo.lastmodified: %4") .arg(previewLastModified.toString(Qt::ISODate)) .arg(bookmark_ts.toString(Qt::ISODate)) .arg(alttext) .arg(pginfo.GetLastModifiedTime(MythDate::ISODate)) + QString("Title: %1\n\t\t\t") .arg(pginfo.toString(ProgramInfo::kTitleSubtitle)) + QString("File '%1' \n\t\t\tCache '%2'") .arg(filename).arg(ret_file) + QString("\n\t\t\tPreview Exists: %1, Bookmark Updated: %2, " "Need Preview: %3") .arg(preview_exists).arg(bookmark_updated) .arg((bookmark_updated || !preview_exists))); } needs_gen = bookmark_updated || !preview_exists; if (!needs_gen) { if (locally_accessible) ret = filename; else if (preview_exists && QFileInfo(ret_file).isReadable()) ret = ret_file; } } if (needs_gen && !IsGeneratingPreview(key)) { uint attempts = IncPreviewGeneratorAttempts(key); if (attempts < m_maxAttempts) { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Requesting preview for '%1'") .arg(key)); PreviewGenerator *pg = new PreviewGenerator(&pginfo, token, m_mode); if (!outputfile.isEmpty() || time >= 0 || size.width() || size.height()) { pg->SetPreviewTime(time, in_seconds); pg->SetOutputFilename(outputfile); pg->SetOutputSize(size); } SetPreviewGenerator(key, pg); LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Requested preview for '%1'").arg(key)); } else if (attempts >= m_maxAttempts) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Attempted to generate preview for '%1' " "%2 times; >= max(%3)") .arg(key).arg(attempts).arg(m_maxAttempts)); } } else if (needs_gen) { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Not requesting preview for %1," "as it is already being generated") .arg(pginfo.toString(ProgramInfo::kTitleSubtitle))); IncPreviewGeneratorPriority(key, token); } UpdatePreviewGeneratorThreads(); if (!ret.isEmpty()) { QString msg = "On Disk"; QDateTime dt = QFileInfo(ret).lastModified(); SendEvent(pginfo, "PREVIEW_SUCCESS", ret, token, msg, dt); } else { uint queue_depth, token_cnt; GetInfo(key, queue_depth, token_cnt); QString msg = QString("Queue depth %1, our tokens %2") .arg(queue_depth).arg(token_cnt); SendEvent(pginfo, "PREVIEW_QUEUED", ret, token, msg, QDateTime()); } return ret; }