MythTV  master
mythplayereditorui.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 
3 // MythTV
6 #include "tv_actions.h"
7 #include "tv_play.h"
8 #include "mythplayereditorui.h"
9 
10 #define LOC QString("Editor: ")
11 
13  : MythPlayerVisualiserUI(MainWindow, Tv, Context, Flags)
14 {
15  qRegisterMetaType<MythEditorState>();
16 
17  // Connect incoming TV signals
18  connect(Tv, &TV::EnableEdit, this, &MythPlayerEditorUI::EnableEdit);
21 
22  // New state
24 }
25 
27 {
28  LOG(VB_GENERAL, LOG_INFO, LOC + "Initialising editor");
30 }
31 
32 void MythPlayerEditorUI::RefreshEditorState(bool CheckSaved /*=false*/)
33 {
34  auto frame = GetFramesPlayed();
35  emit EditorStateChanged({
36  frame,
37  m_deleteMap.GetNearestMark(frame, false),
38  m_deleteMap.GetNearestMark(frame, true),
40  m_deleteMap.IsInDelete(frame),
47  CheckSaved ? m_deleteMap.IsSaved() : false });
48 }
49 
51 {
52  m_deleteMap.SetEditing(false);
53 
55  {
56  LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot edit - no full position map");
57  SetOSDStatus(tr("No Seektable"), kOSDTimeout_Med);
58  return;
59  }
60 
62  return;
63 
64  QMutexLocker locker(&m_osdLock);
66 
68  m_tcWrap[TC_AUDIO] = 0ms;
69 
72  m_deleteMap.SetEditing(true);
73  m_osd.DialogQuit();
74  ResetCaptions();
75  m_osd.HideAll();
76 
77  bool loadedAutoSave = m_deleteMap.LoadAutoSaveMap();
78  if (loadedAutoSave)
79  UpdateOSDMessage(tr("Using previously auto-saved cuts"), kOSDTimeout_Short);
80 
84  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
87  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
88  m_editUpdateTimer.start();
89 }
90 
98 {
99  QMutexLocker locker(&m_osdLock);
100  m_deleteMap.SetEditing(false, &m_osd);
101  if (HowToSave == 0)
103  // Unconditionally save to remove temporary marks from the DB.
104  if (HowToSave >= 0)
108  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
111  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
112  ClearAudioGraph();
115 
116  if (!m_pausedBeforeEdit)
118  else
119  SetOSDStatus(tr("Paused"), kOSDTimeout_None);
120 }
121 
123 {
124  if (qFuzzyCompare(m_deleteMap.GetSeekAmount() + 1000.0F, 1000.0F -2.0F))
125  {
126  uint64_t framenum = m_deleteMap.GetNearestMark(m_framesPlayed, Direction);
127  if (Direction && (framenum > m_framesPlayed))
129  else if (!Direction && (m_framesPlayed > framenum))
131  }
132  else
133  {
134  if (Direction)
136  else
138  }
139 }
140 
141 bool MythPlayerEditorUI::HandleProgramEditorActions(const QStringList& Actions)
142 {
143  bool handled = false;
144  bool refresh = true;
145  auto frame = GetFramesPlayed();
146 
147  for (int i = 0; i < Actions.size() && !handled; i++)
148  {
149  static constexpr float FFREW_MULTICOUNT { 10.0F };
150  const QString& action = Actions[i];
151  handled = true;
152  float seekamount = m_deleteMap.GetSeekAmount();
153  bool seekzero = qFuzzyCompare(seekamount + 1.0F, 1.0F);
154  if (action == ACTION_LEFT)
155  {
156  if (seekzero) // 1 frame
157  {
159  }
160  else if (seekamount > 0)
161  {
162  // Use fully-accurate seeks for less than 1 second.
163  DoRewindSecs(seekamount, seekamount < 1.0F ? kInaccuracyNone :
164  kInaccuracyEditor, false);
165  }
166  else
167  {
168  HandleArbSeek(false);
169  }
170  }
171  else if (action == ACTION_RIGHT)
172  {
173  if (seekzero) // 1 frame
174  {
176  }
177  else if (seekamount > 0)
178  {
179  // Use fully-accurate seeks for less than 1 second.
180  DoFastForwardSecs(seekamount, seekamount < 1.0F ? kInaccuracyNone :
181  kInaccuracyEditor, false);
182  }
183  else
184  {
185  HandleArbSeek(true);
186  }
187  }
188  else if (action == ACTION_LOADCOMMSKIP)
189  {
190  if (m_commBreakMap.HasMap())
191  {
192  frm_dir_map_t map;
193  m_commBreakMap.GetMap(map);
195  }
196  }
197  else if (action == ACTION_PREVCUT)
198  {
199  float old_seekamount = m_deleteMap.GetSeekAmount();
201  HandleArbSeek(false);
202  m_deleteMap.SetSeekAmount(old_seekamount);
203  }
204  else if (action == ACTION_NEXTCUT)
205  {
206  float old_seekamount = m_deleteMap.GetSeekAmount();
208  HandleArbSeek(true);
209  m_deleteMap.SetSeekAmount(old_seekamount);
210  }
211  else if (action == ACTION_BIGJUMPREW)
212  {
213  if (seekzero)
214  DoRewind(FFREW_MULTICOUNT, kInaccuracyNone);
215  else if (seekamount > 0)
216  DoRewindSecs(seekamount * FFREW_MULTICOUNT, kInaccuracyEditor, false);
217  else
218  DoRewindSecs(FFREW_MULTICOUNT / 2, kInaccuracyNone, false);
219  }
220  else if (action == ACTION_BIGJUMPFWD)
221  {
222  if (seekzero)
223  DoFastForward(FFREW_MULTICOUNT, kInaccuracyNone);
224  else if (seekamount > 0)
225  DoFastForwardSecs(seekamount * FFREW_MULTICOUNT, kInaccuracyEditor, false);
226  else
227  DoFastForwardSecs(FFREW_MULTICOUNT / 2, kInaccuracyNone, false);
228  }
229  else if (action == ACTION_SELECT)
230  {
231  m_deleteMap.NewCut(frame);
232  UpdateOSDMessage(tr("New cut added."), kOSDTimeout_Short);
233  refresh = true;
234  }
235  else if (action == "DELETE")
236  {
237  m_deleteMap.Delete(frame, tr("Delete"));
238  refresh = true;
239  }
240  else if (action == "REVERT")
241  {
242  m_deleteMap.LoadMap(tr("Undo Changes"));
243  refresh = true;
244  }
245  else if (action == "REVERTEXIT")
246  {
247  DisableEdit(0);
248  refresh = false;
249  }
250  else if (action == ACTION_SAVEMAP)
251  {
253  refresh = true;
254  }
255  else if (action == "EDIT" || action == "SAVEEXIT")
256  {
257  DisableEdit(1);
258  refresh = false;
259  }
260  else
261  {
262  QString undoMessage = m_deleteMap.GetUndoMessage();
263  QString redoMessage = m_deleteMap.GetRedoMessage();
264  handled = m_deleteMap.HandleAction(action, frame);
265  if (handled && (action == "CUTTOBEGINNING" || action == "CUTTOEND" || action == "NEWCUT"))
266  UpdateOSDMessage(tr("New cut added."), kOSDTimeout_Short);
267  else if (handled && action == "UNDO")
268  UpdateOSDMessage(tr("Undo - %1").arg(undoMessage), kOSDTimeout_Short);
269  else if (handled && action == "REDO")
270  UpdateOSDMessage(tr("Redo - %1").arg(redoMessage), kOSDTimeout_Short);
271  }
272  }
273 
274  if (handled && refresh)
275  {
276  m_osdLock.lock();
278  m_osdLock.unlock();
279  }
280 
281  return handled;
282 }
283 
284 bool MythPlayerEditorUI::DoFastForwardSecs(float Seconds, double Inaccuracy, bool UseCutlist)
285 {
286  float current = ComputeSecs(m_framesPlayed, UseCutlist);
287  uint64_t targetFrame = FindFrame(current + Seconds, UseCutlist);
288  return DoFastForward(targetFrame - m_framesPlayed, Inaccuracy);
289 }
290 
291 bool MythPlayerEditorUI::DoRewindSecs(float Seconds, double Inaccuracy, bool UseCutlist)
292 {
293  float target = std::max(0.0F, ComputeSecs(m_framesPlayed, UseCutlist) - Seconds);
294  uint64_t targetFrame = FindFrame(target, UseCutlist);
295  return DoRewind(m_framesPlayed - targetFrame, Inaccuracy);
296 }
MythPlayerVisualiserUI
Definition: mythplayervisualiserui.h:8
mythplayereditorui.h
DeleteMap::SaveMap
void SaveMap(bool isAutoSave=false)
Saves the delete map to the database.
Definition: deletemap.cpp:773
TVPlaybackState::RefreshEditorState
void RefreshEditorState(bool CheckSaved=false)
TVPlaybackState::EnableEdit
void EnableEdit()
MythPlayerEditorUI::m_speedBeforeEdit
float m_speedBeforeEdit
Definition: mythplayereditorui.h:31
ProgramInfo::SaveEditing
void SaveEditing(bool edit)
Sets "editing" field in "recorded" table to "edit".
Definition: programinfo.cpp:3130
PlayerContext::UnlockPlayingInfo
void UnlockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:245
MythPlayer::GetTotalFrameCount
uint64_t GetTotalFrameCount(void) const
Definition: mythplayer.h:143
MythPlayer::m_commBreakMap
CommBreakMap m_commBreakMap
Definition: mythplayer.h:482
MythPlayerAudioUI::SetupAudioGraph
void SetupAudioGraph(double VideoFrameRate)
Definition: mythplayeraudioui.cpp:91
DeleteMap::TrackerReset
void TrackerReset(uint64_t frame)
Resets the internal state tracker.
Definition: deletemap.cpp:806
MythPlayerEditorUI::DisableEdit
void DisableEdit(int HowToSave)
Leave cutlist edit mode, saving work in 1 of 3 ways.
Definition: mythplayereditorui.cpp:97
MythPlayer::m_playSpeed
float m_playSpeed
Definition: mythplayer.h:495
DeleteMap::LoadAutoSaveMap
bool LoadAutoSaveMap(void)
Returns true if an auto-save map was loaded.
Definition: deletemap.cpp:753
MythPlayerAudioUI::ClearAudioGraph
void ClearAudioGraph()
Definition: mythplayeraudioui.cpp:99
DeleteMap::GetNearestMark
uint64_t GetNearestMark(uint64_t frame, bool right, bool *hasMark=nullptr) const
Returns the next or previous mark.
Definition: deletemap.cpp:610
MythPlayer::m_savedAudioTimecodeOffset
std::chrono::milliseconds m_savedAudioTimecodeOffset
Definition: mythplayer.h:509
ACTION_LEFT
static constexpr const char * ACTION_LEFT
Definition: mythuiactions.h:18
DeleteMap::SetFileEditing
void SetFileEditing(bool edit)
Update the editing status in the file's ProgramInfo.
Definition: deletemap.cpp:234
frm_dir_map_t
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:119
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
OSD::HideAll
void HideAll(bool KeepSubs=true, MythScreenType *Except=nullptr, bool DropNotification=false)
Definition: osd.cpp:94
CommBreakMap::GetMap
void GetMap(frm_dir_map_t &map) const
Definition: commbreakmap.cpp:91
ACTION_PREVCUT
#define ACTION_PREVCUT
Definition: tv_actions.h:91
ACTION_LOADCOMMSKIP
#define ACTION_LOADCOMMSKIP
Definition: tv_actions.h:89
PlayerFlags
PlayerFlags
Definition: mythplayer.h:65
MythPlayer::Pause
bool Pause(void)
Definition: mythplayer.cpp:155
kOSDTimeout_None
@ kOSDTimeout_None
Definition: osd.h:58
ACTION_SELECT
static constexpr const char * ACTION_SELECT
Definition: mythuiactions.h:15
MythPlayerOverlayUI::SetOSDStatus
void SetOSDStatus(const QString &Title, OSDTimeout Timeout)
Definition: mythplayeroverlayui.cpp:90
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
DeleteMap::SetEditing
void SetEditing(bool edit, OSD *osd=nullptr)
Set the edit mode and optionally hide the edit mode OSD.
Definition: deletemap.cpp:226
DeleteMap::GetUndoMessage
QString GetUndoMessage(void) const
Definition: deletemap.cpp:74
MythPlayer::kInaccuracyNone
static const double kInaccuracyNone
Definition: mythplayer.h:242
MythPlayerOverlayUI::UpdateOSDMessage
void UpdateOSDMessage(const QString &Message)
Definition: mythplayeroverlayui.cpp:76
MythPlayer::GetFramesPlayed
uint64_t GetFramesPlayed(void) const
Definition: mythplayer.h:145
MythPlayer::ComputeSecs
float ComputeSecs(uint64_t position, bool use_cutlist) const
Definition: mythplayer.h:275
ACTION_BIGJUMPREW
#define ACTION_BIGJUMPREW
Definition: tv_actions.h:92
DeleteMap::SetSeekAmount
void SetSeekAmount(float amount)
Definition: deletemap.h:35
MythPlayer::m_framesPlayed
uint64_t m_framesPlayed
Definition: mythplayer.h:431
mythlogging.h
PlayerContext::m_playingInfo
ProgramInfo * m_playingInfo
Currently playing info.
Definition: playercontext.h:121
tv_actions.h
MythPlayer::m_tcWrap
tctype_arr m_tcWrap
Definition: mythplayer.h:508
DeleteMap::NewCut
void NewCut(uint64_t frame)
Add a new cut marker (to start or end a cut region)
Definition: deletemap.cpp:394
ACTION_NEXTCUT
#define ACTION_NEXTCUT
Definition: tv_actions.h:90
PlayerContext::LockPlayingInfo
void LockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:233
MythPlayer::FindFrame
uint64_t FindFrame(float offset, bool use_cutlist) const
Definition: mythplayer.cpp:1756
MythPlayerEditorUI::MythPlayerEditorUI
MythPlayerEditorUI(MythMainWindow *MainWindow, TV *Tv, PlayerContext *Context, PlayerFlags Flags)
Definition: mythplayereditorui.cpp:12
MythPlayer::m_hasFullPositionMap
bool m_hasFullPositionMap
Definition: mythplayer.h:413
MythPlayerEditorUI::HandleArbSeek
void HandleArbSeek(bool Direction)
Definition: mythplayereditorui.cpp:122
DeleteMap::IsInDelete
bool IsInDelete(uint64_t frame) const
Returns true if the given frame is deemed to be within a region that should be cut.
Definition: deletemap.cpp:570
kOSDTimeout_Short
@ kOSDTimeout_Short
Definition: osd.h:59
DeleteMap::LoadMap
void LoadMap(const QString &undoMessage="")
Loads the delete map from the database.
Definition: deletemap.cpp:737
MythPlayer::m_videoFrameRate
double m_videoFrameRate
Video (input) Frame Rate (often inaccurate)
Definition: mythplayer.h:442
MythPlayer::m_playerCtx
PlayerContext * m_playerCtx
Definition: mythplayer.h:373
MythPlayerEditorUI::DoRewindSecs
bool DoRewindSecs(float Seconds, double Inaccuracy, bool UseCutlist)
Definition: mythplayereditorui.cpp:291
DeleteMap::IsFileEditing
bool IsFileEditing(void)
Determines whether the file is currently in edit mode.
Definition: deletemap.cpp:246
DeleteMap::LoadCommBreakMap
void LoadCommBreakMap(frm_dir_map_t &map)
Loads the given commercial break map into the deleteMap.
Definition: deletemap.cpp:726
DeleteMap::HasRedo
bool HasRedo(void) const
Definition: deletemap.h:87
MythPlayerOverlayUI::m_osd
OSD m_osd
Definition: mythplayeroverlayui.h:45
MythPlayer::m_deleteMap
DeleteMap m_deleteMap
Definition: mythplayer.h:485
TVPlaybackState::DisableEdit
void DisableEdit(int HowToSave)
MythPlayer::DoFastForward
bool DoFastForward(uint64_t frames, double inaccuracy)
Definition: mythplayer.cpp:1588
MythPlayerEditorUI::InitialiseState
void InitialiseState() override
Definition: mythplayereditorui.cpp:26
MythPlayerCaptionsUI::ResetCaptions
void ResetCaptions()
Definition: mythplayercaptionsui.cpp:120
DeleteMap::IsSaved
bool IsSaved(void) const
Compares the current cut list with the saved cut list.
Definition: deletemap.cpp:872
MythPlayerEditorUI::RefreshEditorState
void RefreshEditorState(bool CheckSaved=false)
Definition: mythplayereditorui.cpp:32
ACTION_SAVEMAP
#define ACTION_SAVEMAP
Definition: tv_actions.h:88
MythPlayerVisualiserUI::InitialiseState
void InitialiseState() override
Set initial state and update player.
Definition: mythplayervisualiserui.cpp:39
ACTION_RIGHT
static constexpr const char * ACTION_RIGHT
Definition: mythuiactions.h:19
DeleteMap::Delete
void Delete(uint64_t frame, const QString &undoMessage)
Remove the mark at the given frame.
Definition: deletemap.cpp:361
MythPlayerOverlayUI::m_osdLock
QRecursiveMutex m_osdLock
Definition: mythplayeroverlayui.h:49
TC_AUDIO
@ TC_AUDIO
Definition: mythplayer.h:58
MythPlayerEditorUI::m_editUpdateTimer
QElapsedTimer m_editUpdateTimer
Definition: mythplayereditorui.h:30
MythPlayer::kInaccuracyEditor
static const double kInaccuracyEditor
Definition: mythplayer.h:244
MythPlayerEditorUI::m_pausedBeforeEdit
bool m_pausedBeforeEdit
Definition: mythplayereditorui.h:32
MythPlayerEditorUI::EnableEdit
void EnableEdit()
Definition: mythplayereditorui.cpp:50
OSD::DialogQuit
void DialogQuit()
Definition: osd.cpp:717
LOC
#define LOC
Definition: mythplayereditorui.cpp:10
PlayerContext
Definition: playercontext.h:53
DeleteMap::HasTemporaryMark
bool HasTemporaryMark(void) const
Returns true if a temporary placeholder mark is defined.
Definition: deletemap.cpp:642
build_compdb.action
action
Definition: build_compdb.py:9
MythPlayerEditorUI::DoFastForwardSecs
bool DoFastForwardSecs(float Seconds, double Inaccuracy, bool UseCutlist)
Definition: mythplayereditorui.cpp:284
ACTION_BIGJUMPFWD
#define ACTION_BIGJUMPFWD
Definition: tv_actions.h:93
MythPlayer::kInaccuracyFull
static const double kInaccuracyFull
Definition: mythplayer.h:245
mythuiactions.h
MythPlayerEditorUI::HandleProgramEditorActions
bool HandleProgramEditorActions(const QStringList &Actions)
Definition: mythplayereditorui.cpp:141
DeleteMap::HasUndo
bool HasUndo(void) const
Definition: deletemap.h:86
DeleteMap::IsTemporaryMark
bool IsTemporaryMark(uint64_t frame) const
Returns true if the given frame is a temporary/placeholder mark.
Definition: deletemap.cpp:595
CommBreakMap::HasMap
bool HasMap(void) const
Definition: commbreakmap.h:29
DeleteMap::GetSeekAmount
float GetSeekAmount(void) const
Definition: deletemap.h:33
DeleteMap::HandleAction
bool HandleAction(const QString &action, uint64_t frame)
Definition: deletemap.cpp:86
TVPlaybackState::EditorStateChanged
void EditorStateChanged(const MythEditorState &EditorState)
Definition: tvplaybackstate.cpp:53
MythPlayer::DoRewind
bool DoRewind(uint64_t frames, double inaccuracy)
Definition: mythplayer.cpp:1405
kOSDTimeout_Med
@ kOSDTimeout_Med
Definition: osd.h:60
MythPlayerEditorUI::EditorStateChanged
void EditorStateChanged(const MythEditorState &EditorState)
DeleteMap::UpdateOSD
void UpdateOSD(uint64_t frame, double frame_rate, OSD *osd)
Show and update the edit mode On Screen Display.
Definition: deletemap.cpp:177
MythMainWindow
Definition: mythmainwindow.h:28
DeleteMap::UpdateSeekAmount
void UpdateSeekAmount(int change)
Definition: deletemap.cpp:137
MythPlayer::Play
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
Definition: mythplayer.cpp:188
DeleteMap::GetRedoMessage
QString GetRedoMessage(void) const
Definition: deletemap.cpp:80
tv_play.h
TV
Control TV playback.
Definition: tv_play.h:154