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"
9
10#define LOC QString("Editor: ")
11
13 : MythPlayerVisualiserUI(MainWindow, Tv, Context, Flags)
14{
15 qRegisterMetaType<MythEditorState>();
16
17 // Connect incoming TV signals
21
22 // New state
24}
25
27{
28 LOG(VB_GENERAL, LOG_INFO, LOC + "Initialising editor");
30}
31
32void MythPlayerEditorUI::RefreshEditorState(bool CheckSaved /*=false*/)
33{
34 auto frame = GetFramesPlayed();
36 frame,
37 m_deleteMap.GetNearestMark(frame, false),
38 m_deleteMap.GetNearestMark(frame, true),
47 CheckSaved ? m_deleteMap.IsSaved() : false });
48}
49
51{
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
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);
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__);
115
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
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
155 if (action == ACTION_LEFT)
156 {
157 if (seekzero) // 1 frame
158 {
160 }
161 else if (seekamount > 0)
162 {
163 // Use fully-accurate seeks for seek amounts less than 6 seconds.
164 auto accuracy = seekamount < 6.0F ? kInaccuracyNone : kInaccuracyEditor;
165 DoRewindSecs(seekamount, accuracy, false);
166 }
167 else
168 {
169 HandleArbSeek(false);
170 }
171 }
172 else if (action == ACTION_RIGHT)
173 {
174 if (seekzero) // 1 frame
175 {
177 }
178 else if (seekamount > 0)
179 {
180 // Use fully-accurate seeks for seek amounts less than 6 seconds.
181 auto accuracy = seekamount < 6.0F ? kInaccuracyNone : kInaccuracyEditor;
182 DoFastForwardSecs(seekamount, accuracy, false);
183 }
184 else
185 {
186 HandleArbSeek(true);
187 }
188 }
189 else if (action == ACTION_LOADCOMMSKIP)
190 {
192 {
193 frm_dir_map_t map;
196 }
197 }
198 else if (action == ACTION_PREVCUT)
199 {
200 float old_seekamount = m_deleteMap.GetSeekAmount();
202 HandleArbSeek(false);
203 m_deleteMap.SetSeekAmount(old_seekamount);
204 }
205 else if (action == ACTION_NEXTCUT)
206 {
207 float old_seekamount = m_deleteMap.GetSeekAmount();
209 HandleArbSeek(true);
210 m_deleteMap.SetSeekAmount(old_seekamount);
211 }
212 else if (action == ACTION_BIGJUMPREW)
213 {
214 if (seekzero)
215 DoRewind(FFREW_MULTICOUNT, kInaccuracyNone);
216 else if (seekamount > 0)
217 DoRewindSecs(seekamount * FFREW_MULTICOUNT, kInaccuracyEditor, false);
218 else
219 DoRewindSecs(FFREW_MULTICOUNT / 2, kInaccuracyNone, false);
220 }
221 else if (action == ACTION_BIGJUMPFWD)
222 {
223 if (seekzero)
224 DoFastForward(FFREW_MULTICOUNT, kInaccuracyNone);
225 else if (seekamount > 0)
226 DoFastForwardSecs(seekamount * FFREW_MULTICOUNT, kInaccuracyEditor, false);
227 else
228 DoFastForwardSecs(FFREW_MULTICOUNT / 2, kInaccuracyNone, false);
229 }
230 else if (action == ACTION_SELECT)
231 {
232 m_deleteMap.NewCut(frame);
233 UpdateOSDMessage(tr("New cut added."), kOSDTimeout_Short);
234 refresh = true;
235 }
236 else if (action == "DELETE")
237 {
238 m_deleteMap.Delete(frame, tr("Delete"));
239 refresh = true;
240 }
241 else if (action == "REVERT")
242 {
243 m_deleteMap.LoadMap(tr("Undo Changes"));
244 refresh = true;
245 }
246 else if (action == "REVERTEXIT")
247 {
248 DisableEdit(0);
249 refresh = false;
250 }
251 else if (action == ACTION_SAVEMAP)
252 {
254 refresh = true;
255 }
256 else if (action == "EDIT" || action == "SAVEEXIT")
257 {
258 DisableEdit(1);
259 refresh = false;
260 }
261 else
262 {
263 QString undoMessage = m_deleteMap.GetUndoMessage();
264 QString redoMessage = m_deleteMap.GetRedoMessage();
265 handled = m_deleteMap.HandleAction(action, frame);
266 if (handled && (action == "CUTTOBEGINNING" || action == "CUTTOEND" || action == "NEWCUT"))
267 UpdateOSDMessage(tr("New cut added."), kOSDTimeout_Short);
268 else if (handled && action == "UNDO")
269 UpdateOSDMessage(tr("Undo - %1").arg(undoMessage), kOSDTimeout_Short);
270 else if (handled && action == "REDO")
271 UpdateOSDMessage(tr("Redo - %1").arg(redoMessage), kOSDTimeout_Short);
272 }
273 }
274
275 if (handled && refresh)
276 {
277 m_osdLock.lock();
279 m_osdLock.unlock();
280 }
281
282 return handled;
283}
284
285bool MythPlayerEditorUI::DoFastForwardSecs(float Seconds, double Inaccuracy, bool UseCutlist)
286{
287 float current = ComputeSecs(m_framesPlayed, UseCutlist);
288 uint64_t targetFrame = FindFrame(current + Seconds, UseCutlist);
289 return DoFastForward(targetFrame - m_framesPlayed, Inaccuracy);
290}
291
292bool MythPlayerEditorUI::DoRewindSecs(float Seconds, double Inaccuracy, bool UseCutlist)
293{
294 float target = std::max(0.0F, ComputeSecs(m_framesPlayed, UseCutlist) - Seconds);
295 uint64_t targetFrame = FindFrame(target, UseCutlist);
296 return DoRewind(m_framesPlayed - targetFrame, Inaccuracy);
297}
bool HasMap(void) const
Definition: commbreakmap.h:25
void GetMap(frm_dir_map_t &map) const
bool HasTemporaryMark(void) const
Returns true if a temporary placeholder mark is defined.
Definition: deletemap.cpp:647
void UpdateOSD(uint64_t frame, double frame_rate, OSD *osd)
Show and update the edit mode On Screen Display.
Definition: deletemap.cpp:177
bool IsTemporaryMark(uint64_t frame) const
Returns true if the given frame is a temporary/placeholder mark.
Definition: deletemap.cpp:600
void NewCut(uint64_t frame)
Add a new cut marker (to start or end a cut region)
Definition: deletemap.cpp:397
float GetSeekAmount(void) const
Definition: deletemap.h:34
void TrackerReset(uint64_t frame)
Resets the internal state tracker.
Definition: deletemap.cpp:811
bool HandleAction(const QString &action, uint64_t frame)
Definition: deletemap.cpp:87
void SetFileEditing(bool edit)
Update the editing status in the file's ProgramInfo.
Definition: deletemap.cpp:234
void SaveMap(bool isAutoSave=false)
Saves the delete map to the database.
Definition: deletemap.cpp:778
void UpdateSeekAmount(int change)
Definition: deletemap.cpp:140
uint64_t GetNearestMark(uint64_t frame, bool right, bool *hasMark=nullptr) const
Returns the next or previous mark.
Definition: deletemap.cpp:615
bool LoadAutoSaveMap(void)
Returns true if an auto-save map was loaded.
Definition: deletemap.cpp:758
void LoadCommBreakMap(frm_dir_map_t &map)
Loads the given commercial break map into the deleteMap.
Definition: deletemap.cpp:731
QString GetRedoMessage(void) const
Definition: deletemap.cpp:81
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:575
QString GetUndoMessage(void) const
Definition: deletemap.cpp:75
bool IsSaved(void) const
Compares the current cut list with the saved cut list.
Definition: deletemap.cpp:879
void Delete(uint64_t frame, const QString &undoMessage)
Remove the mark at the given frame.
Definition: deletemap.cpp:364
void SetSeekAmount(float amount)
Definition: deletemap.h:36
bool HasUndo(void) const
Definition: deletemap.h:87
void LoadMap(const QString &undoMessage="")
Loads the delete map from the database.
Definition: deletemap.cpp:742
bool IsFileEditing(void)
Determines whether the file is currently in edit mode.
Definition: deletemap.cpp:246
void SetEditing(bool edit, OSD *osd=nullptr)
Set the edit mode and optionally hide the edit mode OSD.
Definition: deletemap.cpp:226
bool HasRedo(void) const
Definition: deletemap.h:88
void SetupAudioGraph(double VideoFrameRate)
void RefreshEditorState(bool CheckSaved=false)
MythPlayerEditorUI(MythMainWindow *MainWindow, TV *Tv, PlayerContext *Context, PlayerFlags Flags)
bool HandleProgramEditorActions(const QStringList &Actions)
bool DoFastForwardSecs(float Seconds, double Inaccuracy, bool UseCutlist)
void EditorStateChanged(const MythEditorState &EditorState)
void HandleArbSeek(bool Direction)
void InitialiseState() override
QElapsedTimer m_editUpdateTimer
bool DoRewindSecs(float Seconds, double Inaccuracy, bool UseCutlist)
void DisableEdit(int HowToSave)
Leave cutlist edit mode, saving work in 1 of 3 ways.
void UpdateOSDMessage(const QString &Message)
void SetOSDStatus(const QString &Title, OSDTimeout Timeout)
QRecursiveMutex m_osdLock
void InitialiseState() override
Set initial state and update player.
uint64_t FindFrame(float offset, bool use_cutlist) const
static const double kInaccuracyFull
Definition: mythplayer.h:241
uint64_t GetTotalFrameCount(void) const
Definition: mythplayer.h:141
DeleteMap m_deleteMap
Definition: mythplayer.h:478
std::chrono::milliseconds m_savedAudioTimecodeOffset
Definition: mythplayer.h:497
static const double kInaccuracyNone
Definition: mythplayer.h:238
static const double kInaccuracyEditor
Definition: mythplayer.h:240
uint64_t m_framesPlayed
Definition: mythplayer.h:423
CommBreakMap m_commBreakMap
Definition: mythplayer.h:475
uint64_t GetFramesPlayed(void) const
Definition: mythplayer.h:143
float m_playSpeed
Definition: mythplayer.h:484
tctype_arr m_tcWrap
Definition: mythplayer.h:496
bool Pause(void)
Definition: mythplayer.cpp:153
float ComputeSecs(uint64_t position, bool use_cutlist) const
Definition: mythplayer.h:271
double m_videoFrameRate
Video (input) Frame Rate (often inaccurate)
Definition: mythplayer.h:435
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
Definition: mythplayer.cpp:186
bool m_hasFullPositionMap
Definition: mythplayer.h:405
PlayerContext * m_playerCtx
Definition: mythplayer.h:365
bool DoRewind(uint64_t frames, double inaccuracy)
bool DoFastForward(uint64_t frames, double inaccuracy)
void HideAll(bool KeepSubs=true, MythScreenType *Except=nullptr, bool DropNotification=false)
Definition: osd.cpp:95
void DialogQuit()
Definition: osd.cpp:720
void LockPlayingInfo(const char *file, int line) const
void UnlockPlayingInfo(const char *file, int line) const
ProgramInfo * m_playingInfo
Currently playing info.
void SaveEditing(bool edit)
Sets "editing" field in "recorded" table to "edit".
void DisableEdit(int HowToSave)
void RefreshEditorState(bool CheckSaved=false)
void EditorStateChanged(const MythEditorState &EditorState)
Control TV playback.
Definition: tv_play.h:155
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
PlayerFlags
Definition: mythplayer.h:64
@ TC_AUDIO
Definition: mythplayer.h:56
#define LOC
static constexpr const char * ACTION_LEFT
Definition: mythuiactions.h:18
static constexpr const char * ACTION_RIGHT
Definition: mythuiactions.h:19
static constexpr const char * ACTION_SELECT
Definition: mythuiactions.h:15
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
@ kOSDTimeout_Short
Definition: osd.h:59
@ kOSDTimeout_None
Definition: osd.h:58
@ kOSDTimeout_Med
Definition: osd.h:60
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:117
#define ACTION_PREVCUT
Definition: tv_actions.h:91
#define ACTION_BIGJUMPREW
Definition: tv_actions.h:92
#define ACTION_LOADCOMMSKIP
Definition: tv_actions.h:89
#define ACTION_SAVEMAP
Definition: tv_actions.h:88
#define ACTION_BIGJUMPFWD
Definition: tv_actions.h:93
#define ACTION_NEXTCUT
Definition: tv_actions.h:90