Skip to content

Commit

Permalink
Store calculated duration in the db
Browse files Browse the repository at this point in the history
At recording end, a value of recendts - recstartts (converted to ms) is stored
in the recordedmarkup table.  At the end of commflag or a seektable rebuild,
the accurate number of ms (as determined by adding frame times during playback)
will overwrite this value.

On playback, this value is checked first.  If the value is in the database, it
is used for the duration in the OSD.  If it is not there, then the duration
from ffmpeg will be used instead.

To get this working, it was necessary to reset the calculated duration after
the logo scan in commflagging, otherwise the end result was incorrect.
  • Loading branch information
Beirdo committed Feb 12, 2011
1 parent 46e694c commit 5366399
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 2 deletions.
43 changes: 43 additions & 0 deletions mythtv/libs/libmyth/programinfo.cpp
Expand Up @@ -3327,6 +3327,39 @@ void ProgramInfo::SaveFrameRate(uint64_t frame, uint framerate)
}


/// \brief Store the Total Duration at frame 0 in the recordedmarkup table
void ProgramInfo::SaveTotalDuration(int64_t duration)
{
if (!IsRecording())
return;

MSqlQuery query(MSqlQuery::InitCon());

query.prepare("DELETE FROM recordedmarkup "
" WHERE chanid=:CHANID "
" AND starttime=:STARTTIME "
" AND type=:TYPE");
query.bindValue(":CHANID", chanid);
query.bindValue(":STARTTIME", recstartts);
query.bindValue(":TYPE", MARK_DURATION_MS);

if (!query.exec())
MythDB::DBError("Duration delete", query);

query.prepare("INSERT INTO recordedmarkup"
" (chanid, starttime, mark, type, data)"
" VALUES"
" ( :CHANID, :STARTTIME, 0, :TYPE, :DATA);");
query.bindValue(":CHANID", chanid);
query.bindValue(":STARTTIME", recstartts);
query.bindValue(":TYPE", MARK_DURATION_MS);
query.bindValue(":DATA", (uint)(duration / 1000));

if (!query.exec())
MythDB::DBError("Duration insert", query);
}


/// \brief Store the Resolution at frame in the recordedmarkup table
/// \note All frames until the next one with a stored resolution
/// are assumed to have the same resolution
Expand Down Expand Up @@ -3426,6 +3459,16 @@ uint ProgramInfo::QueryAverageFrameRate(void) const
return load_markup_datum(MARK_VIDEO_RATE, chanid, recstartts);
}

/** \brief If present in recording this loads total duration of the
* main video stream from database's stream markup table.
*/
int64_t ProgramInfo::QueryTotalDuration(void) const
{
int64_t msec = load_markup_datum(MARK_DURATION_MS, chanid, recstartts);
return msec * 1000;
}


void ProgramInfo::SaveResolutionProperty(VideoProperty vid_flags)
{
MSqlQuery query(MSqlQuery::InitCon());
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmyth/programinfo.h
Expand Up @@ -500,6 +500,7 @@ class MPUBLIC ProgramInfo
uint QueryAverageWidth(void) const;
uint QueryAverageHeight(void) const;
uint QueryAverageFrameRate(void) const;
int64_t QueryTotalDuration(void) const;
QString QueryRecordingGroup(void) const;
bool QueryMarkupFlag(MarkTypes type) const;
uint QueryTranscoderID(void) const;
Expand All @@ -521,6 +522,7 @@ class MPUBLIC ProgramInfo
void SaveAspect(uint64_t frame, MarkTypes type, uint customAspect);
void SaveResolution(uint64_t frame, uint width, uint height);
void SaveFrameRate(uint64_t frame, uint framerate);
void SaveTotalDuration(int64_t duration);
void SaveResolutionProperty(VideoProperty vid_flags);
void SaveMarkupFlag(MarkTypes type) const;
void ClearMarkupFlag(MarkTypes type) const { ClearMarkupMap(type); }
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmyth/programtypes.h
Expand Up @@ -62,6 +62,7 @@ typedef enum {
MARK_VIDEO_WIDTH = 30,
MARK_VIDEO_HEIGHT = 31,
MARK_VIDEO_RATE = 32,
MARK_DURATION_MS = 33,
} MarkTypes;
MPUBLIC QString toString(MarkTypes type);

Expand Down
17 changes: 15 additions & 2 deletions mythtv/libs/libmythtv/avformatdecoder.cpp
Expand Up @@ -990,8 +990,21 @@ int AvFormatDecoder::OpenFile(RingBuffer *rbuffer, bool novideo,
}
}

// If watching pre-recorded television or video use ffmpeg duration
int64_t dur = ic->duration / (int64_t)AV_TIME_BASE;
// If watching pre-recorded television or video use the marked duration
// from the db if it exists, else ffmpeg duration
int64_t dur = 0;

if (m_playbackinfo)
{
dur = m_playbackinfo->QueryTotalDuration();
dur /= 1000000;
}

if (dur == 0)
{
dur = ic->duration / (int64_t)AV_TIME_BASE;
}

if (dur > 0 && !livetv && !watchingrecording)
{
m_parent->SetDuration((int)dur);
Expand Down
8 changes: 8 additions & 0 deletions mythtv/libs/libmythtv/decoderbase.cpp
Expand Up @@ -1171,4 +1171,12 @@ int to_track_type(const QString &str)
return ret;
}

void DecoderBase::SaveTotalDuration(void)
{
if (!m_playbackinfo || !totalDuration)
return;

m_playbackinfo->SaveTotalDuration(totalDuration);
}

/* vim: set expandtab tabstop=4 shiftwidth=4: */
3 changes: 3 additions & 0 deletions mythtv/libs/libmythtv/decoderbase.h
Expand Up @@ -198,6 +198,9 @@ class DecoderBase
virtual bool SetAudioByComponentTag(int) { return false; }
virtual bool SetVideoByComponentTag(int) { return false; }

void SaveTotalDuration(void);
void ResetTotalDuration(void) { totalDuration = 0; }

protected:
virtual int AutoSelectTrack(uint type);
inline void AutoSelectTracks(void);
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/mythcommflagplayer.cpp
Expand Up @@ -178,6 +178,8 @@ bool MythCommFlagPlayer::RebuildSeekTable(
fflush( stdout );
}

SaveTotalDuration();

SetPlaying(false);
killdecoder = true;

Expand Down
16 changes: 16 additions & 0 deletions mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -4679,6 +4679,22 @@ void MythPlayer::SetOSDStatus(const QString &title, OSDTimeout timeout)
osd->SetValues("osd_status", info.values, timeout);
}

void MythPlayer::SaveTotalDuration(void)
{
if (!decoder)
return;

decoder->SaveTotalDuration();
}

void MythPlayer::ResetTotalDuration(void)
{
if (!decoder)
return;

decoder->ResetTotalDuration();
}

static unsigned dbg_ident(const MythPlayer *player)
{
static QMutex dbg_lock;
Expand Down
3 changes: 3 additions & 0 deletions mythtv/libs/libmythtv/mythplayer.h
Expand Up @@ -291,6 +291,9 @@ class MPUBLIC MythPlayer
// Public picture controls
void ToggleStudioLevels(void);

void SaveTotalDuration(void);
void ResetTotalDuration(void);

protected:
// Initialization
void OpenDummy(void);
Expand Down
7 changes: 7 additions & 0 deletions mythtv/libs/libmythtv/recorderbase.cpp
Expand Up @@ -376,5 +376,12 @@ void RecorderBase::FrameRateChange(uint framerate, long long frame)
curRecording->SaveFrameRate(frame, framerate);
}

void RecorderBase::SetDuration(uint64_t duration)
{
if (curRecording)
curRecording->SaveTotalDuration(duration);
}



/* vim: set expandtab tabstop=4 shiftwidth=4: */
4 changes: 4 additions & 0 deletions mythtv/libs/libmythtv/recorderbase.h
Expand Up @@ -257,6 +257,10 @@ class MPUBLIC RecorderBase
*/
void FrameRateChange(uint framerate, long long frame);

/** \brief Note the total duration in the recordedmark table
*/
void SetDuration(uint64_t duration);

TVRec *tvrec;
RingBuffer *ringBuffer;
bool weMadeBuffer;
Expand Down
5 changes: 5 additions & 0 deletions mythtv/libs/libmythtv/recordinginfo.cpp
Expand Up @@ -1057,6 +1057,11 @@ void RecordingInfo::FinishedRecording(bool prematurestop)
{
recstatus = rsRecorded;

uint starttime = recstartts.toTime_t();
uint endtime = recendts.toTime_t();
int64_t duration = ((int64_t)endtime - (int64_t)starttime) * 1000000;
SaveTotalDuration(duration);

QString msg = "Finished recording";
QString msg_subtitle = subtitle.isEmpty() ? "" :
QString(" \"%1\"").arg(subtitle);
Expand Down
2 changes: 2 additions & 0 deletions mythtv/programs/mythcommflag/ClassicCommDetector.cpp
Expand Up @@ -397,6 +397,8 @@ bool ClassicCommDetector::go()

emit breathe();

player->ResetTotalDuration();

while (!player->GetEof())
{
struct timeval startTime;
Expand Down
7 changes: 7 additions & 0 deletions mythtv/programs/mythcommflag/CommDetector2.cpp
Expand Up @@ -599,6 +599,8 @@ bool CommDetector2::go(void)
QTime passTime, clock;
struct timeval getframetime;

player->ResetTotalDuration();

if (searchingForLogo(logoFinder, *currentPass))
emit statusUpdate(QObject::tr("Performing Logo Identification"));

Expand Down Expand Up @@ -716,6 +718,11 @@ bool CommDetector2::go(void)
player->DiscardVideoFrame(currentFrame);
}

// Save total duration only on the last pass, which hopefully does
// no skipping.
if (passno + 1 == npasses)
player->SaveTotalDuration();

currentPass->insert(currentPass->end(),
finishedAnalyzers.begin(),
finishedAnalyzers.end());
Expand Down
2 changes: 2 additions & 0 deletions mythtv/programs/mythcommflag/main.cpp
Expand Up @@ -627,6 +627,8 @@ static int DoFlagCommercials(

if (result)
{
cfp->SaveTotalDuration();

frm_dir_map_t commBreakList;
commDetector->GetCommercialBreakList(commBreakList);
comms_found = commBreakList.size() / 2;
Expand Down

0 comments on commit 5366399

Please sign in to comment.