Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixes #10872. Use desired start and end times.

The recording quality measurement needs to know when a recording was
supposed to start and end to know how much is actually missing from
the recording. We used to use the scheduled start and end times for
this, but sometimes a recording is intentionally started late or ended
early. This captures that by tracking the 'desired' start and end point.
This is initially set by the scheduler using and pre and post roll
values, and if the user intentionally stops a recording early that
updates the desired end time as well.

Conflicts:

	mythtv/libs/libmythtv/dtvrecorder.h
  • Loading branch information...
commit ecc1525d83abfed452e3b5f983de7c593063af91 1 parent e8073bc
@daniel-kristjansson daniel-kristjansson authored
View
6 mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
@@ -2806,8 +2806,8 @@ void NuppelVideoRecorder::doWriteThread(void)
}
}
-void NuppelVideoRecorder::SetNextRecording(const ProgramInfo *progInf,
- RingBuffer *rb)
+void NuppelVideoRecorder::SetNextRecording(
+ const RecordingInfo *progInf, RingBuffer *rb)
{
// First we do some of the time consuming stuff we can do now
SavePositionMap(true);
@@ -2819,7 +2819,7 @@ void NuppelVideoRecorder::SetNextRecording(const ProgramInfo *progInf,
QMutexLocker locker(&nextRingBufferLock);
nextRecording = NULL;
if (progInf)
- nextRecording = new ProgramInfo(*progInf);
+ nextRecording = new RecordingInfo(*progInf);
nextRingBuffer = rb;
}
View
2  mythtv/libs/libmythtv/NuppelVideoRecorder.h
@@ -101,7 +101,7 @@ class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input
void SetVideoFilters(QString &filters);
void SetTranscoding(bool value) { transcoding = value; };
- void SetNextRecording(const ProgramInfo*, RingBuffer*);
+ void SetNextRecording(const RecordingInfo*, RingBuffer*);
void ResetForNewFile(void);
void FinishRecording(void);
void StartNewFile(void);
View
4 mythtv/libs/libmythtv/dtvrecorder.cpp
@@ -688,7 +688,7 @@ bool DTVRecorder::FindOtherKeyframes(const TSPacket *tspacket)
}
// documented in recorderbase.h
-void DTVRecorder::SetNextRecording(const ProgramInfo *progInf, RingBuffer *rb)
+void DTVRecorder::SetNextRecording(const RecordingInfo *progInf, RingBuffer *rb)
{
LOG(VB_RECORD, LOG_INFO, LOC + QString("SetNextRecord(0x%1, 0x%2)")
.arg((uint64_t)progInf,0,16).arg((uint64_t)rb,0,16));
@@ -706,7 +706,7 @@ void DTVRecorder::SetNextRecording(const ProgramInfo *progInf, RingBuffer *rb)
nextRecording = NULL;
if (progInf)
- nextRecording = new ProgramInfo(*progInf);
+ nextRecording = new RecordingInfo(*progInf);
nextRingBuffer = rb;
nextRingBufferLock.unlock();
View
2  mythtv/libs/libmythtv/dtvrecorder.h
@@ -50,7 +50,7 @@ class DTVRecorder :
void Initialize(void) {;}
int GetVideoFd(void) { return _stream_fd; }
- virtual void SetNextRecording(const ProgramInfo*, RingBuffer*);
+ virtual void SetNextRecording(const RecordingInfo*, RingBuffer*);
virtual void SetStreamData(void);
void SetStreamData(MPEGStreamData* sd);
MPEGStreamData *GetStreamData(void) const { return _stream_data; }
View
4 mythtv/libs/libmythtv/recorderbase.cpp
@@ -82,7 +82,7 @@ void RecorderBase::SetRingBuffer(RingBuffer *rbuf)
weMadeBuffer = false;
}
-void RecorderBase::SetRecording(const ProgramInfo *pginfo)
+void RecorderBase::SetRecording(const RecordingInfo *pginfo)
{
if (pginfo)
LOG(VB_RECORD, LOG_INFO, LOC + QString("SetRecording(0x%1) title(%2)")
@@ -92,7 +92,7 @@ void RecorderBase::SetRecording(const ProgramInfo *pginfo)
ProgramInfo *oldrec = curRecording;
if (pginfo)
- curRecording = new ProgramInfo(*pginfo);
+ curRecording = new RecordingInfo(*pginfo);
else
curRecording = NULL;
View
10 mythtv/libs/libmythtv/recorderbase.h
@@ -20,10 +20,10 @@
class FireWireDBOptions;
class GeneralDBOptions;
class RecordingProfile;
+class RecordingInfo;
class DVBDBOptions;
class RecorderBase;
class ChannelBase;
-class ProgramInfo;
class RingBuffer;
class TVRec;
@@ -63,7 +63,7 @@ class MTV_PUBLIC RecorderBase : public QRunnable
*
* \sa ChannelNameChanged(const QString&)
*/
- void SetRecording(const ProgramInfo *pginfo);
+ void SetRecording(const RecordingInfo *pginfo);
/** \brief Tells recorder to use an externally created ringbuffer.
*
@@ -116,7 +116,7 @@ class MTV_PUBLIC RecorderBase : public QRunnable
*
* This calls TVRec::RingBufferChanged() when the switch happens.
*/
- virtual void SetNextRecording(const ProgramInfo*, RingBuffer*) = 0;
+ virtual void SetNextRecording(const RecordingInfo*, RingBuffer*) = 0;
/** \brief This is called between SetOptionsFromProfile() and
* run() to initialize any devices, etc.
@@ -276,7 +276,7 @@ class MTV_PUBLIC RecorderBase : public QRunnable
uint m_videoWidth;
double m_frameRate;
- ProgramInfo *curRecording;
+ RecordingInfo *curRecording;
// For handling pausing + stop recording
mutable QMutex pauseLock; // also used for request_recording and recording
@@ -294,7 +294,7 @@ class MTV_PUBLIC RecorderBase : public QRunnable
// For RingBuffer switching
QMutex nextRingBufferLock;
RingBuffer *nextRingBuffer;
- ProgramInfo *nextRecording;
+ RecordingInfo *nextRecording;
// Seektable support
MarkTypes positionMapType;
View
10 mythtv/libs/libmythtv/recordinginfo.cpp
@@ -110,6 +110,8 @@ RecordingInfo::RecordingInfo(
oldrecstatus(_oldrecstatus),
savedrecstatus(rsUnknown),
future(_future),
+ desiredrecstartts(_recstartts),
+ desiredrecendts(_recendts),
record(NULL)
{
hostname = _hostname;
@@ -203,6 +205,8 @@ RecordingInfo::RecordingInfo(
oldrecstatus(rsUnknown),
savedrecstatus(rsUnknown),
future(false),
+ desiredrecstartts(_recstartts),
+ desiredrecendts(_recendts),
record(NULL)
{
recpriority = _recpriority;
@@ -379,6 +383,8 @@ void RecordingInfo::clone(const RecordingInfo &other,
oldrecstatus = other.oldrecstatus;
savedrecstatus = other.savedrecstatus;
future = other.future;
+ desiredrecstartts = other.desiredrecstartts;
+ desiredrecendts = other.desiredrecendts;
}
}
@@ -403,6 +409,8 @@ void RecordingInfo::clone(const ProgramInfo &other,
oldrecstatus = rsUnknown;
savedrecstatus = rsUnknown;
future = false;
+ desiredrecstartts = QDateTime();
+ desiredrecendts = QDateTime();
}
void RecordingInfo::clear(void)
@@ -415,6 +423,8 @@ void RecordingInfo::clear(void)
oldrecstatus = rsUnknown;
savedrecstatus = rsUnknown;
future = false;
+ desiredrecstartts = QDateTime();
+ desiredrecendts = QDateTime();
}
View
11 mythtv/libs/libmythtv/recordinginfo.h
@@ -1,6 +1,9 @@
#ifndef _RECORDING_INFO_H_
#define _RECORDING_INFO_H_
+#include <QDateTime>
+#include <QString>
+
#include "mythtvexp.h"
#include "programinfo.h"
@@ -206,6 +209,12 @@ class MTV_PUBLIC RecordingInfo : public ProgramInfo
void ApplyRecordRecPriorityChange(int);
void ToggleRecord(void);
+ // Used in determining start and end for RecordingQuality determination
+ void SetDesiredStartTime(const QDateTime &dt) { desiredrecstartts = dt; }
+ void SetDesiredEndTime(const QDateTime &dt) { desiredrecendts = dt; }
+ QDateTime GetDesiredStartTime(void) const { return desiredrecstartts; }
+ QDateTime GetDesiredEndTime(void) const { return desiredrecendts; }
+
// these five can be moved to programinfo
void AddHistory(bool resched = true, bool forcedup = false,
bool future = false);//pi
@@ -231,6 +240,8 @@ class MTV_PUBLIC RecordingInfo : public ProgramInfo
RecStatusType oldrecstatus;
RecStatusType savedrecstatus;
bool future;
+ QDateTime desiredrecstartts;
+ QDateTime desiredrecendts;
private:
mutable class RecordingRule *record;
View
55 mythtv/libs/libmythtv/recordingquality.cpp
@@ -3,26 +3,28 @@ using namespace std;
#include "recordingquality.h"
#include "mythcorecontext.h"
+#include "recordinginfo.h"
#include "mythmiscutil.h"
#include "mythlogging.h"
-#include "programinfo.h"
static void merge_overlapping(RecordingGaps &gaps);
-static double score_gaps(const ProgramInfo*, const RecordingGaps&);
+static double score_gaps(const RecordingInfo&, const RecordingGaps&);
+static QDateTime get_start(const RecordingInfo&);
+static QDateTime get_end(const RecordingInfo&);
RecordingQuality::RecordingQuality(
- const ProgramInfo *pi, const RecordingGaps &rg,
+ const RecordingInfo *ri, const RecordingGaps &rg,
const QDateTime &first, const QDateTime &latest) :
m_continuity_error_count(0), m_packet_count(0),
m_overall_score(1.0), m_recording_gaps(rg)
{
- if (!pi)
+ if (!ri)
return;
- m_program_key = pi->MakeUniqueKey();
+ m_program_key = ri->MakeUniqueKey();
// trim start
- QDateTime start = pi->GetScheduledStartTime();
+ QDateTime start = get_start(*ri);
while (!m_recording_gaps.empty() &&
m_recording_gaps.first().GetStart() < start)
{
@@ -34,7 +36,7 @@ RecordingQuality::RecordingQuality(
}
// trim end
- QDateTime end = pi->GetScheduledEndTime();
+ QDateTime end = get_end(*ri);
while (!m_recording_gaps.empty() &&
m_recording_gaps.back().GetEnd() > end)
{
@@ -58,7 +60,13 @@ RecordingQuality::RecordingQuality(
stable_sort(m_recording_gaps.begin(), m_recording_gaps.end());
merge_overlapping(m_recording_gaps);
- m_overall_score = score_gaps(pi, m_recording_gaps);
+ m_overall_score = score_gaps(*ri, m_recording_gaps);
+
+ LOG(VB_RECORD, LOG_INFO,
+ QString("RecordingQuality() start(%1) end(%2) score(%3)")
+ .arg(MythDate::toString(start, MythDate::ISODate))
+ .arg(MythDate::toString(end, MythDate::ISODate))
+ .arg(m_overall_score));
}
void RecordingQuality::AddTSStatistics(
@@ -137,15 +145,15 @@ static void merge_overlapping(RecordingGaps &gaps)
}
}
-static double score_gaps(const ProgramInfo *pi, const RecordingGaps &gaps)
+static double score_gaps(const RecordingInfo &ri, const RecordingGaps &gaps)
{
RecordingGaps::const_iterator it = gaps.begin();
if (it == gaps.end())
return 1.0;
- QDateTime start = pi->GetScheduledStartTime();
+ QDateTime start = get_start(ri);
- double program_length = start.secsTo(pi->GetScheduledEndTime());
+ double program_length = start.secsTo(get_end(ri));
if (program_length < 1.0)
return 0.0;
@@ -190,3 +198,28 @@ static double score_gaps(const ProgramInfo *pi, const RecordingGaps &gaps)
return (score > 0.0) ? score : 0.0;
}
+static QDateTime get_start(const RecordingInfo &ri)
+{
+ if (ri.GetDesiredStartTime().isValid())
+ {
+ return (ri.GetScheduledStartTime() > ri.GetDesiredStartTime()) ?
+ ri.GetScheduledStartTime() : ri.GetDesiredStartTime();
+ }
+ else
+ {
+ return ri.GetScheduledStartTime();
+ }
+}
+
+static QDateTime get_end(const RecordingInfo &ri)
+{
+ if (ri.GetDesiredEndTime().isValid())
+ {
+ return (ri.GetScheduledEndTime() < ri.GetDesiredEndTime()) ?
+ ri.GetScheduledEndTime() : ri.GetDesiredEndTime();
+ }
+ else
+ {
+ return ri.GetScheduledEndTime();
+ }
+}
View
4 mythtv/libs/libmythtv/recordingquality.h
@@ -7,7 +7,7 @@
#include "mythtvexp.h"
-class ProgramInfo;
+class RecordingInfo;
class RecordingGap
{
@@ -33,7 +33,7 @@ class MTV_PUBLIC RecordingQuality
{
public:
RecordingQuality(
- const ProgramInfo*, const RecordingGaps&,
+ const RecordingInfo*, const RecordingGaps&,
const QDateTime &firstData, const QDateTime &latestData);
void AddTSStatistics(int continuity_error_count, int packet_count);
View
7 mythtv/libs/libmythtv/tv_rec.cpp
@@ -693,6 +693,8 @@ void TVRec::SetRecordingStatus(
/** \fn TVRec::StopRecording(bool killFile)
* \brief Changes from a recording state to kState_None.
+ * \note For the sake of recording quality measurements this is
+ * treated as the desired end point of the recording.
* \sa StartRecording(const ProgramInfo *rec), FinishRecording()
*/
void TVRec::StopRecording(bool killFile)
@@ -702,6 +704,8 @@ void TVRec::StopRecording(bool killFile)
QMutexLocker lock(&stateChangeLock);
if (killFile)
SetFlags(kFlagKillRec);
+ else if (curRecording)
+ curRecording->SetDesiredEndTime(MythDate::current(true));
ChangeState(RemoveRecording(GetState()));
// wait for state change to take effect
WaitForEventThreadSleep();
@@ -4170,8 +4174,9 @@ void TVRec::TuningRestartRecorder(void)
{
recorder->SetRingBuffer(ringBuffer);
ProgramInfo *progInfo = tvchain->GetProgramAt(-1);
- recorder->SetRecording(progInfo);
+ RecordingInfo recinfo(*progInfo);
delete progInfo;
+ recorder->SetRecording(&recinfo);
}
recorder->Reset();
Please sign in to comment.
Something went wrong with that request. Please try again.