Skip to content

Commit

Permalink
Fix an issue with total duration in files without seektables.
Browse files Browse the repository at this point in the history
For recordings/videos without seektables, the decoder dynamically adds
keyframes to the in-memory table as it encounters them.  We don't want
to do that for the duration map since each entry represents the
cumulative time of all prior frames, and this gets messed up if
playback doesn't start at the beginning, or jumps forward or backward
at all.  The exception is mythcommflag --rebuild, which plays every
frame from start to end.
  • Loading branch information
stichnot committed Jan 4, 2013
1 parent 90a72ef commit 02bfbc9
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 4 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -12,7 +12,7 @@
/// Update this whenever the plug-in API changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods used by plug-ins.
#define MYTH_BINARY_VERSION "0.27.20130102-1"
#define MYTH_BINARY_VERSION "0.27.20130103-1"

/** \brief Increment this whenever the MythTV network protocol changes.
*
Expand Down
11 changes: 8 additions & 3 deletions mythtv/libs/libmythtv/avformatdecoder.cpp
Expand Up @@ -2956,8 +2956,11 @@ void AvFormatDecoder::HandleGopStart(
m_positionMap.push_back(dur);
}
m_positionMap.push_back(entry);
m_frameToDurMap[framesRead] = totalDuration / 1000;
m_durToFrameMap[m_frameToDurMap[framesRead]] = framesRead;
if (trackTotalDuration)
{
m_frameToDurMap[framesRead] = totalDuration / 1000;
m_durToFrameMap[m_frameToDurMap[framesRead]] = framesRead;
}
}

#if 0
Expand Down Expand Up @@ -3243,7 +3246,9 @@ bool AvFormatDecoder::PreProcessVideoPacket(AVStream *curstream, AVPacket *pkt)
if (on_frame)
framesRead++;

totalDuration += av_q2d(curstream->time_base) * pkt->duration * 1000000; // usec
if (trackTotalDuration)
totalDuration +=
av_q2d(curstream->time_base) * pkt->duration * 1000000; // usec

justAfterChange = false;

Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/decoderbase.cpp
Expand Up @@ -29,6 +29,7 @@ DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo)

framesPlayed(0), framesRead(0), totalDuration(0),
lastKey(0), keyframedist(-1), indexOffset(0),
trackTotalDuration(false),

ateof(false), exitafterdecoded(false), transcoding(false),

Expand Down
6 changes: 6 additions & 0 deletions mythtv/libs/libmythtv/decoderbase.h
Expand Up @@ -242,6 +242,7 @@ class DecoderBase
void ResetTotalDuration(void) { totalDuration = 0; }
void SaveTotalFrames(void);
bool GetVideoInverted(void) const { return video_inverted; }
void TrackTotalDuration(bool track) { trackTotalDuration = track; }

protected:
virtual int AutoSelectTrack(uint type);
Expand Down Expand Up @@ -283,6 +284,11 @@ class DecoderBase
int keyframedist;
long long indexOffset;

// The totalDuration field is only valid when the video is played
// from start to finish without any jumping. trackTotalDuration
// indicates whether this is the case.
bool trackTotalDuration;

bool ateof;
bool exitafterdecoded;
bool transcoding;
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/mythcommflagplayer.cpp
Expand Up @@ -102,6 +102,8 @@ bool MythCommFlagPlayer::RebuildSeekTable(

DecoderGetFrame(kDecodeNothing,true);

decoder->TrackTotalDuration(true);

if (showPercentage)
cout << "\r \r" << flush;

Expand Down

0 comments on commit 02bfbc9

Please sign in to comment.