diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index 5e93d4f..f4f0d27 100644
--- a/mythtv/libs/libmythtv/mythplayer.cpp
+++ b/mythtv/libs/libmythtv/mythplayer.cpp
@@ -3514,7 +3514,7 @@ bool MythPlayer::IsReallyNearEnd(void) const
 
 /** \brief Returns true iff near end of recording.
  */
-bool MythPlayer::IsNearEnd(void)
+bool MythPlayer::IsNearEnd(bool allowVideo)
 {
     uint64_t framesRead, framesLeft = 0;
 
@@ -3522,7 +3522,7 @@ bool MythPlayer::IsNearEnd(void)
         return false;
 
     player_ctx->LockPlayingInfo(__FILE__, __LINE__);
-    if (!player_ctx->playingInfo || player_ctx->playingInfo->IsVideo() ||
+    if (!player_ctx->playingInfo || (player_ctx->playingInfo->IsVideo() && !allowVideo) ||
         !decoder)
     {
         player_ctx->UnlockPlayingInfo(__FILE__, __LINE__);
@@ -3538,11 +3538,14 @@ bool MythPlayer::IsNearEnd(void)
     framesRead = decoder->GetFramesRead();
 
     if (!player_ctx->IsPIP() &&
-        player_ctx->GetState() == kState_WatchingPreRecorded)
-    {
-        if (framesRead >= deleteMap.GetLastFrame(totalFrames))
-            return true;
-        framesLeft = (totalFrames > framesRead) ? totalFrames - framesRead : 0;
+        (player_ctx->GetState() == kState_WatchingPreRecorded ||
+         player_ctx->GetState() == kState_WatchingVideo ||
+         player_ctx->GetState() == kState_WatchingBD ||
+         player_ctx->GetState() == kState_WatchingDVD))
+    {
+        uint64_t realTotalFrames = deleteMap.GetLastFrame(totalFrames);
+        framesLeft = (realTotalFrames > framesRead) ?
+            realTotalFrames - framesRead : 0;
         return (framesLeft < (uint64_t)margin);
     }
 
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
index 28290d9..8358b47 100644
--- a/mythtv/libs/libmythtv/mythplayer.h
+++ b/mythtv/libs/libmythtv/mythplayer.h
@@ -205,7 +205,7 @@ class MTV_PUBLIC MythPlayer
     bool    IsPlaying(uint wait_ms = 0, bool wait_for = true) const;
     bool    AtNormalSpeed(void) const         { return next_normal_speed; }
     bool    IsReallyNearEnd(void) const;
-    bool    IsNearEnd(void);
+    bool    IsNearEnd(bool allowVideo = false);
     bool    HasAudioOut(void) const           { return audio.HasAudioOut(); }
     bool    IsPIPActive(void) const           { return pip_active; }
     bool    IsPIPVisible(void) const          { return pip_visible; }
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
index 036c276..bd330bd 100644
--- a/mythtv/libs/libmythtv/tv_play.cpp
+++ b/mythtv/libs/libmythtv/tv_play.cpp
@@ -3185,15 +3185,18 @@ void TV::PrepToSwitchToRecordedProgram(PlayerContext *ctx,
     SetExitPlayer(true, true);
 }
 
-void TV::PrepareToExitPlayer(PlayerContext *ctx, int line, bool bookmark)
+void TV::PrepareToExitPlayer(PlayerContext *ctx, int line, BookmarkAction bookmark)
 {
-    bool bookmark_it = bookmark && IsBookmarkAllowed(ctx);
+    bool bm_basic = (bookmark == kBookmarkAlways ||
+                     (bookmark == kBookmarkAuto && db_playback_exit_prompt == 2));
+    bool bookmark_it = bm_basic && IsBookmarkAllowed(ctx);
     ctx->LockDeletePlayer(__FILE__, line);
     if (ctx->player)
     {
-        if (bookmark_it && (!(ctx->player->IsNearEnd()) ||
-                            StateIsRecording(GetState(ctx))))
-            SetBookmark(ctx);
+        if (bookmark_it)
+            SetBookmark(ctx,
+                        (ctx->player->IsNearEnd(true) || getEndOfRecording())
+                        && !StateIsRecording(GetState(ctx)));
         if (db_auto_set_watched)
             ctx->player->SetWatched();
     }
@@ -3261,7 +3264,7 @@ void TV::HandleEndOfPlaybackTimerEvent(void)
         if (mctx == ctx)
         {
             endOfRecording = true;
-            PrepareToExitPlayer(mctx, __LINE__, false);
+            PrepareToExitPlayer(mctx, __LINE__);
             SetExitPlayer(true, true);
         }
     }
@@ -4213,7 +4216,7 @@ bool TV::ActiveHandleAction(PlayerContext *ctx,
     }
     else if (has_action(ACTION_STOP, actions))
     {
-        PrepareToExitPlayer(ctx, __LINE__, false);
+        PrepareToExitPlayer(ctx, __LINE__);
         SetExitPlayer(true, true);
     }
     else if (has_action(ACTION_EXITSHOWNOPROMPTS, actions))
@@ -4269,7 +4272,7 @@ bool TV::ActiveHandleAction(PlayerContext *ctx,
                 ShowOSDStopWatchingRecording(ctx);
                 return handled;
             }
-            PrepareToExitPlayer(ctx, __LINE__, db_playback_exit_prompt == 2);
+            PrepareToExitPlayer(ctx, __LINE__);
             requestDelete = false;
             do_exit = true;
         }
@@ -8803,8 +8806,7 @@ void TV::customEvent(QEvent *e)
         for (uint i = 0; mctx && (i < player.size()); i++)
         {
             PlayerContext *ctx = GetPlayer(mctx, i);
-            PrepareToExitPlayer(ctx, __LINE__, db_playback_exit_prompt == 1 ||
-                                               db_playback_exit_prompt == 2);
+            PrepareToExitPlayer(ctx, __LINE__);
         }
 
         SetExitPlayer(true, true);
@@ -9954,7 +9956,7 @@ void TV::OSDDialogEvent(int result, QString text, QString action)
         DoTogglePause(actx, true);
     else if (action == ACTION_STOP)
     {
-        PrepareToExitPlayer(actx, __LINE__, false);
+        PrepareToExitPlayer(actx, __LINE__);
         SetExitPlayer(true, true);
     }
     else if (action == ACTION_JUMPFFWD)
@@ -12203,7 +12205,7 @@ bool TV::HandleOSDVideoExit(PlayerContext *ctx, QString action)
     }
     else if (action == "SAVEPOSITIONANDEXIT" && bookmark_ok)
     {
-        PrepareToExitPlayer(ctx, __LINE__);
+        PrepareToExitPlayer(ctx, __LINE__, kBookmarkAlways);
         SetExitPlayer(true, true);
     }
     else if (action == "KEEPWATCHING" && !near_end)
diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h
index adce496..de46302 100644
--- a/mythtv/libs/libmythtv/tv_play.h
+++ b/mythtv/libs/libmythtv/tv_play.h
@@ -309,8 +309,13 @@ class MTV_PUBLIC TV : public QObject
     void setUnderNetworkControl(bool setting) { underNetworkControl = setting; }
     void PrepToSwitchToRecordedProgram(PlayerContext*,
                                        const ProgramInfo &);
+    enum BookmarkAction {
+        kBookmarkAlways,
+        kBookmarkNever,
+        kBookmarkAuto // set iff db_playback_exit_prompt==2
+    };
     void PrepareToExitPlayer(PlayerContext*, int line,
-                             bool bookmark = true);
+                             BookmarkAction bookmark = kBookmarkAuto);
     void SetExitPlayer(bool set_it, bool wants_to);
 
     bool RequestNextRecorder(PlayerContext *, bool);
