Permalink
Browse files

Provide accurate position/duration/seeking with non-constant framerates.

The recordedseek and filemarkup tables are enhanced to hold timestamp
data in addition to the existing file offset data.  The millisecond
timestamps are produced by all recorders that subclass DTVRecorder, as
well as mythtranscode and mythcommflag --rebuild.  These timestamps
are relative to the start of the recording/video.

A new command is added to the myth protocol, "QUERY_RECORDER
FILL_DURATION_MAP", modeled after FILL_POSITION_MAP, to send updated
timestamp info for playback of an in-progress recording.

The timestamp markup is used during playback to give accurate position
and duration information in the OSD wherever possible, and to provide
accurate time-based seeking, such as "skip forward 30 seconds" or
"jump to the 5-minute mark".  Timestamps are linearly interpolated
from a frame's nearest neighbors in the map, and extrapolated based on
the current frame rate when the map is missing (e.g. legacy
recordings) or incomplete (e.g. in-progress recordings).  Other than
that, the frame rate is not used for seeking or duration calculations.
(With the exception of a handful of areas that still need some
attention, including seeking based on commskipmap, seeking across
program boundaries during Live TV, and the watched flag calculation.)

The cutlist continues to be taken into account for seeking and
displaying timestamps, for the most part making cutlists
indistinguishable from the result of lossless transcoding.

Note that to get the benefit of these changes for preexisting
recordings, it may be necessary to run "mythcommflag --rebuild" on
such recordings.

Bumps the ABI and protocol versions.  "make distclean" is recommended.

Fixes #10104.
  • Loading branch information...
1 parent 1eaecea commit 49dbed5be0729b04a5f0fd0426a32fceb2dd7935 @stichnot stichnot committed Jan 1, 2013
Showing with 881 additions and 379 deletions.
  1. +2 −2 mythtv/bindings/perl/MythTV.pm
  2. +2 −2 mythtv/bindings/php/MythBackend.php
  3. +4 −2 mythtv/bindings/python/MythTV/static.py
  4. +7 −3 mythtv/libs/libmythbase/mythversion.h
  5. +0 −11 mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
  6. +0 −1 mythtv/libs/libmythtv/DVD/mythdvdplayer.h
  7. +11 −0 mythtv/libs/libmythtv/avformatdecoder.cpp
  8. +232 −6 mythtv/libs/libmythtv/decoderbase.cpp
  9. +22 −0 mythtv/libs/libmythtv/decoderbase.h
  10. +107 −136 mythtv/libs/libmythtv/deletemap.cpp
  11. +39 −37 mythtv/libs/libmythtv/deletemap.h
  12. +1 −0 mythtv/libs/libmythtv/mythcommflagplayer.cpp
  13. +162 −111 mythtv/libs/libmythtv/mythplayer.cpp
  14. +29 −7 mythtv/libs/libmythtv/mythplayer.h
  15. +7 −0 mythtv/libs/libmythtv/nuppeldecoder.cpp
  16. +36 −6 mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
  17. +4 −0 mythtv/libs/libmythtv/recorders/dtvrecorder.h
  18. +29 −0 mythtv/libs/libmythtv/recorders/recorderbase.cpp
  19. +4 −0 mythtv/libs/libmythtv/recorders/recorderbase.h
  20. +31 −4 mythtv/libs/libmythtv/remoteencoder.cpp
  21. +5 −2 mythtv/libs/libmythtv/remoteencoder.h
  22. +71 −36 mythtv/libs/libmythtv/tv_play.cpp
  23. +1 −0 mythtv/libs/libmythtv/tv_play.h
  24. +11 −0 mythtv/libs/libmythtv/tv_rec.cpp
  25. +1 −0 mythtv/libs/libmythtv/tv_rec.h
  26. +13 −0 mythtv/programs/mythbackend/encoderlink.cpp
  27. +1 −0 mythtv/programs/mythbackend/encoderlink.h
  28. +24 −2 mythtv/programs/mythbackend/mainserver.cpp
  29. +5 −5 mythtv/programs/mythtranscode/cutter.cpp
  30. +1 −1 mythtv/programs/mythtranscode/cutter.h
  31. +6 −3 mythtv/programs/mythtranscode/main.cpp
  32. +11 −0 mythtv/programs/mythtranscode/mpeg2fix.cpp
  33. +2 −2 mythtv/programs/mythtranscode/transcode.cpp
@@ -107,8 +107,8 @@ package MythTV;
# Note: as of July 21, 2010, this is actually a string, to account for proto
# versions of the form "58a". This will get used if protocol versions are
# changed on a fixes branch ongoing.
- our $PROTO_VERSION = "76";
- our $PROTO_TOKEN = "FireWilde";
+ our $PROTO_VERSION = "77";
+ our $PROTO_TOKEN = "WindMark";
# currentDatabaseVersion is defined in libmythtv in
# mythtv/libs/libmythtv/dbcheck.cpp and should be the current MythTV core
@@ -11,8 +11,8 @@ class MythBackend {
// MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h
// and should be the current MythTV protocol version.
- static $protocol_version = '76';
- static $protocol_token = 'FireWilde';
+ static $protocol_version = '77';
+ static $protocol_token = 'WindMark';
// The character string used by the backend to separate records
static $backend_separator = '[]:[]';
@@ -8,8 +8,8 @@
SCHEMA_VERSION = 1310
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1018
-PROTO_VERSION = '76'
-PROTO_TOKEN = 'FireWilde'
+PROTO_VERSION = '77'
+PROTO_TOKEN = 'WindMark'
BACKEND_SEP = '[]:[]'
INSTALL_PREFIX = '/usr/local'
@@ -34,6 +34,8 @@ class MARKUP( object ):
MARK_ASPECT_CUSTOM = 14
MARK_VIDEO_WIDTH = 30
MARK_VIDEO_HEIGHT = 31
+ MARK_VIDEO_RATE = 32
+ MARK_DURATION_MS = 33
class RECTYPE( object ):
kNotRecording = 0
@@ -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.20121227-2"
+#define MYTH_BINARY_VERSION "0.27.20121231-1"
/** \brief Increment this whenever the MythTV network protocol changes.
*
@@ -34,9 +34,13 @@
* MythTV Python Bindings
* mythtv/bindings/python/MythTV/static.py (version number)
* mythtv/bindings/python/MythTV/mythproto.py (layout)
+ *
+ * Be kind and update the wiki as well.
+ * http://www.mythtv.org/wiki/Category:Myth_Protocol_Commands
+ * http://www.mythtv.org/wiki/Category:Myth_Protocol
*/
-#define MYTH_PROTO_VERSION "76"
-#define MYTH_PROTO_TOKEN "FireWilde"
+#define MYTH_PROTO_VERSION "77"
+#define MYTH_PROTO_TOKEN "WindMark"
/** \brief Increment this whenever the MythTV core database schema changes.
*
@@ -390,17 +390,6 @@ long long MythDVDPlayer::CalcMaxFFTime(long long ff, bool setjump) const
return MythPlayer::CalcMaxFFTime(ff, setjump);
}
-int64_t MythDVDPlayer::GetSecondsPlayed(void)
-{
- if (!player_ctx->buffer->IsDVD())
- return 0;
-
- return (m_stillFrameLength > 0) ?
- (m_stillFrameTimer.elapsed() / 1000) :
- (player_ctx->buffer->DVD()->GetCurrentTime());
-
-}
-
int64_t MythDVDPlayer::GetTotalSeconds(void) const
{
return (m_stillFrameLength > 0) ? m_stillFrameLength: totalLength;
@@ -19,7 +19,6 @@ class MythDVDPlayer : public MythPlayer
// Gets
virtual uint64_t GetBookmark(void);
- virtual int64_t GetSecondsPlayed(void);
virtual int64_t GetTotalSeconds(void) const;
// DVD public stuff
@@ -2945,7 +2945,18 @@ void AvFormatDecoder::HandleGopStart(
PosMapEntry entry = {framesRead, framesRead, startpos};
QMutexLocker locker(&m_positionMapLock);
+ // Create a dummy positionmap entry for frame 0 so that
+ // seeking will work properly. (See
+ // DecoderBase::FindPosition() which subtracts
+ // DecoderBase::indexOffset from each frame number.)
+ if (m_positionMap.empty())
+ {
+ PosMapEntry dur = {0, 0, 0};
+ m_positionMap.push_back(dur);
+ }
m_positionMap.push_back(entry);
+ m_frameToDurMap[framesRead] = totalDuration / 1000;
+ m_durToFrameMap[m_frameToDurMap[framesRead]] = framesRead;
}
#if 0
Oops, something went wrong.

0 comments on commit 49dbed5

Please sign in to comment.