Skip to content

Commit

Permalink
Refs #2320
Browse files Browse the repository at this point in the history
Adds a new 'watched' flag for recordings. It can be manually set or optionally done automatically.

Optionally allow autoexpire to use this new flag to new watched recordings in preference to unwatched ones.

Optionally prevent autoexpired watched recordings from being re-recorded.

Defaults of the new settings maintain current behaviour.

If you are using a custom theme you will need to upgrade it to work with the new icon on the Watched Recordings page. Custom OSDs may break and cause myth to hang, unless updated to include a fifth textarea in the basedialog container.


git-svn-id: http://svn.mythtv.org/svn/trunk@11138 7dbf422c-18fa-0310-86e9-fd20926502f2
  • Loading branch information
stuartm committed Sep 11, 2006
1 parent d8f86a4 commit c3f0c98
Show file tree
Hide file tree
Showing 17 changed files with 238 additions and 19 deletions.
34 changes: 34 additions & 0 deletions mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
Expand Up @@ -3631,6 +3631,36 @@ void NuppelVideoPlayer::AddAudioData(short int *lbuffer, short int *rbuffer,
"Audio buffer overflow, audio data lost!");
}

void NuppelVideoPlayer::SetWatched(bool forceWatched)
{
if (!m_playbackinfo)
return;

int numFrames = totalFrames;

if (m_playbackinfo->GetTranscodedStatus() != TRANSCODING_COMPLETE)
numFrames = (m_playbackinfo->endts.toTime_t() -
m_playbackinfo->recstartts.toTime_t()) * video_frame_rate;

int offset = (int) round(0.2 * (numFrames / video_frame_rate));

if (offset < 300)
offset = 300; // 5 Minutes Min
else if (offset > 720)
offset = 720; // 12 Minutes Max

if (forceWatched || framesPlayed > numFrames - (offset * video_frame_rate))
{
m_playbackinfo->SetWatchedFlag(true);
VERBOSE(VB_GENERAL, QString("Marking recording as watched using offset %1 minutes").arg(offset/60));
}
else
{
m_playbackinfo->SetWatchedFlag(false);
VERBOSE(VB_GENERAL, "Marking recording as unwatched");
}
}

void NuppelVideoPlayer::SetBookmark(void)
{
if (!m_playbackinfo || !osd)
Expand Down Expand Up @@ -6689,6 +6719,10 @@ void NuppelVideoPlayer::SetOSDThemeName(const QString themename)
{
osdtheme = QDeepCopy<QString>(themename);
}

NuppelVideoPlayer SetLiveTVChain( LiveTVChain * tvchain )
{
}
// EIA-708 caption support -- end

/* vim: set expandtab tabstop=4 shiftwidth=4: */
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/NuppelVideoPlayer.h
Expand Up @@ -145,6 +145,7 @@ class NuppelVideoPlayer : public CC608Reader, public CC708Reader

void SetTranscoding(bool value);
void SetWatchingRecording(bool mode);
void SetWatched(bool forceWatched = false);
void SetBookmark(void);
void SetKeyframeDistance(int keyframedistance);
void SetVideoParams(int w, int h, double fps, int keydist,
Expand Down
12 changes: 11 additions & 1 deletion mythtv/libs/libmythtv/dbcheck.cpp
Expand Up @@ -10,7 +10,7 @@ using namespace std;
#include "mythdbcon.h"

/// This is the DB schema version expected by the running MythTV instance.
const QString currentDatabaseVersion = "1158";
const QString currentDatabaseVersion = "1159";

static bool UpdateDBVersionNumber(const QString &newnumber);
static bool performActualUpdate(const QString updates[], QString version,
Expand Down Expand Up @@ -2510,6 +2510,16 @@ static bool doUpgradeTVDatabaseSchema(void)
return false;
}

if (dbver == "1158")
{
const QString updates[] = {
"ALTER TABLE recorded ADD COLUMN watched TINYINT NOT NULL DEFAULT '0';",
""
};

if (!performActualUpdate(updates, "1159", dbver))
return false;
}

//"ALTER TABLE capturecard DROP COLUMN dvb_recordts;" in 0.21
//"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
Expand Down
52 changes: 50 additions & 2 deletions mythtv/libs/libmythtv/programinfo.cpp
Expand Up @@ -1828,6 +1828,30 @@ long long ProgramInfo::GetBookmark(void) const
return pos;
}

/** \fn ProgramInfo::SetWatchedFlag(bool) const
* \brief Set "watched" field in "recorded" table to "watchedFlag".
* \param watchedFlag value to set watched field to.
*/
void ProgramInfo::SetWatchedFlag(bool watchedFlag) const
{
MSqlQuery query(MSqlQuery::InitCon());

query.prepare("UPDATE recorded"
" SET watched = :WATCHEDFLAG"
" WHERE chanid = :CHANID"
" AND starttime = :STARTTIME ;");
query.bindValue(":CHANID", chanid);
query.bindValue(":STARTTIME", recstartts);

if (watchedFlag)
query.bindValue(":WATCHEDFLAG", 1);
else
query.bindValue(":WATCHEDFLAG", 0);

if (!query.exec() || !query.isActive())
MythContext::DBError("Set watched flag", query);
}

/** \fn ProgramInfo::IsEditing(void) const
* \brief Queries "recorded" table for its "editing" field
* and returns true if it is set to true.
Expand Down Expand Up @@ -1970,6 +1994,28 @@ bool ProgramInfo::IsInUse(QString &byWho) const
return false;
}

/** \fn ProgramInfo::GetTranscodedStatus(void) const
* \brief Returns the "transcoded" field in "recorded" table.
*/
int ProgramInfo::GetTranscodedStatus(void) const
{
MSqlQuery query(MSqlQuery::InitCon());

query.prepare("SELECT transcoded FROM recorded"
" WHERE chanid = :CHANID"
" AND starttime = :STARTTIME ;");
query.bindValue(":CHANID", chanid);
query.bindValue(":STARTTIME", recstartts);

if (query.exec() && query.isActive() && query.size() > 0)
{
query.next();
return query.value(0).toInt();
}

return false;
}

/** \fn ProgramInfo::SetTranscoded(int transFlag) const
* \brief Set "transcoded" field in "recorded" table to "transFlag".
* \param transFlag value to set transcoded field to.
Expand Down Expand Up @@ -3533,7 +3579,7 @@ int ProgramInfo::getProgramFlags(void) const
MSqlQuery query(MSqlQuery::InitCon());

query.prepare("SELECT commflagged, cutlist, autoexpire, "
"editing, bookmark, stereo, closecaptioned, hdtv "
"editing, bookmark, stereo, closecaptioned, hdtv, watched "
"FROM recorded LEFT JOIN recordedprogram ON "
"(recorded.chanid = recordedprogram.chanid AND "
"recorded.starttime = recordedprogram.starttime) "
Expand All @@ -3555,6 +3601,7 @@ int ProgramInfo::getProgramFlags(void) const
flags |= (query.value(5).toInt() == 1) ? FL_STEREO : 0;
flags |= (query.value(6).toInt() == 1) ? FL_CC : 0;
flags |= (query.value(7).toInt() == 1) ? FL_HDTV : 0;
flags |= (query.value(8).toInt() == 1) ? FL_WATCHED : 0;
}

return flags;
Expand Down Expand Up @@ -4201,7 +4248,7 @@ bool ProgramList::FromRecorded( bool bDescending, ProgramList *pSchedList )
"recorded.basename, recorded.progstart, "
"recorded.progend, recorded.stars, "
"recordedprogram.stereo, recordedprogram.hdtv, "
"recordedprogram.closecaptioned "
"recordedprogram.closecaptioned, recorded.watched "
"FROM recorded "
"LEFT JOIN record ON recorded.recordid = record.recordid "
"LEFT JOIN channel ON recorded.chanid = channel.chanid "
Expand Down Expand Up @@ -4294,6 +4341,7 @@ bool ProgramList::FromRecorded( bool bDescending, ProgramList *pSchedList )
flags |= (query.value(32).toInt() == 1) ? FL_STEREO : 0;
flags |= (query.value(34).toInt() == 1) ? FL_CC : 0;
flags |= (query.value(33).toInt() == 1) ? FL_HDTV : 0;
flags |= (query.value(35).toInt() == 1) ? FL_WATCHED : 0;

inUseKey = query.value(0).toString() + " " +
query.value(1).toDateTime().toString(Qt::ISODate);
Expand Down
5 changes: 4 additions & 1 deletion mythtv/libs/libmythtv/programinfo.h
Expand Up @@ -55,7 +55,8 @@ enum FlagMask {
FL_STEREO = 0x080,
FL_CC = 0x100,
FL_HDTV = 0x200,
FL_TRANSCODED = 0x400
FL_TRANSCODED = 0x400,
FL_WATCHED = 0x800
};

enum RecStatusType {
Expand Down Expand Up @@ -183,6 +184,7 @@ class ProgramInfo
bool IsCommFlagged(void) const;
bool IsInUse(QString &byWho) const;
int GetAutoExpireFromRecorded(void) const;
int GetTranscodedStatus(void) const;
bool GetPreserveEpisodeFromRecorded(void) const;
bool UsesMaxEpisodes(void) const;
int getProgramFlags(void) const;
Expand All @@ -195,6 +197,7 @@ class ProgramInfo
void SetBookmark(long long pos) const;
void SetEditing(bool edit) const;
void SetTranscoded(int transFlag) const;
void SetWatchedFlag(bool watchedFlag) const;
void SetDeleteFlag(bool deleteFlag) const;
void SetCommFlagged(int flag) const; // 1 = flagged, 2 = processing
void SetAutoExpire(int autoExpire) const;
Expand Down
14 changes: 11 additions & 3 deletions mythtv/libs/libmythtv/tv_play.cpp
Expand Up @@ -1216,7 +1216,7 @@ void TV::StopStuff(bool stopRingBuffers, bool stopPlayers, bool stopRecorders)
{
VERBOSE(VB_PLAYBACK,LOC + " StopStuff() -- get dvd player out of still frame or wait status");
prbuffer->DVD()->IgnoreStillOrWait(true);
}
}

if (stopRingBuffers)
{
Expand Down Expand Up @@ -2116,11 +2116,16 @@ void TV::ProcessKeypress(QKeyEvent *e)
wantsToQuit = true;
exitPlayer = true;
break;
case 3: case 0:
case 3:
nvp->SetWatched(true);
wantsToQuit = true;
exitPlayer = true;
break;
case 4: case 0:
paused = !paused;
DoPause();
break;
case 4:
case 5:
wantsToQuit = true;
exitPlayer = true;
requestDelete = true;
Expand Down Expand Up @@ -2486,6 +2491,7 @@ void TV::ProcessKeypress(QKeyEvent *e)
QStringList options;
options += tr("Save this position and go to the menu");
options += tr("Do not save, just exit to the menu");
options += tr("Mark as watched and go to the menu");
options += tr("Keep watching");
options += tr("Delete this recording");

Expand Down Expand Up @@ -2520,6 +2526,8 @@ void TV::ProcessKeypress(QKeyEvent *e)
{
if (nvp && gContext->GetNumSetting("PlaybackExitPrompt") == 2)
nvp->SetBookmark();
if (nvp && gContext->GetNumSetting("AutomaticSetWatched", 0))
nvp->SetWatched();
exitPlayer = true;
wantsToQuit = true;
}
Expand Down
12 changes: 9 additions & 3 deletions mythtv/programs/mythbackend/autoexpire.cpp
Expand Up @@ -762,15 +762,21 @@ void AutoExpire::FillDBOrdered(int expMethod, bool allHosts)
default:
case emOldestFirst:
where = "autoexpire > 0";
orderby = "starttime ASC";
if (gContext->GetNumSetting("AutoExpireWatchedPriority", 0))
orderby = "recorded.watched DESC, ";
orderby += "starttime ASC";
break;
case emLowestPriorityFirst:
where = "autoexpire > 0";
orderby = "recorded.recpriority ASC, starttime ASC";
if (gContext->GetNumSetting("AutoExpireWatchedPriority", 0))
orderby = "recorded.watched DESC, ";
orderby += "recorded.recpriority ASC, starttime ASC";
break;
case emWeightedTimePriority:
where = "autoexpire > 0";
orderby = QString("DATE_ADD(starttime, INTERVAL '%1' * "
if (gContext->GetNumSetting("AutoExpireWatchedPriority", 0))
orderby = "recorded.watched DESC, ";
orderby += QString("DATE_ADD(starttime, INTERVAL '%1' * "
"recorded.recpriority DAY) ASC")
.arg(gContext->GetNumSetting("AutoExpireDayPriority", 3));
break;
Expand Down
8 changes: 6 additions & 2 deletions mythtv/programs/mythbackend/mainserver.cpp
Expand Up @@ -661,8 +661,11 @@ void MainServer::customEvent(QCustomEvent *e)
if (pinfo)
{
// allow re-record if auto expired but not expired live buffers
if (pinfo->recgroup != "LiveTV")
if (pinfo->recgroup != "LiveTV" &&
(gContext->GetNumSetting("RerecordWatched", 0) ||
(!pinfo->getProgramFlags() & FL_WATCHED)))
pinfo->ForgetHistory();

DoHandleDeleteRecording(pinfo, NULL, false);
}
else
Expand Down Expand Up @@ -1028,7 +1031,7 @@ void MainServer::HandleQueryRecordings(QString type, PlaybackSock *pbs)
"recorded.progend, recorded.stars, "
"recordedprogram.stereo, recordedprogram.hdtv, "
"recordedprogram.closecaptioned, transcoded, "
"recorded.recpriority "
"recorded.recpriority, watched "
"FROM recorded "
"LEFT JOIN record ON recorded.recordid = record.recordid "
"LEFT JOIN channel ON recorded.chanid = channel.chanid "
Expand Down Expand Up @@ -1132,6 +1135,7 @@ void MainServer::HandleQueryRecordings(QString type, PlaybackSock *pbs)
flags |= (query.value(34).toInt() == 1) ? FL_CC : 0;
flags |= (query.value(35).toInt() == TRANSCODING_COMPLETE) ?
FL_TRANSCODED : 0;
flags |= (query.value(37).toInt() == 1) ? FL_WATCHED : 0;

inUseKey = query.value(0).toString() + " " +
query.value(1).toDateTime().toString(Qt::ISODate);
Expand Down
37 changes: 37 additions & 0 deletions mythtv/programs/mythfrontend/globalsettings.cpp
Expand Up @@ -570,6 +570,16 @@ static GlobalComboBox *AutoExpireMethod()
return bc;
}

static GlobalCheckBox *AutoExpireWatchedPriority()
{
GlobalCheckBox *bc = new GlobalCheckBox("AutoExpireWatchedPriority");
bc->setLabel(QObject::tr("Auto Expire watched programs before unwatched"));
bc->setValue(false);
bc->setHelpText(QObject::tr("If set, programs that have been marked as "
"watched will be expired first"));
return bc;
}

static GlobalSpinBox *AutoExpireDayPriority()
{
GlobalSpinBox *bs = new GlobalSpinBox("AutoExpireDayPriority", 1, 400, 1);
Expand Down Expand Up @@ -620,6 +630,17 @@ static GlobalSpinBox *MinRecordDiskThreshold()
}
#endif

static GlobalCheckBox *RerecordWatched()
{
GlobalCheckBox *bc = new GlobalCheckBox("RerecordWatched");
bc->setLabel(QObject::tr("Re-record watched programs"));
bc->setValue(true);
bc->setHelpText(QObject::tr("If set, programs that have been marked as "
"watched and are auto-expired will be re-recorded if "
"they are shown again."));
return bc;
}

static GlobalSpinBox *RecordPreRoll()
{
GlobalSpinBox *bs = new GlobalSpinBox("RecordPreRoll", 0, 600, 60, true);
Expand Down Expand Up @@ -1226,6 +1247,19 @@ static HostCheckBox *EndOfRecordingExitPrompt()
return gc;
}

static HostCheckBox *AutomaticSetWatched()
{
HostCheckBox *gc = new HostCheckBox("AutomaticSetWatched");
gc->setLabel(QObject::tr("Automatically mark a record watched"));
gc->setValue(false);
gc->setHelpText(QObject::tr("If set, when you exit near the end of a "
"recording it will be marked as watched. The automatic "
"detection is not foolproof, so do not enable this "
"setting if you don't want an unwatched recording marked "
"as watched."));
return gc;
}

static HostCheckBox *GeneratePreviewPixmaps()
{
HostCheckBox *gc = new HostCheckBox("GeneratePreviewPixmaps");
Expand Down Expand Up @@ -3416,6 +3450,7 @@ PlaybackSettings::PlaybackSettings()
gen2->setLabel(QObject::tr("General playback (part 2)"));
gen2->addChild(PlaybackExitPrompt());
gen2->addChild(EndOfRecordingExitPrompt());
gen2->addChild(AutomaticSetWatched());
gen2->addChild(ClearSavedPosition());
gen2->addChild(AltClearSavedPosition());
#ifdef USING_XV
Expand Down Expand Up @@ -3540,9 +3575,11 @@ GeneralSettings::GeneralSettings()
VerticalConfigurationGroup* autoexp = new VerticalConfigurationGroup(false);
autoexp->setLabel(QObject::tr("General (AutoExpire)"));
autoexp->addChild(AutoExpireMethod());
autoexp->addChild(AutoExpireWatchedPriority());
autoexp->addChild(AutoExpireDayPriority());
autoexp->addChild(AutoExpireDefault());
autoexp->addChild(AutoExpireLiveTVMaxAge());
autoexp->addChild(RerecordWatched());
autoexp->addChild(AutoExpireExtraSpace());
addChild(autoexp);

Expand Down

0 comments on commit c3f0c98

Please sign in to comment.